public void HistoryNoDuplicates() { TestSetup(KeyMode.Cmd); PSConsoleReadLine.SetOptions(new SetPSReadLineOption { HistoryNoDuplicates = false }); SetHistory("zzzz", "aaaa", "bbbb", "bbbb", "cccc"); Assert.Equal(5, PSConsoleReadLine.GetHistoryItems().Length); Test("aaaa", Keys(Enumerable.Repeat(_.UpArrow, 4))); // Changing the option should affect existing history. PSConsoleReadLine.SetOptions(new SetPSReadLineOption { HistoryNoDuplicates = true }); Test("zzzz", Keys(Enumerable.Repeat(_.UpArrow, 4))); SetHistory("aaaa", "bbbb", "bbbb", "cccc"); Assert.Equal(3, PSConsoleReadLine.GetHistoryItems().Length); Test("aaaa", Keys(Enumerable.Repeat(_.UpArrow, 3))); SetHistory("aaaa", "bbbb", "bbbb", "cccc"); Test("cccc", Keys( Enumerable.Repeat(_.UpArrow, 3), Enumerable.Repeat(_.DownArrow, 2))); // No history SetHistory(); Test("", Keys(_.UpArrow, _.DownArrow)); }
public void SensitiveHistoryDefaultBehavior() { TestSetup(KeyMode.Cmd); // No history SetHistory(); Test("", Keys(_.UpArrow, _.DownArrow)); var options = PSConsoleReadLine.GetOptions(); var oldHistoryFilePath = options.HistorySavePath; var oldHistorySaveStyle = options.HistorySaveStyle; // AddToHistoryHandler should be set to the default handler. Assert.Same(PSConsoleReadLineOptions.DefaultAddToHistoryHandler, options.AddToHistoryHandler); var newHistoryFilePath = Path.GetTempFileName(); var newHistorySaveStyle = HistorySaveStyle.SaveIncrementally; string[] expectedHistoryItems = new[] { "gcm c*", "ConvertTo-SecureString -AsPlainText -String abc -Force", "dir p*", "Publish-Module -NuGetApiKey abc", "ps c*", "mycommand -password abc", "echo foo", "cmd1 /token abc", "echo bar", "cmd2 --key abc", "echo zoo", "pki secret", "gcm p*" }; string[] expectedSavedItems = new[] { "gcm c*", "dir p*", "ps c*", "echo foo", "echo bar", "echo zoo", "gcm p*" }; try { options.HistorySavePath = newHistoryFilePath; options.HistorySaveStyle = newHistorySaveStyle; SetHistory(expectedHistoryItems); // Sensitive input history should be kept in the internal history queue. var historyItems = PSConsoleReadLine.GetHistoryItems(); Assert.Equal(expectedHistoryItems.Length, historyItems.Length); for (int i = 0; i < expectedHistoryItems.Length; i++) { Assert.Equal(expectedHistoryItems[i], historyItems[i].CommandLine); } // Sensitive input history should NOT be saved to the history file. string[] text = File.ReadAllLines(newHistoryFilePath); Assert.Equal(expectedSavedItems.Length, text.Length); for (int i = 0; i < text.Length; i++) { Assert.Equal(expectedSavedItems[i], text[i]); } } finally { options.HistorySavePath = oldHistoryFilePath; options.HistorySaveStyle = oldHistorySaveStyle; File.Delete(newHistoryFilePath); } }
public void SensitiveHistoryOptionalBehaviorWithScriptBlock() { TestSetup(KeyMode.Cmd); // No history SetHistory(); Test("", Keys(_.UpArrow, _.DownArrow)); var options = PSConsoleReadLine.GetOptions(); var oldHistoryFilePath = options.HistorySavePath; var oldHistorySaveStyle = options.HistorySaveStyle; // AddToHistoryHandler should be set to the default handler. Assert.Same(PSConsoleReadLineOptions.DefaultAddToHistoryHandler, options.AddToHistoryHandler); var newHistoryFilePath = Path.GetTempFileName(); var newHistorySaveStyle = HistorySaveStyle.SaveIncrementally; Func <string, object> newAddToHistoryHandler_ReturnBool = LanguagePrimitives.ConvertTo <Func <string, object> >( ScriptBlock.Create(@" param([string]$line) $line.Contains('gal')")); Func <string, object> newAddToHistoryHandler_ReturnEnum = LanguagePrimitives.ConvertTo <Func <string, object> >( ScriptBlock.Create(@" param([string]$line) if ($line.Contains('gal')) { [psobject]::AsPSObject([Microsoft.PowerShell.AddToHistoryOption]::MemoryOnly) } elseif ($line.Contains('gmo')) { 'SkipAdding' } else { [Microsoft.PowerShell.AddToHistoryOption]::MemoryAndFile }")); Func <string, object> newAddToHistoryHandler_ReturnOther = LanguagePrimitives.ConvertTo <Func <string, object> >( ScriptBlock.Create(@" param([string]$line) 'string value'")); string[] commandInputs = new[] { "gmo p*", "gcm c*", "gal dir", "ConvertTo-SecureString -AsPlainText -String abc -Force" }; string[] expectedQueuedItems = new[] { "gcm c*", "gal dir", "ConvertTo-SecureString -AsPlainText -String abc -Force" }; string[] expectedSavedItems = new[] { "gcm c*", "ConvertTo-SecureString -AsPlainText -String abc -Force" }; try { options.HistorySavePath = newHistoryFilePath; options.HistorySaveStyle = newHistorySaveStyle; // // Set null to the handler means we don't do the check. // options.AddToHistoryHandler = null; SetHistory(commandInputs); // All commands should be kept in the internal history queue. var historyItems = PSConsoleReadLine.GetHistoryItems(); Assert.Equal(commandInputs.Length, historyItems.Length); for (int i = 0; i < commandInputs.Length; i++) { Assert.Equal(commandInputs[i], historyItems[i].CommandLine); } // All commands are saved to the history file when 'ScrubSensitiveHistory' is set to 'false'. string[] text = File.ReadAllLines(newHistoryFilePath); Assert.Equal(commandInputs.Length, text.Length); for (int i = 0; i < text.Length; i++) { Assert.Equal(commandInputs[i], text[i]); } // // Use a handler that return boolean value. // true: Add to memory and file // false: Skip adding to history // options.AddToHistoryHandler = newAddToHistoryHandler_ReturnBool; // Clear the history file. File.WriteAllText(newHistoryFilePath, string.Empty); SetHistory(commandInputs); historyItems = PSConsoleReadLine.GetHistoryItems(); Assert.Single(historyItems); Assert.Equal("gal dir", historyItems[0].CommandLine); text = File.ReadAllLines(newHistoryFilePath); Assert.Single(text); Assert.Equal("gal dir", text[0]); // // Use a handler that return the expected enum type. // options.AddToHistoryHandler = newAddToHistoryHandler_ReturnEnum; File.WriteAllText(newHistoryFilePath, string.Empty); SetHistory(commandInputs); historyItems = PSConsoleReadLine.GetHistoryItems(); Assert.Equal(expectedQueuedItems.Length, historyItems.Length); for (int i = 0; i < expectedQueuedItems.Length; i++) { Assert.Equal(expectedQueuedItems[i], historyItems[i].CommandLine); } text = File.ReadAllLines(newHistoryFilePath); Assert.Equal(expectedSavedItems.Length, text.Length); for (int i = 0; i < text.Length; i++) { Assert.Equal(expectedSavedItems[i], text[i]); } // // Use a handler that return unexpected value. // - same behavior as setting the handler to null. // options.AddToHistoryHandler = newAddToHistoryHandler_ReturnOther; File.WriteAllText(newHistoryFilePath, string.Empty); SetHistory(commandInputs); historyItems = PSConsoleReadLine.GetHistoryItems(); Assert.Equal(commandInputs.Length, historyItems.Length); for (int i = 0; i < commandInputs.Length; i++) { Assert.Equal(commandInputs[i], historyItems[i].CommandLine); } // All commands are saved to the history file when 'ScrubSensitiveHistory' is set to 'false'. text = File.ReadAllLines(newHistoryFilePath); Assert.Equal(commandInputs.Length, text.Length); for (int i = 0; i < text.Length; i++) { Assert.Equal(commandInputs[i], text[i]); } } finally { options.HistorySavePath = oldHistoryFilePath; options.HistorySaveStyle = oldHistorySaveStyle; options.AddToHistoryHandler = PSConsoleReadLineOptions.DefaultAddToHistoryHandler; File.Delete(newHistoryFilePath); } }