Skip to content

Commit

Permalink
Added --azure-credential-type that can be used to specify which Azure…
Browse files Browse the repository at this point in the history
… credential type should be enabled. (#725)

Progress on #724.
  • Loading branch information
dlemstra committed Jun 24, 2024
1 parent 1e5a01d commit 0c3c240
Show file tree
Hide file tree
Showing 18 changed files with 199 additions and 3 deletions.
28 changes: 26 additions & 2 deletions src/Sign.Cli/AzureCredentialOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,49 @@
using System.CommandLine;
using System.CommandLine.Invocation;
using System.CommandLine.IO;
using System.CommandLine.Parsing;
using Azure.Core;
using Azure.Identity;

namespace Sign.Cli
{
internal sealed class AzureCredentialOptions
{
internal Option<bool?> ManagedIdentityOption { get; } = new(["-kvm", "--azure-key-vault-managed-identity"], Resources.ManagedIdentityOptionDescription);
internal Option<string?> CredentialTypeOption { get; } = new Option<string?>(["-act", "--azure-credential-type"], Resources.CredentialTypeOptionDescription).FromAmong(
AzureCredentialType.Environment);
internal Option<bool?> ManagedIdentityOption { get; } = new(["-kvm", "--azure-key-vault-managed-identity"], Resources.ManagedIdentityOptionDescription) { IsHidden = true };
internal Option<string?> TenantIdOption { get; } = new(["-kvt", "--azure-key-vault-tenant-id"], Resources.TenantIdOptionDescription);
internal Option<string?> ClientIdOption { get; } = new(["-kvi", "--azure-key-vault-client-id"], Resources.ClientIdOptionDescription);
internal Option<string?> ClientSecretOption { get; } = new(["-kvs", "--azure-key-vault-client-secret"], Resources.ClientSecretOptionDescription);

internal void AddOptionsToCommand(Command command)
{
command.AddOption(CredentialTypeOption);
command.AddOption(ManagedIdentityOption);
command.AddOption(TenantIdOption);
command.AddOption(ClientIdOption);
command.AddOption(ClientSecretOption);
}

internal DefaultAzureCredentialOptions CreateDefaultAzureCredentialOptions(ParseResult parseResult)
{
DefaultAzureCredentialOptions options = new();

string? credentialType = parseResult.GetValueForOption(CredentialTypeOption);
if (credentialType is not null)
{
options.ExcludeAzureCliCredential = true;
options.ExcludeAzureDeveloperCliCredential = true;
options.ExcludeAzurePowerShellCredential = true;
options.ExcludeEnvironmentCredential = credentialType != AzureCredentialType.Environment;
options.ExcludeManagedIdentityCredential = true;
options.ExcludeVisualStudioCredential = true;
options.ExcludeWorkloadIdentityCredential = true;
}

return options;
}

internal TokenCredential? CreateTokenCredential(InvocationContext context)
{
bool? useManagedIdentity = context.ParseResult.GetValueForOption(ManagedIdentityOption);
Expand All @@ -45,7 +68,8 @@ internal void AddOptionsToCommand(Command command)
return new ClientSecretCredential(tenantId, clientId, secret);
}

return new DefaultAzureCredential();
DefaultAzureCredentialOptions options = CreateDefaultAzureCredentialOptions(context.ParseResult);
return new DefaultAzureCredential(options);
}
}
}
11 changes: 11 additions & 0 deletions src/Sign.Cli/AzureCredentialType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE.txt file in the project root for more information.

namespace Sign.Cli
{
internal static class AzureCredentialType
{
public const string Environment = "environment";
}
}
9 changes: 9 additions & 0 deletions src/Sign.Cli/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/Sign.Cli/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@
<data name="CodeCommandDescription" xml:space="preserve">
<value>Sign binaries and containers.</value>
</data>
<data name="CredentialTypeOptionDescription" xml:space="preserve">
<value>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</value>
</data>
<data name="DescriptionOptionDescription" xml:space="preserve">
<value>Description of the signing certificate.</value>
</data>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.cs.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">Podepisovat binární soubory a kontejnery.</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">Popis podpisového certifikátu.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.de.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">Signieren Sie Binärdateien und Container.</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">Beschreibung des Signaturzertifikats.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.es.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">Firmar archivos binarios y contenedores.</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">Descripción del certificado de firma.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.fr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">Signer les fichiers binaires et les conteneurs.</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">Description du certificat de signature.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.it.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">Consente di firmare file binari e contenitori.</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">Descrizione del certificato di firma.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.ja.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">バイナリとコンテナーに署名します。</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">署名証明書の説明。</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.ko.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">이진 파일 및 컨테이너에 서명합니다.</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">서명 인증서에 대한 설명입니다.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.pl.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">Podpisz pliki binarne i kontenery.</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">Opis certyfikatu podpisywania.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.pt-BR.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">Autenticar contêineres e binários.</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">Descrição do certificado de autenticação.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.ru.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">Подписывание двоичных файлов и контейнеров.</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">Описание сертификата для подписи</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.tr.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">İkili dosyaları ve kapsayıcıları imzalayın.</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">İmzalama sertifikasının açıklaması.</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.zh-Hans.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">对二进制文件和容器进行签名。</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">签名证书的说明。</target>
Expand Down
5 changes: 5 additions & 0 deletions src/Sign.Cli/xlf/Resources.zh-Hant.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@
<target state="translated">簽署二進位檔和容器。</target>
<note />
</trans-unit>
<trans-unit id="CredentialTypeOptionDescription">
<source>Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</source>
<target state="new">Azure credential type that will be used. This defaults to all types except interactive browser, shared token and Visual Studio Code.</target>
<note />
</trans-unit>
<trans-unit id="DescriptionOptionDescription">
<source>Description of the signing certificate.</source>
<target state="translated">簽署憑證的描述。</target>
Expand Down
86 changes: 85 additions & 1 deletion test/Sign.Cli.Test/AzureCredentialOptionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,38 @@
// See the LICENSE.txt file in the project root for more information.

using System.CommandLine;
using System.CommandLine.Builder;
using System.CommandLine.Parsing;
using Azure.Identity;
using Moq;
using Sign.Core;

namespace Sign.Cli.Test
{
public class AzureCredentialOptionsTests
{
private readonly AzureCredentialOptions _options = new();
private readonly AzureCredentialOptions _options;
private readonly AzureKeyVaultCommand _command;
private readonly Parser _parser;

public AzureCredentialOptionsTests()
{
_command = new(new CodeCommand(), Mock.Of<IServiceProviderFactory>());
_parser = new CommandLineBuilder(_command).Build();
_options = _command.AzureCredentialOptions;
}

[Fact]
public void CredentialTypeOption_Always_HasArityOfExactlyOne()
{
Assert.Equal(ArgumentArity.ExactlyOne, _options.CredentialTypeOption.Arity);
}

[Fact]
public void CredentialTypeOption_Always_IsNotRequired()
{
Assert.False(_options.CredentialTypeOption.IsRequired);
}

[Fact]
public void ManagedIdentityOption_Always_HasArityOfZeroOrOne()
Expand All @@ -22,6 +48,12 @@ public void ManagedIdentityOption_Always_IsNotRequired()
Assert.False(_options.ManagedIdentityOption.IsRequired);
}

[Fact]
public void ManagedIdentityOption_Always_IsHidden()
{
Assert.True(_options.ManagedIdentityOption.IsHidden);
}

[Fact]
public void TenantIdOption_Always_HasArityOfExactlyOne()
{
Expand Down Expand Up @@ -57,5 +89,57 @@ public void ClientSecretOption_Always_IsNotRequired()
{
Assert.False(_options.ClientSecretOption.IsRequired);
}

[Fact]
public void AddOptionsToCommand_Always_AddsAllOptionsToCommand()
{
var command = new Command("test");

_options.AddOptionsToCommand(command);

Assert.Contains(_options.CredentialTypeOption, command.Options);
Assert.Contains(_options.ManagedIdentityOption, command.Options);
Assert.Contains(_options.TenantIdOption, command.Options);
Assert.Contains(_options.ClientIdOption, command.Options);
Assert.Contains(_options.ClientSecretOption, command.Options);
}

[Fact]
public void CreateDefaultAzureCredentialOptions_WhenNoOptionsAreSpecified_ExcludeOptionsHaveTheCorrectDefaultValues()
{
ParseResult result = _parser.Parse("azure-key-vault -kvu https://keyvault.test -kvc a b");

DefaultAzureCredentialOptions credentialOptions = _options.CreateDefaultAzureCredentialOptions(result);

Assert.True(credentialOptions.ExcludeInteractiveBrowserCredential);
Assert.True(credentialOptions.ExcludeSharedTokenCacheCredential);
Assert.True(credentialOptions.ExcludeVisualStudioCodeCredential);
Assert.False(credentialOptions.ExcludeAzureCliCredential);
Assert.False(credentialOptions.ExcludeAzureDeveloperCliCredential);
Assert.False(credentialOptions.ExcludeAzurePowerShellCredential);
Assert.False(credentialOptions.ExcludeEnvironmentCredential);
Assert.False(credentialOptions.ExcludeManagedIdentityCredential);
Assert.False(credentialOptions.ExcludeVisualStudioCredential);
Assert.False(credentialOptions.ExcludeWorkloadIdentityCredential);
}

[Fact]
public void CreateDefaultAzureCredentialOptions_WhenEnvironmentIsSpecified_ExcludeOptionsHaveTheCorrectValues()
{
ParseResult result = _parser.Parse(@"azure-key-vault -kvu https://keyvault.test -kvc a -act environment b");

DefaultAzureCredentialOptions credentialOptions = _options.CreateDefaultAzureCredentialOptions(result);

Assert.True(credentialOptions.ExcludeAzureCliCredential);
Assert.True(credentialOptions.ExcludeAzureDeveloperCliCredential);
Assert.True(credentialOptions.ExcludeAzurePowerShellCredential);
Assert.False(credentialOptions.ExcludeEnvironmentCredential);
Assert.True(credentialOptions.ExcludeInteractiveBrowserCredential);
Assert.True(credentialOptions.ExcludeManagedIdentityCredential);
Assert.True(credentialOptions.ExcludeSharedTokenCacheCredential);
Assert.True(credentialOptions.ExcludeVisualStudioCodeCredential);
Assert.True(credentialOptions.ExcludeVisualStudioCredential);
Assert.True(credentialOptions.ExcludeWorkloadIdentityCredential);
}
}
}

0 comments on commit 0c3c240

Please sign in to comment.