Skip to content

Commit

Permalink
updated commands structure
Browse files Browse the repository at this point in the history
  • Loading branch information
Kevin Beier committed Apr 20, 2024
1 parent 3aa3a2d commit 2bb5c98
Show file tree
Hide file tree
Showing 14 changed files with 250 additions and 127 deletions.
11 changes: 8 additions & 3 deletions src/KeyVaultCli.Application/Cli/Commands/ExitCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,15 @@ namespace KeyVaultCli.Application.Cli.Commands;

public class ExitCommand(IConsole consoleService) : ICommand
{
string asciiExitingApplication = " _____ _ _ _ _ _ _ _ _ \n | ____|_ _(_) |_(_)_ __ __ _ / \\ _ __ _ __ | (_) ___ __ _| |_(_) ___ _ __ \n | _| \\ \\/ / | __| | '_ \\ / _` | / _ \\ | '_ \\| '_ \\| | |/ __/ _` | __| |/ _ \\| '_ \\ \n | |___ > <| | |_| | | | | (_| | / ___ \\| |_) | |_) | | | (_| (_| | |_| | (_) | | | |\n |_____/_/\\_\\_|\\__|_|_| |_|\\__, | /_/ \\_\\ .__/| .__/|_|_|\\___\\__,_|\\__|_|\\___/|_| |_|\n |___/ |_| |_| ";

private readonly string exitPrompt = "Are you sure you want to close the application?";
private readonly string asciiExitingApplication = " _____ _ _ _ _ _ _ _ _ \n | ____|_ _(_) |_(_)_ __ __ _ / \\ _ __ _ __ | (_) ___ __ _| |_(_) ___ _ __ \n | _| \\ \\/ / | __| | '_ \\ / _` | / _ \\ | '_ \\| '_ \\| | |/ __/ _` | __| |/ _ \\| '_ \\ \n | |___ > <| | |_| | | | | (_| | / ___ \\| |_) | |_) | | | (_| (_| | |_| | (_) | | | |\n |_____/_/\\_\\_|\\__|_|_| |_|\\__, | /_/ \\_\\ .__/| .__/|_|_|\\___\\__,_|\\__|_|\\___/|_| |_|\n |___/ |_| |_| ";

public void Execute()
{
consoleService.WriteError(asciiExitingApplication);
if (consoleService.GetUserConfirmation(exitPrompt))
{
consoleService.WriteError(asciiExitingApplication);
Environment.Exit(0);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,23 @@ namespace KeyVaultCli.Application.PasswordEntry.Commands.CreatePasswordEntry;

public class CreatePasswordCommand(IVault vault, IConsole consoleService) : ICommand
{
private readonly string serviceNamePrompt = "Enter service name for the new password: ";
private readonly string accountNamePrompt = "Enter account name for the new password: ";
private readonly string passwordPrompt = "Enter the password: ";
private readonly string urlPrompt = "Enter the URL (leave empty if not applicable): ";
private readonly string categoryPrompt = "Enter the category (leave empty if not applicable): ";
private readonly string successMessage = "A new password has been created and stored for {0}, {1}.";

public void Execute()
{
var serviceName = consoleService.GetInputFromPrompt("Enter service name for the new password: "); // Use the service
var accountName = consoleService.GetInputFromPrompt("Enter account name for the new password: "); // Use the service
var password = consoleService.GetInputFromPrompt("Enter the password: "); // Use the service
var url = consoleService.GetInputFromPrompt("Enter the URL (leave empty if not applicable): "); // Use the service
var category = consoleService.GetInputFromPrompt("Enter the category (leave empty if not applicable): "); // Use the service
var serviceName = consoleService.GetInputFromPrompt(serviceNamePrompt);
var accountName = consoleService.GetInputFromPrompt(accountNamePrompt);
var password = consoleService.GetInputFromPrompt(passwordPrompt);
var url = consoleService.GetInputFromPrompt(urlPrompt);
var category = consoleService.GetInputFromPrompt(categoryPrompt);

vault.AddPasswordEntry(serviceName, accountName, password, url, category);

consoleService.WriteSuccess($"A new password has been created and stored for {serviceName}, {accountName}."); // Use the service
consoleService.WriteSuccess(string.Format(successMessage, serviceName, accountName));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,43 @@ namespace KeyVaultCli.Application.PasswordEntry.Commands.CreatePasswordEntry;

public class CreatePasswordGenerateCommand(IVault vault, IConsole consoleService) : ICommand
{
private readonly string serviceNamePrompt = "Enter service name for the new password: ";
private readonly string accountNamePrompt = "Enter account name for the new password: ";
private readonly string passwordLengthPrompt = "Enter the desired password length: ";
private readonly string urlPrompt = "Enter the URL (leave empty if not applicable): ";
private readonly string categoryPrompt = "Enter the category (leave empty if not applicable): ";
private readonly string invalidLengthError = "Invalid input for password length. Ensure you enter a valid number.";
private readonly string successMessage = "A new password has been created and stored for {0}, {1} with the value {2}.";

public void Execute()
{
var serviceName = consoleService.GetInputFromPrompt("Enter service name for the new password: ");
var accountName = consoleService.GetInputFromPrompt("Enter account name for the new password: ");
var passwordLengthStr = consoleService.GetInputFromPrompt("Enter the desired password length: ");
var url = consoleService.GetInputFromPrompt("Enter the URL (leave empty if not applicable): "); // Use the service
var category = consoleService.GetInputFromPrompt("Enter the category (leave empty if not applicable): "); // Use the service
var serviceName = consoleService.GetInputFromPrompt(serviceNamePrompt);
var accountName = consoleService.GetInputFromPrompt(accountNamePrompt);
var passwordLength = GetPasswordLength();

if (!int.TryParse(passwordLengthStr, out var passwordLength))
// If the password length is not valid, abort the operation.
if (passwordLength < 1)
{
consoleService.WriteError("Invalid input for password length. Ensure you enter a valid number.");
return;
}

var url = consoleService.GetInputFromPrompt(urlPrompt);
var category = consoleService.GetInputFromPrompt(categoryPrompt);

// Generate password internally and add a password entry
var password = vault.GenerateAndAddPasswordEntry(serviceName, accountName, passwordLength, url, category);

consoleService.WriteSuccess($"A new password has been created and stored for {serviceName}, {accountName} with the value {password}.");
consoleService.WriteSuccess(string.Format(successMessage, serviceName, accountName, password));
}

private int GetPasswordLength()
{
var passwordLengthStr = consoleService.GetInputFromPrompt(passwordLengthPrompt);
if (!int.TryParse(passwordLengthStr, out var passwordLength))
{
consoleService.WriteError(invalidLengthError);
return -1;
}
return passwordLength;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,21 @@ namespace KeyVaultCli.Application.PasswordEntry.Commands.DeletePasswordEntry;

public class DeleteAllPasswordsCommand(IVault vault, IConsole consoleService) : ICommand
{
private readonly string confirmationPrompt = "Are you sure you want to delete all passwords?";
private readonly string successMessage = "All passwords have been deleted.";
private readonly string errorMessage = "Operation cancelled.";

public void Execute()
{
var confirmation = consoleService.GetInputFromPrompt("Are you sure you want to delete all passwords? (yes/no): ");
if (confirmation.ToLower() == "yes")
var confirmation = consoleService.GetUserConfirmation(confirmationPrompt);
if (confirmation)
{
vault.DeleteAllPasswordEntries();
consoleService.WriteSuccess("All passwords have been deleted.");
consoleService.WriteSuccess(successMessage);
}
else
{
consoleService.WriteError("Operation cancelled.");
consoleService.WriteError(errorMessage);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,35 @@ namespace KeyVaultCli.Application.PasswordEntry.Commands.DeletePasswordEntry;

public class DeletePasswordCommand(IVault vault, IConsole consoleService) : ICommand
{
private readonly string serviceNamePrompt = "Enter the service name for the password you want to delete: ";
private readonly string accountNamePrompt = "Enter the account name for the password you want to delete: ";
private readonly string successMessage = "Password entry has been deleted.";
private readonly string errorMessage = "Failed to delete the password entry. Ensure the service and account names are correct.";

public void Execute()
{
var serviceName = consoleService.GetInputFromPrompt("Enter the service name for the password you want to delete: ");
var accountName = consoleService.GetInputFromPrompt("Enter the account name for the password you want to delete: ");
var serviceName = GetServiceName();
var accountName = GetAccountName();

var isDeleted = vault.DeletePasswordEntry(serviceName, accountName);

if (isDeleted)
{
consoleService.WriteSuccess("Password entry has been deleted.");
consoleService.WriteSuccess(successMessage);
}
else
{
consoleService.WriteError("Failed to delete the password entry. Ensure the service and account names are correct.");
consoleService.WriteError(errorMessage);
}
}

private string GetServiceName()
{
return consoleService.GetInputFromPrompt(serviceNamePrompt);
}

private string GetAccountName()
{
return consoleService.GetInputFromPrompt(accountNamePrompt);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ public class GetAllPasswordsCommand : ICommand
private readonly IVault vault;
private readonly IConsole consoleService;
private readonly PasswordHealthService passwordHealthService;
private readonly string infoMessage = "A healthy password should be unique within the vault, at least 8 characters long, and contain at least one uppercase letter, one lowercase letter, and one digit.";
private readonly string[] headers = { "GUID", "Service Name", "Account Name", "Password (Decrypted)", "URL", "Category", "Creation Date", "Last Modified Date", "Password Health" };
private readonly string errorMessage = "No password entries found.";

public GetAllPasswordsCommand(IVault vault, IConsole consoleService)
{
Expand All @@ -20,24 +23,20 @@ public GetAllPasswordsCommand(IVault vault, IConsole consoleService)

public void Execute()
{
consoleService.WriteInfo("A healthy password should be unique within the vault, at least 8 characters long, and contain at least one uppercase letter, one lowercase letter, and one digit.");
consoleService.WriteInfo(infoMessage);

var allPasswordEntries = vault.LoadPasswordEntries();

if (allPasswordEntries.Any())
{
string[] headers = { "GUID", "Service Name", "Account Name", "Password (Decrypted)", "URL", "Category", "Creation Date", "Last Modified Date", "Password Health" };

// Transform every PasswordEntry into a List of objects
var dataRows = allPasswordEntries
.Select(entry => {
var decryptedPassword = vault.GetPassword(entry.ServiceName, entry.AccountName);
var passwordHealthResult = passwordHealthService.CheckPasswordHealthAsync(decryptedPassword).Result;

var passwordHealthDescription = passwordHealthResult.IsStrong && passwordHealthResult.IsUnique && !passwordHealthResult.IsCompromised
? "Healthy"
: "Not Healthy";

var passwordHealthDescription = GetPasswordHealthDescription(passwordHealthResult);

return new List<object>
{
entry.EntryId,
Expand All @@ -56,7 +55,14 @@ public void Execute()
}
else
{
consoleService.WriteError("No password entries found.");
consoleService.WriteError(errorMessage);
}
}

private string GetPasswordHealthDescription(PasswordHealthResult passwordHealthResult)
{
return passwordHealthResult.IsStrong && passwordHealthResult.IsUnique && !passwordHealthResult.IsCompromised
? "Healthy"
: "Not Healthy";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ public class GetPasswordCommand : ICommand
private readonly IConsole consoleService;
private readonly PasswordHealthService passwordHealthService;

private readonly string serviceNamePrompt = "Enter the service name: ";
private readonly string accountNamePrompt = "Enter the account name: ";
private readonly string errorEmptyInputMessage = "Service name and account name cannot be empty.";
private readonly string passwordInfoMessage = "Information for {0}, {1}:";
private readonly string passwordNotFoundMessage = "No password entry found for service {0}, account {1}.";
private readonly string warningMessage = "This password is not healthy. A healthy password should be at least 8 characters long, contain at least one uppercase letter, one lowercase letter, one digit and be unique inside this Vault.";
private readonly string passwordHealthyMessage = "This password is healthy.";

public GetPasswordCommand(IVault vault, IConsole consoleService)
{
this.vault = vault;
Expand All @@ -22,40 +30,54 @@ public GetPasswordCommand(IVault vault, IConsole consoleService)

public void Execute()
{
var serviceName = consoleService.GetInputFromPrompt("Enter the service name: ");
var accountName = consoleService.GetInputFromPrompt("Enter the account name: ");
var serviceName = GetServiceName();
var accountName = GetAccountName();

if (accountName == string.Empty || serviceName == string.Empty)
{
consoleService.WriteError("Service name and account name cannot be empty.");
consoleService.WriteError(errorEmptyInputMessage);
return;
}

var passwordEntry = vault.GetPasswordEntry(serviceName, accountName);

if (passwordEntry != null)
{
var decryptedPassword = vault.GetPassword(serviceName, accountName);
var passwordHealthResult = passwordHealthService.CheckPasswordHealthAsync(decryptedPassword).Result;

consoleService.WriteInfo($"Information for {serviceName}, {accountName}:");
consoleService.WriteInfo($"Password: {decryptedPassword}");
consoleService.WriteInfo($"URL: {passwordEntry.Url}");
consoleService.WriteInfo($"Category: {passwordEntry.Category}");

if (passwordHealthResult.IsStrong && passwordHealthResult.IsUnique && !passwordHealthResult.IsCompromised)
{
consoleService.WriteInfo("This password is healthy.");
}
else
{
consoleService.WriteWarning(
"This password is not healthy. A healthy password should be at least 8 characters long, contain at least one uppercase letter, one lowercase letter, one digit and be unique inside this Vault.");
}
WritePasswordInfo(passwordEntry, serviceName, accountName);
}
else
{
consoleService.WriteError(string.Format(passwordNotFoundMessage, serviceName, accountName));
}
}

private string GetServiceName()
{
return consoleService.GetInputFromPrompt(serviceNamePrompt);
}

private string GetAccountName()
{
return consoleService.GetInputFromPrompt(accountNamePrompt);
}

private void WritePasswordInfo(Domain.Entities.PasswordEntry passwordEntry, string serviceName, string accountName)
{
var decryptedPassword = vault.GetPassword(serviceName, accountName);
var passwordHealthResult = passwordHealthService.CheckPasswordHealthAsync(decryptedPassword).Result;

consoleService.WriteInfo(string.Format(passwordInfoMessage, serviceName, accountName));
consoleService.WriteInfo($"Password: {decryptedPassword}");
consoleService.WriteInfo($"URL: {passwordEntry.Url}");
consoleService.WriteInfo($"Category: {passwordEntry.Category}");

if (passwordHealthResult.IsStrong && passwordHealthResult.IsUnique && !passwordHealthResult.IsCompromised)
{
consoleService.WriteInfo(passwordHealthyMessage);
}
else
{
consoleService.WriteError($"No password entry found for service {serviceName}, account {accountName}.");
consoleService.WriteWarning(warningMessage);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,42 +5,47 @@ namespace KeyVaultCli.Application.PasswordEntry.Commands.GetPasswordEntry;

public class SearchPasswordEntriesCommand(IVault vault, IConsole consoleService) : ICommand
{
private readonly string searchPrompt = "Enter your search query: ";
private readonly string matchingEntriesMessage = "Matching search entries:";
private readonly string noEntriesFoundError = "No matching entries found.";
private readonly string[] headers = { "GUID", "Service Name", "AccountName", "Password (Decrypted)", "URL", "Category", "Creation Date", "Last Modified Date", };

public void Execute()
{
var query = consoleService.GetInputFromPrompt("Enter your search query: ");
var query = consoleService.GetInputFromPrompt(searchPrompt);

var matchingEntries = vault.SearchPasswordEntries(query);

if (matchingEntries != null && matchingEntries.Any())
{
consoleService.WriteInfo("Matching search entries:");

string[] headers = { "GUID", "Service Name", "AccountName", "Password (Decrypted)", "URL", "Category", "Creation Date", "Last Modified Date", };

// Transform every PasswordEntry into a List of objects
var dataRows = matchingEntries
.Where(entry => entry != null)
.Select(entry =>
{
var password = vault.GetPassword(entry.ServiceName, entry.AccountName);
return new List<object>
{
entry.EntryId,
entry.ServiceName,
entry.AccountName,
password != null ? password : "N/A",
entry.Url,
entry.Category,
entry.CreationDate,
entry.LastModifiedDate
};
}).ToList();

consoleService.WriteInfo(matchingEntriesMessage);
var dataRows = GetMatchingEntriesDataRows(matchingEntries);
consoleService.WriteTable(headers, dataRows);
}
else
{
consoleService.WriteError("No matching entries found.");
consoleService.WriteError(noEntriesFoundError);
}
}

private List<List<object>> GetMatchingEntriesDataRows(IEnumerable<Domain.Entities.PasswordEntry> matchingEntries)
{
return matchingEntries
.Where(entry => entry != null)
.Select(entry =>
{
var password = vault.GetPassword(entry.ServiceName, entry.AccountName);
return new List<object>
{
entry.EntryId,
entry.ServiceName,
entry.AccountName,
password != null ? password : "N/A",
entry.Url,
entry.Category,
entry.CreationDate,
entry.LastModifiedDate
};
}).ToList();
}
}
Loading

0 comments on commit 2bb5c98

Please sign in to comment.