/*
* 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);
}
}
}