aliyun-net-credentials/Provider/CLIProfileCredentialsProvider.cs (364 lines of code) (raw):

using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Threading.Tasks; using Aliyun.Credentials.Exceptions; using Aliyun.Credentials.Models; using Aliyun.Credentials.Utils; using Newtonsoft.Json; namespace Aliyun.Credentials.Provider { /// <summary> /// Obtain the credential information from a configuration file. The path of the configuration file varies based on the operating system: /// <list type="bullet"> /// <item><description>Linux: ~/.aliyun/config.json</description></item> /// <item><description>Windows: C:\Users\USER_NAME\.aliyun\config.json</description></item> /// </list> /// </summary> public class CLIProfileCredentialsProvider : IAlibabaCloudCredentialsProvider { private readonly string CLI_CREDENTIALS_CONFIG_PATH = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".aliyun", "config.json"); private volatile IAlibabaCloudCredentialsProvider credentialsProvider; private volatile string currentProfileName; private readonly object credentialsProviderLock = new object(); public CLIProfileCredentialsProvider(string profileName = null) { currentProfileName = profileName ?? Environment.GetEnvironmentVariable("ALIBABA_CLOUD_PROFILE"); } public CredentialModel GetCredentials() { if (AuthUtils.EnvironmentDisableCLIProfile) { throw new CredentialException("CLI credentials file is disabled."); } Config config = ParseProfile(CLI_CREDENTIALS_CONFIG_PATH); if (config == null) { throw new CredentialException("Unable to get profile form empty CLI credentials file."); } string refreshedProfileName = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_PROFILE"); if (ShouldReloadCredentialsProvider(refreshedProfileName)) { lock (credentialsProviderLock) { if (ShouldReloadCredentialsProvider(refreshedProfileName)) { if (!string.IsNullOrEmpty(refreshedProfileName)) { this.currentProfileName = refreshedProfileName; } this.credentialsProvider = ReloadCredentialsProvider(config, this.currentProfileName); } } } var credentials = this.credentialsProvider.GetCredentials(); return new CredentialModel { AccessKeyId = credentials.AccessKeyId, AccessKeySecret = credentials.AccessKeySecret, SecurityToken = credentials.SecurityToken, ProviderName = string.Format("{0}/{1}", this.GetProviderName(), credentials.ProviderName) }; } internal CredentialModel GetCredentials(string path) { if (AuthUtils.EnvironmentDisableCLIProfile) { throw new CredentialException("CLI credentials file is disabled."); } Config config = ParseProfile(path); if (config == null) { throw new CredentialException("Unable to get profile form empty CLI credentials file."); } string refreshedProfileName = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_PROFILE"); if (ShouldReloadCredentialsProvider(refreshedProfileName)) { lock (credentialsProviderLock) { if (ShouldReloadCredentialsProvider(refreshedProfileName)) { if (!string.IsNullOrEmpty(refreshedProfileName)) { this.currentProfileName = refreshedProfileName; } this.credentialsProvider = ReloadCredentialsProvider(config, this.currentProfileName); } } } var credentials = this.credentialsProvider.GetCredentials(); return new CredentialModel { AccessKeyId = credentials.AccessKeyId, AccessKeySecret = credentials.AccessKeySecret, SecurityToken = credentials.SecurityToken, ProviderName = string.Format("{0}/{1}", this.GetProviderName(), credentials.ProviderName) }; } public async Task<CredentialModel> GetCredentialsAsync() { if (AuthUtils.EnvironmentDisableCLIProfile) { throw new CredentialException("CLI credentials file is disabled."); } Config config = ParseProfile(CLI_CREDENTIALS_CONFIG_PATH); if (config == null) { throw new CredentialException("Unable to get profile form empty CLI credentials file."); } string refreshedProfileName = Environment.GetEnvironmentVariable("ALIBABA_CLOUD_PROFILE"); if (ShouldReloadCredentialsProvider(refreshedProfileName)) { lock (credentialsProviderLock) { if (ShouldReloadCredentialsProvider(refreshedProfileName)) { if (!string.IsNullOrEmpty(refreshedProfileName)) { this.currentProfileName = refreshedProfileName; } this.credentialsProvider = ReloadCredentialsProvider(config, this.currentProfileName); } } } var credentials = await this.credentialsProvider.GetCredentialsAsync(); return new CredentialModel { AccessKeyId = credentials.AccessKeyId, AccessKeySecret = credentials.AccessKeySecret, SecurityToken = credentials.SecurityToken, ProviderName = string.Format("{0}/{1}", this.GetProviderName(), credentials.ProviderName) }; } internal string GetProfileName() { return this.currentProfileName; } internal IAlibabaCloudCredentialsProvider ReloadCredentialsProvider(Config config, string profileName) { string currentProfileName = !string.IsNullOrEmpty(profileName) ? profileName : config.GetCurrent(); List<Profile> profiles = config.GetProfiles(); if (profiles != null && profiles.Count > 0) { foreach (var profile in profiles) { if (!string.IsNullOrEmpty(profile.GetName()) && profile.GetName().Equals(currentProfileName)) { switch (profile.GetMode()) { case "AK": return new StaticAKCredentialsProvider.Builder() .AccessKeyId(profile.GetAccessKeyId()) .AccessKeySecret(profile.GetAccessKeySecret()) .Build(); case "StsToken": return new StaticSTSCredentialsProvider.Builder() .AccessKeyId(profile.GetAccessKeyId()) .AccessKeySecret(profile.GetAccessKeySecret()) .SecurityToken(profile.GetSecurityToken()) .Build(); case "RamRoleArn": CredentialModel credentialModel = new CredentialModel { AccessKeyId = ParameterHelper.ValidateNotEmpty(profile.GetAccessKeyId(), "AccessKeyId", "AccessKeyId must not be null or empty."), AccessKeySecret = ParameterHelper.ValidateNotEmpty(profile.GetAccessKeySecret(), "AccessKeySecret", "AccessKeySecret must not be null or empty."), Type = AuthConstant.AccessKey }; IAlibabaCloudCredentialsProvider innerProvider = new StaticCredentialsProvider(credentialModel); return new RamRoleArnCredentialProvider.Builder() .CredentialsProvider(innerProvider) .RoleArn(profile.GetRoleArn()) .DurationSeconds(profile.GetDurationSeconds()) .RoleSessionName(profile.GetRoleSessionName()) .StsRegionId(profile.GetStsRegionId()) .EnableVpc(profile.GetEnableVpc()) .Policy(profile.GetPolicy()) .ExternalId(profile.GetExternalId()) .Build(); case "EcsRamRole": return new EcsRamRoleCredentialProvider.Builder().RoleName(profile.GetRamRoleName()).Build(); case "OIDC": return new OIDCRoleArnCredentialProvider.Builder() .DurationSeconds(profile.GetDurationSeconds()) .RoleArn(profile.GetRoleArn()) .RoleSessionName(profile.GetRoleSessionName()) .OIDCProviderArn(profile.GetOidcProviderArn()) .OIDCTokenFilePath(profile.GetOidcTokenFile()) .StsRegionId(profile.GetStsRegionId()) .Policy(profile.GetPolicy()) .EnableVpc(profile.GetEnableVpc()) .Build(); case "ChainableRamRoleArn": if (profile.GetSourceProfile() == profile.GetName()) { throw new CredentialException("Source profile name can not be the same as profile name."); } IAlibabaCloudCredentialsProvider previousProvider = ReloadCredentialsProvider(config, profile.GetSourceProfile()); return new RamRoleArnCredentialProvider.Builder() .CredentialsProvider(previousProvider) .RoleArn(profile.GetRoleArn()) .DurationSeconds(profile.GetDurationSeconds()) .RoleSessionName(profile.GetRoleSessionName()) .StsRegionId(profile.GetStsRegionId()) .EnableVpc(profile.GetEnableVpc()) .Policy(profile.GetPolicy()) .ExternalId(profile.GetExternalId()) .Build(); default: throw new CredentialException(string.Format("Unsupported profile mode '{0}' form CLI credentials file.", profile.GetMode())); } } } } throw new CredentialException(string.Format("Unable to get profile with '{0}' form CLI credentials file.", currentProfileName)); } internal Config ParseProfile(string configFilePath) { FileInfo configFile = new FileInfo(configFilePath); if (!configFile.Exists) { throw new CredentialException(string.Format("Unable to open credentials file: {0}.", configFile.FullName)); } try { using (StreamReader sr = new StreamReader(configFile.FullName)) { StringBuilder sb = new StringBuilder(); string line; while ((line = sr.ReadLine()) != null) { sb.Append(line); } string jsonContent = sb.ToString(); return JsonConvert.DeserializeObject<Config>(jsonContent); } } catch (Exception) { throw new CredentialException(string.Format("Failed to parse credential from CLI credentials file: {0}.", configFile.FullName)); } } internal bool ShouldReloadCredentialsProvider(string profileName) { return credentialsProvider == null || (!string.IsNullOrEmpty(currentProfileName) && !string.IsNullOrEmpty(profileName) && !currentProfileName.Equals(profileName)); } public string GetProviderName() { return "cli_profile"; } internal class Config { [JsonProperty("current")] private readonly string current; [JsonProperty("profiles")] private readonly List<Profile> profiles; public string GetCurrent() { return current; } public List<Profile> GetProfiles() { return profiles; } } internal class Profile { [JsonProperty("name")] private readonly string name; [JsonProperty("mode")] private readonly string mode; [JsonProperty("access_key_id")] private readonly string accessKeyId; [JsonProperty("access_key_secret")] private readonly string accessKeySecret; [JsonProperty("sts_token")] private readonly string securityToken; [JsonProperty("ram_role_arn")] private readonly string roleArn; [JsonProperty("ram_session_name")] private readonly string roleSessionName; [JsonProperty("expired_seconds")] private readonly int? durationSeconds; [JsonProperty("sts_region")] private readonly string stsRegionId; [JsonProperty("ram_role_name")] private readonly string ramRoleName; [JsonProperty("oidc_token_file")] private readonly string oidcTokenFile; [JsonProperty("oidc_provider_arn")] private readonly string oidcProviderArn; [JsonProperty("source_profile")] private readonly string sourceProfile; [JsonProperty("policy")] private readonly string policy; [JsonProperty("region_id")] private readonly string regionId; [JsonProperty("enable_vpc")] private readonly bool? enableVpc; [JsonProperty("external_id")] private readonly string externalId; public string GetName() { return name; } public string GetMode() { return mode; } public string GetAccessKeyId() { return accessKeyId; } public string GetAccessKeySecret() { return accessKeySecret; } public string GetSecurityToken() { return securityToken; } public string GetRoleArn() { return roleArn; } public string GetRoleSessionName() { return roleSessionName; } public int? GetDurationSeconds() { return durationSeconds; } public string GetStsRegionId() { return stsRegionId; } public string GetRamRoleName() { return ramRoleName; } public string GetOidcTokenFile() { return oidcTokenFile; } public string GetOidcProviderArn() { return oidcProviderArn; } public string GetSourceProfile() { return sourceProfile; } public string GetPolicy() { return policy; } public string GetRegionId() { return regionId; } public bool? GetEnableVpc() { return enableVpc; } public string GetExternalId() { return externalId; } } } }