Compare commits

...

11 Commits

Author SHA1 Message Date
Alex Johnson
b72f0f1825 Merge 9d0020d999 into 6b7c5c01f8 2021-04-29 17:53:07 +00:00
Alex Johnson
9d0020d999 Merge branch 'development' into bugfix/discovery-routing-endless-loop 2021-04-29 13:52:36 -04:00
Alex Johnson
fb44a3b93c Resolves looping in IRouting by adding the device to the tracking list before iterating down further. Adds debug statement to print when this condition occurs - "Skipping input <device> on <router-device>, this was already checked" 2021-04-29 13:44:47 -04:00
Andrew Welker
6b7c5c01f8 Merge pull request #693 from PepperDash/hotfix/console-response-crlf-fixes
Hotfix/console response crlf fixes
2021-04-28 21:58:44 -06:00
Andrew Welker
1a3eb9a546 Merge branch 'development' into hotfix/console-response-crlf-fixes 2021-04-28 09:54:39 -06:00
Andrew Welker
44c171c8f4 Merge pull request #692 from PepperDash/hotfix/console-response-crlf-fixes
Changes cr to crlf for some console command responses
2021-04-28 09:54:24 -06:00
Alex Johnson
ae9833ffaa Changes cr to crlf for some console command responses 2021-04-23 08:58:43 -04:00
Andrew Welker
e6f5142fc3 Merge pull request #688 from PepperDash/feature/secretsManager
Feature/secrets manager
2021-04-16 12:13:38 -06:00
Trevor Payne
3c9ca1e527 Resoves #688
Added some QoL improvements to SecretsManager meant to protect the integrity of the providers dictionary from accidental manipulation

Debug statement improvements

Improvements to verbosity of console command returns for the SecretsManager
2021-04-16 12:29:41 -05:00
Trevor Payne
452d0a5a39 Changed DeviceFactory.GetSecret(SecretsPropertiesConfig data) to return an empty string instead of null on a failed retrieval 2021-04-16 09:59:58 -05:00
Andrew Welker
e12a5e95bf Merge pull request #683 from PepperDash/release/v1.8.3
add flags on both ends to prevent input switching loop
2021-04-09 16:50:44 -06:00
6 changed files with 125 additions and 62 deletions

View File

@@ -72,7 +72,7 @@ namespace PepperDash.Essentials
CrestronConsole.AddNewConsoleCommand(s =>
{
foreach (var tl in TieLineCollection.Default)
CrestronConsole.ConsoleCommandResponse(" {0}\r", tl);
CrestronConsole.ConsoleCommandResponse(" {0}\r\n", tl);
},
"listtielines", "Prints out all tie lines", ConsoleAccessLevelEnum.AccessOperator);
@@ -86,8 +86,8 @@ namespace PepperDash.Essentials
CrestronConsole.AddNewConsoleCommand(s =>
{
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r" +
"System URL: {0}\r" +
CrestronConsole.ConsoleCommandResponse("This system can be found at the following URLs:\r\n" +
"System URL: {0}\r\n" +
"Template URL: {1}", ConfigReader.ConfigObject.SystemUrl, ConfigReader.ConfigObject.TemplateUrl);
}, "portalinfo", "Shows portal URLS from configuration", ConsoleAccessLevelEnum.AccessOperator);

View File

@@ -93,7 +93,8 @@ namespace PepperDash.Essentials.Core
{
if (prop.Name.ToLower() == "secret")
{
var secret = GetSecret(JsonConvert.DeserializeObject<SecretsPropertiesConfig>(prop.Children().First().ToString()));
var secret = GetSecret(prop.Children().First().ToObject<SecretsPropertiesConfig>());
//var secret = GetSecret(JsonConvert.DeserializeObject<SecretsPropertiesConfig>(prop.Children().First().ToString()));
prop.Parent.Replace(secret);
}
var recurseProp = prop.Value as JObject;
@@ -111,7 +112,7 @@ namespace PepperDash.Essentials.Core
Debug.Console(1,
"Unable to retrieve secret {0}{1} - Make sure you've added it to the secrets provider",
data.Provider, data.Key);
return null;
return String.Empty;
}
@@ -121,8 +122,7 @@ namespace PepperDash.Essentials.Core
/// </summary>
/// <param name="dc"></param>
/// <returns></returns>
public static
IKeyed GetDevice(DeviceConfig dc)
public static IKeyed GetDevice(DeviceConfig dc)
{
try
{
@@ -153,7 +153,9 @@ namespace PepperDash.Essentials.Core
}
catch (Exception ex)
{
Debug.Console(2, "Issue with getting device - {0}", ex.Message);
Debug.Console(0, Debug.ErrorLogLevel.Error, "Exception occurred while creating device {0}: {1}", dc.Key, ex.Message);
Debug.Console(2, "{0}", ex.StackTrace);
return null;
}
}

View File

@@ -123,25 +123,34 @@ namespace PepperDash.Essentials.Core
// No direct tie? Run back out on the inputs' attached devices...
// Only the ones that are routing devices
var attachedMidpoints = destDevInputTies.Where(t => t.SourcePort.ParentDevice is IRoutingInputsOutputs);
//Create a list for tracking already checked devices to avoid loops, if it doesn't already exist from previous iteration
if (alreadyCheckedDevices == null)
alreadyCheckedDevices = new List<IRoutingInputsOutputs>();
alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs);
foreach (var inputTieToTry in attachedMidpoints)
{
Debug.Console(2, destination, "Trying to find route on {0}", inputTieToTry.SourcePort.ParentDevice.Key);
var upstreamDeviceOutputPort = inputTieToTry.SourcePort;
var upstreamRoutingDevice = upstreamDeviceOutputPort.ParentDevice as IRoutingInputsOutputs;
Debug.Console(2, destination, "Trying to find route on {0}", upstreamRoutingDevice.Key);
// Check if this previous device has already been walked
if (!(alreadyCheckedDevices != null && alreadyCheckedDevices.Contains(upstreamRoutingDevice)))
{
// haven't seen this device yet. Do it. Pass the output port to the next
// level to enable switching on success
var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
alreadyCheckedDevices, signalType, cycle, routeTable);
if (upstreamRoutingSuccess)
{
Debug.Console(2, destination, "Upstream device route found");
goodInputPort = inputTieToTry.DestinationPort;
break; // Stop looping the inputs in this cycle
}
}
if (alreadyCheckedDevices.Contains(upstreamRoutingDevice))
{
Debug.Console(2, destination, "Skipping input {0} on {1}, this was already checked", upstreamRoutingDevice.Key, destination.Key);
continue;
}
// haven't seen this device yet. Do it. Pass the output port to the next
// level to enable switching on success
var upstreamRoutingSuccess = upstreamRoutingDevice.GetRouteToSource(source, upstreamDeviceOutputPort,
alreadyCheckedDevices, signalType, cycle, routeTable);
if (upstreamRoutingSuccess)
{
Debug.Console(2, destination, "Upstream device route found");
goodInputPort = inputTieToTry.DestinationPort;
break; // Stop looping the inputs in this cycle
}
}
}
@@ -163,10 +172,6 @@ namespace PepperDash.Essentials.Core
//Debug.Console(2, destination, "Exiting cycle {0}", cycle);
return true;
}
if(alreadyCheckedDevices == null)
alreadyCheckedDevices = new List<IRoutingInputsOutputs>();
alreadyCheckedDevices.Add(destination as IRoutingInputsOutputs);
Debug.Console(2, destination, "No route found to {0}", source.Key);
return false;

View File

@@ -10,19 +10,22 @@ namespace PepperDash.Essentials.Core
{
public string Key { get; set; }
//Added for reference
//private readonly bool _secureSupported;
private static readonly bool SecureSupported;
public CrestronSecretsProvider(string key)
{
Key = key;
}
static CrestronSecretsProvider()
{
//Added for future encrypted reference
//_secureSupported = CrestronSecureStorage.Supported;
SecureSupported = CrestronSecureStorage.Supported;
//if (_secureSupported)
//{
// return;
//}
CrestronDataStoreStatic.InitCrestronDataStore();
if (SecureSupported)
{
//doThingsFuture
}
}
/// <summary>
@@ -30,23 +33,23 @@ namespace PepperDash.Essentials.Core
/// </summary>
/// <param name="key">Secret Key</param>
/// <param name="value">Secret Value</param>
public void SetSecret(string key, object value)
public bool 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;
return false;
}
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;
Debug.Console(1, this,"Secret Successfully Set for {0}:{1}", Key, key);
return true;
default:
Debug.Console(2, this, Debug.ErrorLogLevel.Notice, "Unable to set secret for {0}:{1} - {2}", Key, key, setErrorCode.ToString());
break;
return false;
}
}
@@ -68,7 +71,7 @@ namespace PepperDash.Essentials.Core
default:
Debug.Console(0, this, Debug.ErrorLogLevel.Notice, "Unable to retrieve secret for {0}:{1} - {2}",
Key, key, getErrorCode.ToString());
return new CrestronSecret(key, String.Empty, this);
return null;
}
}
}

View File

@@ -7,7 +7,7 @@ namespace PepperDash.Essentials.Core
/// </summary>
public interface ISecretProvider : IKeyed
{
void SetSecret(string key, object value);
bool SetSecret(string key, object value);
ISecret GetSecret(string key);
}

View File

@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharp;
using PepperDash.Core;
@@ -9,15 +8,16 @@ namespace PepperDash.Essentials.Core
{
public static class SecretsManager
{
public static List<ISecretProvider> Secrets { get; set; }
public static Dictionary<string, ISecretProvider> Secrets { get; private set; }
/// <summary>
/// Initialize the SecretsManager
/// </summary>
public static void Initialize()
{
Secrets = new List<ISecretProvider> {new CrestronSecretsProvider("default")};
AddSecretProvider("default", new CrestronSecretsProvider("default"));
CrestronConsole.AddNewConsoleCommand(SetSecretProcess, "setsecret",
"Adds secrets to secret provider",
ConsoleAccessLevelEnum.AccessOperator);
@@ -29,18 +29,24 @@ namespace PepperDash.Essentials.Core
CrestronConsole.AddNewConsoleCommand(DeleteSecretProcess, "deletesecret",
"Deletes secrets in secret provider",
ConsoleAccessLevelEnum.AccessAdministrator);
}
static SecretsManager()
{
Secrets = new Dictionary<string, ISecretProvider>();
}
/// <summary>
/// Method to return a ISecretProvider to Set, Get, and Delete Secrets
/// Get Secret Provider from dictionary by key
/// </summary>
/// <param name="key">Secret Provider Key</param>
/// <returns></returns>
/// <param name="key">Dictionary Key for provider</param>
/// <returns>ISecretProvider</returns>
public static ISecretProvider GetSecretProviderByKey(string key)
{
var secret = Secrets.FirstOrDefault(o => o.Key == key);
ISecretProvider secret;
Secrets.TryGetValue(key, out secret);
if (secret == null)
{
Debug.Console(1, "SecretsManager unable to retrieve SecretProvider with the key '{0}'", key);
@@ -48,6 +54,44 @@ namespace PepperDash.Essentials.Core
return secret;
}
/// <summary>
/// Add secret provider to secrets dictionary
/// </summary>
/// <param name="key">Key of new entry</param>
/// <param name="provider">New Provider Entry</param>
public static void AddSecretProvider(string key, ISecretProvider provider)
{
if (!Secrets.ContainsKey(key))
{
Secrets.Add(key, provider);
Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key);
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key );
}
/// <summary>
/// Add secret provider to secrets dictionary, with optional overwrite parameter
/// </summary>
/// <param name="key">Key of new entry</param>
/// <param name="provider">New provider entry</param>
/// <param name="overwrite">true to overwrite any existing providers in the dictionary</param>
public static void AddSecretProvider(string key, ISecretProvider provider, bool overwrite)
{
if (!Secrets.ContainsKey(key))
{
Secrets.Add(key, provider);
Debug.Console(1, "Secrets provider '{0}' added to SecretsManager", key);
}
if (overwrite)
{
Secrets.Add(key, provider);
Debug.Console(1, Debug.ErrorLogLevel.Notice, "Provider with the key '{0}' already exists in secrets. Overwriting with new secrets provider.", key);
}
Debug.Console(0, Debug.ErrorLogLevel.Notice, "Unable to add Provider '{0}' to Secrets. Provider with that key already exists", key);
}
private static void SetSecretProcess(string cmd)
{
string response;
@@ -76,7 +120,7 @@ namespace PepperDash.Essentials.Core
}
var provider = Secrets.FirstOrDefault(o => o.Key == args[0]);
var provider = GetSecretProviderByKey(args[0]);
if (provider == null)
{
@@ -92,11 +136,14 @@ namespace PepperDash.Essentials.Core
if (provider.GetSecret(key) == null)
{
provider.SetSecret(key, secret);
response =
String.Format(
response = provider.SetSecret(key, secret)
? String.Format(
"Secret successfully set for {0}:{1}",
provider.Key, key);
provider.Key, key)
: String.Format(
"Unable to set secret for {0}:{1}",
provider.Key, key);
CrestronConsole.ConsoleCommandResponse(response);
return;
}
@@ -137,7 +184,7 @@ namespace PepperDash.Essentials.Core
}
var provider = Secrets.FirstOrDefault(o => o.Key == args[0]);
var provider = GetSecretProviderByKey(args[0]);
if (provider == null)
{
@@ -153,10 +200,12 @@ namespace PepperDash.Essentials.Core
if (provider.GetSecret(key) != null)
{
provider.SetSecret(key, secret);
response =
String.Format(
"Secret successfully updated for {0}:{1}",
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;
@@ -199,7 +248,7 @@ namespace PepperDash.Essentials.Core
}
var provider = Secrets.FirstOrDefault(o => o.Key == args[0]);
var provider = GetSecretProviderByKey(args[0]);
if (provider == null)
{
@@ -214,11 +263,15 @@ namespace PepperDash.Essentials.Core
provider.SetSecret(key, "");
response =
String.Format(
response = provider.SetSecret(key, "")
? String.Format(
"Secret successfully deleted for {0}:{1}",
provider.Key, key)
: String.Format(
"Unable to delete secret for {0}:{1}",
provider.Key, key);
CrestronConsole.ConsoleCommandResponse(response);
return;
}