using System; using System.Collections.Generic; using Crestron.SimplSharp; namespace PepperDash.Core.PasswordManagement { /// /// Represents a PasswordManager /// public class PasswordManager { /// /// Public dictionary of known passwords /// public static Dictionary Passwords = new Dictionary(); /// /// Private dictionary, used when passwords are updated /// private Dictionary _passwords = new Dictionary(); /// /// Timer used to wait until password changes have stopped before updating the dictionary /// CTimer PasswordTimer; /// /// Timer length /// public long PasswordTimerElapsedMs = 5000; /// /// Boolean event /// public event EventHandler BoolChange; /// /// Ushort event /// public event EventHandler UshrtChange; /// /// String event /// public event EventHandler StringChange; /// /// Event to notify clients of an updated password at the specified index (uint) /// public static event EventHandler PasswordChange; /// /// Constructor /// public PasswordManager() { } /// /// Initialize password manager /// public void Initialize() { if (Passwords == null) Passwords = new Dictionary(); if (_passwords == null) _passwords = new Dictionary(); OnBoolChange(true, 0, PasswordManagementConstants.PasswordInitializedChange); } /// /// Updates password stored in the dictonary /// /// /// /// /// UpdatePassword method /// public void UpdatePassword(ushort key, string password) { // validate the parameters if (key > 0 && string.IsNullOrEmpty(password)) { Debug.Console(1, string.Format("PasswordManager.UpdatePassword: key [{0}] or password are not valid", key, password)); return; } try { // if key exists, update the value if(_passwords.ContainsKey(key)) _passwords[key] = password; // else add the key & value else _passwords.Add(key, password); Debug.Console(1, string.Format("PasswordManager.UpdatePassword: _password[{0}] = {1}", key, _passwords[key])); if (PasswordTimer == null) { PasswordTimer = new CTimer((o) => PasswordTimerElapsed(), PasswordTimerElapsedMs); Debug.Console(1, string.Format("PasswordManager.UpdatePassword: CTimer Started")); OnBoolChange(true, 0, PasswordManagementConstants.PasswordUpdateBusyChange); } else { PasswordTimer.Reset(PasswordTimerElapsedMs); Debug.Console(1, string.Format("PasswordManager.UpdatePassword: CTimer Reset")); } } catch (Exception e) { var msg = string.Format("PasswordManager.UpdatePassword key-value[{0}, {1}] failed:\r{2}", key, password, e); Debug.Console(1, msg); } } /// /// CTimer callback function /// private void PasswordTimerElapsed() { try { PasswordTimer.Stop(); Debug.Console(1, string.Format("PasswordManager.PasswordTimerElapsed: CTimer Stopped")); OnBoolChange(false, 0, PasswordManagementConstants.PasswordUpdateBusyChange); foreach (var pw in _passwords) { // if key exists, continue if (Passwords.ContainsKey(pw.Key)) { Debug.Console(1, string.Format("PasswordManager.PasswordTimerElapsed: pw.key[{0}] = {1}", pw.Key, pw.Value)); if (Passwords[pw.Key] != _passwords[pw.Key]) { Passwords[pw.Key] = _passwords[pw.Key]; Debug.Console(1, string.Format("PasswordManager.PasswordTimerElapsed: Updated Password[{0} = {1}", pw.Key, Passwords[pw.Key])); OnPasswordChange(Passwords[pw.Key], (ushort)pw.Key, PasswordManagementConstants.StringValueChange); } } // else add the key & value else { Passwords.Add(pw.Key, pw.Value); } } OnUshrtChange((ushort)Passwords.Count, 0, PasswordManagementConstants.PasswordManagerCountChange); } catch (Exception e) { var msg = string.Format("PasswordManager.PasswordTimerElapsed failed:\r{0}", e); Debug.Console(1, msg); } } /// /// Method to change the default timer value, (default 5000ms/5s) /// /// /// /// PasswordTimerMs method /// public void PasswordTimerMs(ushort time) { PasswordTimerElapsedMs = Convert.ToInt64(time); } /// /// Helper method for debugging to see what passwords are in the lists /// public void ListPasswords() { Debug.Console(0, "PasswordManager.ListPasswords:\r"); foreach (var pw in Passwords) Debug.Console(0, "Passwords[{0}]: {1}\r", pw.Key, pw.Value); Debug.Console(0, "\n"); foreach (var pw in _passwords) Debug.Console(0, "_passwords[{0}]: {1}\r", pw.Key, pw.Value); } /// /// Protected boolean change event handler /// /// /// /// protected void OnBoolChange(bool state, ushort index, ushort type) { var handler = BoolChange; if (handler != null) { var args = new BoolChangeEventArgs(state, type); args.Index = index; BoolChange(this, args); } } /// /// Protected ushort change event handler /// /// /// /// protected void OnUshrtChange(ushort value, ushort index, ushort type) { var handler = UshrtChange; if (handler != null) { var args = new UshrtChangeEventArgs(value, type); args.Index = index; UshrtChange(this, args); } } /// /// Protected string change event handler /// /// /// /// protected void OnStringChange(string value, ushort index, ushort type) { var handler = StringChange; if (handler != null) { var args = new StringChangeEventArgs(value, type); args.Index = index; StringChange(this, args); } } /// /// Protected password change event handler /// /// /// /// protected void OnPasswordChange(string value, ushort index, ushort type) { var handler = PasswordChange; if (handler != null) { var args = new StringChangeEventArgs(value, type); args.Index = index; PasswordChange(this, args); } } } }