// Copyright Epic Games, Inc. All Rights Reserved.
using System.Diagnostics.CodeAnalysis;
using System.Security.Claims;
using EpicGames.Horde.Acls;
namespace HordeServer.Acls
{
///
/// Functionality for manipulating ACLs
///
public interface IAclService
{
///
/// Issues a bearer token with the given roles
///
/// List of claims to include
/// Time that the token expires
/// Cancellation token for the operation
/// JWT security token with a claim for creating new agents
ValueTask IssueBearerTokenAsync(IEnumerable claims, TimeSpan? expiry, CancellationToken cancellationToken = default);
///
/// Finds an ACL scope by name
///
/// Name of the scope to auth against
/// Configuration for the scope
bool TryGetAclScope(AclScopeName scopeName, [NotNullWhen(true)] out AclConfig? scopeConfig);
}
///
/// Extension methods for
///
public static class AclServiceExtensions
{
///
/// Authorizes a user to perform a given action
///
/// Instance of the ACL service
/// Name of the scope to auth against
/// The action being performed
/// The principal to validate
public static bool Authorize(this IAclService aclService, AclScopeName scopeName, AclAction action, ClaimsPrincipal user)
=> aclService.TryGetAclScope(scopeName, out AclConfig? scopeConfig) && scopeConfig.Authorize(action, user);
///
/// Issues a bearer token with the given roles
///
/// Instance of the ACL service
/// List of claims to include
/// Time that the token expires
/// Cancellation token for the operation
/// JWT security token with a claim for creating new agents
public static async ValueTask IssueBearerTokenAsync(this IAclService aclService, IEnumerable claims, TimeSpan? expiry, CancellationToken cancellationToken = default)
=> await aclService.IssueBearerTokenAsync(claims.Select(x => new Claim(x.Type, x.Value)), expiry, cancellationToken);
}
}