Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added --azure-credential-type that can be used to specify which Azure credential type should be enabled. #725

Merged
merged 3 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
dtivel marked this conversation as resolved.
Show resolved Hide resolved
{
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;
dtivel marked this conversation as resolved.
Show resolved Hide resolved
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";
dtivel marked this conversation as resolved.
Show resolved Hide resolved
}
}
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);
}
}
}