public void Encrypt <TProperty>(Expression <Func <T, TProperty> > expression) { MemberExpression member = expression.Body as MemberExpression; if (member == null) { throw new ArgumentException($"Expression '{expression}' refers to a method, not a property."); } PropertyInfo propInfo = member.Member as PropertyInfo; if (propInfo == null) { throw new ArgumentException($"Expression '{expression}' refers to a field, not a property."); } if (Type != propInfo.DeclaringType && propInfo.DeclaringType != null && !Type.GetTypeInfo().IsSubclassOf(propInfo.DeclaringType)) { throw new ArgumentException( $"Expresion '{expression}' refers to a property that is not from type {Type}."); } PropertiesToEncrypt.Add(propInfo.Name); }
/// <summary> /// Encrypts all the fields in the current object based on the EncryptFieldList /// </summary> /// <returns></returns> public virtual void EncryptFields(AppConfiguration config) { if (string.IsNullOrEmpty(PropertiesToEncrypt)) { return; } MemberInfo[] mi = config.GetType().FindMembers(MemberTypes.Property | MemberTypes.Field, ReflectionUtils.MemberAccess, null, null); string encryptFieldList = "," + PropertiesToEncrypt.ToLower() + ","; foreach (MemberInfo Member in mi) { string FieldName = Member.Name.ToLower(); // Encrypt the field if in list if (encryptFieldList.Contains("," + FieldName + ",")) { object val = string.Empty; if (Member.MemberType == MemberTypes.Field) { val = ((FieldInfo)Member).GetValue(config); } else { val = ((PropertyInfo)Member).GetValue(config, null); } if (val == null || !(val is string)) { continue; } var strVal = val as string; if (string.IsNullOrEmpty(strVal)) { continue; } val = Encryption.EncryptString(strVal, EncryptionKey); if (Member.MemberType == MemberTypes.Field) { ((FieldInfo)Member).SetValue(config, val); } else { ((PropertyInfo)Member).SetValue(config, val, null); } } } }
/// <summary> /// Internally decryptes all the fields in the current object based on the EncryptFieldList /// </summary> /// <returns></returns> public virtual void DecryptFields(AppConfiguration config) { if (string.IsNullOrEmpty(PropertiesToEncrypt)) { return; } string encryptFieldList = "," + PropertiesToEncrypt.ToLower() + ","; string[] fieldTokens = encryptFieldList.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string fieldName in fieldTokens) { // Encrypt the field if in list if (encryptFieldList.Contains("," + fieldName.ToLower() + ",")) { object val = string.Empty; try { val = ReflectionUtils.GetPropertyEx(config, fieldName); } catch { throw new ArgumentException(string.Format("{0}: {1}", Resources.InvalidEncryptionPropertyName, fieldName)); } // only encrypt string values var strVal = val as string; if (string.IsNullOrEmpty(strVal)) { continue; } val = Encryption.DecryptString(strVal, EncryptionKey); try { ReflectionUtils.SetPropertyEx(config, fieldName, val); } catch { throw new ArgumentException(string.Format("{0}: {1}", Resources.InvalidEncryptionPropertyName, fieldName)); } } } }
private void WriteConfigurationValue(string keyName, string Value, MemberInfo Field, XmlDocument Dom, string ConfigSection) { string fieldsToEncrypt = "," + PropertiesToEncrypt.ToLower() + ","; // Encrypt the field if in list if (fieldsToEncrypt.IndexOf("," + Field.Name.ToLower() + ",") > -1) { Value = Encryption.EncryptString(Value, EncryptionKey); } XmlNode Node = Dom.DocumentElement.SelectSingleNode( XmlNamespacePrefix + ConfigSection + "/" + XmlNamespacePrefix + "add[@key='" + keyName + "']", XmlNamespaces); if (Node == null) { // Create the node and attributes and write it Node = Dom.CreateNode(XmlNodeType.Element, "add", Dom.DocumentElement.NamespaceURI); XmlAttribute Attr2 = Dom.CreateAttribute("key"); Attr2.Value = keyName; XmlAttribute Attr = Dom.CreateAttribute("value"); Attr.Value = Value; Node.Attributes.Append(Attr2); Node.Attributes.Append(Attr); XmlNode Parent = Dom.DocumentElement.SelectSingleNode( XmlNamespacePrefix + ConfigSection, XmlNamespaces); if (Parent == null) { Parent = CreateConfigSection(Dom, ConfigSection); } Parent.AppendChild(Node); } else { // just write the value into the attribute Node.Attributes.GetNamedItem("value").Value = Value; } }
/// <summary> /// Internally decryptes all the fields in the current object based on the EncryptFieldList /// </summary> /// <returns></returns> public virtual void DecryptFields(AppConfiguration config) { if (string.IsNullOrEmpty(PropertiesToEncrypt)) { return; } MemberInfo[] mi = config.GetType().FindMembers(MemberTypes.Property | MemberTypes.Field, ReflectionUtils.MemberAccess, null, null); string encryptFieldList = "," + PropertiesToEncrypt.ToLower() + ","; foreach (MemberInfo Member in mi) { string FieldName = Member.Name.ToLower(); // Encrypt the field if in list if (encryptFieldList.IndexOf("," + FieldName + ",") > -1) { object Value = string.Empty; if (Member.MemberType == MemberTypes.Field) { Value = ((FieldInfo)Member).GetValue(config); } else { Value = ((PropertyInfo)Member).GetValue(config, null); } Value = Encryption.DecryptString((string)Value, EncryptionKey); if (Member.MemberType == MemberTypes.Field) { ((FieldInfo)Member).SetValue(config, Value); } else { ((PropertyInfo)Member).SetValue(config, Value, null); } } } }
/// <summary> /// Reads Configuration settings from an external file or explicitly from a file. /// Uses XML DOM to read values instead of using the native APIs. /// </summary> /// <typeparam name="TAppConfiguration"></typeparam> /// <param name="config">Configuration instance</param> /// <param name="filename">Filename to read from</param> /// <returns></returns> public override bool Read(AppConfiguration config, string filename) { Type typeWebConfig = config.GetType(); MemberInfo[] Fields = typeWebConfig.GetMembers(BindingFlags.Public | BindingFlags.Instance); // Set a flag for missing fields // If we have any we'll need to write them out bool missingFields = false; XmlDocument Dom = new XmlDocument(); try { Dom.Load(filename); } catch { // Can't open or doesn't exist - so try to create it if (!Write(config)) { return(false); } // Now load again Dom.Load(filename); } // Retrieve XML Namespace information to assign default // Namespace explicitly. GetXmlNamespaceInfo(Dom); string ConfigSection = ConfigurationSection; if (ConfigSection == string.Empty) { ConfigSection = "appSettings"; } string fieldsToEncrypt = "," + PropertiesToEncrypt.ToLower() + ","; foreach (MemberInfo Member in Fields) { FieldInfo Field = null; PropertyInfo Property = null; Type FieldType = null; string TypeName = null; if (Member.MemberType == MemberTypes.Field) { Field = (FieldInfo)Member; FieldType = Field.FieldType; TypeName = Field.FieldType.Name.ToLower(); } else if (Member.MemberType == MemberTypes.Property) { Property = (PropertyInfo)Member; FieldType = Property.PropertyType; TypeName = Property.PropertyType.Name.ToLower(); } else { continue; } string Fieldname = Member.Name; if (Fieldname == "Provider" || Fieldname == "ErrorMessage") { continue; } XmlNode Section = Dom.DocumentElement.SelectSingleNode(XmlNamespacePrefix + ConfigSection, XmlNamespaces); if (Section == null) { Section = CreateConfigSection(Dom, ConfigurationSection); Dom.DocumentElement.AppendChild(Section); } string Value = GetNamedValueFromXml(Dom, Fieldname, ConfigSection); if (Value == null) { missingFields = true; continue; } Fieldname = Fieldname.ToLower(); // If we're encrypting decrypt any field that are encyrpted if (Value != string.Empty && fieldsToEncrypt.IndexOf("," + Fieldname + ",") > -1) { Value = Encryption.DecryptString(Value, EncryptionKey); } // Assign the Property ReflectionUtils.SetPropertyEx(config, Fieldname, StringToTypedValue(Value, FieldType, CultureInfo.InvariantCulture)); } // We have to write any missing keys if (missingFields) { Write(config); } return(true); }
/// <summary> /// Reads configuration settings from the current configuration manager. /// Uses the internal APIs to write these values. /// </summary> /// <typeparam name="TAppConfiguration"></typeparam> /// <param name="config"></param> /// <returns></returns> public override bool Read(AppConfiguration config) { // Config reading from external files works a bit differently // so use a separate method to handle it if (!string.IsNullOrEmpty(ConfigurationFile)) { return(Read(config, ConfigurationFile)); } Type typeWebConfig = config.GetType(); MemberInfo[] Fields = typeWebConfig.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.GetField); // Set a flag for missing fields // If we have any we'll need to write them out into .config bool missingFields = false; string fieldsToEncrypt = "," + PropertiesToEncrypt.ToLower() + ","; // Refresh the sections - req'd after write operations // sometimes sections don't want to re-read if (string.IsNullOrEmpty(ConfigurationSection)) { ConfigurationManager.RefreshSection("appSettings"); } else { ConfigurationManager.RefreshSection(ConfigurationSection); } NameValueCollection configManager; configManager = string.IsNullOrEmpty(ConfigurationSection) ? ConfigurationManager.AppSettings as NameValueCollection : ConfigurationManager.GetSection(ConfigurationSection) as NameValueCollection; if (configManager == null) { Write(config); return(true); } // Loop through all fields and properties foreach (MemberInfo Member in Fields) { FieldInfo field = null; PropertyInfo property = null; Type fieldType = null; if (Member.MemberType == MemberTypes.Field) { field = (FieldInfo)Member; fieldType = field.FieldType; } else if (Member.MemberType == MemberTypes.Property) { property = (PropertyInfo)Member; fieldType = property.PropertyType; } else { continue; } string fieldName = Member.Name.ToLower(); // Error Message is an internal public property if (fieldName == "errormessage" || fieldName == "provider") { continue; } if (!IsIList(fieldType)) { // Single value string value = configManager[fieldName]; if (value == null) { missingFields = true; continue; } // If we're encrypting decrypt any field that are encyrpted if (value != string.Empty && fieldsToEncrypt.IndexOf("," + fieldName + ",") > -1) { value = Encryption.DecryptString(value, EncryptionKey); } try { // Assign the value to the property ReflectionUtils.SetPropertyEx(config, Member.Name, StringToTypedValue(value, fieldType, CultureInfo.InvariantCulture)); } catch { } } else { // List Value var list = Activator.CreateInstance(fieldType) as IList; var elType = fieldType.GetElementType(); if (elType == null) { var generic = fieldType.GetGenericArguments(); if (generic != null && generic.Length > 0) { elType = generic[0]; } } int count = 1; string value = string.Empty; while (value != null) { value = configManager[fieldName + count]; if (value == null) { break; } list.Add(StringToTypedValue(value, elType, CultureInfo.InvariantCulture)); count++; } try { ReflectionUtils.SetPropertyEx(config, Member.Name, list); } catch { } } } // We have to write any missing keys if (missingFields) { Write(config); } return(true); }
bool IExtendedXmlSerializerConfig.CheckPropertyEncryption(string propertyName) { return(PropertiesToEncrypt.Contains(propertyName)); }
public override bool Write(AppConfiguration config) { lock (syncWriteLock) { // Load the config file into DOM parser XmlDocument Dom = new XmlDocument(); string configFile = ConfigurationFile; if (string.IsNullOrEmpty(configFile)) { configFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; } try { Dom.Load(configFile); } catch { // Can't load the file - create an empty document string Xml = @"<?xml version='1.0'?> <configuration> </configuration>" ; Dom.LoadXml(Xml); } // Load up the Namespaces object so we can // reference the appropriate default namespace GetXmlNamespaceInfo(Dom); // Parse through each of hte properties of the properties Type typeWebConfig = config.GetType(); MemberInfo[] Fields = typeWebConfig.GetMembers(BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.Public); string fieldsToEncrypt = "," + PropertiesToEncrypt.ToLower() + ","; string ConfigSection = "appSettings"; if (!string.IsNullOrEmpty(ConfigurationSection)) { ConfigSection = ConfigurationSection; } ConfigurationManager.RefreshSection(ConfigSection); foreach (MemberInfo Field in Fields) { // If we can't find the key - write it out to the document string Value = null; object RawValue = null; if (Field.MemberType == MemberTypes.Field) { RawValue = ((FieldInfo)Field).GetValue(config); } else if (Field.MemberType == MemberTypes.Property) { RawValue = ((PropertyInfo)Field).GetValue(config, null); } else { continue; // not a property or field } // Don't persist ErrorMessage property if (Field.Name == "ErrorMessage" || Field.Name == "Provider") { continue; } Value = ReflectionUtils.TypedValueToString(RawValue, CultureInfo.InvariantCulture); // Encrypt the field if in list if (fieldsToEncrypt.IndexOf("," + Field.Name.ToLower() + ",") > -1) { Value = Encryption.EncryptString(Value, EncryptionKey); } XmlNode Node = Dom.DocumentElement.SelectSingleNode( XmlNamespacePrefix + ConfigSection + "/" + XmlNamespacePrefix + "add[@key='" + Field.Name + "']", XmlNamespaces); if (Node == null) { // Create the node and attributes and write it Node = Dom.CreateNode(XmlNodeType.Element, "add", Dom.DocumentElement.NamespaceURI); XmlAttribute Attr2 = Dom.CreateAttribute("key"); Attr2.Value = Field.Name; XmlAttribute Attr = Dom.CreateAttribute("value"); Attr.Value = Value; Node.Attributes.Append(Attr2); Node.Attributes.Append(Attr); XmlNode Parent = Dom.DocumentElement.SelectSingleNode( XmlNamespacePrefix + ConfigSection, XmlNamespaces); if (Parent == null) { Parent = CreateConfigSection(Dom, ConfigSection); } Parent.AppendChild(Node); } else { // just write the value into the attribute Node.Attributes.GetNamedItem("value").Value = Value; } string XML = Node.OuterXml; } // for each try { // this will fail if permissions are not there Dom.Save(configFile); ConfigurationManager.RefreshSection(ConfigSection); } catch { return(false); } } return(true); }
/// <summary> /// Reads configuration settings from the current configuration manager. /// Uses the internal APIs to write these values. /// </summary> /// <typeparam name="TAppConfiguration"></typeparam> /// <param name="config"></param> /// <returns></returns> public override bool Read(AppConfiguration config) { // Config reading from external files works a bit differently // so use a separate method to handle it if (!string.IsNullOrEmpty(ConfigurationFile)) { return(Read(config, ConfigurationFile)); } Type typeWebConfig = config.GetType(); MemberInfo[] Fields = typeWebConfig.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.GetField); // Set a flag for missing fields // If we have any we'll need to write them out into .config bool missingFields = false; string fieldsToEncrypt = "," + PropertiesToEncrypt.ToLower() + ","; // Refresh the sections - req'd after write operations // sometimes sections don't want to re-read if (string.IsNullOrEmpty(ConfigurationSection)) { ConfigurationManager.RefreshSection("appSettings"); } else { ConfigurationManager.RefreshSection(ConfigurationSection); } // Loop through all fields and properties foreach (MemberInfo Member in Fields) { string typeName = null; FieldInfo field = null; PropertyInfo property = null; Type fieldType = null; if (Member.MemberType == MemberTypes.Field) { field = (FieldInfo)Member; fieldType = field.FieldType; typeName = fieldType.Name.ToLower(); } else if (Member.MemberType == MemberTypes.Property) { property = (PropertyInfo)Member; fieldType = property.PropertyType; typeName = fieldType.Name.ToLower(); } else { continue; } string fieldName = Member.Name.ToLower(); // Error Message is an internal public property if (fieldName == "errormessage" || fieldName == "provider") { continue; } string value = null; if (string.IsNullOrEmpty(ConfigurationSection)) { value = ConfigurationManager.AppSettings[fieldName]; } else { NameValueCollection Values = ConfigurationManager.GetSection(ConfigurationSection) as NameValueCollection; if (Values != null) { value = Values[fieldName]; } } if (value == null) { missingFields = true; continue; } // If we're encrypting decrypt any field that are encyrpted if (value != string.Empty && fieldsToEncrypt.IndexOf("," + fieldName + ",") > -1) { value = Encryption.DecryptString(value, EncryptionKey); } try { // Assign the value to the property ReflectionUtils.SetPropertyEx(config, fieldName, ReflectionUtils.StringToTypedValue(value, fieldType, CultureInfo.InvariantCulture)); } catch {; } } // We have to write any missing keys if (missingFields) { Write(config); } return(true); }