mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-02-14 20:24:57 +00:00
Added SecretsManager
Added ISecrets Added ISecretsProvider
This commit is contained in:
@@ -36,6 +36,7 @@ namespace PepperDash.Essentials
|
|||||||
Thread.MaxNumberOfUserThreads = 400;
|
Thread.MaxNumberOfUserThreads = 400;
|
||||||
Global.ControlSystem = this;
|
Global.ControlSystem = this;
|
||||||
DeviceManager.Initialize(this);
|
DeviceManager.Initialize(this);
|
||||||
|
SecretsManager.Initialize();
|
||||||
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
SystemMonitor.ProgramInitialization.ProgramInitializationUnderUserControl = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ namespace PepperDash.Essentials.Core
|
|||||||
public GenericComm(DeviceConfig config)
|
public GenericComm(DeviceConfig config)
|
||||||
: base(config)
|
: base(config)
|
||||||
{
|
{
|
||||||
|
|
||||||
PropertiesConfig = CommFactory.GetControlPropertiesConfig(config);
|
PropertiesConfig = CommFactory.GetControlPropertiesConfig(config);
|
||||||
|
|
||||||
var commPort = CommFactory.CreateCommForDevice(config);
|
var commPort = CommFactory.CreateCommForDevice(config);
|
||||||
|
|||||||
@@ -30,7 +30,19 @@ namespace PepperDash.Essentials.Core.Config
|
|||||||
|
|
||||||
[JsonProperty("properties")]
|
[JsonProperty("properties")]
|
||||||
[JsonConverter(typeof(DevicePropertiesConverter))]
|
[JsonConverter(typeof(DevicePropertiesConverter))]
|
||||||
public JToken Properties { get; set; }
|
public JToken Properties { get; set; }
|
||||||
|
|
||||||
|
public DeviceConfig(DeviceConfig dc)
|
||||||
|
{
|
||||||
|
Key = dc.Key;
|
||||||
|
Uid = dc.Uid;
|
||||||
|
Name = dc.Name;
|
||||||
|
Group = dc.Group;
|
||||||
|
Type = dc.Type;
|
||||||
|
Properties = JToken.FromObject(dc.Properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeviceConfig() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ using Crestron.SimplSharpPro;
|
|||||||
using Crestron.SimplSharpPro.GeneralIO;
|
using Crestron.SimplSharpPro.GeneralIO;
|
||||||
using Crestron.SimplSharp.Reflection;
|
using Crestron.SimplSharp.Reflection;
|
||||||
using PepperDash.Core;
|
using PepperDash.Core;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
using PepperDash.Essentials.Core;
|
using PepperDash.Essentials.Core;
|
||||||
using PepperDash.Essentials.Core.Config;
|
using PepperDash.Essentials.Core.Config;
|
||||||
using PepperDash.Essentials.Core.CrestronIO;
|
using PepperDash.Essentials.Core.CrestronIO;
|
||||||
@@ -91,24 +93,84 @@ namespace PepperDash.Essentials.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="dc"></param>
|
/// <param name="dc"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IKeyed GetDevice(DeviceConfig dc)
|
public static IKeyed GetDevice(DeviceConfig dc)
|
||||||
{
|
{
|
||||||
var key = dc.Key;
|
try
|
||||||
var name = dc.Name;
|
{
|
||||||
var type = dc.Type;
|
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
|
||||||
var properties = dc.Properties;
|
|
||||||
|
var localDc = new DeviceConfig(dc);
|
||||||
var typeName = dc.Type.ToLower();
|
|
||||||
|
var key = localDc.Key;
|
||||||
// Check for types that have been added by plugin dlls.
|
var name = localDc.Name;
|
||||||
if (FactoryMethods.ContainsKey(typeName))
|
var type = localDc.Type;
|
||||||
{
|
var properties = localDc.Properties;
|
||||||
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Loading '{0}' from Essentials Core", dc.Type);
|
|
||||||
return FactoryMethods[typeName].FactoryMethod(dc);
|
|
||||||
}
|
|
||||||
|
var typeName = localDc.Type.ToLower();
|
||||||
return null;
|
|
||||||
}
|
Debug.Console(2, "typeName = {0}", typeName);
|
||||||
|
// Check for types that have been added by plugin dlls.
|
||||||
|
if (FactoryMethods.ContainsKey(typeName))
|
||||||
|
{
|
||||||
|
//look for secret in username
|
||||||
|
var userSecretToken = properties["control"]["tcpSshProperties"]["username"]["secret"];
|
||||||
|
|
||||||
|
if (userSecretToken != null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Found a secret for {0} - attempting to retrieve it!", name);
|
||||||
|
var userSecretResult =
|
||||||
|
JsonConvert.DeserializeObject<SecretsPropertiesConfig>(userSecretToken.ToString());
|
||||||
|
var userProvider = SecretsManager.GetSecretProviderByKey(userSecretResult.Provider);
|
||||||
|
if (userProvider != null)
|
||||||
|
{
|
||||||
|
var user = userProvider.GetSecret(userSecretResult.Key);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1,
|
||||||
|
"Unable to retrieve secret for {0} - Make sure you've added it to the secrets provider");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
properties["control"]["tcpSshProperties"]["username"] = (string) user.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//look for secret in password
|
||||||
|
var passwordSecretToken = properties["control"]["tcpSshProperties"]["password"]["secret"];
|
||||||
|
|
||||||
|
if (passwordSecretToken != null)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Found a secret for {0} - attempting to retrieve it!", name);
|
||||||
|
|
||||||
|
var passwordSecretResult =
|
||||||
|
JsonConvert.DeserializeObject<SecretsPropertiesConfig>(passwordSecretToken.ToString());
|
||||||
|
var passwordProvider = SecretsManager.GetSecretProviderByKey(passwordSecretResult.Provider);
|
||||||
|
if (passwordProvider != null)
|
||||||
|
{
|
||||||
|
var password = passwordProvider.GetSecret(passwordSecretResult.Key);
|
||||||
|
if (password == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1,
|
||||||
|
"Unable to retrieve secret for {0} - Make sure you've added it to the secrets provider");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
properties["control"]["tcpSshProperties"]["password"] = (string) password.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Debug.Console(0, "{0}", localDc.Properties.ToString());
|
||||||
|
|
||||||
|
return FactoryMethods[typeName].FactoryMethod(localDc);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.Console(2, "Issue with getting device - {0}", ex.Message);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Prints the type names and associated metadata from the FactoryMethods collection.
|
/// Prints the type names and associated metadata from the FactoryMethods collection.
|
||||||
|
|||||||
@@ -320,6 +320,10 @@
|
|||||||
<Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" />
|
<Compile Include="Feedbacks\BoolFeedbackPulseExtender.cs" />
|
||||||
<Compile Include="Routing\RoutingPortNames.cs" />
|
<Compile Include="Routing\RoutingPortNames.cs" />
|
||||||
<Compile Include="Routing\TieLineConfig.cs" />
|
<Compile Include="Routing\TieLineConfig.cs" />
|
||||||
|
<Compile Include="Secrets\CrestronSecretsProvider.cs" />
|
||||||
|
<Compile Include="Secrets\Interfaces.cs" />
|
||||||
|
<Compile Include="Secrets\SecretsManager.cs" />
|
||||||
|
<Compile Include="Secrets\SecretsPropertiesConfig.cs" />
|
||||||
<Compile Include="Shades\Shade Interfaces.cs" />
|
<Compile Include="Shades\Shade Interfaces.cs" />
|
||||||
<Compile Include="Shades\ShadeBase.cs" />
|
<Compile Include="Shades\ShadeBase.cs" />
|
||||||
<Compile Include="Shades\ShadeController.cs" />
|
<Compile Include="Shades\ShadeController.cs" />
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
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 readonly bool _secureSupported;
|
||||||
|
public CrestronSecretsProvider(string key)
|
||||||
|
{
|
||||||
|
Key = key;
|
||||||
|
//Added for future encrypted reference
|
||||||
|
//_secureSupported = CrestronSecureStorage.Supported;
|
||||||
|
|
||||||
|
//if (_secureSupported)
|
||||||
|
//{
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
CrestronDataStoreStatic.InitCrestronDataStore();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void SetSecret(string key, object value)
|
||||||
|
{
|
||||||
|
var secret = value as string;
|
||||||
|
if (String.IsNullOrEmpty(secret))
|
||||||
|
{
|
||||||
|
Debug.Console(2, this, "Unable to set secret for {0}:{1} - value is empty.", Key, key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Debug.Console(2, this, "Attempting to set Secret to {0}", secret);
|
||||||
|
var setErrorCode = CrestronDataStoreStatic.SetLocalStringValue(key, secret);
|
||||||
|
switch (setErrorCode)
|
||||||
|
{
|
||||||
|
case CrestronDataStore.CDS_ERROR.CDS_SUCCESS:
|
||||||
|
Debug.Console(2, this,"Secret Successfully Set for {0}:{1}", Key, key);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, setErrorCode.ToString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
Debug.Console(2, this, "Retreived Secret = {0}", mySecret);
|
||||||
|
return new CrestronSecret(key, mySecret, this);
|
||||||
|
default:
|
||||||
|
Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}",
|
||||||
|
Key, key, getErrorCode.ToString());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public interface ISecretProvider : IKeyed
|
||||||
|
{
|
||||||
|
void SetSecret(string key, object value);
|
||||||
|
|
||||||
|
ISecret GetSecret(string key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ISecret
|
||||||
|
{
|
||||||
|
ISecretProvider Provider { get; }
|
||||||
|
string Key { get; }
|
||||||
|
object Value { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using PepperDash.Core;
|
||||||
|
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public static class SecretsManager
|
||||||
|
{
|
||||||
|
public static List<ISecretProvider> Secrets { get; set; }
|
||||||
|
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
Secrets = new List<ISecretProvider> {new CrestronSecretsProvider("default")};
|
||||||
|
|
||||||
|
CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret",
|
||||||
|
"Adds secrets to secret provider",
|
||||||
|
ConsoleAccessLevelEnum.AccessOperator);
|
||||||
|
|
||||||
|
CrestronConsole.AddNewConsoleCommand(UpdateSecretProcess, "updatesecret",
|
||||||
|
"Updates secrets in secret provider",
|
||||||
|
ConsoleAccessLevelEnum.AccessAdministrator);
|
||||||
|
|
||||||
|
CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret",
|
||||||
|
"Deletes secrets in secret provider",
|
||||||
|
ConsoleAccessLevelEnum.AccessAdministrator);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ISecretProvider GetSecretProviderByKey(string key)
|
||||||
|
{
|
||||||
|
var secret = Secrets.FirstOrDefault(o => o.Key == key);
|
||||||
|
if (secret == null)
|
||||||
|
{
|
||||||
|
Debug.Console(1, "SecretsManager unable to retrieve SecretProvider with the key '{0}'", key);
|
||||||
|
}
|
||||||
|
return secret;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SetSecretProcess(string cmd)
|
||||||
|
{
|
||||||
|
string response;
|
||||||
|
var args = cmd.Split(' ');
|
||||||
|
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
//some Instructional Text
|
||||||
|
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length == 1 && args[0] == "?")
|
||||||
|
{
|
||||||
|
response = "Adds secrets to secret provider. Format 'setsecret <provider> <secretKey> <secret>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length < 3)
|
||||||
|
{
|
||||||
|
response = "Improper number of arguments";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var provider = Secrets.FirstOrDefault(o => o.Key == args[0]);
|
||||||
|
|
||||||
|
if (provider == null)
|
||||||
|
{
|
||||||
|
//someFail
|
||||||
|
response = "Provider key invalid";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = args[1];
|
||||||
|
var secret = args[2];
|
||||||
|
|
||||||
|
if (provider.GetSecret(key) == null)
|
||||||
|
{
|
||||||
|
provider.SetSecret(key, secret);
|
||||||
|
response =
|
||||||
|
String.Format(
|
||||||
|
"Secret successfully set 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateSecretProcess(string cmd)
|
||||||
|
{
|
||||||
|
string response;
|
||||||
|
var args = cmd.Split(' ');
|
||||||
|
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
//some Instructional Text
|
||||||
|
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.Length == 1 && args[0] == "?")
|
||||||
|
{
|
||||||
|
response = "Updates secrets in secret provider. Format 'updatesecret <provider> <secretKey> <secret>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (args.Length < 3)
|
||||||
|
{
|
||||||
|
//someFail
|
||||||
|
response = "Improper number of arguments";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var provider = Secrets.FirstOrDefault(o => o.Key == args[0]);
|
||||||
|
|
||||||
|
if (provider == null)
|
||||||
|
{
|
||||||
|
//someFail
|
||||||
|
response = "Provider key invalid";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = args[1];
|
||||||
|
var secret = args[2];
|
||||||
|
|
||||||
|
if (provider.GetSecret(key) != null)
|
||||||
|
{
|
||||||
|
provider.SetSecret(key, secret);
|
||||||
|
response =
|
||||||
|
String.Format(
|
||||||
|
"Secret successfully updated for {0}:{1}",
|
||||||
|
provider.Key, key);
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
string response;
|
||||||
|
var args = cmd.Split(' ');
|
||||||
|
|
||||||
|
if (args.Length == 0)
|
||||||
|
{
|
||||||
|
//some Instructional Text
|
||||||
|
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (args.Length == 1 && args[0] == "?")
|
||||||
|
{
|
||||||
|
response = "Deletes secrets in secret provider. Format 'deletesecret <provider> <secretKey>";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (args.Length < 2)
|
||||||
|
{
|
||||||
|
//someFail
|
||||||
|
response = "Improper number of arguments";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var provider = Secrets.FirstOrDefault(o => o.Key == args[0]);
|
||||||
|
|
||||||
|
if (provider == null)
|
||||||
|
{
|
||||||
|
//someFail
|
||||||
|
response = "Provider key invalid";
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = args[1];
|
||||||
|
|
||||||
|
|
||||||
|
provider.SetSecret(key, "");
|
||||||
|
response =
|
||||||
|
String.Format(
|
||||||
|
"Secret successfully deleted for {0}:{1}",
|
||||||
|
provider.Key, key);
|
||||||
|
CrestronConsole.ConsoleCommandResponse(response);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using Crestron.SimplSharp;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace PepperDash.Essentials.Core
|
||||||
|
{
|
||||||
|
public class SecretsPropertiesConfig
|
||||||
|
{
|
||||||
|
[JsonProperty("provider")]
|
||||||
|
public string Provider { get; set; }
|
||||||
|
[JsonProperty("key")]
|
||||||
|
public string Key { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user