Files
scadaproj/ZB.MOM.WW.Secrets/src/ZB.MOM.WW.Secrets.Ui/SecretActorResolver.cs
T

46 lines
1.9 KiB
C#

using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.Extensions.DependencyInjection;
using ZB.MOM.WW.Secrets.Abstractions;
namespace ZB.MOM.WW.Secrets.Ui;
/// <summary>
/// Resolves the principal to record as the audit <c>Actor</c> for a UI-driven secret mutation or
/// reveal. The resolution order is: an explicitly wired <see cref="ISecretActorAccessor"/> (if the
/// host registered one and it reports a non-blank actor); otherwise the authenticated user's
/// <see cref="System.Security.Principal.IIdentity.Name"/> from the cascading authentication state;
/// otherwise the literal <c>"unknown"</c> so an action is never attributed to a blank actor.
/// </summary>
internal static class SecretActorResolver
{
/// <summary>The fallback actor used when no accessor and no authenticated identity name is available.</summary>
public const string Unknown = "unknown";
/// <summary>
/// Resolves the audit actor. Never returns <c>null</c> or blank.
/// </summary>
/// <param name="services">The component's service provider, used to optionally resolve an <see cref="ISecretActorAccessor"/>.</param>
/// <param name="authState">The cascading authentication-state task, or <c>null</c> if unavailable.</param>
/// <returns>The resolved actor identity string.</returns>
public static async Task<string> ResolveAsync(IServiceProvider services, Task<AuthenticationState>? authState)
{
string? fromAccessor = services.GetService<ISecretActorAccessor>()?.CurrentActor;
if (!string.IsNullOrWhiteSpace(fromAccessor))
{
return fromAccessor;
}
if (authState is not null)
{
AuthenticationState state = await authState.ConfigureAwait(false);
string? name = state.User.Identity?.Name;
if (!string.IsNullOrWhiteSpace(name))
{
return name;
}
}
return Unknown;
}
}