Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added TrustedSigningCommand.
Browse files Browse the repository at this point in the history
dlemstra committed Jun 14, 2024
1 parent 0614fe5 commit 774f3f7
Showing 19 changed files with 1,250 additions and 4 deletions.
12 changes: 11 additions & 1 deletion src/Sign.Cli/Sign.Cli.csproj
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@
<ProjectReference Include="..\Sign.Core\Sign.Core.csproj" />
<ProjectReference Include="..\Sign.SignatureProviders.CertificateStore\Sign.SignatureProviders.CertificateStore.csproj" />
<ProjectReference Include="..\Sign.SignatureProviders.KeyVault\Sign.SignatureProviders.KeyVault.csproj" />
<ProjectReference Include="..\Sign.SignatureProviders.TrustedSigning\Sign.SignatureProviders.TrustedSigning.csproj" />
</ItemGroup>

<ItemGroup>
@@ -68,6 +69,11 @@
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="TrustedSigningResources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>TrustedSigningResources.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
@@ -83,5 +89,9 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="TrustedSigningResources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>TrustedSigningResources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>
</Project>
12 changes: 9 additions & 3 deletions src/Sign.Cli/SignCommand.cs
Original file line number Diff line number Diff line change
@@ -23,11 +23,17 @@ internal SignCommand(IServiceProviderFactory? serviceProviderFactory = null)

codeCommand.AddCommand(azureKeyVaultCommand);

CertificateStoreCommand certManagerCommand = new(
CertificateStoreCommand certificateStoreCommand = new(
codeCommand,
serviceProviderFactory);

codeCommand.AddCommand(certManagerCommand);
codeCommand.AddCommand(certificateStoreCommand);

TrustedSigningCommand trustedSigningCommand = new(
codeCommand,
serviceProviderFactory);

codeCommand.AddCommand(trustedSigningCommand);
}
}
}
}
100 changes: 100 additions & 0 deletions src/Sign.Cli/TrustedSigningCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// 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.

using System.CommandLine;
using System.CommandLine.Invocation;
using System.CommandLine.IO;
using Azure.Core;
using Azure.Identity;
using Sign.Core;
using Sign.SignatureProviders.TrustedSigning;

namespace Sign.Cli
{
internal sealed class TrustedSigningCommand : Command
{
internal Option<Uri> EndpointOption { get; } = new(["-tse", "--trusted-signing-endpoint"], TrustedSigningResources.EndpointOptionDescription);
internal Option<string> AccountOption { get; } = new(["-tsa", "--trusted-signing-account"], TrustedSigningResources.AccountOptionDescription);
internal Option<string> CertificateProfileOption { get; } = new(["-tsc", "--trusted-signing-certificate-profile"], TrustedSigningResources.CertificateProfileOptionDescription);
internal Option<bool> ManagedIdentityOption { get; } = new(["-tsm", "--trusted-signing-managed-identity"], getDefaultValue: () => false, TrustedSigningResources.ManagedIdentityOptionDescription);
internal Option<string?> TenantIdOption { get; } = new(["-tst", "--trusted-signing-tenant-id"], TrustedSigningResources.TenantIdOptionDescription);
internal Option<string?> ClientIdOption { get; } = new(["-tsi", "--trusted-signing-client-id"], TrustedSigningResources.ClientIdOptionDescription);
internal Option<string?> ClientSecretOption { get; } = new(["-tss", "--trusted-signing-client-secret"], TrustedSigningResources.ClientSecretOptionDescription);

internal Argument<string?> FileArgument { get; } = new("file(s)", Resources.FilesArgumentDescription);

internal TrustedSigningCommand(CodeCommand codeCommand, IServiceProviderFactory serviceProviderFactory)
: base("trusted-signing", TrustedSigningResources.CommandDescription)
{
ArgumentNullException.ThrowIfNull(codeCommand, nameof(codeCommand));
ArgumentNullException.ThrowIfNull(serviceProviderFactory, nameof(serviceProviderFactory));

EndpointOption.IsRequired = true;
AccountOption.IsRequired = true;
CertificateProfileOption.IsRequired = true;

AddOption(EndpointOption);
AddOption(AccountOption);
AddOption(CertificateProfileOption);
AddOption(ManagedIdentityOption);
AddOption(TenantIdOption);
AddOption(ClientIdOption);
AddOption(ClientSecretOption);

AddArgument(FileArgument);

this.SetHandler(async (InvocationContext context) =>
{
string? fileArgument = context.ParseResult.GetValueForArgument(FileArgument);

if (string.IsNullOrEmpty(fileArgument))
{
context.Console.Error.WriteLine(Resources.MissingFileValue);
context.ExitCode = ExitCode.InvalidOptions;
return;
}

bool useManagedIdentity = context.ParseResult.GetValueForOption(ManagedIdentityOption);

TokenCredential? credential = null;

if (useManagedIdentity)
{
credential = new DefaultAzureCredential();
}
else
{
string? tenantId = context.ParseResult.GetValueForOption(TenantIdOption);
string? clientId = context.ParseResult.GetValueForOption(ClientIdOption);
string? clientSecret = context.ParseResult.GetValueForOption(ClientSecretOption);

if (string.IsNullOrEmpty(tenantId) ||
string.IsNullOrEmpty(clientId) ||
string.IsNullOrEmpty(clientSecret))
{
context.Console.Error.WriteFormattedLine(
TrustedSigningResources.InvalidClientSecretCredential,
TenantIdOption,
ClientIdOption,
ClientSecretOption);
context.ExitCode = ExitCode.NoInputsFound;
return;
}

credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
}

// Some of the options are required and that is why we can safely use
// the null-forgiving operator (!) to simplify the code.
Uri endpointUrl = context.ParseResult.GetValueForOption(EndpointOption)!;
string accountName = context.ParseResult.GetValueForOption(AccountOption)!;
string certificateProfileName = context.ParseResult.GetValueForOption(CertificateProfileOption)!;

TrustedSigningServiceProvider trustedSigningServiceProvider = new(credential, endpointUrl, accountName, certificateProfileName);

await codeCommand.HandleAsync(context, serviceProviderFactory, trustedSigningServiceProvider, fileArgument);
});
}
}
}
144 changes: 144 additions & 0 deletions src/Sign.Cli/TrustedSigningResources.Designer.cs

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

Loading

0 comments on commit 774f3f7

Please sign in to comment.