// 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); } }