using CH.Authority.Attributes; using OpenHarbor.CQRS.Abstractions.Discovery; using OpenHarbor.CQRS.Abstractions.Security; using OpenHarbor.CQRS.DynamicQuery.Discover; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; namespace CH.Authority.Services; public class CQAuthorizationService(IQueryDiscovery queryDiscovery, UserIdentityService userIdentityService) : IQueryAuthorizationService, ICommandAuthorizationService { public async Task IsAllowedAsync(bool isQuery, Type queryOrCommandType, CancellationToken cancellationToken) { // determine subject type. Type subjectType = queryOrCommandType; if (isQuery) { var queryMeta = queryDiscovery.FindQuery(queryOrCommandType); if (queryMeta != null && queryMeta is DynamicQueryMeta dqMeta) { subjectType = dqMeta.DestinationType; } } // allow guest calls. var allowGuestAttributes = subjectType.GetCustomAttribute(true); if (null != allowGuestAttributes) return AuthorizationResult.Allowed; if (false == userIdentityService.IsAuthenticated()) return AuthorizationResult.Unauthorized; var isAllowed = await userIdentityService.IsAuthorizedAsync(cancellationToken); return isAllowed ? AuthorizationResult.Allowed : AuthorizationResult.Forbidden; } Task IQueryAuthorizationService.IsAllowedAsync(Type queryType, CancellationToken cancellationToken) => IsAllowedAsync(true, queryType, cancellationToken); Task ICommandAuthorizationService.IsAllowedAsync(Type commandType, CancellationToken cancellationToken) => IsAllowedAsync(false, commandType, cancellationToken); }