From 8490278ef76a6f870607338346347a27606a0205 Mon Sep 17 00:00:00 2001 From: alerickson <25858831+alerickson@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:00:03 -0800 Subject: [PATCH] Update SecretManagement credential use with ACR repos (#1498) --- src/code/ACRServerAPICalls.cs | 30 +++++---------- src/code/Utils.cs | 72 ++--------------------------------- 2 files changed, 14 insertions(+), 88 deletions(-) diff --git a/src/code/ACRServerAPICalls.cs b/src/code/ACRServerAPICalls.cs index a96734b0e..6c284d075 100644 --- a/src/code/ACRServerAPICalls.cs +++ b/src/code/ACRServerAPICalls.cs @@ -146,10 +146,8 @@ public override FindResults FindName(string packageName, bool includePrerelease, _cmdletPassedIn.WriteVerbose("Access token retrieved."); - tenantID = Utils.GetSecretInfoFromSecretManagement( - Repository.Name, - repositoryCredentialInfo, - _cmdletPassedIn); + tenantID = repositoryCredentialInfo.SecretName; + _cmdletPassedIn.WriteVerbose($"Tenant ID: {tenantID}"); } // Call asynchronous network methods in a try/catch block to handle exceptions. @@ -284,10 +282,8 @@ public override FindResults FindVersion(string packageName, string version, Reso _cmdletPassedIn.WriteVerbose("Access token retrieved."); - tenantID = Utils.GetSecretInfoFromSecretManagement( - Repository.Name, - repositoryCredentialInfo, - _cmdletPassedIn); + tenantID = repositoryCredentialInfo.SecretName; + _cmdletPassedIn.WriteVerbose($"Tenant ID: {tenantID}"); } // Call asynchronous network methods in a try/catch block to handle exceptions. @@ -405,10 +401,8 @@ internal static PSResourceInfo Install( callingCmdlet.WriteVerbose("Access token retrieved."); - tenantID = Utils.GetSecretInfoFromSecretManagement( - repo.Name, - repositoryCredentialInfo, - callingCmdlet); + tenantID = repositoryCredentialInfo.SecretName; + callingCmdlet.WriteVerbose($"Tenant ID: {tenantID}"); } // Call asynchronous network methods in a try/catch block to handle exceptions. @@ -534,10 +528,8 @@ internal static List Find(PSRepositoryInfo repo, string pkgName, callingCmdlet.WriteVerbose("Access token retrieved."); - tenantID = Utils.GetSecretInfoFromSecretManagement( - repo.Name, - repositoryCredentialInfo, - callingCmdlet); + tenantID = repositoryCredentialInfo.SecretName; + callingCmdlet.WriteVerbose($"Tenant ID: {tenantID}"); } // Call asynchronous network methods in a try/catch block to handle exceptions. @@ -860,10 +852,8 @@ private bool PushNupkgACR(string outputNupkgDir, string pkgName, NuGetVersion pk _cmdletPassedIn.WriteVerbose("Access token retrieved."); - tenantID = Utils.GetSecretInfoFromSecretManagement( - repository.Name, - repositoryCredentialInfo, - _cmdletPassedIn); + tenantID = repositoryCredentialInfo.SecretName; + _cmdletPassedIn.WriteVerbose($"Tenant ID: {tenantID}"); } // Call asynchronous network methods in a try/catch block to handle exceptions. diff --git a/src/code/Utils.cs b/src/code/Utils.cs index a3a3bfe06..f09110423 100644 --- a/src/code/Utils.cs +++ b/src/code/Utils.cs @@ -607,6 +607,10 @@ public static PSCredential GetRepositoryCredentialFromSecretManagement( { return secretCredential; } + else if (secretObject.BaseObject is SecureString secretString) + { + return new PSCredential(repositoryCredentialInfo.SecretName, secretString); + } } cmdletPassedIn.ThrowTerminatingError( @@ -700,74 +704,6 @@ public static string GetACRAccessTokenFromSecretManagement( return null; } - public static string GetSecretInfoFromSecretManagement( - string repositoryName, - PSCredentialInfo repositoryCredentialInfo, - PSCmdlet cmdletPassedIn) - { - if (!IsSecretManagementVaultAccessible(repositoryName, repositoryCredentialInfo, cmdletPassedIn)) - { - cmdletPassedIn.ThrowTerminatingError( - new ErrorRecord( - new PSInvalidOperationException($"Cannot access Microsoft.PowerShell.SecretManagement vault \"{repositoryCredentialInfo.VaultName}\" for PSResourceRepository ({repositoryName}) authentication."), - "RepositoryCredentialSecretManagementInaccessibleVault", - ErrorCategory.ResourceUnavailable, - cmdletPassedIn)); - return null; - } - - var results = PowerShellInvoker.InvokeScriptWithHost( - cmdlet: cmdletPassedIn, - script: @" - param ( - [string] $VaultName, - [string] $SecretName - ) - $module = Microsoft.PowerShell.Core\Import-Module -Name Microsoft.PowerShell.SecretManagement -PassThru - if ($null -eq $module) { - return - } - - $secretInfo = & $module ""Get-SecretInfo"" -Name $SecretName -Vault $VaultName - $secretInfo.Metadata - ", - args: new object[] { repositoryCredentialInfo.VaultName, repositoryCredentialInfo.SecretName }, - out Exception terminatingError); - - var secretInfoValue = (results.Count == 1) ? results[0] : null; - if (secretInfoValue == null) - { - cmdletPassedIn.ThrowTerminatingError( - new ErrorRecord( - new PSInvalidOperationException( - message: $"Microsoft.PowerShell.SecretManagement\\Get-Secret encountered an error while reading secret \"{repositoryCredentialInfo.SecretName}\" from vault \"{repositoryCredentialInfo.VaultName}\" for PSResourceRepository ({repositoryName}) authentication.", - innerException: terminatingError), - "ACRRepositoryCannotGetSecretInfoFromVault", - ErrorCategory.InvalidOperation, - cmdletPassedIn)); - } - - var tenantMetadata = secretInfoValue as ReadOnlyDictionary; - - // "TenantID" is case sensitive so we want to loop through and do a string comparison to accommodate for this - foreach (var entry in tenantMetadata) - { - if (entry.Key.Equals("TenantId", StringComparison.OrdinalIgnoreCase)) - { - return entry.Value as string; - } - } - - cmdletPassedIn.ThrowTerminatingError( - new ErrorRecord( - new PSNotSupportedException($"Secret \"{repositoryCredentialInfo.SecretName}\" from vault \"{repositoryCredentialInfo.VaultName}\" has an invalid type. The only supported type is PSCredential."), - "RepositorySecretInfoIsInvalidSecretType", - ErrorCategory.InvalidType, - cmdletPassedIn)); - - return null; - } - public static void SaveRepositoryCredentialToSecretManagementVault( string repositoryName, PSCredentialInfo repositoryCredentialInfo,