using Microsoft.AspNetCore.Authorization;
namespace ZB.MOM.WW.MxGateway.Server.Dashboard;
///
/// Requirement satisfied ONLY by an authenticated principal holding one of
/// as a real role claim. Unlike
/// there is no environment bypass: it is a
/// distinct requirement type, so —
/// an AuthorizationHandler<DashboardAuthorizationRequirement> — is never invoked for
/// it and its Authentication:Mode=Disabled / anonymous-localhost arms cannot reach it.
/// The type distinction is the enforcement; adding a bypass arm to the other handler cannot leak
/// into this one by accident.
///
///
/// Introduced to gate the alarm feed (AlarmsHub and the /alarms page),
/// which is gateway-central and session-less and therefore carries no per-session provenance the
/// tag ACL could scope it by. Requiring a real dashboard role claim is the narrowing that
/// is actually available: it keeps galaxy-wide alarm metadata — alarm reference (a full tag path),
/// state, severity, category, area, acknowledging operator — away from the read-only environment
/// bypasses, which exist for local development and unauthenticated deployments rather than as a
/// grant of plant-wide visibility. The same pattern the shared Secrets UI relies on: a policy the
/// dashboard bypass handler cannot satisfy because the requirement type differs.
///
/// Roles any one of which satisfies the requirement.
public sealed class AuthenticatedDashboardRoleRequirement(IReadOnlyList requiredRoles)
: IAuthorizationRequirement
{
/// Gets the roles, any one of which satisfies this requirement.
public IReadOnlyList RequiredRoles { get; } = requiredRoles;
///
/// Gets the requirement satisfied by an authenticated caller holding either dashboard role.
/// Same role set as ; the
/// difference is entirely that no environment bypass applies.
///
public static AuthenticatedDashboardRoleRequirement AnyDashboardRole { get; } =
new([DashboardRoles.Admin, DashboardRoles.Viewer]);
}