/* * 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.Internal; using Amazon.Runtime.CredentialManagement.Internal; using Amazon.Runtime.Internal.Util; using Amazon.Util; using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; namespace Amazon.Runtime.CredentialManagement { /// /// A named group of options that are persisted and used to obtain AWSCredentials. /// public class CredentialProfile { private Dictionary _properties; private Dictionary> _nestedProperties; /// /// An optional Dictionary of Dictionaries that can contain nested properties. /// For example: in a configuration file like so: /// [profile foo] /// s3 = /// max_retries = 10 /// max_concurrent_requests = 50 /// NestedProperties contains: {{s3:{max_retries:10},{max_concurrent_requests:50}}} /// internal Dictionary> NestedProperties { get => _nestedProperties ?? (_nestedProperties = new Dictionary>()); set => _nestedProperties = value; } /// /// The name of the CredentialProfile /// public string Name { get; private set; } /// /// The options to be used to create AWSCredentials. /// public CredentialProfileOptions Options { get; private set; } /// /// The region to be used with this CredentialProfile /// public RegionEndpoint Region { get; set; } /// /// The unique key for this CredentialProfile. /// This key is used by the Visual Studio Toolkit to associate external artifacts with this profile. /// internal Guid? UniqueKey { get; set; } /// /// The desired that /// should use. /// /// If this is null/empty, then the Mode will be used. /// public string DefaultConfigurationModeName { get; set; } /// /// The endpoint discovery enabled value for this CredentialProfile /// public bool? EndpointDiscoveryEnabled { get; set; } /// /// If true the region identified in the S3 access point arn will be used when making requests. /// public bool? S3UseArnRegion { get; set; } /// /// If true, the use of multi-region access points is disabled. /// public bool? S3DisableMultiRegionAccessPoints { get; set; } /// /// The Sts Regional Endpoints Value as either legacy or regional /// public StsRegionalEndpointsValue? StsRegionalEndpoints { get; set; } /// /// The S3 Regional Endpoint Value as either legacy or regional /// public S3UsEast1RegionalEndpointValue? S3RegionalEndpoint { get; set; } /// /// The request retry mode as legacy, standard, or adaptive /// public RequestRetryMode? RetryMode { get; set; } /// /// Specified how many HTTP requests an SDK should make for a single /// SDK operation invocation before giving up. /// public int? MaxAttempts { get; set; } /// /// Endpoint of the EC2 Instance Metadata Service /// public string EC2MetadataServiceEndpoint { get; set; } /// /// Internet protocol version to be used for communicating with the EC2 Instance Metadata Service /// public EC2MetadataServiceEndpointMode? EC2MetadataServiceEndpointMode { get; set; } /// /// Configures the endpoint calculation to go to a dual stack (ipv6 enabled) endpoint /// for the configured region. /// public bool? UseDualstackEndpoint { get; set; } /// /// Configures the endpoint calculation to go to a FIPS (https://aws.amazon.com/compliance/fips/) endpoint /// for the configured region. /// public bool? UseFIPSEndpoint { get; set; } /// /// If this flag is set to true, the SDK will ignore the configured endpoint urls set in the /// configuration file. /// public bool? IgnoreConfiguredEndpointUrls { get; set; } /// /// This configures the global endpoint URL for a profile. This cannot be used in a services section /// and will be ignored if set in the services section. /// public string EndpointUrl { get; set; } /// /// An optional dictionary of name-value pairs stored with the CredentialProfile /// internal Dictionary Properties { get => _properties ?? (_properties = new Dictionary()); set => _properties = value; } /// /// True if the properties of the Options object can be converted into AWSCredentials, false otherwise. /// See for more details about which options are available. /// public bool CanCreateAWSCredentials => ProfileType.HasValue; /// /// The that this is associated with. /// Null if this is not associated with a . /// public ICredentialProfileStore CredentialProfileStore { get; internal set; } /// /// If CanCreateAWSCredentials is true, returns a short description of the type of /// credentials that would be created. /// If CanCreateAWSCredentials is false, return null. /// public string CredentialDescription => CredentialProfileTypeDetector.GetUserFriendlyCredentialType(ProfileType); /// /// The CredentialProfileType of this CredentialProfile, if one applies. /// internal CredentialProfileType? ProfileType => CredentialProfileTypeDetector.DetectProfileType(Options); /// /// Determine this CredentialProfile will generate AWSCredentials that require a callback to be set on them. /// internal bool IsCallbackRequired => AWSCredentialsFactory.IsCallbackRequired(ProfileType); /// /// Construct a new CredentialProfile. /// /// /// public CredentialProfile(string name, CredentialProfileOptions profileOptions) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException("Name must not be null or empty."); } Options = profileOptions ?? throw new ArgumentNullException("profileOptions"); Name = name; } /// /// Gets the AWSCredentials for this profile if CanCreateAWSCredentials is true /// and AWSCredentials can be created. Throws an exception otherwise. /// /// See for a list of AWSCredentials returned by this method. /// /// The profile source, for profiles that reference other profiles. /// AWSCredentials for this profile. public AWSCredentials GetAWSCredentials(ICredentialProfileSource profileSource) { return GetAWSCredentials(profileSource, false); } /// /// Gets the AWSCredentials for this profile if CanCreateAWSCredentials is true /// and AWSCredentials can be created. Throws an exception otherwise. /// /// See for a list of AWSCredentials returned by this method. /// /// The profile source, for profiles that reference other profiles. /// If true, throw a descriptive exception for any credentials that would not operate as-is. /// In other words, any credentials that require programmatic callbacks at runtime. /// AWSCredentials for this profile. internal AWSCredentials GetAWSCredentials(ICredentialProfileSource profileSource, bool nonCallbackOnly) { return AWSCredentialsFactory.GetAWSCredentials(this, profileSource, nonCallbackOnly); } private string GetPropertiesString() { return "{" + string.Join(",", Properties.OrderBy(p=>p.Key).Select(p => p.Key + "=" + p.Value).ToArray()) + "}"; } public override string ToString() { return "[Name=" + Name + "," + "Options = " + Options + "," + "Region = " + (Region == null ? "" : Region.SystemName) + "," + "Properties = " + GetPropertiesString() + "," + "ProfileType = " + ProfileType + "," + "UniqueKey = " + UniqueKey + "," + "CanCreateAWSCredentials = " + CanCreateAWSCredentials + "," + "RetryMode= " + RetryMode + "," + "MaxAttempts= " + MaxAttempts + "]"; } public override bool Equals(object obj) { if (object.ReferenceEquals(this, obj)) return true; var p = obj as CredentialProfile; if (p == null) return false; return AWSSDKUtils.AreEqual( new object[] { Name, Options, Region, ProfileType, CanCreateAWSCredentials, UniqueKey }, new object[] { p.Name, p.Options, p.Region, p.ProfileType, p.CanCreateAWSCredentials, p.UniqueKey }) && AWSSDKUtils.DictionariesAreEqual(Properties, p.Properties); } public override int GetHashCode() { return Hashing.Hash(Name, Options, Region, ProfileType, CanCreateAWSCredentials, GetPropertiesString(), UniqueKey); } } }