From f1c11d058dcd84a44ef392b424d685058c6f106e Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Wed, 11 Dec 2024 10:09:28 -0500 Subject: [PATCH 01/17] Add service addition functionality to ServiceProviderFactory - Introduced a private field `servicesToAdd` in `ServiceProviderFactory` to store additional services. - Added `AddServices` method to `ServiceProviderFactory` to add services via an `Action` parameter. - Updated `Create` method to include `servicesToAdd` if not null. - Added `ServiceProviderFactoryTests` to verify new functionality. - Tests include null check, service addition, and service provider creation. - Defined `ITestService`, `TestService`, `ITestService2`, and `TestService2` for testing purposes. --- src/Sign.Core/IServiceProviderFactory.cs | 4 +- src/Sign.Core/ServiceProviderFactory.cs | 17 ++++- .../TestServiceProviderFactory.cs | 6 +- .../ServiceProviderFactoryTests.cs | 67 +++++++++++++++++++ 4 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 test/Sign.Core.Test/ServiceProviderFactoryTests.cs diff --git a/src/Sign.Core/IServiceProviderFactory.cs b/src/Sign.Core/IServiceProviderFactory.cs index 94ff81bf..a2f5807f 100644 --- a/src/Sign.Core/IServiceProviderFactory.cs +++ b/src/Sign.Core/IServiceProviderFactory.cs @@ -13,5 +13,7 @@ IServiceProvider Create( LogLevel logLevel = LogLevel.Information, ILoggerProvider? loggerProvider = null, Action? addServices = null); + + void AddServices(Action services); } -} \ No newline at end of file +} diff --git a/src/Sign.Core/ServiceProviderFactory.cs b/src/Sign.Core/ServiceProviderFactory.cs index 9933e973..541eff81 100644 --- a/src/Sign.Core/ServiceProviderFactory.cs +++ b/src/Sign.Core/ServiceProviderFactory.cs @@ -9,12 +9,27 @@ namespace Sign.Core { internal sealed class ServiceProviderFactory : IServiceProviderFactory { + private Action? servicesToAdd; + public IServiceProvider Create( LogLevel logLevel = LogLevel.Information, ILoggerProvider? loggerProvider = null, Action? addServices = null) { + + if (servicesToAdd is not null) + { + addServices += servicesToAdd; + } + return ServiceProvider.CreateDefault(logLevel, loggerProvider, addServices); } + + public void AddServices(Action services) + { + ArgumentNullException.ThrowIfNull(services, nameof(services)); + + servicesToAdd += services; + } } -} \ No newline at end of file +} diff --git a/test/Sign.Cli.Test/TestInfrastructure/TestServiceProviderFactory.cs b/test/Sign.Cli.Test/TestInfrastructure/TestServiceProviderFactory.cs index 271655ee..28deb7ec 100644 --- a/test/Sign.Cli.Test/TestInfrastructure/TestServiceProviderFactory.cs +++ b/test/Sign.Cli.Test/TestInfrastructure/TestServiceProviderFactory.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; + using Sign.Core; namespace Sign.Cli.Test @@ -24,5 +25,8 @@ public IServiceProvider Create( { return _serviceProvider; } + + public void AddServices(Action services) + { } } -} \ No newline at end of file +} diff --git a/test/Sign.Core.Test/ServiceProviderFactoryTests.cs b/test/Sign.Core.Test/ServiceProviderFactoryTests.cs new file mode 100644 index 00000000..40442ecd --- /dev/null +++ b/test/Sign.Core.Test/ServiceProviderFactoryTests.cs @@ -0,0 +1,67 @@ +// 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 Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + +namespace Sign.Core.Test +{ + public class ServiceProviderFactoryTests + { + [Fact] + public void AddService_ServicesIsNull_Throws() + { + var factory = new ServiceProviderFactory(); + + ArgumentNullException exception = Assert.Throws( + () => factory.AddServices(null!)); + + Assert.Equal("services", exception.ParamName); + } + + [Fact] + public void AddServices_AddedServicesAreAdded() + { + var factory = new ServiceProviderFactory(); + factory.AddServices(services => services.AddSingleton()); + IServiceProvider serviceProvider = factory.Create(); + Assert.NotNull(serviceProvider.GetRequiredService()); + } + + [Fact] + public void AddServices_AddedIfAddedServicesAreAlsoPresent() + { + var factory = new ServiceProviderFactory(); + factory.AddServices(services => services.AddSingleton()); + IServiceProvider serviceProvider = factory.Create(addServices: services => services.AddSingleton()); + Assert.NotNull(serviceProvider.GetRequiredService()); + Assert.NotNull(serviceProvider.GetRequiredService()); + } + + [Fact] + public void Create_NoAddedServices() + { + var factory = new ServiceProviderFactory(); + IServiceProvider serviceProvider = factory.Create(); + Assert.NotNull(serviceProvider.GetRequiredService>()); + } + + } + + public interface ITestService + { + } + + public class TestService : ITestService + { + } + + public interface ITestService2 + { + } + + public class TestService2 : ITestService2 + { + } +} From ebf2361ced0ebc780b025282ea29c015631ddddb Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Wed, 11 Dec 2024 11:37:09 -0500 Subject: [PATCH 02/17] Refactor TrustedSigningService for DI and add Azure support Introduce Microsoft.Extensions.Azure package and refactor TrustedSigningService to use dependency injection for CertificateProfileClient. Update TrustedSigningServiceProvider to rely on service provider for instances. Add localized string resources for "Certificate Details" in multiple languages. Update tests to reflect changes and remove obsolete tests. Log detailed certificate information in TrustedSigningService. --- Directory.Packages.props | 1 + src/Sign.Cli/TrustedSigningCommand.cs | 36 +++++- src/Sign.Core/Sign.Core.csproj | 1 + .../Resources.Designer.cs | 9 ++ .../Resources.resx | 3 + .../TrustedSigningService.cs | 16 +-- .../TrustedSigningServiceProvider.cs | 52 +-------- .../xlf/Resources.cs.xlf | 5 + .../xlf/Resources.de.xlf | 5 + .../xlf/Resources.es.xlf | 5 + .../xlf/Resources.fr.xlf | 5 + .../xlf/Resources.it.xlf | 5 + .../xlf/Resources.ja.xlf | 5 + .../xlf/Resources.ko.xlf | 5 + .../xlf/Resources.pl.xlf | 5 + .../xlf/Resources.pt-BR.xlf | 5 + .../xlf/Resources.ru.xlf | 5 + .../xlf/Resources.tr.xlf | 5 + .../xlf/Resources.zh-Hans.xlf | 5 + .../xlf/Resources.zh-Hant.xlf | 5 + .../TrustedSigningServiceProviderTests.cs | 104 ++---------------- .../TrustedSigningServiceTests.cs | 30 ++--- 22 files changed, 148 insertions(+), 169 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 4749d114..eabbe801 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -13,6 +13,7 @@ + diff --git a/src/Sign.Cli/TrustedSigningCommand.cs b/src/Sign.Cli/TrustedSigningCommand.cs index 1247d5b2..7bcb7ee1 100644 --- a/src/Sign.Cli/TrustedSigningCommand.cs +++ b/src/Sign.Cli/TrustedSigningCommand.cs @@ -5,7 +5,15 @@ using System.CommandLine; using System.CommandLine.Invocation; using System.CommandLine.IO; + +using Azure.CodeSigning; +using Azure.CodeSigning.Extensions; using Azure.Core; + +using Microsoft.Extensions.Azure; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + using Sign.Core; using Sign.SignatureProviders.TrustedSigning; @@ -60,7 +68,33 @@ internal TrustedSigningCommand(CodeCommand codeCommand, IServiceProviderFactory string accountName = context.ParseResult.GetValueForOption(AccountOption)!; string certificateProfileName = context.ParseResult.GetValueForOption(CertificateProfileOption)!; - TrustedSigningServiceProvider trustedSigningServiceProvider = new(credential, endpointUrl, accountName, certificateProfileName); + serviceProviderFactory.AddServices(services => + { + services.AddAzureClients(builder => + { + builder.AddCertificateProfileClient(endpointUrl); + builder.UseCredential(credential); + builder.ConfigureDefaults(options => options.Retry.Mode = RetryMode.Exponential); + }); + + + var opt = new CertificateProfileClientOptions(); + + + + services.AddSingleton(serviceProvider => + { + return new TrustedSigningService( + serviceProvider.GetRequiredService(), + accountName, + certificateProfileName, + serviceProvider.GetRequiredService>() + ); + }); + }); + + + TrustedSigningServiceProvider trustedSigningServiceProvider = new(); await codeCommand.HandleAsync(context, serviceProviderFactory, trustedSigningServiceProvider, fileArgument); }); diff --git a/src/Sign.Core/Sign.Core.csproj b/src/Sign.Core/Sign.Core.csproj index ecffcb0b..af0314ba 100644 --- a/src/Sign.Core/Sign.Core.csproj +++ b/src/Sign.Core/Sign.Core.csproj @@ -8,6 +8,7 @@ + diff --git a/src/Sign.SignatureProviders.TrustedSigning/Resources.Designer.cs b/src/Sign.SignatureProviders.TrustedSigning/Resources.Designer.cs index a7210e20..5d53d788 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/Resources.Designer.cs +++ b/src/Sign.SignatureProviders.TrustedSigning/Resources.Designer.cs @@ -60,6 +60,15 @@ internal Resources() { } } + /// + /// Looks up a localized string similar to Certificate Details:\n{details}. + /// + internal static string CertificateDetails { + get { + return ResourceManager.GetString("CertificateDetails", resourceCulture); + } + } + /// /// Looks up a localized string similar to Fetched certificate. [{milliseconds} ms]. /// diff --git a/src/Sign.SignatureProviders.TrustedSigning/Resources.resx b/src/Sign.SignatureProviders.TrustedSigning/Resources.resx index 821cb271..3152a5ff 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/Resources.resx +++ b/src/Sign.SignatureProviders.TrustedSigning/Resources.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Certificate Details:\n{details} + Fetched certificate. [{milliseconds} ms] {Placeholder="{milliseconds}"} is a decimal number representing the number of milliseconds elapsed, and "ms" is the unit abbreviation for milliseconds. diff --git a/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs b/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs index 076d83b0..e6e8a50a 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs +++ b/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs @@ -5,11 +5,13 @@ using System.Diagnostics; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; + using Azure; using Azure.CodeSigning; using Azure.CodeSigning.Models; -using Azure.Core; + using Microsoft.Extensions.Logging; + using Sign.Core; namespace Sign.SignatureProviders.TrustedSigning @@ -26,23 +28,20 @@ internal sealed class TrustedSigningService : ISignatureAlgorithmProvider, ICert private X509Certificate2? _certificate; public TrustedSigningService( - TokenCredential tokenCredential, - Uri endpointUrl, + CertificateProfileClient certificateProfileClient, string accountName, string certificateProfileName, ILogger logger) { - ArgumentNullException.ThrowIfNull(tokenCredential, nameof(tokenCredential)); - ArgumentNullException.ThrowIfNull(endpointUrl, nameof(endpointUrl)); + ArgumentNullException.ThrowIfNull(certificateProfileClient, paramName: nameof(certificateProfileClient)); ArgumentException.ThrowIfNullOrEmpty(accountName, nameof(accountName)); ArgumentException.ThrowIfNullOrEmpty(certificateProfileName, nameof(certificateProfileName)); ArgumentNullException.ThrowIfNull(logger, nameof(logger)); + _client = certificateProfileClient; _accountName = accountName; _certificateProfileName = certificateProfileName; _logger = logger; - - _client = new CertificateProfileClient(tokenCredential, endpointUrl); } public void Dispose() @@ -81,6 +80,9 @@ public async Task GetCertificateAsync(CancellationToken cancel _certificate = collection[collection.Count - 1]; _logger.LogTrace(Resources.FetchedCertificate, stopwatch.Elapsed.TotalMilliseconds); + //print the certificate info + _logger.LogTrace(Resources.CertificateDetails, _certificate.ToString(true)); + response.Value.Dispose(); } } diff --git a/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningServiceProvider.cs b/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningServiceProvider.cs index aca0bd90..3f1f7b4c 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningServiceProvider.cs +++ b/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningServiceProvider.cs @@ -2,72 +2,26 @@ // 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 Azure.Core; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; + using Sign.Core; namespace Sign.SignatureProviders.TrustedSigning { internal sealed class TrustedSigningServiceProvider : ISignatureProvider { - private readonly TokenCredential _tokenCredential; - private readonly Uri _endpointUrl; - private readonly string _accountName; - private readonly string _certificateProfileName; - private readonly object _lockObject = new(); - private TrustedSigningService? _trustedSigningService; - - public TrustedSigningServiceProvider( - TokenCredential tokenCredential, - Uri endpointUrl, - string accountName, - string certificateProfileName) - { - ArgumentNullException.ThrowIfNull(tokenCredential, nameof(tokenCredential)); - ArgumentNullException.ThrowIfNull(endpointUrl, nameof(endpointUrl)); - ArgumentException.ThrowIfNullOrEmpty(accountName, nameof(accountName)); - ArgumentException.ThrowIfNullOrEmpty(certificateProfileName, nameof(certificateProfileName)); - - _tokenCredential = tokenCredential; - _endpointUrl = endpointUrl; - _accountName = accountName; - _certificateProfileName = certificateProfileName; - } - public ISignatureAlgorithmProvider GetSignatureAlgorithmProvider(IServiceProvider serviceProvider) { ArgumentNullException.ThrowIfNull(serviceProvider, nameof(serviceProvider)); - return GetService(serviceProvider); + return serviceProvider.GetRequiredService(); } public ICertificateProvider GetCertificateProvider(IServiceProvider serviceProvider) { ArgumentNullException.ThrowIfNull(serviceProvider, nameof(serviceProvider)); - return GetService(serviceProvider); - } - - private TrustedSigningService GetService(IServiceProvider serviceProvider) - { - if (_trustedSigningService is not null) - { - return _trustedSigningService; - } - - lock (_lockObject) - { - if (_trustedSigningService is not null) - { - return _trustedSigningService; - } - - ILogger logger = serviceProvider.GetRequiredService>(); - _trustedSigningService = new TrustedSigningService(_tokenCredential, _endpointUrl, _accountName, _certificateProfileName, logger); - } - - return _trustedSigningService; + return serviceProvider.GetRequiredService(); } } } diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.cs.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.cs.xlf index 236d3f03..8e260c85 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.cs.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.cs.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Načetl se certifikát. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.de.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.de.xlf index 51cb638c..7ce4003d 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.de.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.de.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Zertifikat abgerufen. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.es.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.es.xlf index 924c8b94..fd76990f 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.es.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.es.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Certificado capturado. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.fr.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.fr.xlf index e5b50231..2c924989 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.fr.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.fr.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Certificat récupéré. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.it.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.it.xlf index 883024a8..eb696486 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.it.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.it.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Il certificato è stato recuperato. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ja.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ja.xlf index 65c4f194..e15c26a4 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ja.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ja.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] 証明書をフェッチしました。[{milliseconds} ミリ秒] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ko.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ko.xlf index 9eeebf50..f8af6f11 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ko.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ko.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] 인증서를 가져왔습니다. [{milliseconds}ms] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pl.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pl.xlf index b49d771d..6dedae66 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pl.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pl.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Pobrano certyfikat. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pt-BR.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pt-BR.xlf index accf1e49..5e73c2ed 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pt-BR.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pt-BR.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Certificado buscado. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ru.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ru.xlf index ddfba710..12e8c09e 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ru.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ru.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Получен сертификат. [{milliseconds} мс] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.tr.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.tr.xlf index dfcfe289..2442f2cd 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.tr.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.tr.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Sertifika getirildi. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hans.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hans.xlf index 7e3b4260..5bcd5fe2 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hans.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hans.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] 已提取证书。[{milliseconds} 毫秒] diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hant.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hant.xlf index 7ffb45a4..e33b6697 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hant.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hant.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] 已擷取憑證。[{milliseconds} 毫秒] diff --git a/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceProviderTests.cs b/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceProviderTests.cs index 5918d019..d874a59d 100644 --- a/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceProviderTests.cs +++ b/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceProviderTests.cs @@ -2,22 +2,15 @@ // 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.Collections.Concurrent; -using Azure.Core; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Moq; -using Sign.Core; + using Sign.TestInfrastructure; namespace Sign.SignatureProviders.TrustedSigning.Test { public class TrustedSigningServiceProviderTests { - private readonly static TokenCredential TokenCredential = Mock.Of(); - private readonly static Uri EndpointUrl = new("https://trustedsigning.test"); - private const string AccountName = "a"; - private const string CertificateProfileName = "b"; private readonly IServiceProvider serviceProvider; public TrustedSigningServiceProviderTests() @@ -27,64 +20,10 @@ public TrustedSigningServiceProviderTests() serviceProvider = services.BuildServiceProvider(); } - [Fact] - public void Constructor_WhenTokenCredentialIsNull_Throws() - { - ArgumentNullException exception = Assert.Throws( - () => new TrustedSigningServiceProvider(tokenCredential: null!, EndpointUrl, AccountName, CertificateProfileName)); - - Assert.Equal("tokenCredential", exception.ParamName); - } - - [Fact] - public void Constructor_WhenEndpointUrlIsNull_Throws() - { - ArgumentNullException exception = Assert.Throws( - () => new TrustedSigningServiceProvider(TokenCredential, endpointUrl: null!, AccountName, CertificateProfileName)); - - Assert.Equal("endpointUrl", exception.ParamName); - } - - [Fact] - public void Constructor_WhenAccountNameIsNull_Throws() - { - ArgumentNullException exception = Assert.Throws( - () => new TrustedSigningServiceProvider(TokenCredential, EndpointUrl, accountName: null!, CertificateProfileName)); - - Assert.Equal("accountName", exception.ParamName); - } - - [Fact] - public void Constructor_WhenAccountNameIsEmpty_Throws() - { - ArgumentException exception = Assert.Throws( - () => new TrustedSigningServiceProvider(TokenCredential, EndpointUrl, accountName: string.Empty, CertificateProfileName)); - - Assert.Equal("accountName", exception.ParamName); - } - - [Fact] - public void Constructor_WhenCertificateProfileNameIsNull_Throws() - { - ArgumentNullException exception = Assert.Throws( - () => new TrustedSigningServiceProvider(TokenCredential, EndpointUrl, AccountName, certificateProfileName: null!)); - - Assert.Equal("certificateProfileName", exception.ParamName); - } - - [Fact] - public void Constructor_WhenCertificateProfileNameIsEmpty_Throws() - { - ArgumentException exception = Assert.Throws( - () => new TrustedSigningServiceProvider(TokenCredential, EndpointUrl, AccountName, certificateProfileName: string.Empty)); - - Assert.Equal("certificateProfileName", exception.ParamName); - } - [Fact] public void GetSignatureAlgorithmProvider_WhenServiceProviderIsNull_Throws() { - TrustedSigningServiceProvider provider = new(TokenCredential, EndpointUrl, AccountName, CertificateProfileName); + TrustedSigningServiceProvider provider = new(); ArgumentNullException exception = Assert.Throws( () => provider.GetSignatureAlgorithmProvider(serviceProvider: null!)); @@ -92,45 +31,24 @@ public void GetSignatureAlgorithmProvider_WhenServiceProviderIsNull_Throws() Assert.Equal("serviceProvider", exception.ParamName); } - [Fact] - public void GetSignatureAlgorithmProvider_ReturnsSameInstance() - { - TrustedSigningServiceProvider provider = new(TokenCredential, EndpointUrl, AccountName, CertificateProfileName); - - ConcurrentBag signatureAlgorithmProviders = []; - Parallel.For(0, 2, (_, _) => - { - signatureAlgorithmProviders.Add(provider.GetSignatureAlgorithmProvider(serviceProvider)); - }); - - Assert.Equal(2, signatureAlgorithmProviders.Count); - Assert.Same(signatureAlgorithmProviders.First(), signatureAlgorithmProviders.Last()); - } [Fact] - public void GetCertificateProvider_WhenServiceProviderIsNull_Throws() + public void GetSignatureAlgorithmProvider_ReturnsInstance() { - TrustedSigningServiceProvider provider = new(TokenCredential, EndpointUrl, AccountName, CertificateProfileName); + TrustedSigningServiceProvider provider = new(); - ArgumentNullException exception = Assert.Throws( - () => provider.GetSignatureAlgorithmProvider(serviceProvider: null!)); - - Assert.Equal("serviceProvider", exception.ParamName); + // TODO: Not sure how to test this without creating a CertificateProfileClient + //Assert.IsAssignableFrom(provider.GetSignatureAlgorithmProvider(serviceProvider)); + //Assert.IsAssignableFrom(provider.GetSignatureAlgorithmProvider(serviceProvider)); } [Fact] - public void GetCertificateProvider_ReturnsSameInstance() + public void GetCertificateProvider_ReturnsInstance() { - TrustedSigningServiceProvider provider = new(TokenCredential, EndpointUrl, AccountName, CertificateProfileName); - - ConcurrentBag certificateProviders = []; - Parallel.For(0, 2, (_, _) => - { - certificateProviders.Add(provider.GetCertificateProvider(serviceProvider)); - }); + TrustedSigningServiceProvider provider = new(); - Assert.Equal(2, certificateProviders.Count); - Assert.Same(certificateProviders.First(), certificateProviders.Last()); + // TODO: Not sure how to test this without creating a CertificateProfileClient + //Assert.IsAssignableFrom(provider.GetSignatureAlgorithmProvider(serviceProvider)); } } } diff --git a/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceTests.cs b/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceTests.cs index e78d4215..0091fee9 100644 --- a/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceTests.cs +++ b/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceTests.cs @@ -2,43 +2,35 @@ // 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 Azure.Core; +using Azure.CodeSigning; + using Microsoft.Extensions.Logging; + using Moq; namespace Sign.SignatureProviders.TrustedSigning.Test { public class TrustedSigningServiceTests { - private readonly static TokenCredential TokenCredential = Mock.Of(); - private readonly static Uri EndpointUrl = new("https://trustedsigning.test"); + private static readonly CertificateProfileClient CertificateProfileClient = Mock.Of(); private const string AccountName = "a"; private const string CertificateProfileName = "b"; - private readonly static ILogger Logger = Mock.Of>(); + private static readonly ILogger Logger = Mock.Of>(); [Fact] public void Constructor_WhenTokenCredentialIsNull_Throws() { ArgumentNullException exception = Assert.Throws( - () => new TrustedSigningService(tokenCredential: null!, EndpointUrl, AccountName, CertificateProfileName, Logger)); + () => new TrustedSigningService(certificateProfileClient: null!, AccountName, CertificateProfileName, Logger)); Assert.Equal("tokenCredential", exception.ParamName); } - [Fact] - public void Constructor_WhenEndpointUrlIsNull_Throws() - { - ArgumentNullException exception = Assert.Throws( - () => new TrustedSigningService(TokenCredential, endpointUrl: null!, AccountName, CertificateProfileName, Logger)); - - Assert.Equal("endpointUrl", exception.ParamName); - } - [Fact] public void Constructor_WhenAccountNameIsNull_Throws() { ArgumentNullException exception = Assert.Throws( - () => new TrustedSigningService(TokenCredential, EndpointUrl, accountName: null!, CertificateProfileName, Logger)); + () => new TrustedSigningService(CertificateProfileClient, accountName: null!, CertificateProfileName, Logger)); Assert.Equal("accountName", exception.ParamName); } @@ -47,7 +39,7 @@ public void Constructor_WhenAccountNameIsNull_Throws() public void Constructor_WhenAccountNameIsEmpty_Throws() { ArgumentException exception = Assert.Throws( - () => new TrustedSigningService(TokenCredential, EndpointUrl, accountName: string.Empty, CertificateProfileName, Logger)); + () => new TrustedSigningService(CertificateProfileClient, accountName: string.Empty, CertificateProfileName, Logger)); Assert.Equal("accountName", exception.ParamName); } @@ -56,7 +48,7 @@ public void Constructor_WhenAccountNameIsEmpty_Throws() public void Constructor_WhenCertificateProfileNameIsNull_Throws() { ArgumentNullException exception = Assert.Throws( - () => new TrustedSigningService(TokenCredential, EndpointUrl, AccountName, certificateProfileName: null!, Logger)); + () => new TrustedSigningService(CertificateProfileClient, AccountName, certificateProfileName: null!, Logger)); Assert.Equal("certificateProfileName", exception.ParamName); } @@ -65,7 +57,7 @@ public void Constructor_WhenCertificateProfileNameIsNull_Throws() public void Constructor_WhenCertificateProfileNameIsEmpty_Throws() { ArgumentException exception = Assert.Throws( - () => new TrustedSigningService(TokenCredential, EndpointUrl, AccountName, certificateProfileName: string.Empty, Logger)); + () => new TrustedSigningService(CertificateProfileClient, AccountName, certificateProfileName: string.Empty, Logger)); Assert.Equal("certificateProfileName", exception.ParamName); } @@ -74,7 +66,7 @@ public void Constructor_WhenCertificateProfileNameIsEmpty_Throws() public void Constructor_WhenLoggerIsNull_Throws() { ArgumentNullException exception = Assert.Throws( - () => new TrustedSigningService(TokenCredential, EndpointUrl, AccountName, CertificateProfileName, logger: null!)); + () => new TrustedSigningService(CertificateProfileClient, AccountName, CertificateProfileName, logger: null!)); Assert.Equal("logger", exception.ParamName); } From 863eb2bcef57a6d578fb9c75aecbab82f7fb5597 Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Wed, 11 Dec 2024 11:43:15 -0500 Subject: [PATCH 03/17] cleanup --- src/Sign.Cli/TrustedSigningCommand.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Sign.Cli/TrustedSigningCommand.cs b/src/Sign.Cli/TrustedSigningCommand.cs index 7bcb7ee1..9933cf5b 100644 --- a/src/Sign.Cli/TrustedSigningCommand.cs +++ b/src/Sign.Cli/TrustedSigningCommand.cs @@ -77,11 +77,6 @@ internal TrustedSigningCommand(CodeCommand codeCommand, IServiceProviderFactory builder.ConfigureDefaults(options => options.Retry.Mode = RetryMode.Exponential); }); - - var opt = new CertificateProfileClientOptions(); - - - services.AddSingleton(serviceProvider => { return new TrustedSigningService( @@ -93,7 +88,6 @@ internal TrustedSigningCommand(CodeCommand codeCommand, IServiceProviderFactory }); }); - TrustedSigningServiceProvider trustedSigningServiceProvider = new(); await codeCommand.HandleAsync(context, serviceProviderFactory, trustedSigningServiceProvider, fileArgument); From 22af646be3aad7e2fea49672492e6ea5227bc3f5 Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Wed, 11 Dec 2024 11:46:06 -0500 Subject: [PATCH 04/17] Rename private field `servicesToAdd` to `_servicesToAdd` --- src/Sign.Core/ServiceProviderFactory.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Sign.Core/ServiceProviderFactory.cs b/src/Sign.Core/ServiceProviderFactory.cs index 541eff81..a7405644 100644 --- a/src/Sign.Core/ServiceProviderFactory.cs +++ b/src/Sign.Core/ServiceProviderFactory.cs @@ -9,7 +9,7 @@ namespace Sign.Core { internal sealed class ServiceProviderFactory : IServiceProviderFactory { - private Action? servicesToAdd; + private Action? _servicesToAdd; public IServiceProvider Create( LogLevel logLevel = LogLevel.Information, @@ -17,9 +17,9 @@ public IServiceProvider Create( Action? addServices = null) { - if (servicesToAdd is not null) + if (_servicesToAdd is not null) { - addServices += servicesToAdd; + addServices += _servicesToAdd; } return ServiceProvider.CreateDefault(logLevel, loggerProvider, addServices); @@ -29,7 +29,7 @@ public void AddServices(Action services) { ArgumentNullException.ThrowIfNull(services, nameof(services)); - servicesToAdd += services; + _servicesToAdd += services; } } } From 0b9d7332782e1aab6c8a7d590469005f833b4a24 Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Wed, 11 Dec 2024 12:15:21 -0500 Subject: [PATCH 05/17] Fix parameter name in test --- .../TrustedSigningServiceTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceTests.cs b/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceTests.cs index 0091fee9..c7be349a 100644 --- a/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceTests.cs +++ b/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceTests.cs @@ -23,7 +23,7 @@ public void Constructor_WhenTokenCredentialIsNull_Throws() ArgumentNullException exception = Assert.Throws( () => new TrustedSigningService(certificateProfileClient: null!, AccountName, CertificateProfileName, Logger)); - Assert.Equal("tokenCredential", exception.ParamName); + Assert.Equal("certificateProfileClient", exception.ParamName); } [Fact] From 2a7c63add12dfc1f7a6d1f9dbd4435b25c6e0b40 Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Wed, 11 Dec 2024 15:42:28 -0500 Subject: [PATCH 06/17] Some formatting and renames based on feedback --- src/Sign.Cli/TrustedSigningCommand.cs | 3 +-- src/Sign.Core/IServiceProviderFactory.cs | 2 +- src/Sign.Core/ServiceProviderFactory.cs | 12 ++++++------ .../TrustedSigningService.cs | 5 +---- .../TestInfrastructure/TestServiceProviderFactory.cs | 2 +- 5 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/Sign.Cli/TrustedSigningCommand.cs b/src/Sign.Cli/TrustedSigningCommand.cs index 9933cf5b..b657eebf 100644 --- a/src/Sign.Cli/TrustedSigningCommand.cs +++ b/src/Sign.Cli/TrustedSigningCommand.cs @@ -83,8 +83,7 @@ internal TrustedSigningCommand(CodeCommand codeCommand, IServiceProviderFactory serviceProvider.GetRequiredService(), accountName, certificateProfileName, - serviceProvider.GetRequiredService>() - ); + serviceProvider.GetRequiredService>()); }); }); diff --git a/src/Sign.Core/IServiceProviderFactory.cs b/src/Sign.Core/IServiceProviderFactory.cs index a2f5807f..510ac365 100644 --- a/src/Sign.Core/IServiceProviderFactory.cs +++ b/src/Sign.Core/IServiceProviderFactory.cs @@ -14,6 +14,6 @@ IServiceProvider Create( ILoggerProvider? loggerProvider = null, Action? addServices = null); - void AddServices(Action services); + void AddServices(Action addServices); } } diff --git a/src/Sign.Core/ServiceProviderFactory.cs b/src/Sign.Core/ServiceProviderFactory.cs index a7405644..18863fef 100644 --- a/src/Sign.Core/ServiceProviderFactory.cs +++ b/src/Sign.Core/ServiceProviderFactory.cs @@ -9,7 +9,7 @@ namespace Sign.Core { internal sealed class ServiceProviderFactory : IServiceProviderFactory { - private Action? _servicesToAdd; + private Action? _addServices; public IServiceProvider Create( LogLevel logLevel = LogLevel.Information, @@ -17,19 +17,19 @@ public IServiceProvider Create( Action? addServices = null) { - if (_servicesToAdd is not null) + if (_addServices is not null) { - addServices += _servicesToAdd; + addServices += _addServices; } return ServiceProvider.CreateDefault(logLevel, loggerProvider, addServices); } - public void AddServices(Action services) + public void AddServices(Action addServices) { - ArgumentNullException.ThrowIfNull(services, nameof(services)); + ArgumentNullException.ThrowIfNull(addServices, nameof(addServices)); - _servicesToAdd += services; + _addServices += addServices; } } } diff --git a/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs b/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs index e6e8a50a..5353ecf3 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs +++ b/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs @@ -8,7 +8,6 @@ using Azure; using Azure.CodeSigning; -using Azure.CodeSigning.Models; using Microsoft.Extensions.Logging; @@ -18,8 +17,6 @@ namespace Sign.SignatureProviders.TrustedSigning { internal sealed class TrustedSigningService : ISignatureAlgorithmProvider, ICertificateProvider, IDisposable { - private static readonly SignRequest _emptyRequest = new(SignatureAlgorithm.RS256, new byte[32]); - private readonly CertificateProfileClient _client; private readonly string _accountName; private readonly string _certificateProfileName; @@ -81,7 +78,7 @@ public async Task GetCertificateAsync(CancellationToken cancel _logger.LogTrace(Resources.FetchedCertificate, stopwatch.Elapsed.TotalMilliseconds); //print the certificate info - _logger.LogTrace(Resources.CertificateDetails, _certificate.ToString(true)); + _logger.LogTrace(Resources.CertificateDetails, _certificate.ToString(verbose: true)); response.Value.Dispose(); } diff --git a/test/Sign.Cli.Test/TestInfrastructure/TestServiceProviderFactory.cs b/test/Sign.Cli.Test/TestInfrastructure/TestServiceProviderFactory.cs index 28deb7ec..38877a81 100644 --- a/test/Sign.Cli.Test/TestInfrastructure/TestServiceProviderFactory.cs +++ b/test/Sign.Cli.Test/TestInfrastructure/TestServiceProviderFactory.cs @@ -26,7 +26,7 @@ public IServiceProvider Create( return _serviceProvider; } - public void AddServices(Action services) + public void AddServices(Action addServices) { } } } From 67fb84ebc7f255174ca1743b4c48b3f9800c1a4e Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Wed, 11 Dec 2024 16:52:43 -0500 Subject: [PATCH 07/17] Update editorconfig to match VS output, add additioal rules and sort existing ones to match. --- .editorconfig | 273 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 270 insertions(+), 3 deletions(-) diff --git a/.editorconfig b/.editorconfig index e38f8b14..364e97d2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,14 +5,282 @@ insert_final_newline = true indent_style = space indent_size = 4 trim_trailing_whitespace = true +dotnet_style_allow_multiple_blank_lines_experimental = true:silent [*.{csproj,md,props,targets,yml}] indent_size = 2 [*.cs] +#### Core EditorConfig Options #### -# IDE0063: Use simple 'using' statement -csharp_prefer_simple_using_statement = false +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 + +# New line preferences +end_of_line = crlf + +#### .NET Code Actions #### + +# Type members +dotnet_hide_advanced_members = false +dotnet_member_insertion_location = with_other_members_of_the_same_kind +dotnet_property_generation_behavior = prefer_auto_properties + +# Symbol search +dotnet_search_reference_assemblies = true + +# Organize usings +dotnet_separate_import_directive_groups = true +dotnet_sort_system_directives_first = true +file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.\nSee the LICENSE.txt file in the project root for more information. + +# this. and Me. preferences +dotnet_style_qualification_for_field = false:silent +dotnet_style_qualification_for_property = false:silent +dotnet_style_qualification_for_method = false:silent +dotnet_style_qualification_for_event = false:silent + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent + +# Expression-level preferences +dotnet_prefer_system_hash_code = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_namespace_match_folder = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_operator_placement_when_wrapping = beginning_of_line +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed:suggestion +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion +dotnet_style_prefer_simplified_boolean_expressions = true:suggestion +dotnet_style_prefer_simplified_interpolation = true:suggestion + +# Field preferences +dotnet_style_readonly_field = true:suggestion + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:warning + +# Suppression preferences +dotnet_remove_unnecessary_suppression_exclusions = none + +# New line preferences +dotnet_style_allow_multiple_blank_lines_experimental = true:silent +dotnet_style_allow_statement_immediately_after_block_experimental = true:silent + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = false:silent +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = false:silent + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_prefer_extended_property_pattern = true:suggestion +csharp_style_prefer_not_pattern = true:suggestion +csharp_style_prefer_pattern_matching = true:silent +csharp_style_prefer_switch_expression = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_prefer_static_anonymous_function = true:suggestion +csharp_prefer_static_local_function = true:suggestion +csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async +csharp_style_prefer_readonly_struct = true:suggestion +csharp_style_prefer_readonly_struct_member = true:suggestion + +# Code-block preferences +csharp_prefer_braces = true:silent +csharp_prefer_simple_using_statement = false:suggestion +csharp_prefer_system_threading_lock = true:suggestion +csharp_style_namespace_declarations = block_scoped:silent +csharp_style_prefer_method_group_conversion = true:silent +csharp_style_prefer_primary_constructors = true:suggestion +csharp_style_prefer_top_level_statements = true:silent + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_local_over_anonymous_function = true:suggestion +csharp_style_prefer_null_check_over_type_check = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_prefer_tuple_swap = true:suggestion +csharp_style_prefer_utf8_string_literals = true:suggestion +csharp_style_throw_expression = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# 'using' directive preferences +csharp_using_directive_placement = outside_namespace:silent + +# New line preferences +csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent +csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent +csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent +csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent +csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true:silent +csharp_new_line_before_else = true:silent +csharp_new_line_before_finally = true:silent +csharp_new_line_before_members_in_anonymous_types = true:silent +csharp_new_line_before_members_in_object_initializers = true:silent +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true:silent + +# Indentation preferences +csharp_indent_block_contents = true:suggestion +csharp_indent_braces = false:suggestion +csharp_indent_case_contents = true:suggestion +csharp_indent_case_contents_when_block = true:suggestion +csharp_indent_labels = no_change +csharp_indent_switch_labels = true:suggestion + +# Space preferences +csharp_space_after_cast = false:silent +csharp_space_after_colon_in_inheritance_clause = true:silent +csharp_space_after_comma = true:silent +csharp_space_after_dot = false:silent +csharp_space_after_keywords_in_control_flow_statements = true:silent +csharp_space_after_semicolon_in_for_statement = true:silent +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false:silent +csharp_space_before_colon_in_inheritance_clause = true:silent +csharp_space_before_comma = false:silent +csharp_space_before_dot = false:silent +csharp_space_before_open_square_brackets = false:silent +csharp_space_before_semicolon_in_for_statement = false:silent +csharp_space_between_empty_square_brackets = false:silent +csharp_space_between_method_call_empty_parameter_list_parentheses = false:silent +csharp_space_between_method_call_name_and_opening_parenthesis = false:silent +csharp_space_between_method_call_parameter_list_parentheses = false:silent +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false:silent +csharp_space_between_method_declaration_name_and_open_parenthesis = false:silent +csharp_space_between_method_declaration_parameter_list_parentheses = false:silent +csharp_space_between_parentheses = false:silent +csharp_space_between_square_brackets = false:silent + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +#### Naming styles #### + +# Naming rules + +dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion +dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface +dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i + +dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.types_should_be_pascal_case.symbols = types +dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion +dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members +dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case + +dotnet_naming_rule.private_fields_underscored.severity = error +dotnet_naming_rule.private_fields_underscored.symbols = private_fields +dotnet_naming_rule.private_fields_underscored.style = underscored + +dotnet_naming_rule.private_static_fields_none.severity = none +dotnet_naming_rule.private_static_fields_none.symbols = private_static_fields +dotnet_naming_rule.private_static_fields_none.style = underscored + + +# Symbol specifications + +dotnet_naming_symbols.interface.applicable_kinds = interface +dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.interface.required_modifiers = + +dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum +dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.types.required_modifiers = + +dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method +dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected +dotnet_naming_symbols.non_field_members.required_modifiers = + +dotnet_naming_symbols.private_fields.applicable_kinds = field +dotnet_naming_symbols.private_fields.applicable_accessibilities = private + +dotnet_naming_symbols.private_static_fields.applicable_kinds = field +dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private +dotnet_naming_symbols.private_static_fields.required_modifiers = static + +# Naming styles + +dotnet_naming_style.begins_with_i.required_prefix = I +dotnet_naming_style.begins_with_i.required_suffix = +dotnet_naming_style.begins_with_i.word_separator = +dotnet_naming_style.begins_with_i.capitalization = pascal_case + +dotnet_naming_style.pascal_case.required_prefix = +dotnet_naming_style.pascal_case.required_suffix = +dotnet_naming_style.pascal_case.word_separator = +dotnet_naming_style.pascal_case.capitalization = pascal_case + +dotnet_naming_style.underscored.capitalization = +dotnet_naming_style.underscored.required_prefix = _ + + + +# Analyzers # CA2254: Template should be a static expression # See https://github.com/dotnet/roslyn-analyzers/issues/5626 @@ -20,4 +288,3 @@ dotnet_diagnostic.CA2254.severity = none # IDE0073: File header dotnet_diagnostic.IDE0073.severity = warning -file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.\nSee the LICENSE.txt file in the project root for more information. From a59fe63710681f42107e575bce34807eae4d3271 Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Thu, 12 Dec 2024 13:01:17 -0500 Subject: [PATCH 08/17] Wrapped the Stream object in a using statement to ensure it is properly disposed of after use. --- .../TrustedSigningService.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs b/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs index 5353ecf3..cd70d006 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs +++ b/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs @@ -67,20 +67,21 @@ public async Task GetCertificateAsync(CancellationToken cancel Response response = await _client.GetSignCertificateChainAsync(_accountName, _certificateProfileName, cancellationToken: cancellationToken); - byte[] rawData = new byte[response.Value.Length]; - response.Value.Read(rawData, 0, rawData.Length); + using (response.Value) + { + byte[] rawData = new byte[response.Value.Length]; + response.Value.Read(rawData, 0, rawData.Length); - X509Certificate2Collection collection = []; - collection.Import(rawData); + X509Certificate2Collection collection = []; + collection.Import(rawData); - // This should contain the certificate chain in root->leaf order. - _certificate = collection[collection.Count - 1]; + // This should contain the certificate chain in root->leaf order. + _certificate = collection[collection.Count - 1]; - _logger.LogTrace(Resources.FetchedCertificate, stopwatch.Elapsed.TotalMilliseconds); - //print the certificate info - _logger.LogTrace(Resources.CertificateDetails, _certificate.ToString(verbose: true)); - - response.Value.Dispose(); + _logger.LogTrace(Resources.FetchedCertificate, stopwatch.Elapsed.TotalMilliseconds); + //print the certificate info + _logger.LogTrace(Resources.CertificateDetails, _certificate.ToString(verbose: true)); + } } } finally From fdfe4254215a5a610402358142d8a4723b64ad54 Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Thu, 12 Dec 2024 14:34:30 -0500 Subject: [PATCH 09/17] Enhance Azure Key Vault integration - Updated `AzureKeyVaultCommand.cs` to construct and validate URIs for certificates and keys using Azure SDK, and configured Azure clients and services with dependency injection so logging forwards through. - Added `InvalidKeyVaultUrl` localized string in `AzureKeyVaultResources.Designer.cs` and updated `AzureKeyVaultResources.resx`. - Refactored `KeyVaultService.cs` to use `CertificateClient` and `CryptographyClient` for simplified service operations. - Simplified `KeyVaultServiceProvider.cs` by using dependency injection for `KeyVaultService` retrieval. - Removed `PrivateAssets` attribute from `Azure.Security.KeyVault.Certificates` and `Azure.Security.KeyVault.Keys` in `Sign.SignatureProviders.KeyVault.csproj` for runtime availability. --- src/Sign.Cli/AzureKeyVaultCommand.cs | 52 ++++++++++++++++++- .../AzureKeyVaultResources.Designer.cs | 9 ++++ src/Sign.Cli/AzureKeyVaultResources.resx | 3 ++ .../xlf/AzureKeyVaultResources.cs.xlf | 5 ++ .../xlf/AzureKeyVaultResources.de.xlf | 5 ++ .../xlf/AzureKeyVaultResources.es.xlf | 5 ++ .../xlf/AzureKeyVaultResources.fr.xlf | 5 ++ .../xlf/AzureKeyVaultResources.it.xlf | 5 ++ .../xlf/AzureKeyVaultResources.ja.xlf | 5 ++ .../xlf/AzureKeyVaultResources.ko.xlf | 5 ++ .../xlf/AzureKeyVaultResources.pl.xlf | 5 ++ .../xlf/AzureKeyVaultResources.pt-BR.xlf | 5 ++ .../xlf/AzureKeyVaultResources.ru.xlf | 5 ++ .../xlf/AzureKeyVaultResources.tr.xlf | 5 ++ .../xlf/AzureKeyVaultResources.zh-Hans.xlf | 5 ++ .../xlf/AzureKeyVaultResources.zh-Hant.xlf | 5 ++ .../KeyVaultService.cs | 26 +++++----- .../KeyVaultServiceProvider.cs | 48 ++--------------- .../Sign.SignatureProviders.KeyVault.csproj | 4 +- 19 files changed, 146 insertions(+), 61 deletions(-) diff --git a/src/Sign.Cli/AzureKeyVaultCommand.cs b/src/Sign.Cli/AzureKeyVaultCommand.cs index d6616635..8dadea3f 100644 --- a/src/Sign.Cli/AzureKeyVaultCommand.cs +++ b/src/Sign.Cli/AzureKeyVaultCommand.cs @@ -5,7 +5,16 @@ using System.CommandLine; using System.CommandLine.Invocation; using System.CommandLine.IO; + using Azure.Core; +using Azure.Security.KeyVault.Certificates; +using Azure.Security.KeyVault.Keys; +using Azure.Security.KeyVault.Keys.Cryptography; + +using Microsoft.Extensions.Azure; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; + using Sign.Core; using Sign.SignatureProviders.KeyVault; @@ -65,7 +74,48 @@ internal AzureKeyVaultCommand(CodeCommand codeCommand, IServiceProviderFactory s Uri url = context.ParseResult.GetValueForOption(UrlOption)!; string certificateId = context.ParseResult.GetValueForOption(CertificateOption)!; - KeyVaultServiceProvider keyVaultServiceProvider = new(credential, url, certificateId); + // Construct the URI for the certificate and the key from user parameters. We'll validate those with the SDK + var certUri = new Uri($"{url.Scheme}://{url.Authority}/certificates/{certificateId}"); + + if (!KeyVaultCertificateIdentifier.TryCreate(certUri, out var certId)) + { + context.Console.Error.WriteLine(AzureKeyVaultResources.InvalidKeyVaultUrl); + context.ExitCode = ExitCode.InvalidOptions; + return; + } + + // The key uri is similar and the key name matches the certificate name + var keyUri = new Uri($"{url.Scheme}://{url.Authority}/keys/{certificateId}"); + + if (!KeyVaultKeyIdentifier.TryCreate(certUri, out var keyId)) + { + context.Console.Error.WriteLine(AzureKeyVaultResources.InvalidKeyVaultUrl); + context.ExitCode = ExitCode.InvalidOptions; + return; + } + + serviceProviderFactory.AddServices(services => + { + services.AddAzureClients(builder => + { + builder.AddCertificateClient(certId.VaultUri); + builder.AddKeyClient(keyId.VaultUri); + builder.UseCredential(credential); + builder.ConfigureDefaults(options => options.Retry.Mode = RetryMode.Exponential); + }); + + services.AddSingleton(serviceProvider => + { + return new KeyVaultService( + serviceProvider.GetRequiredService(), + serviceProvider.GetRequiredService(), + certId.Name, + serviceProvider.GetRequiredService>()); + }); + }); + + + KeyVaultServiceProvider keyVaultServiceProvider = new(); await codeCommand.HandleAsync(context, serviceProviderFactory, keyVaultServiceProvider, fileArgument); }); } diff --git a/src/Sign.Cli/AzureKeyVaultResources.Designer.cs b/src/Sign.Cli/AzureKeyVaultResources.Designer.cs index ae840eba..6e23bb0d 100644 --- a/src/Sign.Cli/AzureKeyVaultResources.Designer.cs +++ b/src/Sign.Cli/AzureKeyVaultResources.Designer.cs @@ -87,6 +87,15 @@ internal static string CommandDescription { } } + /// + /// Looks up a localized string similar to URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/). + /// + internal static string InvalidKeyVaultUrl { + get { + return ResourceManager.GetString("InvalidKeyVaultUrl", resourceCulture); + } + } + /// /// Looks up a localized string similar to URL to an Azure Key Vault.. /// diff --git a/src/Sign.Cli/AzureKeyVaultResources.resx b/src/Sign.Cli/AzureKeyVaultResources.resx index 97762b0d..6c853b10 100644 --- a/src/Sign.Cli/AzureKeyVaultResources.resx +++ b/src/Sign.Cli/AzureKeyVaultResources.resx @@ -126,6 +126,9 @@ Use Azure Key Vault. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL to an Azure Key Vault. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.cs.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.cs.xlf index 0c35af0d..12b535e8 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.cs.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.cs.xlf @@ -17,6 +17,11 @@ Použijte Azure Key Vault. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. Adresa URL Azure Key Vault. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.de.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.de.xlf index be16e6c8..a46ced0e 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.de.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.de.xlf @@ -17,6 +17,11 @@ Verwenden Sie Azure Key Vault. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. URL zu einem Azure Key Vault. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.es.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.es.xlf index 05cc2178..1be81985 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.es.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.es.xlf @@ -17,6 +17,11 @@ Use Azure Key Vault. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. Dirección URL a un Azure Key Vault. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.fr.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.fr.xlf index 0944b34e..594a64f8 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.fr.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.fr.xlf @@ -17,6 +17,11 @@ Utilisez Azure Key Vault. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. URL d’un Azure Key Vault. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.it.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.it.xlf index 41c944c4..6365b8f1 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.it.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.it.xlf @@ -17,6 +17,11 @@ Usare Azure Key Vault. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. URL a un Azure Key Vault. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.ja.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.ja.xlf index ea8b1e01..c5741136 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.ja.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.ja.xlf @@ -17,6 +17,11 @@ Azure Key Vault を使用してください。 + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. Azure Key Vault への URL。 diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.ko.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.ko.xlf index bf448e15..53eb626e 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.ko.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.ko.xlf @@ -17,6 +17,11 @@ Azure Key Vault를 사용합니다. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. Azure Key Vault에 대한 URL입니다. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.pl.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.pl.xlf index ec2a609b..14721e70 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.pl.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.pl.xlf @@ -17,6 +17,11 @@ Użyj usługi Azure Key Vault. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. Adres URL do usługi Azure Key Vault. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.pt-BR.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.pt-BR.xlf index 46c29ed6..4079c440 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.pt-BR.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.pt-BR.xlf @@ -17,6 +17,11 @@ Use o Azure Key Vault. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. URL para um Azure Key Vault. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.ru.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.ru.xlf index e1cc1b47..389dc7f3 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.ru.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.ru.xlf @@ -17,6 +17,11 @@ Использование Azure Key Vault. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. URL-адрес для Azure Key Vault. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.tr.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.tr.xlf index 60a93955..c856b8f9 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.tr.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.tr.xlf @@ -17,6 +17,11 @@ Azure Key Vault’u kullanın. + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. Azure Key Vault URL’si. diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.zh-Hans.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.zh-Hans.xlf index d6ec9934..6cab9d61 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.zh-Hans.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.zh-Hans.xlf @@ -17,6 +17,11 @@ 使用 Azure Key Vault。 + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. 指向 Azure Key Vault 的 URL。 diff --git a/src/Sign.Cli/xlf/AzureKeyVaultResources.zh-Hant.xlf b/src/Sign.Cli/xlf/AzureKeyVaultResources.zh-Hant.xlf index 4d51be73..fd743d71 100644 --- a/src/Sign.Cli/xlf/AzureKeyVaultResources.zh-Hant.xlf +++ b/src/Sign.Cli/xlf/AzureKeyVaultResources.zh-Hant.xlf @@ -17,6 +17,11 @@ 使用 Azure Key Vault。 + + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + URL must only contain the protocol and host. (e.g.: https://<vault-name>.vault.azure.net/) + + URL to an Azure Key Vault. Azure Key Vault 的 URL。 diff --git a/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs b/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs index 3876f2c6..086cd1c9 100644 --- a/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs +++ b/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs @@ -5,38 +5,40 @@ using System.Diagnostics; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; + using Azure; -using Azure.Core; using Azure.Security.KeyVault.Certificates; using Azure.Security.KeyVault.Keys.Cryptography; + using Microsoft.Extensions.Logging; + using Sign.Core; namespace Sign.SignatureProviders.KeyVault { internal sealed class KeyVaultService : ISignatureAlgorithmProvider, ICertificateProvider, IDisposable { - private readonly TokenCredential _tokenCredential; - private readonly Uri _keyVaultUrl; + private readonly CertificateClient _certificateClient; + private readonly CryptographyClient _cryptographyClient; private readonly string _certificateName; private readonly ILogger _logger; private readonly SemaphoreSlim _mutex = new(1); private KeyVaultCertificateWithPolicy? _certificateWithPolicy; internal KeyVaultService( - TokenCredential tokenCredential, - Uri keyVaultUrl, + CertificateClient certificateClient, + CryptographyClient cryptographyClient, string certificateName, ILogger logger) { - ArgumentNullException.ThrowIfNull(tokenCredential, nameof(tokenCredential)); - ArgumentNullException.ThrowIfNull(keyVaultUrl, nameof(keyVaultUrl)); + ArgumentNullException.ThrowIfNull(certificateClient, nameof(certificateClient)); + ArgumentNullException.ThrowIfNull(cryptographyClient, nameof(cryptographyClient)); ArgumentException.ThrowIfNullOrEmpty(certificateName, nameof(certificateName)); ArgumentNullException.ThrowIfNull(logger, nameof(logger)); - _tokenCredential = tokenCredential; - _keyVaultUrl = keyVaultUrl; _certificateName = certificateName; + _certificateClient = certificateClient; + _cryptographyClient = cryptographyClient; _logger = logger; } @@ -57,8 +59,7 @@ public async Task GetRsaAsync(CancellationToken cancellationToken) { KeyVaultCertificateWithPolicy certificateWithPolicy = await GetCertificateWithPolicyAsync(cancellationToken); - CryptographyClient cryptoClient = new(certificateWithPolicy.KeyId, _tokenCredential); - return await cryptoClient.CreateRSAAsync(cancellationToken); + return await _cryptographyClient.CreateRSAAsync(cancellationToken); } private async Task GetCertificateWithPolicyAsync(CancellationToken cancellationToken) @@ -78,8 +79,7 @@ private async Task GetCertificateWithPolicyAsync( _logger.LogTrace(Resources.FetchingCertificate); - CertificateClient client = new(_keyVaultUrl, _tokenCredential); - Response response = await client.GetCertificateAsync(_certificateName, cancellationToken); + Response response = await _certificateClient.GetCertificateAsync(_certificateName, cancellationToken); _logger.LogTrace(Resources.FetchedCertificate, stopwatch.Elapsed.TotalMilliseconds); diff --git a/src/Sign.SignatureProviders.KeyVault/KeyVaultServiceProvider.cs b/src/Sign.SignatureProviders.KeyVault/KeyVaultServiceProvider.cs index 4e8ebf3e..d9de7294 100644 --- a/src/Sign.SignatureProviders.KeyVault/KeyVaultServiceProvider.cs +++ b/src/Sign.SignatureProviders.KeyVault/KeyVaultServiceProvider.cs @@ -2,68 +2,26 @@ // 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 Azure.Core; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; + using Sign.Core; namespace Sign.SignatureProviders.KeyVault { internal sealed class KeyVaultServiceProvider : ISignatureProvider { - private readonly string _certificateName; - private readonly Uri _keyVaultUrl; - private readonly TokenCredential _tokenCredential; - private readonly object _lockObject = new(); - private KeyVaultService? _keyVaultService; - - internal KeyVaultServiceProvider( - TokenCredential tokenCredential, - Uri keyVaultUrl, - string certificateName) - { - ArgumentNullException.ThrowIfNull(tokenCredential, nameof(tokenCredential)); - ArgumentNullException.ThrowIfNull(keyVaultUrl, nameof(keyVaultUrl)); - ArgumentException.ThrowIfNullOrEmpty(certificateName, nameof(certificateName)); - - _tokenCredential = tokenCredential; - _keyVaultUrl = keyVaultUrl; - _certificateName = certificateName; - } - public ISignatureAlgorithmProvider GetSignatureAlgorithmProvider(IServiceProvider serviceProvider) { ArgumentNullException.ThrowIfNull(serviceProvider, nameof(serviceProvider)); - return GetService(serviceProvider); + return serviceProvider.GetRequiredService(); } public ICertificateProvider GetCertificateProvider(IServiceProvider serviceProvider) { ArgumentNullException.ThrowIfNull(serviceProvider, nameof(serviceProvider)); - return GetService(serviceProvider); - } - - private KeyVaultService GetService(IServiceProvider serviceProvider) - { - if (_keyVaultService is not null) - { - return _keyVaultService; - } - - lock (_lockObject) - { - if (_keyVaultService is not null) - { - return _keyVaultService; - } - - ILogger logger = serviceProvider.GetRequiredService>(); - _keyVaultService = new KeyVaultService(_tokenCredential, _keyVaultUrl, _certificateName, logger); - } - - return _keyVaultService; + return serviceProvider.GetRequiredService(); } } } diff --git a/src/Sign.SignatureProviders.KeyVault/Sign.SignatureProviders.KeyVault.csproj b/src/Sign.SignatureProviders.KeyVault/Sign.SignatureProviders.KeyVault.csproj index 4c783594..9c630e68 100644 --- a/src/Sign.SignatureProviders.KeyVault/Sign.SignatureProviders.KeyVault.csproj +++ b/src/Sign.SignatureProviders.KeyVault/Sign.SignatureProviders.KeyVault.csproj @@ -7,8 +7,8 @@ - - + + From 425cfa8021cc732f675face006a90ec0e2dfe4bf Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Thu, 12 Dec 2024 15:22:51 -0500 Subject: [PATCH 10/17] Add additional logging Also avoids unused parameter error --- src/Sign.Core/Tools/NuGet/NuGetSignatureProvider.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Sign.Core/Tools/NuGet/NuGetSignatureProvider.cs b/src/Sign.Core/Tools/NuGet/NuGetSignatureProvider.cs index 3bb8b35c..e2efc994 100644 --- a/src/Sign.Core/Tools/NuGet/NuGetSignatureProvider.cs +++ b/src/Sign.Core/Tools/NuGet/NuGetSignatureProvider.cs @@ -7,6 +7,7 @@ using System.Security.Cryptography.Pkcs; using System.Security.Cryptography.X509Certificates; using System.Text; + using NuGet.Common; using NuGet.Packaging.Signing; @@ -76,6 +77,7 @@ private async Task CreateAuthorSignatureAsync( private PrimarySignature CreatePrimarySignature(AuthorSignPackageRequest request, SignatureContent signatureContent, ILogger logger) { + logger.LogInformation($"{nameof(CreateAuthorSignatureAsync)}: Retrieving certificate chain"); const string PropertyName = "Chain"; PropertyInfo? property = typeof(SignPackageRequest) @@ -94,6 +96,10 @@ private PrimarySignature CreatePrimarySignature(AuthorSignPackageRequest request } var certificates = (IReadOnlyList?)getter.Invoke(request, parameters: null); + logger.LogInformation($"{nameof(CreateAuthorSignatureAsync)}: Retrieved certificate chain"); + + + logger.LogInformation($"{nameof(CreateAuthorSignatureAsync)}: Computing signature"); CmsSigner cmsSigner = CreateCmsSigner(request, certificates!); ContentInfo contentInfo = new(signatureContent.GetBytes()); SignedCms signedCms = new(contentInfo); @@ -108,6 +114,8 @@ private PrimarySignature CreatePrimarySignature(AuthorSignPackageRequest request stringBuilder.AppendLine("Invalid _rsa type"); stringBuilder.AppendLine(CertificateUtility.X509Certificate2ToString(request.Certificate, NuGet.Common.HashAlgorithmName.SHA256)); + logger.LogError($"{nameof(CreateAuthorSignatureAsync)}: Cannot read private key"); + throw new SignatureException(NuGetLogCode.NU3001, stringBuilder.ToString()); } From a348fe663216100588833272fa1fab708e9193e2 Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Thu, 12 Dec 2024 15:45:25 -0500 Subject: [PATCH 11/17] Refactor KeyVaultService and update tests --- .../KeyVaultService.cs | 35 ++++---- .../Resources.Designer.cs | 9 ++ .../Resources.resx | 3 + .../KeyVaultServiceProviderTests.cs | 82 +++++-------------- 4 files changed, 48 insertions(+), 81 deletions(-) diff --git a/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs b/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs index 086cd1c9..2a5458d9 100644 --- a/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs +++ b/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs @@ -23,7 +23,7 @@ internal sealed class KeyVaultService : ISignatureAlgorithmProvider, ICertificat private readonly string _certificateName; private readonly ILogger _logger; private readonly SemaphoreSlim _mutex = new(1); - private KeyVaultCertificateWithPolicy? _certificateWithPolicy; + private X509Certificate2? _certificate; internal KeyVaultService( CertificateClient certificateClient, @@ -45,35 +45,22 @@ internal KeyVaultService( public void Dispose() { _mutex.Dispose(); + _certificate?.Dispose(); GC.SuppressFinalize(this); } public async Task GetCertificateAsync(CancellationToken cancellationToken) { - KeyVaultCertificateWithPolicy certificateWithPolicy = await GetCertificateWithPolicyAsync(cancellationToken); - - return new X509Certificate2(certificateWithPolicy.Cer); - } - - public async Task GetRsaAsync(CancellationToken cancellationToken) - { - KeyVaultCertificateWithPolicy certificateWithPolicy = await GetCertificateWithPolicyAsync(cancellationToken); - - return await _cryptographyClient.CreateRSAAsync(cancellationToken); - } - - private async Task GetCertificateWithPolicyAsync(CancellationToken cancellationToken) - { - if (_certificateWithPolicy is not null) + if (_certificate is not null) { - return _certificateWithPolicy; + return new X509Certificate2(_certificate); // clone it as it's disposable } await _mutex.WaitAsync(cancellationToken); try { - if (_certificateWithPolicy is null) + if (_certificate is null) { Stopwatch stopwatch = Stopwatch.StartNew(); @@ -83,7 +70,10 @@ private async Task GetCertificateWithPolicyAsync( _logger.LogTrace(Resources.FetchedCertificate, stopwatch.Elapsed.TotalMilliseconds); - _certificateWithPolicy = response.Value; + _certificate = new X509Certificate2(response.Value.Cer); + + //print the certificate info + _logger.LogTrace(Resources.CertificateDetails, _certificate.ToString(verbose: true)); } } finally @@ -91,7 +81,12 @@ private async Task GetCertificateWithPolicyAsync( _mutex.Release(); } - return _certificateWithPolicy; + return new X509Certificate2(_certificate); // clone it as it's disposable + } + + public async Task GetRsaAsync(CancellationToken cancellationToken) + { + return await _cryptographyClient.CreateRSAAsync(cancellationToken); } } } diff --git a/src/Sign.SignatureProviders.KeyVault/Resources.Designer.cs b/src/Sign.SignatureProviders.KeyVault/Resources.Designer.cs index 41cc61ea..035994b4 100644 --- a/src/Sign.SignatureProviders.KeyVault/Resources.Designer.cs +++ b/src/Sign.SignatureProviders.KeyVault/Resources.Designer.cs @@ -60,6 +60,15 @@ internal Resources() { } } + /// + /// Looks up a localized string similar to Certificate Details:\n{details}. + /// + internal static string CertificateDetails { + get { + return ResourceManager.GetString("CertificateDetails", resourceCulture); + } + } + /// /// Looks up a localized string similar to Fetched certificate. [{milliseconds} ms]. /// diff --git a/src/Sign.SignatureProviders.KeyVault/Resources.resx b/src/Sign.SignatureProviders.KeyVault/Resources.resx index 8db53377..a63a2574 100644 --- a/src/Sign.SignatureProviders.KeyVault/Resources.resx +++ b/src/Sign.SignatureProviders.KeyVault/Resources.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Certificate Details:\n{details} + Fetched certificate. [{milliseconds} ms] {Placeholder="{milliseconds}"} is a decimal number representing the number of milliseconds elapsed, and "ms" is the unit abbreviation for milliseconds. diff --git a/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceProviderTests.cs b/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceProviderTests.cs index a2bd8908..75c95a1d 100644 --- a/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceProviderTests.cs +++ b/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceProviderTests.cs @@ -2,21 +2,15 @@ // 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.Collections.Concurrent; -using Azure.Core; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Moq; -using Sign.Core; + using Sign.TestInfrastructure; namespace Sign.SignatureProviders.KeyVault.Test { public class KeyVaultServiceProviderTests { - private readonly static TokenCredential TokenCredential = Mock.Of(); - private readonly static Uri KeyVaultUrl = new("https://keyvault.test"); - private const string CertificateName = "a"; private readonly IServiceProvider serviceProvider; public KeyVaultServiceProviderTests() @@ -26,46 +20,10 @@ public KeyVaultServiceProviderTests() serviceProvider = services.BuildServiceProvider(); } - [Fact] - public void Constructor_WhenTokenCredentialIsNull_Throws() - { - ArgumentNullException exception = Assert.Throws( - () => new KeyVaultServiceProvider(tokenCredential: null!, KeyVaultUrl, CertificateName)); - - Assert.Equal("tokenCredential", exception.ParamName); - } - - [Fact] - public void Constructor_WhenKeyVaultUrlIsNull_Throws() - { - ArgumentNullException exception = Assert.Throws( - () => new KeyVaultServiceProvider(TokenCredential, keyVaultUrl: null!, CertificateName)); - - Assert.Equal("keyVaultUrl", exception.ParamName); - } - - [Fact] - public void Constructor_WhenCertificateNameIsNull_Throws() - { - ArgumentNullException exception = Assert.Throws( - () => new KeyVaultServiceProvider(TokenCredential, KeyVaultUrl, certificateName: null!)); - - Assert.Equal("certificateName", exception.ParamName); - } - - [Fact] - public void Constructor_WhenCertificateNameIsEmpty_Throws() - { - ArgumentException exception = Assert.Throws( - () => new KeyVaultServiceProvider(TokenCredential, KeyVaultUrl, certificateName: string.Empty)); - - Assert.Equal("certificateName", exception.ParamName); - } - [Fact] public void GetSignatureAlgorithmProvider_WhenServiceProviderIsNull_Throws() { - KeyVaultServiceProvider provider = new(TokenCredential, KeyVaultUrl, CertificateName); + KeyVaultServiceProvider provider = new(); ArgumentNullException exception = Assert.Throws( () => provider.GetSignatureAlgorithmProvider(serviceProvider: null!)); @@ -76,22 +34,23 @@ public void GetSignatureAlgorithmProvider_WhenServiceProviderIsNull_Throws() [Fact] public void GetSignatureAlgorithmProvider_ReturnsSameInstance() { - KeyVaultServiceProvider provider = new(TokenCredential, KeyVaultUrl, CertificateName); + KeyVaultServiceProvider provider = new(); - ConcurrentBag signatureAlgorithmProviders = []; - Parallel.For(0, 2, (_, _) => - { - signatureAlgorithmProviders.Add(provider.GetSignatureAlgorithmProvider(serviceProvider)); - }); + // TODO: Write tests + //ConcurrentBag signatureAlgorithmProviders = []; + //Parallel.For(0, 2, (_, _) => + //{ + // signatureAlgorithmProviders.Add(provider.GetSignatureAlgorithmProvider(serviceProvider)); + //}); - Assert.Equal(2, signatureAlgorithmProviders.Count); - Assert.Same(signatureAlgorithmProviders.First(), signatureAlgorithmProviders.Last()); + //Assert.Equal(2, signatureAlgorithmProviders.Count); + //Assert.Same(signatureAlgorithmProviders.First(), signatureAlgorithmProviders.Last()); } [Fact] public void GetCertificateProvider_WhenServiceProviderIsNull_Throws() { - KeyVaultServiceProvider provider = new(TokenCredential, KeyVaultUrl, CertificateName); + KeyVaultServiceProvider provider = new(); ArgumentNullException exception = Assert.Throws( () => provider.GetSignatureAlgorithmProvider(serviceProvider: null!)); @@ -102,16 +61,17 @@ public void GetCertificateProvider_WhenServiceProviderIsNull_Throws() [Fact] public void GetCertificateProvider_ReturnsSameInstance() { - KeyVaultServiceProvider provider = new(TokenCredential, KeyVaultUrl, CertificateName); + KeyVaultServiceProvider provider = new(); - ConcurrentBag certificateProviders = []; - Parallel.For(0, 2, (_, _) => - { - certificateProviders.Add(provider.GetCertificateProvider(serviceProvider)); - }); + // TODO: Write tests + //ConcurrentBag certificateProviders = []; + //Parallel.For(0, 2, (_, _) => + //{ + // certificateProviders.Add(provider.GetCertificateProvider(serviceProvider)); + //}); - Assert.Equal(2, certificateProviders.Count); - Assert.Same(certificateProviders.First(), certificateProviders.Last()); + //Assert.Equal(2, certificateProviders.Count); + //Assert.Same(certificateProviders.First(), certificateProviders.Last()); } } } From ec80c5886b965a5fefaa8dc5dd93a682c9c47db3 Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Fri, 13 Dec 2024 11:49:40 -0500 Subject: [PATCH 12/17] Update tests --- .../xlf/Resources.cs.xlf | 5 ++++ .../xlf/Resources.de.xlf | 5 ++++ .../xlf/Resources.es.xlf | 5 ++++ .../xlf/Resources.fr.xlf | 5 ++++ .../xlf/Resources.it.xlf | 5 ++++ .../xlf/Resources.ja.xlf | 5 ++++ .../xlf/Resources.ko.xlf | 5 ++++ .../xlf/Resources.pl.xlf | 5 ++++ .../xlf/Resources.pt-BR.xlf | 5 ++++ .../xlf/Resources.ru.xlf | 5 ++++ .../xlf/Resources.tr.xlf | 5 ++++ .../xlf/Resources.zh-Hans.xlf | 5 ++++ .../xlf/Resources.zh-Hant.xlf | 5 ++++ .../ServiceProviderFactoryTests.cs | 2 +- .../KeyVaultServiceTests.cs | 29 ++++++++++--------- 15 files changed, 82 insertions(+), 14 deletions(-) diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.cs.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.cs.xlf index c66d047d..56c8d426 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.cs.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.cs.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Načetl se certifikát. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.de.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.de.xlf index 854640b6..3fc60b7c 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.de.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.de.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Zertifikat abgerufen. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.es.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.es.xlf index 932b4b8b..9ef60e10 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.es.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.es.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Certificado capturado. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.fr.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.fr.xlf index 5ffecba0..886ba6a6 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.fr.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.fr.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Certificat récupéré. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.it.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.it.xlf index 5a7e64f4..74bcb3c6 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.it.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.it.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Il certificato è stato recuperato. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ja.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ja.xlf index 42778df7..a12f1991 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ja.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ja.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] 証明書をフェッチしました。[{milliseconds} ミリ秒] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ko.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ko.xlf index 620a6607..b9918433 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ko.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ko.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] 인증서를 가져왔습니다. [{milliseconds}ms] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pl.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pl.xlf index 5381181f..85e0f6eb 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pl.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pl.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Pobrano certyfikat. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pt-BR.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pt-BR.xlf index 2db196f9..651cffb9 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pt-BR.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pt-BR.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Certificado buscado. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ru.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ru.xlf index a1c99396..5dd751d2 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ru.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ru.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Получен сертификат. [{milliseconds} мс] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.tr.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.tr.xlf index d4487949..a0b9ef21 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.tr.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.tr.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] Sertifika getirildi. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hans.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hans.xlf index ae0ba91d..3104935d 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hans.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hans.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] 已提取证书。[{milliseconds} 毫秒] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hant.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hant.xlf index ac9fdc9e..b21c1fdb 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hant.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hant.xlf @@ -2,6 +2,11 @@ + + Certificate Details:\n{details} + Certificate Details:\n{details} + + Fetched certificate. [{milliseconds} ms] 已擷取憑證。[{milliseconds} 毫秒] diff --git a/test/Sign.Core.Test/ServiceProviderFactoryTests.cs b/test/Sign.Core.Test/ServiceProviderFactoryTests.cs index 40442ecd..79794153 100644 --- a/test/Sign.Core.Test/ServiceProviderFactoryTests.cs +++ b/test/Sign.Core.Test/ServiceProviderFactoryTests.cs @@ -17,7 +17,7 @@ public void AddService_ServicesIsNull_Throws() ArgumentNullException exception = Assert.Throws( () => factory.AddServices(null!)); - Assert.Equal("services", exception.ParamName); + Assert.Equal("addServices", exception.ParamName); } [Fact] diff --git a/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceTests.cs b/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceTests.cs index ebc1e164..0781e8d4 100644 --- a/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceTests.cs +++ b/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceTests.cs @@ -2,42 +2,45 @@ // 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 Azure.Core; +using Azure.Security.KeyVault.Certificates; +using Azure.Security.KeyVault.Keys.Cryptography; + using Microsoft.Extensions.Logging; + using Moq; namespace Sign.SignatureProviders.KeyVault.Test { public class KeyVaultServiceTests { - private readonly static TokenCredential TokenCredential = Mock.Of(); - private readonly static Uri KeyVaultUrl = new("https://keyvault.test"); + private static readonly CertificateClient CertificateClient = Mock.Of(); + private static readonly CryptographyClient CryptographyClient = Mock.Of(); private const string CertificateName = "a"; - private readonly static ILogger logger = Mock.Of>(); + private static readonly ILogger logger = Mock.Of>(); [Fact] - public void Constructor_WhenTokenCredentialIsNull_Throws() + public void Constructor_WhenCertificateClientIsNull_Throws() { ArgumentNullException exception = Assert.Throws( - () => new KeyVaultService(tokenCredential: null!, KeyVaultUrl, CertificateName, logger)); + () => new KeyVaultService(certificateClient: null!, CryptographyClient, CertificateName, logger)); - Assert.Equal("tokenCredential", exception.ParamName); + Assert.Equal("certificateClient", exception.ParamName); } [Fact] - public void Constructor_WhenKeyVaultUrlIsNull_Throws() + public void Constructor_WhenCryptographyClientIsNull_Throws() { ArgumentNullException exception = Assert.Throws( - () => new KeyVaultService(TokenCredential, keyVaultUrl: null!, CertificateName, logger)); + () => new KeyVaultService(CertificateClient, cryptographyClient: null!, CertificateName, logger)); - Assert.Equal("keyVaultUrl", exception.ParamName); + Assert.Equal("cryptographyClient", exception.ParamName); } [Fact] public void Constructor_WhenCertificateNameIsNull_Throws() { ArgumentNullException exception = Assert.Throws( - () => new KeyVaultService(TokenCredential, KeyVaultUrl, certificateName: null!, logger)); + () => new KeyVaultService(CertificateClient, CryptographyClient, certificateName: null!, logger)); Assert.Equal("certificateName", exception.ParamName); } @@ -46,7 +49,7 @@ public void Constructor_WhenCertificateNameIsNull_Throws() public void Constructor_WhenCertificateNameIsEmpty_Throws() { ArgumentException exception = Assert.Throws( - () => new KeyVaultService(TokenCredential, KeyVaultUrl, certificateName: string.Empty, logger)); + () => new KeyVaultService(CertificateClient, CryptographyClient, certificateName: string.Empty, logger)); Assert.Equal("certificateName", exception.ParamName); } @@ -55,7 +58,7 @@ public void Constructor_WhenCertificateNameIsEmpty_Throws() public void Constructor_WhenLoggerIsNull_Throws() { ArgumentNullException exception = Assert.Throws( - () => new KeyVaultService(TokenCredential, KeyVaultUrl, CertificateName, logger: null!)); + () => new KeyVaultService(CertificateClient, CryptographyClient, CertificateName, logger: null!)); Assert.Equal("logger", exception.ParamName); } From 727482ef2786936f2e4513bfb43f8889ec77151a Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Fri, 13 Dec 2024 12:01:40 -0500 Subject: [PATCH 13/17] Finish tests --- .../KeyVaultServiceProviderTests.cs | 34 ++++++++----------- .../TrustedSigningServiceProviderTests.cs | 20 ++++++++--- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceProviderTests.cs b/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceProviderTests.cs index 75c95a1d..fc5d1cd5 100644 --- a/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceProviderTests.cs +++ b/test/Sign.SignatureProviders.KeyVault.Test/KeyVaultServiceProviderTests.cs @@ -2,9 +2,14 @@ // 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 Azure.Security.KeyVault.Certificates; +using Azure.Security.KeyVault.Keys.Cryptography; + using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Moq; + using Sign.TestInfrastructure; namespace Sign.SignatureProviders.KeyVault.Test @@ -12,11 +17,18 @@ namespace Sign.SignatureProviders.KeyVault.Test public class KeyVaultServiceProviderTests { private readonly IServiceProvider serviceProvider; - public KeyVaultServiceProviderTests() { ServiceCollection services = new(); services.AddSingleton>(new TestLogger()); + services.AddSingleton(sp => + { + return new KeyVaultService( + Mock.Of(), + Mock.Of(), + "a", sp.GetRequiredService>() + ); + }); serviceProvider = services.BuildServiceProvider(); } @@ -36,15 +48,7 @@ public void GetSignatureAlgorithmProvider_ReturnsSameInstance() { KeyVaultServiceProvider provider = new(); - // TODO: Write tests - //ConcurrentBag signatureAlgorithmProviders = []; - //Parallel.For(0, 2, (_, _) => - //{ - // signatureAlgorithmProviders.Add(provider.GetSignatureAlgorithmProvider(serviceProvider)); - //}); - - //Assert.Equal(2, signatureAlgorithmProviders.Count); - //Assert.Same(signatureAlgorithmProviders.First(), signatureAlgorithmProviders.Last()); + Assert.IsType(provider.GetSignatureAlgorithmProvider(serviceProvider)); } [Fact] @@ -63,15 +67,7 @@ public void GetCertificateProvider_ReturnsSameInstance() { KeyVaultServiceProvider provider = new(); - // TODO: Write tests - //ConcurrentBag certificateProviders = []; - //Parallel.For(0, 2, (_, _) => - //{ - // certificateProviders.Add(provider.GetCertificateProvider(serviceProvider)); - //}); - - //Assert.Equal(2, certificateProviders.Count); - //Assert.Same(certificateProviders.First(), certificateProviders.Last()); + Assert.IsType(provider.GetSignatureAlgorithmProvider(serviceProvider)); } } } diff --git a/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceProviderTests.cs b/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceProviderTests.cs index d874a59d..6ea3dbb8 100644 --- a/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceProviderTests.cs +++ b/test/Sign.SignatureProviders.TrustedSigning.Test/TrustedSigningServiceProviderTests.cs @@ -2,9 +2,13 @@ // 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 Azure.CodeSigning; + using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Moq; + using Sign.TestInfrastructure; namespace Sign.SignatureProviders.TrustedSigning.Test @@ -17,6 +21,15 @@ public TrustedSigningServiceProviderTests() { ServiceCollection services = new(); services.AddSingleton>(new TestLogger()); + services.AddSingleton(sp => + { + return new TrustedSigningService( + Mock.Of(), + "account", + "profile", + sp.GetRequiredService>() + ); + }); serviceProvider = services.BuildServiceProvider(); } @@ -37,9 +50,7 @@ public void GetSignatureAlgorithmProvider_ReturnsInstance() { TrustedSigningServiceProvider provider = new(); - // TODO: Not sure how to test this without creating a CertificateProfileClient - //Assert.IsAssignableFrom(provider.GetSignatureAlgorithmProvider(serviceProvider)); - //Assert.IsAssignableFrom(provider.GetSignatureAlgorithmProvider(serviceProvider)); + Assert.IsType(provider.GetSignatureAlgorithmProvider(serviceProvider)); } [Fact] @@ -47,8 +58,7 @@ public void GetCertificateProvider_ReturnsInstance() { TrustedSigningServiceProvider provider = new(); - // TODO: Not sure how to test this without creating a CertificateProfileClient - //Assert.IsAssignableFrom(provider.GetSignatureAlgorithmProvider(serviceProvider)); + Assert.IsType(provider.GetSignatureAlgorithmProvider(serviceProvider)); } } } From c3ce79a26eff4076f66dbb01138347143e720caf Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Fri, 13 Dec 2024 12:03:34 -0500 Subject: [PATCH 14/17] Revert editorconfig update. separate pr for that --- .editorconfig | 273 +------------------------------------------------- 1 file changed, 3 insertions(+), 270 deletions(-) diff --git a/.editorconfig b/.editorconfig index 364e97d2..e38f8b14 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,282 +5,14 @@ insert_final_newline = true indent_style = space indent_size = 4 trim_trailing_whitespace = true -dotnet_style_allow_multiple_blank_lines_experimental = true:silent [*.{csproj,md,props,targets,yml}] indent_size = 2 [*.cs] -#### Core EditorConfig Options #### -# Indentation and spacing -indent_size = 4 -indent_style = space -tab_width = 4 - -# New line preferences -end_of_line = crlf - -#### .NET Code Actions #### - -# Type members -dotnet_hide_advanced_members = false -dotnet_member_insertion_location = with_other_members_of_the_same_kind -dotnet_property_generation_behavior = prefer_auto_properties - -# Symbol search -dotnet_search_reference_assemblies = true - -# Organize usings -dotnet_separate_import_directive_groups = true -dotnet_sort_system_directives_first = true -file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.\nSee the LICENSE.txt file in the project root for more information. - -# this. and Me. preferences -dotnet_style_qualification_for_field = false:silent -dotnet_style_qualification_for_property = false:silent -dotnet_style_qualification_for_method = false:silent -dotnet_style_qualification_for_event = false:silent - -# Language keywords vs BCL types preferences -dotnet_style_predefined_type_for_locals_parameters_members = true:silent -dotnet_style_predefined_type_for_member_access = true:silent - -# Parentheses preferences -dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent -dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent -dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent - -# Modifier preferences -dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent - -# Expression-level preferences -dotnet_prefer_system_hash_code = true:suggestion -dotnet_style_coalesce_expression = true:suggestion -dotnet_style_collection_initializer = true:suggestion -dotnet_style_explicit_tuple_names = true:suggestion -dotnet_style_namespace_match_folder = true:suggestion -dotnet_style_null_propagation = true:suggestion -dotnet_style_object_initializer = true:suggestion -dotnet_style_operator_placement_when_wrapping = beginning_of_line -dotnet_style_prefer_auto_properties = true:silent -dotnet_style_prefer_collection_expression = when_types_loosely_match:suggestion -dotnet_style_prefer_compound_assignment = true:suggestion -dotnet_style_prefer_conditional_expression_over_assignment = true:silent -dotnet_style_prefer_conditional_expression_over_return = true:silent -dotnet_style_prefer_foreach_explicit_cast_in_source = when_strongly_typed:suggestion -dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion -dotnet_style_prefer_inferred_tuple_names = true:suggestion -dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion -dotnet_style_prefer_simplified_boolean_expressions = true:suggestion -dotnet_style_prefer_simplified_interpolation = true:suggestion - -# Field preferences -dotnet_style_readonly_field = true:suggestion - -# Parameter preferences -dotnet_code_quality_unused_parameters = all:warning - -# Suppression preferences -dotnet_remove_unnecessary_suppression_exclusions = none - -# New line preferences -dotnet_style_allow_multiple_blank_lines_experimental = true:silent -dotnet_style_allow_statement_immediately_after_block_experimental = true:silent - -#### C# Coding Conventions #### - -# var preferences -csharp_style_var_elsewhere = false:silent -csharp_style_var_for_built_in_types = false:silent -csharp_style_var_when_type_is_apparent = false:silent - -# Expression-bodied members -csharp_style_expression_bodied_accessors = true:silent -csharp_style_expression_bodied_constructors = false:silent -csharp_style_expression_bodied_indexers = true:silent -csharp_style_expression_bodied_lambdas = true:silent -csharp_style_expression_bodied_local_functions = false:silent -csharp_style_expression_bodied_methods = false:silent -csharp_style_expression_bodied_operators = false:silent -csharp_style_expression_bodied_properties = true:silent - -# Pattern matching preferences -csharp_style_pattern_matching_over_as_with_null_check = true:suggestion -csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion -csharp_style_prefer_extended_property_pattern = true:suggestion -csharp_style_prefer_not_pattern = true:suggestion -csharp_style_prefer_pattern_matching = true:silent -csharp_style_prefer_switch_expression = true:suggestion - -# Null-checking preferences -csharp_style_conditional_delegate_call = true:suggestion - -# Modifier preferences -csharp_prefer_static_anonymous_function = true:suggestion -csharp_prefer_static_local_function = true:suggestion -csharp_preferred_modifier_order = public,private,protected,internal,file,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,required,volatile,async -csharp_style_prefer_readonly_struct = true:suggestion -csharp_style_prefer_readonly_struct_member = true:suggestion - -# Code-block preferences -csharp_prefer_braces = true:silent -csharp_prefer_simple_using_statement = false:suggestion -csharp_prefer_system_threading_lock = true:suggestion -csharp_style_namespace_declarations = block_scoped:silent -csharp_style_prefer_method_group_conversion = true:silent -csharp_style_prefer_primary_constructors = true:suggestion -csharp_style_prefer_top_level_statements = true:silent - -# Expression-level preferences -csharp_prefer_simple_default_expression = true:suggestion -csharp_style_deconstructed_variable_declaration = true:suggestion -csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion -csharp_style_inlined_variable_declaration = true:suggestion -csharp_style_prefer_index_operator = true:suggestion -csharp_style_prefer_local_over_anonymous_function = true:suggestion -csharp_style_prefer_null_check_over_type_check = true:suggestion -csharp_style_prefer_range_operator = true:suggestion -csharp_style_prefer_tuple_swap = true:suggestion -csharp_style_prefer_utf8_string_literals = true:suggestion -csharp_style_throw_expression = true:suggestion -csharp_style_unused_value_assignment_preference = discard_variable:suggestion -csharp_style_unused_value_expression_statement_preference = discard_variable:silent - -# 'using' directive preferences -csharp_using_directive_placement = outside_namespace:silent - -# New line preferences -csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent -csharp_style_allow_blank_line_after_token_in_arrow_expression_clause_experimental = true:silent -csharp_style_allow_blank_line_after_token_in_conditional_expression_experimental = true:silent -csharp_style_allow_blank_lines_between_consecutive_braces_experimental = true:silent -csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent - -#### C# Formatting Rules #### - -# New line preferences -csharp_new_line_before_catch = true:silent -csharp_new_line_before_else = true:silent -csharp_new_line_before_finally = true:silent -csharp_new_line_before_members_in_anonymous_types = true:silent -csharp_new_line_before_members_in_object_initializers = true:silent -csharp_new_line_before_open_brace = all -csharp_new_line_between_query_expression_clauses = true:silent - -# Indentation preferences -csharp_indent_block_contents = true:suggestion -csharp_indent_braces = false:suggestion -csharp_indent_case_contents = true:suggestion -csharp_indent_case_contents_when_block = true:suggestion -csharp_indent_labels = no_change -csharp_indent_switch_labels = true:suggestion - -# Space preferences -csharp_space_after_cast = false:silent -csharp_space_after_colon_in_inheritance_clause = true:silent -csharp_space_after_comma = true:silent -csharp_space_after_dot = false:silent -csharp_space_after_keywords_in_control_flow_statements = true:silent -csharp_space_after_semicolon_in_for_statement = true:silent -csharp_space_around_binary_operators = before_and_after -csharp_space_around_declaration_statements = false:silent -csharp_space_before_colon_in_inheritance_clause = true:silent -csharp_space_before_comma = false:silent -csharp_space_before_dot = false:silent -csharp_space_before_open_square_brackets = false:silent -csharp_space_before_semicolon_in_for_statement = false:silent -csharp_space_between_empty_square_brackets = false:silent -csharp_space_between_method_call_empty_parameter_list_parentheses = false:silent -csharp_space_between_method_call_name_and_opening_parenthesis = false:silent -csharp_space_between_method_call_parameter_list_parentheses = false:silent -csharp_space_between_method_declaration_empty_parameter_list_parentheses = false:silent -csharp_space_between_method_declaration_name_and_open_parenthesis = false:silent -csharp_space_between_method_declaration_parameter_list_parentheses = false:silent -csharp_space_between_parentheses = false:silent -csharp_space_between_square_brackets = false:silent - -#### Naming styles #### - -# Naming rules - -dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion -dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface -dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i - -dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.types_should_be_pascal_case.symbols = types -dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case - -dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members -dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case - -#### Naming styles #### - -# Naming rules - -dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion -dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface -dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i - -dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.types_should_be_pascal_case.symbols = types -dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case - -dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion -dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members -dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case - -dotnet_naming_rule.private_fields_underscored.severity = error -dotnet_naming_rule.private_fields_underscored.symbols = private_fields -dotnet_naming_rule.private_fields_underscored.style = underscored - -dotnet_naming_rule.private_static_fields_none.severity = none -dotnet_naming_rule.private_static_fields_none.symbols = private_static_fields -dotnet_naming_rule.private_static_fields_none.style = underscored - - -# Symbol specifications - -dotnet_naming_symbols.interface.applicable_kinds = interface -dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.interface.required_modifiers = - -dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum -dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.types.required_modifiers = - -dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method -dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected -dotnet_naming_symbols.non_field_members.required_modifiers = - -dotnet_naming_symbols.private_fields.applicable_kinds = field -dotnet_naming_symbols.private_fields.applicable_accessibilities = private - -dotnet_naming_symbols.private_static_fields.applicable_kinds = field -dotnet_naming_symbols.private_static_fields.applicable_accessibilities = private -dotnet_naming_symbols.private_static_fields.required_modifiers = static - -# Naming styles - -dotnet_naming_style.begins_with_i.required_prefix = I -dotnet_naming_style.begins_with_i.required_suffix = -dotnet_naming_style.begins_with_i.word_separator = -dotnet_naming_style.begins_with_i.capitalization = pascal_case - -dotnet_naming_style.pascal_case.required_prefix = -dotnet_naming_style.pascal_case.required_suffix = -dotnet_naming_style.pascal_case.word_separator = -dotnet_naming_style.pascal_case.capitalization = pascal_case - -dotnet_naming_style.underscored.capitalization = -dotnet_naming_style.underscored.required_prefix = _ - - - -# Analyzers +# IDE0063: Use simple 'using' statement +csharp_prefer_simple_using_statement = false # CA2254: Template should be a static expression # See https://github.com/dotnet/roslyn-analyzers/issues/5626 @@ -288,3 +20,4 @@ dotnet_diagnostic.CA2254.severity = none # IDE0073: File header dotnet_diagnostic.IDE0073.severity = warning +file_header_template = Licensed to the .NET Foundation under one or more agreements.\nThe .NET Foundation licenses this file to you under the MIT license.\nSee the LICENSE.txt file in the project root for more information. From 27de4da0c0bf80c0b18667a63634b4b9970de4e4 Mon Sep 17 00:00:00 2001 From: Claire Novotny <1427284+clairernovotny@users.noreply.github.com> Date: Fri, 13 Dec 2024 12:07:03 -0500 Subject: [PATCH 15/17] Update src/Sign.SignatureProviders.TrustedSigning/Resources.resx Co-authored-by: Damon Tivel --- src/Sign.SignatureProviders.TrustedSigning/Resources.resx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Sign.SignatureProviders.TrustedSigning/Resources.resx b/src/Sign.SignatureProviders.TrustedSigning/Resources.resx index 3152a5ff..60cd19c5 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/Resources.resx +++ b/src/Sign.SignatureProviders.TrustedSigning/Resources.resx @@ -118,7 +118,8 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Certificate Details:\n{details} + Certificate details:\n{details} + {Placeholder="{details}"} is text provided by the Azure Code Signing SDK and describes an X.509 certificate. Fetched certificate. [{milliseconds} ms] From 841e02b3131ddff36b64705cf5da713079c6c629 Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Fri, 13 Dec 2024 13:41:18 -0500 Subject: [PATCH 16/17] Ensure the cert details are printed on a new line --- src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs | 2 +- src/Sign.SignatureProviders.KeyVault/Resources.Designer.cs | 2 +- src/Sign.SignatureProviders.KeyVault/Resources.resx | 2 +- src/Sign.SignatureProviders.KeyVault/xlf/Resources.cs.xlf | 4 ++-- src/Sign.SignatureProviders.KeyVault/xlf/Resources.de.xlf | 4 ++-- src/Sign.SignatureProviders.KeyVault/xlf/Resources.es.xlf | 4 ++-- src/Sign.SignatureProviders.KeyVault/xlf/Resources.fr.xlf | 4 ++-- src/Sign.SignatureProviders.KeyVault/xlf/Resources.it.xlf | 4 ++-- src/Sign.SignatureProviders.KeyVault/xlf/Resources.ja.xlf | 4 ++-- src/Sign.SignatureProviders.KeyVault/xlf/Resources.ko.xlf | 4 ++-- src/Sign.SignatureProviders.KeyVault/xlf/Resources.pl.xlf | 4 ++-- src/Sign.SignatureProviders.KeyVault/xlf/Resources.pt-BR.xlf | 4 ++-- src/Sign.SignatureProviders.KeyVault/xlf/Resources.ru.xlf | 4 ++-- src/Sign.SignatureProviders.KeyVault/xlf/Resources.tr.xlf | 4 ++-- .../xlf/Resources.zh-Hans.xlf | 4 ++-- .../xlf/Resources.zh-Hant.xlf | 4 ++-- .../Resources.Designer.cs | 2 +- src/Sign.SignatureProviders.TrustedSigning/Resources.resx | 5 ++--- .../TrustedSigningService.cs | 2 +- .../xlf/Resources.cs.xlf | 4 ++-- .../xlf/Resources.de.xlf | 4 ++-- .../xlf/Resources.es.xlf | 4 ++-- .../xlf/Resources.fr.xlf | 4 ++-- .../xlf/Resources.it.xlf | 4 ++-- .../xlf/Resources.ja.xlf | 4 ++-- .../xlf/Resources.ko.xlf | 4 ++-- .../xlf/Resources.pl.xlf | 4 ++-- .../xlf/Resources.pt-BR.xlf | 4 ++-- .../xlf/Resources.ru.xlf | 4 ++-- .../xlf/Resources.tr.xlf | 4 ++-- .../xlf/Resources.zh-Hans.xlf | 4 ++-- .../xlf/Resources.zh-Hant.xlf | 4 ++-- 32 files changed, 59 insertions(+), 60 deletions(-) diff --git a/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs b/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs index 2a5458d9..50463b7c 100644 --- a/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs +++ b/src/Sign.SignatureProviders.KeyVault/KeyVaultService.cs @@ -73,7 +73,7 @@ public async Task GetCertificateAsync(CancellationToken cancel _certificate = new X509Certificate2(response.Value.Cer); //print the certificate info - _logger.LogTrace(Resources.CertificateDetails, _certificate.ToString(verbose: true)); + _logger.LogTrace($"{Resources.CertificateDetails}{Environment.NewLine}{_certificate.ToString(verbose: true)}"); } } finally diff --git a/src/Sign.SignatureProviders.KeyVault/Resources.Designer.cs b/src/Sign.SignatureProviders.KeyVault/Resources.Designer.cs index 035994b4..0ba23774 100644 --- a/src/Sign.SignatureProviders.KeyVault/Resources.Designer.cs +++ b/src/Sign.SignatureProviders.KeyVault/Resources.Designer.cs @@ -61,7 +61,7 @@ internal Resources() { } /// - /// Looks up a localized string similar to Certificate Details:\n{details}. + /// Looks up a localized string similar to Certificate Details:. /// internal static string CertificateDetails { get { diff --git a/src/Sign.SignatureProviders.KeyVault/Resources.resx b/src/Sign.SignatureProviders.KeyVault/Resources.resx index a63a2574..39700f0a 100644 --- a/src/Sign.SignatureProviders.KeyVault/Resources.resx +++ b/src/Sign.SignatureProviders.KeyVault/Resources.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Certificate Details:\n{details} + Certificate Details: Fetched certificate. [{milliseconds} ms] diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.cs.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.cs.xlf index 56c8d426..6e906004 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.cs.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.cs.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.de.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.de.xlf index 3fc60b7c..2db2aff5 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.de.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.de.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.es.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.es.xlf index 9ef60e10..ccfbd0ae 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.es.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.es.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.fr.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.fr.xlf index 886ba6a6..74068688 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.fr.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.fr.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.it.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.it.xlf index 74bcb3c6..e3e128e7 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.it.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.it.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ja.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ja.xlf index a12f1991..166862be 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ja.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ja.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ko.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ko.xlf index b9918433..9959453a 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ko.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ko.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pl.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pl.xlf index 85e0f6eb..c65a78c1 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pl.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pl.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pt-BR.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pt-BR.xlf index 651cffb9..730868ae 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pt-BR.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.pt-BR.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ru.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ru.xlf index 5dd751d2..456e85de 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ru.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.ru.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.tr.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.tr.xlf index a0b9ef21..28fba9ff 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.tr.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.tr.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hans.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hans.xlf index 3104935d..15d4c0f1 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hans.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hans.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hant.xlf b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hant.xlf index b21c1fdb..692bc81e 100644 --- a/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hant.xlf +++ b/src/Sign.SignatureProviders.KeyVault/xlf/Resources.zh-Hant.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate Details: + Certificate Details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/Resources.Designer.cs b/src/Sign.SignatureProviders.TrustedSigning/Resources.Designer.cs index 5d53d788..c129550f 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/Resources.Designer.cs +++ b/src/Sign.SignatureProviders.TrustedSigning/Resources.Designer.cs @@ -61,7 +61,7 @@ internal Resources() { } /// - /// Looks up a localized string similar to Certificate Details:\n{details}. + /// Looks up a localized string similar to Certificate details:. /// internal static string CertificateDetails { get { diff --git a/src/Sign.SignatureProviders.TrustedSigning/Resources.resx b/src/Sign.SignatureProviders.TrustedSigning/Resources.resx index 60cd19c5..3c1407b5 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/Resources.resx +++ b/src/Sign.SignatureProviders.TrustedSigning/Resources.resx @@ -118,8 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Certificate details:\n{details} - {Placeholder="{details}"} is text provided by the Azure Code Signing SDK and describes an X.509 certificate. + Certificate details: Fetched certificate. [{milliseconds} ms] @@ -128,4 +127,4 @@ Fetching certificate from Trusted Signing certificate profile. - \ No newline at end of file + diff --git a/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs b/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs index cd70d006..33b26282 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs +++ b/src/Sign.SignatureProviders.TrustedSigning/TrustedSigningService.cs @@ -80,7 +80,7 @@ public async Task GetCertificateAsync(CancellationToken cancel _logger.LogTrace(Resources.FetchedCertificate, stopwatch.Elapsed.TotalMilliseconds); //print the certificate info - _logger.LogTrace(Resources.CertificateDetails, _certificate.ToString(verbose: true)); + _logger.LogTrace($"{Resources.CertificateDetails}{Environment.NewLine}{_certificate.ToString(verbose: true)}"); } } } diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.cs.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.cs.xlf index 8e260c85..8823a7e7 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.cs.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.cs.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.de.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.de.xlf index 7ce4003d..3887cf4c 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.de.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.de.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.es.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.es.xlf index fd76990f..56b0edef 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.es.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.es.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.fr.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.fr.xlf index 2c924989..eda7b86f 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.fr.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.fr.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.it.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.it.xlf index eb696486..3cfea3ed 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.it.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.it.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ja.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ja.xlf index e15c26a4..0e4403b9 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ja.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ja.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ko.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ko.xlf index f8af6f11..35daa624 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ko.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ko.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pl.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pl.xlf index 6dedae66..6d3f68a8 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pl.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pl.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pt-BR.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pt-BR.xlf index 5e73c2ed..e27838e3 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pt-BR.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.pt-BR.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ru.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ru.xlf index 12e8c09e..f8ab8927 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ru.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.ru.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.tr.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.tr.xlf index 2442f2cd..684cfd8d 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.tr.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.tr.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hans.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hans.xlf index 5bcd5fe2..bda5f083 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hans.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hans.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: diff --git a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hant.xlf b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hant.xlf index e33b6697..d9446ac0 100644 --- a/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hant.xlf +++ b/src/Sign.SignatureProviders.TrustedSigning/xlf/Resources.zh-Hant.xlf @@ -3,8 +3,8 @@ - Certificate Details:\n{details} - Certificate Details:\n{details} + Certificate details: + Certificate details: From 5b02eb918faa14d7cc7f9dbefcefef75289b798d Mon Sep 17 00:00:00 2001 From: Claire Novotny Date: Fri, 13 Dec 2024 14:12:20 -0500 Subject: [PATCH 17/17] Handle the error with a better output message instead of a stack trace when signing fails --- .../DataFormatSigners/AzureSignToolSigner.cs | 4 +++- src/Sign.Core/Signer.cs | 6 ++++++ src/Sign.Core/SigningException.cs | 21 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/Sign.Core/SigningException.cs diff --git a/src/Sign.Core/DataFormatSigners/AzureSignToolSigner.cs b/src/Sign.Core/DataFormatSigners/AzureSignToolSigner.cs index ec53fe71..101fc356 100644 --- a/src/Sign.Core/DataFormatSigners/AzureSignToolSigner.cs +++ b/src/Sign.Core/DataFormatSigners/AzureSignToolSigner.cs @@ -5,7 +5,9 @@ using System.Globalization; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; + using AzureSign.Core; + using Microsoft.Extensions.Logging; namespace Sign.Core @@ -111,7 +113,7 @@ await Parallel.ForEachAsync(files, async (file, state) => { string message = string.Format(CultureInfo.CurrentCulture, Resources.SigningFailed, file.FullName); - throw new Exception(message); + throw new SigningException(message); } }); } diff --git a/src/Sign.Core/Signer.cs b/src/Sign.Core/Signer.cs index 840c67a2..a7cb2c75 100644 --- a/src/Sign.Core/Signer.cs +++ b/src/Sign.Core/Signer.cs @@ -6,6 +6,7 @@ using System.Security.Authentication; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; + using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileSystemGlobbing; using Microsoft.Extensions.Logging; @@ -167,6 +168,11 @@ await Parallel.ForEachAsync(inputFiles, parallelOptions, async (input, token) => _logger.LogError(e, e.Message); return ExitCode.Failed; } + catch (SigningException) + { + _logger.LogError(Resources.SigningFailedAfterAllAttempts); + return ExitCode.Failed; + } catch (Exception e) { _logger.LogError(e, e.Message); diff --git a/src/Sign.Core/SigningException.cs b/src/Sign.Core/SigningException.cs new file mode 100644 index 00000000..a38c06ba --- /dev/null +++ b/src/Sign.Core/SigningException.cs @@ -0,0 +1,21 @@ +// 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.Core +{ + internal class SigningException : Exception + { + public SigningException() + { + } + public SigningException(string message) + : base(message) + { + } + public SigningException(string message, Exception inner) + : base(message, inner) + { + } + } +}