public async ValueTask <OperationResult> RequirePermissionsAsync(
            IReadOnlyCollection <int> permissionIds,
            CancellationToken cancellationToken)
        {
            AuthorizationLogMessages.PermissionsRequired(_logger, permissionIds);

            var authenticationResult = RequireAuthentication();

            if (authenticationResult.IsFailure)
            {
                return(authenticationResult);
            }

            var missingPermissionIds = permissionIds
                                       .Where(id => !_authenticationService.CurrentTicket !.GrantedPermissions
                                              .ContainsKey(id))
                                       .ToHashSet();

            if (!missingPermissionIds.Any())
            {
                AuthorizationLogMessages.RequiredPermissionsFound(_logger);
                return(OperationResult.Success);
            }
            AuthorizationLogMessages.RequiredPermissionsNotFound(_logger, missingPermissionIds);

            var missingPermissions = (await _permissionsService
                                      .GetIdentitiesAsync(cancellationToken))
                                     .Where(x => missingPermissionIds.Contains(x.Id))
                                     .ToDictionary(x => x.Id, x => x.Name);

            AuthorizationLogMessages.MissingPermissionsFetched(_logger, missingPermissions);

            return(new InsufficientPermissionsError(missingPermissions));
        }
        public OperationResult RequireAuthentication()
        {
            AuthorizationLogMessages.AuthenticationRequired(_logger);

            if (_authenticationService.CurrentTicket is null)
            {
                AuthorizationLogMessages.AuthenticatedUserNotFound(_logger);
                return(new UnauthenticatedUserError());
            }
            else
            {
                AuthorizationLogMessages.AuthenticatedUserFound(_logger, _authenticationService.CurrentTicket.UserId);
                return(OperationResult.Success);
            }
        }