Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Aspire.Dashboard/Components/Layout/MainLayout.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ protected override async Task OnInitializedAsync()
TimeProvider.SetBrowserTimeZone(result.TimeZone);
TelemetryContextProvider.SetBrowserUserAgent(result.UserAgent);

if (Options.CurrentValue.Otlp.AuthMode == OtlpAuthMode.Unsecured)
if (Options.CurrentValue.Otlp.AuthMode == OtlpAuthMode.Unsecured && !Options.CurrentValue.Otlp.SuppressUnsecuredTelemetryMessage)
{
var dismissedResult = await LocalStorage.GetUnprotectedAsync<bool>(BrowserStorageKeys.UnsecuredTelemetryMessageDismissedKey);
var skipMessage = dismissedResult.Success && dismissedResult.Value;
Expand Down
6 changes: 6 additions & 0 deletions src/Aspire.Dashboard/Configuration/DashboardOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ public sealed class OtlpOptions

public List<AllowedCertificateRule> AllowedCertificates { get; set; } = new();

/// <summary>
/// Gets or sets a value indicating whether to suppress the unsecured telemetry message in the dashboard UI.
/// When true, the warning message about unsecured OTLP endpoints will not be displayed.
/// </summary>
public bool SuppressUnsecuredTelemetryMessage { get; set; }

public BindingAddress? GetGrpcEndpointAddress()
{
return _parsedGrpcEndpointAddress;
Expand Down
1 change: 1 addition & 0 deletions src/Shared/DashboardConfigNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ internal static class DashboardConfigNames
public static readonly ConfigName DashboardOtlpAuthModeName = new("Dashboard:Otlp:AuthMode", "DASHBOARD__OTLP__AUTHMODE");
public static readonly ConfigName DashboardOtlpPrimaryApiKeyName = new("Dashboard:Otlp:PrimaryApiKey", "DASHBOARD__OTLP__PRIMARYAPIKEY");
public static readonly ConfigName DashboardOtlpSecondaryApiKeyName = new("Dashboard:Otlp:SecondaryApiKey", "DASHBOARD__OTLP__SECONDARYAPIKEY");
public static readonly ConfigName DashboardOtlpSuppressUnsecuredTelemetryMessageName = new("Dashboard:Otlp:SuppressUnsecuredTelemetryMessage", "DASHBOARD__OTLP__SUPPRESSUNSECUREDTELEMETRYMESSAGE");
public static readonly ConfigName DashboardOtlpCorsAllowedOriginsKeyName = new("Dashboard:Otlp:Cors:AllowedOrigins", "DASHBOARD__OTLP__CORS__ALLOWEDORIGINS");
public static readonly ConfigName DashboardOtlpCorsAllowedHeadersKeyName = new("Dashboard:Otlp:Cors:AllowedHeaders", "DASHBOARD__OTLP__CORS__ALLOWEDHEADERS");
public static readonly ConfigName DashboardOtlpAllowedCertificatesName = new("Dashboard:Otlp:AllowedCertificates", "DASHBOARD__OTLP__ALLOWEDCERTIFICATES");
Expand Down
62 changes: 60 additions & 2 deletions tests/Aspire.Dashboard.Components.Tests/Layout/MainLayoutTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,61 @@ public async Task OnInitialize_UnsecuredOtlp_Dismissed_NoMessageBar()
Assert.Empty(messageService.AllMessages);
}

private void SetupMainLayoutServices(TestLocalStorage? localStorage = null, MessageService? messageService = null)
[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task OnInitialize_UnsecuredOtlp_SuppressConfigured_NoMessageBar(bool suppressUnsecuredMessage)
{
// Arrange
var testLocalStorage = new TestLocalStorage();
var messageService = new MessageService();

SetupMainLayoutServices(localStorage: testLocalStorage, messageService: messageService, suppressUnsecuredMessage: suppressUnsecuredMessage);

var messageShownTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
messageService.OnMessageItemsUpdatedAsync += () =>
{
messageShownTcs.TrySetResult();
return Task.CompletedTask;
};

testLocalStorage.OnGetUnprotectedAsync = key =>
{
if (key == BrowserStorageKeys.UnsecuredTelemetryMessageDismissedKey)
{
return (false, false); // Message not dismissed, but should be suppressed by config if suppressUnsecuredMessage is true
}
else
{
throw new InvalidOperationException("Unexpected key.");
}
};

// Act
var cut = RenderComponent<MainLayout>(builder =>
{
builder.Add(p => p.ViewportInformation, new ViewportInformation(IsDesktop: true, IsUltraLowHeight: false, IsUltraLowWidth: false));
});

// Assert
var timeoutTask = Task.Delay(100);
var completedTask = await Task.WhenAny(messageShownTcs.Task, timeoutTask).WaitAsync(TimeSpan.FromSeconds(5));

if (suppressUnsecuredMessage)
{
// When suppressed, no message should be displayed
Assert.True(completedTask != messageShownTcs.Task, "No message bar should be displayed when suppressed by configuration.");
Assert.Empty(messageService.AllMessages);
}
else
{
// When not suppressed, message should be displayed since it wasn't dismissed
Assert.True(completedTask == messageShownTcs.Task, "Message bar should be displayed when not suppressed and not dismissed.");
Assert.NotEmpty(messageService.AllMessages);
}
}

private void SetupMainLayoutServices(TestLocalStorage? localStorage = null, MessageService? messageService = null, bool suppressUnsecuredMessage = false)
{
Services.AddLocalization();
Services.AddOptions();
Expand All @@ -144,7 +198,11 @@ private void SetupMainLayoutServices(TestLocalStorage? localStorage = null, Mess
Services.AddSingleton<DashboardTelemetryService>();
Services.AddSingleton<IDashboardTelemetrySender, TestDashboardTelemetrySender>();
Services.AddSingleton<ComponentTelemetryContextProvider>();
Services.Configure<DashboardOptions>(o => o.Otlp.AuthMode = OtlpAuthMode.Unsecured);
Services.Configure<DashboardOptions>(o =>
{
o.Otlp.AuthMode = OtlpAuthMode.Unsecured;
o.Otlp.SuppressUnsecuredTelemetryMessage = suppressUnsecuredMessage;
});

var version = typeof(FluentMain).Assembly.GetName().Version!;

Expand Down
Loading