diff --git a/src/Sign.Cli/Sign.Cli.csproj b/src/Sign.Cli/Sign.Cli.csproj index d5b1a9f1..8c34c446 100644 --- a/src/Sign.Cli/Sign.Cli.csproj +++ b/src/Sign.Cli/Sign.Cli.csproj @@ -22,6 +22,7 @@ + @@ -68,6 +69,11 @@ True Resources.resx + + True + True + TrustedSigningResources.resx + @@ -83,5 +89,9 @@ ResXFileCodeGenerator Resources.Designer.cs + + ResXFileCodeGenerator + TrustedSigningResources.Designer.cs + - \ No newline at end of file + diff --git a/src/Sign.Cli/SignCommand.cs b/src/Sign.Cli/SignCommand.cs index ab7d8706..dc54a0a7 100644 --- a/src/Sign.Cli/SignCommand.cs +++ b/src/Sign.Cli/SignCommand.cs @@ -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); } } -} \ No newline at end of file +} diff --git a/src/Sign.Cli/TrustedSigningCommand.cs b/src/Sign.Cli/TrustedSigningCommand.cs new file mode 100644 index 00000000..a32cef77 --- /dev/null +++ b/src/Sign.Cli/TrustedSigningCommand.cs @@ -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 EndpointOption { get; } = new(["-tse", "--trusted-signing-endpoint"], TrustedSigningResources.EndpointOptionDescription); + internal Option AccountOption { get; } = new(["-tsa", "--trusted-signing-account"], TrustedSigningResources.AccountOptionDescription); + internal Option CertificateProfileOption { get; } = new(["-tsc", "--trusted-signing-certificate-profile"], TrustedSigningResources.CertificateProfileOptionDescription); + internal Option ManagedIdentityOption { get; } = new(["-tsm", "--trusted-signing-managed-identity"], getDefaultValue: () => false, TrustedSigningResources.ManagedIdentityOptionDescription); + internal Option TenantIdOption { get; } = new(["-tst", "--trusted-signing-tenant-id"], TrustedSigningResources.TenantIdOptionDescription); + internal Option ClientIdOption { get; } = new(["-tsi", "--trusted-signing-client-id"], TrustedSigningResources.ClientIdOptionDescription); + internal Option ClientSecretOption { get; } = new(["-tss", "--trusted-signing-client-secret"], TrustedSigningResources.ClientSecretOptionDescription); + + internal Argument 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); + }); + } + } +} diff --git a/src/Sign.Cli/TrustedSigningResources.Designer.cs b/src/Sign.Cli/TrustedSigningResources.Designer.cs new file mode 100644 index 00000000..bb83ef8d --- /dev/null +++ b/src/Sign.Cli/TrustedSigningResources.Designer.cs @@ -0,0 +1,144 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Sign.Cli { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class TrustedSigningResources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal TrustedSigningResources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Sign.Cli.TrustedSigningResources", typeof(TrustedSigningResources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to The Trusted Signing Account name.. + /// + internal static string AccountOptionDescription { + get { + return ResourceManager.GetString("AccountOptionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Certificate Profile name.. + /// + internal static string CertificateProfileOptionDescription { + get { + return ResourceManager.GetString("CertificateProfileOptionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Client ID to authenticate to Trusted Signing.. + /// + internal static string ClientIdOptionDescription { + get { + return ResourceManager.GetString("ClientIdOptionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Client secret to authenticate to Trusted Signing.. + /// + internal static string ClientSecretOptionDescription { + get { + return ResourceManager.GetString("ClientSecretOptionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use Trusted Signing. + /// + internal static string CommandDescription { + get { + return ResourceManager.GetString("CommandDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources.. + /// + internal static string EndpointOptionDescription { + get { + return ResourceManager.GetString("EndpointOptionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to If not using a managed identity, all of these options are required: {0}, {1}, and {2}.. + /// + internal static string InvalidClientSecretCredential { + get { + return ResourceManager.GetString("InvalidClientSecretCredential", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Managed identity to authenticate to Trusted Signing.. + /// + internal static string ManagedIdentityOptionDescription { + get { + return ResourceManager.GetString("ManagedIdentityOptionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Tenant ID to authenticate to Trusted Signing.. + /// + internal static string TenantIdOptionDescription { + get { + return ResourceManager.GetString("TenantIdOptionDescription", resourceCulture); + } + } + } +} diff --git a/src/Sign.Cli/TrustedSigningResources.resx b/src/Sign.Cli/TrustedSigningResources.resx new file mode 100644 index 00000000..c561010d --- /dev/null +++ b/src/Sign.Cli/TrustedSigningResources.resx @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + The Trusted Signing Account name. + + + The Certificate Profile name. + + + Client ID to authenticate to Trusted Signing. + + + Client secret to authenticate to Trusted Signing. + + + Use Trusted Signing + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + + + Tenant ID to authenticate to Trusted Signing. + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.cs.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.cs.xlf new file mode 100644 index 00000000..60055953 --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.cs.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.de.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.de.xlf new file mode 100644 index 00000000..b509a8ee --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.de.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.es.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.es.xlf new file mode 100644 index 00000000..6c3ee824 --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.es.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.fr.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.fr.xlf new file mode 100644 index 00000000..e7ab7de6 --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.fr.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.it.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.it.xlf new file mode 100644 index 00000000..9cc34f71 --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.it.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.ja.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.ja.xlf new file mode 100644 index 00000000..b350db7a --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.ja.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.ko.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.ko.xlf new file mode 100644 index 00000000..6d1e1b17 --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.ko.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.pl.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.pl.xlf new file mode 100644 index 00000000..f70d470f --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.pl.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.pt-BR.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.pt-BR.xlf new file mode 100644 index 00000000..c8382898 --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.pt-BR.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.ru.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.ru.xlf new file mode 100644 index 00000000..d770d712 --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.ru.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.tr.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.tr.xlf new file mode 100644 index 00000000..08e308eb --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.tr.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.zh-Hans.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.zh-Hans.xlf new file mode 100644 index 00000000..9ae6cda8 --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.zh-Hans.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/src/Sign.Cli/xlf/TrustedSigningResources.zh-Hant.xlf b/src/Sign.Cli/xlf/TrustedSigningResources.zh-Hant.xlf new file mode 100644 index 00000000..4451f442 --- /dev/null +++ b/src/Sign.Cli/xlf/TrustedSigningResources.zh-Hant.xlf @@ -0,0 +1,52 @@ + + + + + + The Trusted Signing Account name. + The Trusted Signing Account name. + + + + The Certificate Profile name. + The Certificate Profile name. + + + + Client ID to authenticate to Trusted Signing. + Client ID to authenticate to Trusted Signing. + + + + Client secret to authenticate to Trusted Signing. + Client secret to authenticate to Trusted Signing. + + + + Use Trusted Signing + Use Trusted Signing + + + + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + The Trusted Signing Account endpoint. The URI value must have a URI that aligns to the region your Trusted Signing Account and Certificate Profile you are specifying were created in during the setup of these resources. + + + + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + If not using a managed identity, all of these options are required: {0}, {1}, and {2}. + {NumberedPlaceholder="{0}", "{1}", "{2}"} are option names and should not be localized. + + + Managed identity to authenticate to Trusted Signing. + Managed identity to authenticate to Trusted Signing. + + + + Tenant ID to authenticate to Trusted Signing. + Tenant ID to authenticate to Trusted Signing. + + + + + \ No newline at end of file diff --git a/test/Sign.Cli.Test/TrustedSigningCommandTests.cs b/test/Sign.Cli.Test/TrustedSigningCommandTests.cs new file mode 100644 index 00000000..49e4b4ec --- /dev/null +++ b/test/Sign.Cli.Test/TrustedSigningCommandTests.cs @@ -0,0 +1,162 @@ +// 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.Builder; +using System.CommandLine.Parsing; +using Moq; +using Sign.Core; + +namespace Sign.Cli.Test +{ + public class TrustedSigningCommandTests + { + private readonly TrustedSigningCommand _command = new(new CodeCommand(), Mock.Of()); + + [Fact] + public void Constructor_WhenCodeCommandIsNull_Throws() + { + ArgumentNullException exception = Assert.Throws( + () => new TrustedSigningCommand(codeCommand: null!, Mock.Of())); + + Assert.Equal("codeCommand", exception.ParamName); + } + + [Fact] + public void Constructor_WhenServiceProviderFactoryIsNull_Throws() + { + ArgumentNullException exception = Assert.Throws( + () => new TrustedSigningCommand(new CodeCommand(), serviceProviderFactory: null!)); + + Assert.Equal("serviceProviderFactory", exception.ParamName); + } + + [Fact] + public void EndpointOption_Always_HasArityOfExactlyOne() + { + Assert.Equal(ArgumentArity.ExactlyOne, _command.EndpointOption.Arity); + } + + [Fact] + public void EndpointOption_Always_IsRequired() + { + Assert.True(_command.EndpointOption.IsRequired); + } + + [Fact] + public void AccountOption_Always_HasArityOfExactlyOne() + { + Assert.Equal(ArgumentArity.ExactlyOne, _command.AccountOption.Arity); + } + + [Fact] + public void AccountOption_Always_IsRequired() + { + Assert.True(_command.AccountOption.IsRequired); + } + + [Fact] + public void CertificateProfileOption_Always_HasArityOfExactlyOne() + { + Assert.Equal(ArgumentArity.ExactlyOne, _command.CertificateProfileOption.Arity); + } + + [Fact] + public void CertificateProfileOption_Always_IsRequired() + { + Assert.True(_command.CertificateProfileOption.IsRequired); + } + + [Fact] + public void ManagedIdentityOption_Always_HasArityOfZeroOrOne() + { + Assert.Equal(ArgumentArity.ZeroOrOne, _command.ManagedIdentityOption.Arity); + } + + [Fact] + public void ManagedIdentityOption_Always_IsNotRequired() + { + Assert.False(_command.ManagedIdentityOption.IsRequired); + } + + [Fact] + public void TenantIdOption_Always_HasArityOfExactlyOne() + { + Assert.Equal(ArgumentArity.ExactlyOne, _command.TenantIdOption.Arity); + } + + [Fact] + public void TenantIdOption_Always_IsNotRequired() + { + Assert.False(_command.TenantIdOption.IsRequired); + } + + [Fact] + public void ClientIdOption_Always_HasArityOfExactlyOne() + { + Assert.Equal(ArgumentArity.ExactlyOne, _command.ClientIdOption.Arity); + } + + [Fact] + public void ClientIdOption_Always_IsNotRequired() + { + Assert.False(_command.ClientIdOption.IsRequired); + } + + [Fact] + public void ClientSecretOption_Always_HasArityOfExactlyOne() + { + Assert.Equal(ArgumentArity.ExactlyOne, _command.ClientSecretOption.Arity); + } + + [Fact] + public void ClientSecretOption_Always_IsNotRequired() + { + Assert.False(_command.ClientSecretOption.IsRequired); + } + + public class ParserTests + { + private readonly TrustedSigningCommand _command; + private readonly Parser _parser; + + public ParserTests() + { + _command = new(new CodeCommand(), Mock.Of()); + _parser = new CommandLineBuilder(_command).Build(); + } + + [Theory] + [InlineData("trusted-signing")] + [InlineData("trusted-signing a")] + [InlineData("trusted-signing -tse")] + [InlineData("trusted-signing -tse https://trustedsigning.test")] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa")] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa a")] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa a -tsc b")] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa a -tsc b -tst")] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa a -tsc b -tst c")] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa a -tsc b -tst c -tsi")] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa a -tsc b -tst c -tsi d")] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa a -tsc b -tst c -tsi d -tss")] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa a -tsc b -tst c -tsi d -tss e")] + public void Command_WhenRequiredArgumentOrOptionsAreMissing_HasError(string command) + { + ParseResult result = _parser.Parse(command); + + Assert.NotEmpty(result.Errors); + } + + [Theory] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa a -tsc b -tsm c")] + [InlineData("trusted-signing -tse https://trustedsigning.test -tsa a -tsc b -tst c -tsi d -tss e f")] + public void Command_WhenRequiredArgumentsArePresent_HasNoError(string command) + { + ParseResult result = _parser.Parse(command); + + Assert.Empty(result.Errors); + } + } + } +}