Skip to content

Commit 9619ea7

Browse files
authored
Do not fail on partial trust warning. (#9384)
* Do not fail on partial trust warning. * Reuse message in tests. * Use exit code as well. * Ignore failures in certificate trust but display a warning.
1 parent 242a053 commit 9619ea7

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

src/Aspire.Cli/Certificates/CertificateService.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public async Task EnsureCertificatesTrustedAsync(IDotNetCliRunner runner, Cancel
4242
StandardOutputCallback = ensureCertificateCollector.AppendOutput,
4343
StandardErrorCallback = ensureCertificateCollector.AppendError,
4444
};
45+
4546
var trustExitCode = await interactionService.ShowStatusAsync(
4647
":locked_with_key: Trusting certificates...",
4748
() => runner.TrustHttpCertificateAsync(
@@ -51,10 +52,12 @@ public async Task EnsureCertificatesTrustedAsync(IDotNetCliRunner runner, Cancel
5152
if (trustExitCode != 0)
5253
{
5354
interactionService.DisplayLines(ensureCertificateCollector.GetLines());
54-
throw new CertificateServiceException($"Failed to trust certificates, trust command failed with exit code: {trustExitCode}");
55+
interactionService.DisplayMessage("warning", $"Developer certificates may not be fully trusted (trust exit code was: {trustExitCode})");
5556
}
5657
}
5758
}
59+
60+
internal const string DevCertsPartialTrustMessage = "There was an error trusting the HTTPS developer certificate. It will be trusted by some clients but not by others.";
5861
}
5962

6063
public sealed class CertificateServiceException(string message) : Exception(message)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Aspire.Cli.Certificates;
5+
using Aspire.Cli.Tests.TestServices;
6+
using Aspire.Cli.Tests.Utils;
7+
using Microsoft.Extensions.DependencyInjection;
8+
using Xunit;
9+
10+
namespace Aspire.Cli.Tests.Certificates;
11+
12+
public class CertificateServiceTests(ITestOutputHelper outputHelper)
13+
{
14+
[Fact]
15+
public async Task EnsureCertificatesTrustedAsyncSucceedsOnNonZeroExitCode()
16+
{
17+
var services = CliTestHelper.CreateServiceCollection(outputHelper, options =>
18+
{
19+
options.DotNetCliRunnerFactory = sp =>
20+
{
21+
var runner = new TestDotNetCliRunner();
22+
runner.CheckHttpCertificateAsyncCallback = (_, _) => 1;
23+
runner.TrustHttpCertificateAsyncCallback = (options, _) =>
24+
{
25+
Assert.NotNull(options.StandardErrorCallback);
26+
options.StandardErrorCallback!.Invoke(CertificateService.DevCertsPartialTrustMessage);
27+
return 4;
28+
};
29+
return runner;
30+
};
31+
});
32+
33+
var sp = services.BuildServiceProvider();
34+
var cs = sp.GetRequiredService<ICertificateService>();
35+
var runner = sp.GetRequiredService<IDotNetCliRunner>();
36+
37+
// If this does not throw then the code is behaving correctly.
38+
await cs.EnsureCertificatesTrustedAsync(runner, TestContext.Current.CancellationToken).WaitAsync(CliTestConstants.DefaultTimeout);
39+
}
40+
}

0 commit comments

Comments
 (0)