/* * 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. Objects are primarily accessed by DisplayName rather than unique key. /// 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 NamedSettingsManager { /// /// True if the encrypted store is availble, false otherwise. /// public static bool IsAvailable { get { return UserCrypto.IsUserCryptAvailable; } } private SettingsManager settingsManager; /// /// Construct an NamedSettingsManager. /// /// The base filename to read/write. public NamedSettingsManager(string settingsType) { settingsManager = new SettingsManager(settingsType); } /// /// Register an object. Let the uniqueKey be assigned automatically. /// /// The display name for the object. /// The property names and values for the object. /// The unique key that was assigned to the object. public string RegisterObject(string displayName, Dictionary properties) { if (string.IsNullOrEmpty(displayName)) throw new ArgumentException("displayName cannot be null or empty."); var propertiesPlusName = new Dictionary(properties); propertiesPlusName[SettingsConstants.DisplayNameField] = displayName; string uniqueKey; if (settingsManager.TryGetObjectByProperty(SettingsConstants.DisplayNameField, displayName, out uniqueKey, out properties)) return settingsManager.RegisterObject(uniqueKey, propertiesPlusName); else return settingsManager.RegisterObject(propertiesPlusName); } /// /// Try to get an object form the store. /// /// The display name for the object. /// The property names and values for the object. /// True if the object was found, false otherwise. public bool TryGetObject(string displayName, out Dictionary properties) { string uniqueKey; return TryGetObject(displayName, out uniqueKey, out properties); } /// /// Try to get an object form the store. /// /// The display name for the object. /// 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 displayName, out string uniqueKey, out Dictionary properties) { return settingsManager.TryGetObjectByProperty(SettingsConstants.DisplayNameField, displayName, out uniqueKey, out properties); } /// /// Unregister an object from the store. /// /// The display name for the object. public void UnregisterObject(string displayName) { string uniqueKey; Dictionary properties; if (settingsManager.TryGetObjectByProperty(SettingsConstants.DisplayNameField, displayName, out uniqueKey, out properties)) { settingsManager.UnregisterObject(uniqueKey); } } /// /// Rename an object in the store. /// /// /// /// if true and destination object already exists overwrite it public void RenameObject(string oldDisplayName, string newDisplayName, bool force) { Dictionary fromObject; string fromUniqueKey; Dictionary toObject; string toUniqueKey; if (TryGetObject(oldDisplayName, out fromUniqueKey, out fromObject)) { if (TryGetObject(newDisplayName, out toUniqueKey, out toObject)) { // if oldDisplayName == newDisplayName it's a no op if (!string.Equals(oldDisplayName, newDisplayName, StringComparison.Ordinal)) { if (force) { settingsManager.UnregisterObject(toUniqueKey); // recursive call with force == false now that the destination object is gone RenameObject(oldDisplayName, newDisplayName, false); } else throw new ArgumentException("Cannot rename object. The destination object '" + newDisplayName + "' already exists."); } } else { fromObject[SettingsConstants.DisplayNameField] = newDisplayName; settingsManager.RegisterObject(fromUniqueKey, fromObject); } } else throw new ArgumentException("Cannot rename object. The source object '" + oldDisplayName + "' does not exist."); } /// /// Copy an object in the store. /// The new object will be a copy of the original, except it will be assigned a new unique key. /// /// /// /// if true and destination object already exists overwrite it public void CopyObject(string fromDisplayName, string toDisplayName, bool force) { Dictionary fromObject; Dictionary toObject; string toUniqueKey; if (TryGetObject(fromDisplayName, out fromObject)) { if (TryGetObject(toDisplayName, out toUniqueKey, out toObject)) { // if fromDisplayName == toDisplayName it's a no op if (!string.Equals(fromDisplayName, toDisplayName, StringComparison.Ordinal)) { if (force) { settingsManager.UnregisterObject(toUniqueKey); // recursive call with force == false now that the destination object is gone CopyObject(fromDisplayName, toDisplayName, force); } else throw new ArgumentException("Cannot copy object. The destination object '" + toDisplayName + "' already exists."); } } else { // Register the copy. A new unique key will be automatically assigned. RegisterObject(toDisplayName, fromObject); } } else throw new ArgumentException("Cannot copy object. The source object '" + fromDisplayName + "' does not exist."); } /// /// Get a list of the display names for the objects in the store. /// /// A list of display names. public List ListObjectNames() { return settingsManager.SelectProperty(SettingsConstants.DisplayNameField); } } }