/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using Amazon.Runtime; using Amazon.Runtime.Internal.Settings; using Amazon.Runtime.Internal.Util; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; namespace Amazon.Util.Internal { /// /// Manager to access a settings store file. /// Settings store files are located under the current user's AppData\Local\AWSToolkit folder. /// Select keys in these files are encrypted on a per user, per machine basis using the Windows Data Protection API; /// the encrypted values cannot be used by any other user or on any other machine. /// /// This class is not threadsafe. /// public class SettingsManager { /// /// True if the encrypted store is availble, false otherwise. /// public static bool IsAvailable { get { return UserCrypto.IsUserCryptAvailable; } } /// /// Construct a SettingsManager. /// /// The base filename to read/write. public SettingsManager(string settingsType) { EnsureAvailable(); SettingsType = settingsType; } /// /// The base filename to read/write. /// public string SettingsType { get; private set; } /// /// Register an object. Let the uniqueKey be assigned automatically. /// /// The property names and values for the object. /// The unique key that was assigned to the object. public string RegisterObject(Dictionary properties) { return RegisterObject(null, properties); } /// /// Register an object. /// /// The uniqueKey for the object, or null if one should be assigned automatically. /// The property names and values for the object. /// The unique key that was assigned to the object. public string RegisterObject(string uniqueKey, Dictionary properties) { var settings = GetSettings(); SettingsCollection.ObjectSettings objectSettings; if (!TryGetObjectSettings(uniqueKey, settings, out objectSettings)) { string actualUniqueKey; if (string.IsNullOrEmpty(uniqueKey)) actualUniqueKey = Guid.NewGuid().ToString("D"); else actualUniqueKey = uniqueKey; objectSettings = settings.NewObjectSettings(actualUniqueKey); } foreach (var pair in properties) { if (pair.Value == null) objectSettings.Remove(pair.Key); else objectSettings[pair.Key] = pair.Value; } SaveSettings(settings); return objectSettings.UniqueKey; } /// /// Try to get an object form the store. /// /// The uniqueKey of the object in the store /// The property names and values for the object. /// True if the object was found, false otherwise. public bool TryGetObject(string uniqueKey, out Dictionary properties) { var settings = GetSettings(); SettingsCollection.ObjectSettings objectSettings; properties = null; if (TryGetObjectSettings(uniqueKey, settings, out objectSettings)) { uniqueKey = objectSettings.UniqueKey; properties = new Dictionary(); foreach (var key in objectSettings.Keys) { properties.Add(key, objectSettings[key]); } } return properties != null; } /// /// Try to get an object form the store based on the value of a specific property. /// If multiple objects with the same property value exist, return the first one. /// /// The name of the property to search on. /// The value of the property to search on. /// The unique key of the object. /// The properties of the object. /// public bool TryGetObjectByProperty(string propertyName, string value, out string uniqueKey, out Dictionary properties) { var settings = GetSettings(); SettingsCollection.ObjectSettings objectSettings; properties = null; uniqueKey = null; if (TryGetObjectSettings(propertyName, value, settings, out objectSettings)) { uniqueKey = objectSettings.UniqueKey; properties = new Dictionary(); foreach (var key in objectSettings.Keys) { properties.Add(key, objectSettings[key]); } } return properties != null; } /// /// Get a list of the unique keys of all the objects in the store. /// /// public List ListUniqueKeys() { var settings = GetSettings(); return new List(settings.Select(x => x.UniqueKey)); } /// /// Get the value of a specific property for each object in the store. /// /// /// public List SelectProperty(string propertyName) { var settings = GetSettings(); return new List(settings.Select(x => x[propertyName])); } /// /// Unregister an object from the store. /// /// The unique key for the object. public void UnregisterObject(string uniqueKey) { var settings = GetSettings(); SettingsCollection.ObjectSettings objectSettings = null; if (TryGetObjectSettings(uniqueKey, settings, out objectSettings)) { settings.Remove(objectSettings.UniqueKey); SaveSettings(settings); } } private SettingsCollection GetSettings() { return PersistenceManager.Instance.GetSettings(SettingsType); } private void SaveSettings(SettingsCollection settings) { PersistenceManager.Instance.SaveSettings(SettingsType, settings); } private static bool TryGetObjectSettings(string propertyName, string value, SettingsCollection settings, out SettingsCollection.ObjectSettings objectSettings) { objectSettings = settings.FirstOrDefault(x => string.Equals(x[propertyName], value, StringComparison.OrdinalIgnoreCase)); return objectSettings != null; } private static bool TryGetObjectSettings(string uniqueKey, SettingsCollection settings, out SettingsCollection.ObjectSettings objectSettings) { objectSettings = settings.FirstOrDefault(x => string.Equals(x.UniqueKey, uniqueKey, StringComparison.OrdinalIgnoreCase)); return objectSettings != null; } private static void EnsureAvailable() { if (!IsAvailable) { throw new AmazonClientException("The encrypted store is not available. This may be due to use of a non-Windows operating system or Windows Nano Server, or the current user account may not have its profile loaded."); } } } }