using Dpz.Core.Public.Entity.Auth;
using Dpz.Core.Service.Mediator.Features.Auth.Contracts;

namespace Dpz.Core.Service.Mediator.Features.Auth.Queries;

public class CheckApplicationAccessQueryHandler(
    IRepository<AllowedClient> allowedClientRepository,
    IRepository<ApplicationAccessRequest> accessRequestRepository,
    IConfiguration configuration
) : IRequestHandler<CheckApplicationAccessQuery, ApplicationAccessCheckResult>
{
    public async ValueTask<ApplicationAccessCheckResult> Handle(
        CheckApplicationAccessQuery request,
        CancellationToken cancellationToken
    )
    {
        var defaultApplications =
            configuration.GetSection("DefaultApplications").Get<string[]>() ?? [];

        var isAllowed =
            request.IsSystemUser
            || defaultApplications.Contains(request.ClientId)
            || await allowedClientRepository
                .SearchFor(x => x.Account == request.UserId && x.ApplicationId == request.ClientId)
                .AnyAsync(cancellationToken);

        if (isAllowed)
        {
            return new ApplicationAccessCheckResult { IsAllowed = true };
        }

        var pendingRequest = await accessRequestRepository
            .SearchFor(x =>
                x.UserId == request.UserId
                && x.ClientId == request.ClientId
                && x.Status == AccessRequestStatus.Pending
            )
            .AnyAsync(cancellationToken);

        return new ApplicationAccessCheckResult
        {
            IsAllowed = false,
            HasPendingRequest = pendingRequest,
        };
    }
}
评论加载中...