diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj index c0903526..252a881e 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/PepperDash_Essentials_Core.csproj @@ -338,7 +338,9 @@ - + + + diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronGlobalSecretsProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronGlobalSecretsProvider.cs new file mode 100644 index 00000000..5adefd9e --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronGlobalSecretsProvider.cs @@ -0,0 +1,102 @@ +using System; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronDataStore; +using PepperDash.Core; + + +namespace PepperDash.Essentials.Core +{ + public class CrestronGlobalSecretsProvider : ISecretProvider + { + public string Key { get; set; } + //Added for reference + public string Description { get; private set; } + + public CrestronGlobalSecretsProvider(string key) + { + Key = key; + Description = String.Format("Default secret provider serving all local applications"); + + } + + static CrestronGlobalSecretsProvider() + { + //Added for future encrypted reference + var secureSupported = CrestronSecureStorage.Supported; + + CrestronDataStoreStatic.InitCrestronDataStore(); + if (secureSupported) + { + //doThingsFuture + } + } + + /// + /// Set secret for item in the CrestronSecretsProvider + /// + /// Secret Key + /// Secret Value + public bool SetSecret(string key, object value) + { + var secret = value as string; + CrestronDataStore.CDS_ERROR returnCode; + + if (String.IsNullOrEmpty(secret)) + { + returnCode = CrestronDataStoreStatic.clearGlobal(key); + if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS) + { + Debug.Console(0, this, "Successfully removed secret \"{0}\"", secret); + return true; + } + } + + else + { + returnCode = CrestronDataStoreStatic.SetGlobalStringValue(key, secret); + if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS) + { + Debug.Console(0, this, "Successfully set secret \"{0}\"", secret); + return true; + } + } + + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, returnCode.ToString()); + return false; + } + + /// + /// Retrieve secret for item in the CrestronSecretsProvider + /// + /// Secret Key + /// ISecret Object containing key, provider, and value + public ISecret GetSecret(string key) + { + string mySecret; + var getErrorCode = CrestronDataStoreStatic.GetGlobalStringValue(key, out mySecret); + + switch (getErrorCode) + { + case CrestronDataStore.CDS_ERROR.CDS_SUCCESS: + Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key); + return new CrestronSecret(key, mySecret, this); + default: + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}", + Key, key, getErrorCode.ToString()); + return null; + } + } + + /// + /// Determine if a secret is present within the provider without retrieving it + /// + /// Secret Key + /// bool if present + public bool TestSecret(string key) + { + string mySecret; + return CrestronDataStoreStatic.GetGlobalStringValue(key, out mySecret) == CrestronDataStore.CDS_ERROR.CDS_SUCCESS; + } + } + +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronLocalSecretsProvider.cs similarity index 65% rename from essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs rename to essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronLocalSecretsProvider.cs index 0c531a08..955c875c 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecretsProvider.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronLocalSecretsProvider.cs @@ -1,98 +1,103 @@ -using System; -using Crestron.SimplSharp; -using Crestron.SimplSharp.CrestronDataStore; -using PepperDash.Core; - - -namespace PepperDash.Essentials.Core -{ - public class CrestronSecretsProvider : ISecretProvider - { - public string Key { get; set; } - //Added for reference - private static readonly bool SecureSupported; - public CrestronSecretsProvider(string key) - { - Key = key; - } - - static CrestronSecretsProvider() - { - //Added for future encrypted reference - SecureSupported = CrestronSecureStorage.Supported; - - CrestronDataStoreStatic.InitCrestronDataStore(); - if (SecureSupported) - { - //doThingsFuture - } - } - - /// - /// Set secret for item in the CrestronSecretsProvider - /// - /// Secret Key - /// Secret Value - public bool SetSecret(string key, object value) - { - var secret = value as string; - CrestronDataStore.CDS_ERROR returnCode; - - if (String.IsNullOrEmpty(secret)) - { - returnCode = CrestronDataStoreStatic.clearLocal(key); - if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS) return true; - } - - else - { - returnCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret); - if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS) return true; - } - - Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, returnCode.ToString()); - return false; - } - - /// - /// Retrieve secret for item in the CrestronSecretsProvider - /// - /// Secret Key - /// ISecret Object containing key, provider, and value - public ISecret GetSecret(string key) - { - string mySecret; - var getErrorCode = CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret); - - switch (getErrorCode) - { - case CrestronDataStore.CDS_ERROR.CDS_SUCCESS: - Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key); - return new CrestronSecret(key, mySecret, this); - default: - Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}", - Key, key, getErrorCode.ToString()); - return null; - } - } - } - - /// - /// Special container class for CrestronSecret provider - /// - public class CrestronSecret : ISecret - { - public ISecretProvider Provider { get; private set; } - public string Key { get; private set; } - - public object Value { get; private set; } - - public CrestronSecret(string key, string value, ISecretProvider provider) - { - Key = key; - Value = value; - Provider = provider; - } - - } +using System; +using Crestron.SimplSharp; +using Crestron.SimplSharp.CrestronDataStore; +using PepperDash.Core; +using Crestron.SimplSharpPro; + + +namespace PepperDash.Essentials.Core +{ + public class CrestronLocalSecretsProvider : ISecretProvider + { + public string Key { get; set; } + //Added for reference + public string Description { get; private set; } + + + public CrestronLocalSecretsProvider(string key) + { + Key = key; + Description = String.Format("Default secret provider serving Essentials Application {0}", InitialParametersClass.ApplicationNumber); + } + + static CrestronLocalSecretsProvider() + { + //Added for future encrypted reference + var secureSupported = CrestronSecureStorage.Supported; + + CrestronDataStoreStatic.InitCrestronDataStore(); + if (secureSupported) + { + //doThingsFuture + } + } + + /// + /// Set secret for item in the CrestronSecretsProvider + /// + /// Secret Key + /// Secret Value + public bool SetSecret(string key, object value) + { + var secret = value as string; + CrestronDataStore.CDS_ERROR returnCode; + + if (String.IsNullOrEmpty(secret)) + { + returnCode = CrestronDataStoreStatic.clearLocal(key); + if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS) + { + Debug.Console(0, this, "Successfully removed secret \"{0}\"", secret); + return true; + } + } + + else + { + returnCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret); + if (returnCode == CrestronDataStore.CDS_ERROR.CDS_SUCCESS) + { + Debug.Console(0, this, "Successfully set secret \"{0}\"", secret); + return true; + } + } + + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, returnCode.ToString()); + return false; + } + + /// + /// Retrieve secret for item in the CrestronSecretsProvider + /// + /// Secret Key + /// ISecret Object containing key, provider, and value + public ISecret GetSecret(string key) + { + string mySecret; + var getErrorCode = CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret); + + switch (getErrorCode) + { + case CrestronDataStore.CDS_ERROR.CDS_SUCCESS: + Debug.Console(2, this, "Secret Successfully retrieved for {0}:{1}", Key, key); + return new CrestronSecret(key, mySecret, this); + default: + Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}", + Key, key, getErrorCode.ToString()); + return null; + } + } + + /// + /// Determine if a secret is present within the provider without retrieving it + /// + /// Secret Key + /// bool if present + public bool TestSecret(string key) + { + string mySecret; + return CrestronDataStoreStatic.GetLocalStringValue(key, out mySecret) == CrestronDataStore.CDS_ERROR.CDS_SUCCESS; + } + } + } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecret.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecret.cs new file mode 100644 index 00000000..27fbcdad --- /dev/null +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/CrestronSecret.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Crestron.SimplSharp; + +namespace PepperDash.Essentials.Core +{ + /// + /// Special container class for CrestronSecret provider + /// + public class CrestronSecret : ISecret + { + public ISecretProvider Provider { get; private set; } + public string Key { get; private set; } + + public object Value { get; private set; } + + public CrestronSecret(string key, string value, ISecretProvider provider) + { + Key = key; + Value = value; + Provider = provider; + } + + } + +} \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs index 43c6a230..e61ac208 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/Interfaces.cs @@ -7,9 +7,32 @@ namespace PepperDash.Essentials.Core /// public interface ISecretProvider : IKeyed { + /// + /// Set secret value for provider by key + /// + /// key of secret to set + /// value to set secret to + /// bool SetSecret(string key, object value); + /// + /// Return object containing secret from provider + /// + /// key of secret to retrieve + /// ISecret GetSecret(string key); + + /// + /// Verifies presence of secret + /// + /// key of secret to chek + /// + bool TestSecret(string key); + + /// + /// Description of the secrets provider + /// + string Description { get; } } /// @@ -17,8 +40,19 @@ namespace PepperDash.Essentials.Core /// public interface ISecret { + /// + /// Instance of ISecretProvider that the secret belongs to + /// ISecretProvider Provider { get; } + + /// + /// Key of the secret in the provider + /// string Key { get; } + + /// + /// Value of the secret + /// object Value { get; } } } \ No newline at end of file diff --git a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs index bcb46ff5..95a94a24 100644 --- a/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs +++ b/essentials-framework/Essentials Core/PepperDashEssentialsBase/Secrets/SecretsManager.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; +using System.Linq; using Crestron.SimplSharp; using PepperDash.Core; - namespace PepperDash.Essentials.Core { public static class SecretsManager @@ -16,18 +16,28 @@ namespace PepperDash.Essentials.Core public static void Initialize() { - AddSecretProvider("default", new CrestronSecretsProvider("default")); + AddSecretProvider("default", new CrestronLocalSecretsProvider("default")); + + AddSecretProvider("CrestronGlobalSecrets", new CrestronGlobalSecretsProvider("CrestronGlobalSecrets")); CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret", - "Adds secrets to secret provider", + "Adds secret to secrets provider", ConsoleAccessLevelEnum.AccessOperator); CrestronConsole.AddNewConsoleCommand(UpdateSecretProcess, "updatesecret", - "Updates secrets in secret provider", + "Updates secret in secrets provider", ConsoleAccessLevelEnum.AccessAdministrator); CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret", - "Deletes secrets in secret provider", + "Deletes secret from secrest provider", + ConsoleAccessLevelEnum.AccessAdministrator); + + CrestronConsole.AddNewConsoleCommand(ListProviders, "secretproviderlist", + "Return list of all valid secrets providers", + ConsoleAccessLevelEnum.AccessAdministrator); + + CrestronConsole.AddNewConsoleCommand(GetProviderInfo, "secretproviderinfo", + "Return data about secrets provider", ConsoleAccessLevelEnum.AccessAdministrator); } @@ -54,6 +64,79 @@ namespace PepperDash.Essentials.Core return secret; } + public static void GetProviderInfo(string cmd) + { + string response; + var args = cmd.Split(' '); + + if (cmd.Length == 0 || (args.Length == 1 && args[0] == "?")) + { + response = "Returns data about secrets provider. Format 'secretproviderinfo '"; + CrestronConsole.ConsoleCommandResponse(response); + return; + + } + + if (args.Length == 1) + { + var provider = GetSecretProviderByKey(args[0]); + + if (provider == null) + { + response = "Invalid secrets provider key"; + CrestronConsole.ConsoleCommandResponse(response); + return; + } + + response = String.Format("{0} : {1}", provider.Key, provider.Description); + CrestronConsole.ConsoleCommandResponse(response); + return; + } + + response = "Improper number of arguments"; + CrestronConsole.ConsoleCommandResponse(response); + + } + + + /// + /// Console Command that returns all valid secrets in the essentials program. + /// + /// + public static void ListProviders(string cmd) + { + var response = String.Empty; + var args = cmd.Split(' '); + + if (cmd.Length == 0) + { + if (Secrets != null && Secrets.Count > 0) + { + response = Secrets.Aggregate(response, + (current, secretProvider) => current + (secretProvider.Key + "\n\r")); + } + else + { + response = "No Secrets Providers Available"; + } + CrestronConsole.ConsoleCommandResponse(response); + return; + + } + + if (args.Length == 1 && args[0] == "?") + { + response = "Reports all valid and preset Secret providers"; + CrestronConsole.ConsoleCommandResponse(response); + return; + } + + + response = "Improper number of arguments"; + CrestronConsole.ConsoleCommandResponse(response); + + } + /// /// Add secret provider to secrets dictionary /// @@ -100,14 +183,14 @@ namespace PepperDash.Essentials.Core if (args.Length == 0) { //some Instructional Text - response = "Adds secrets to secret provider. Format 'setsecret "; + response = "Adds secrets to secret provider. Format 'setsecret '"; CrestronConsole.ConsoleCommandResponse(response); return; } if (args.Length == 1 && args[0] == "?") { - response = "Adds secrets to secret provider. Format 'setsecret "; + response = "Adds secrets to secret provider. Format 'setsecret '"; CrestronConsole.ConsoleCommandResponse(response); return; } @@ -134,23 +217,7 @@ namespace PepperDash.Essentials.Core var key = args[1]; var secret = args[2]; - if (provider.GetSecret(key) == null) - { - - response = provider.SetSecret(key, secret) - ? String.Format( - "Secret successfully set for {0}:{1}", - provider.Key, key) - : String.Format( - "Unable to set secret for {0}:{1}", - provider.Key, key); - CrestronConsole.ConsoleCommandResponse(response); - return; - } - response = - String.Format( - "Unable to set secret for {0}:{1} - Please use the 'UpdateSecret' command to modify it"); - CrestronConsole.ConsoleCommandResponse(response); + CrestronConsole.ConsoleCommandResponse(SetSecret(provider, key, secret)); } private static void UpdateSecretProcess(string cmd) @@ -161,7 +228,7 @@ namespace PepperDash.Essentials.Core if (args.Length == 0) { //some Instructional Text - response = "Updates secrets in secret provider. Format 'updatesecret "; + response = "Updates secrets in secret provider. Format 'updatesecret '"; CrestronConsole.ConsoleCommandResponse(response); return; @@ -169,7 +236,7 @@ namespace PepperDash.Essentials.Core if (args.Length == 1 && args[0] == "?") { - response = "Updates secrets in secret provider. Format 'updatesecret "; + response = "Updates secrets in secret provider. Format 'updatesecret '"; CrestronConsole.ConsoleCommandResponse(response); return; } @@ -198,23 +265,49 @@ namespace PepperDash.Essentials.Core var key = args[1]; var secret = args[2]; - if (provider.GetSecret(key) != null) - { - response = provider.SetSecret(key, secret) - ? String.Format( - "Secret successfully set for {0}:{1}", - provider.Key, key) - : String.Format( - "Unable to set secret for {0}:{1}", - provider.Key, key); - CrestronConsole.ConsoleCommandResponse(response); - return; - } + CrestronConsole.ConsoleCommandResponse(UpdateSecret(provider, key, secret)); + + } + + private static string UpdateSecret(ISecretProvider provider, string key, string secret) + { + var secretPresent = provider.TestSecret(key); + + Debug.Console(2, provider, "SecretsProvider {0} {1} contain a secret entry for {2}", provider.Key, secretPresent ? "does" : "does not", key); + + if (!secretPresent) + return + String.Format( + "Unable to update secret for {0}:{1} - Please use the 'SetSecret' command to modify it"); + var response = provider.SetSecret(key, secret) + ? String.Format( + "Secret successfully set for {0}:{1}", + provider.Key, key) + : String.Format( + "Unable to set secret for {0}:{1}", + provider.Key, key); + return response; + } + + private static string SetSecret(ISecretProvider provider, string key, string secret) + { + var secretPresent = provider.TestSecret(key); + + Debug.Console(2, provider, "SecretsProvider {0} {1} contain a secret entry for {2}", provider.Key, secretPresent ? "does" : "does not", key); + + if (secretPresent) + return + String.Format( + "Unable to set secret for {0}:{1} - Please use the 'UpdateSecret' command to modify it"); + var response = provider.SetSecret(key, secret) + ? String.Format( + "Secret successfully set for {0}:{1}", + provider.Key, key) + : String.Format( + "Unable to set secret for {0}:{1}", + provider.Key, key); + return response; - response = - String.Format( - "Unable to update secret for {0}:{1} - Please use the 'SetSecret' command to create a new secret"); - CrestronConsole.ConsoleCommandResponse(response); } private static void DeleteSecretProcess(string cmd) @@ -225,14 +318,14 @@ namespace PepperDash.Essentials.Core if (args.Length == 0) { //some Instructional Text - response = "Deletes secrets in secret provider. Format 'deletesecret "; + response = "Deletes secrets in secret provider. Format 'deletesecret '"; CrestronConsole.ConsoleCommandResponse(response); return; } if (args.Length == 1 && args[0] == "?") { - response = "Deletes secrets in secret provider. Format 'deletesecret "; + response = "Deletes secrets in secret provider. Format 'deletesecret '"; CrestronConsole.ConsoleCommandResponse(response); return; }