using DigitalOps.Authority.Services; using DigitalOps.Dal; using DigitalOps.Dal.DbEntity; using FluentValidation; using Microsoft.EntityFrameworkCore; namespace DigitalOps.Authority.Validators; public class HasAccessToOrganizationValidator : AbstractValidator { private readonly OrganizationRole _role; private readonly MainDbContext _dbContext; private readonly UserIdentityService _userIdentityService; public HasAccessToOrganizationValidator(OrganizationRole role, MainDbContext dbContext, UserIdentityService userIdentityService) { _role = role; _userIdentityService = userIdentityService; _dbContext = dbContext; RuleFor(organizationId => organizationId) .MustAsync(HasAccess) .WithMessage("You do not have the proper role to this organization for this action."); } private async Task HasAccess(long organizationId, CancellationToken cancellationToken) { var user = await _userIdentityService.GetUserOrDefaultAsync(cancellationToken); if (user is null) return false; // todo: extract this into a reusable helper class var roles = new List(); if (_role == OrganizationRole.Owner) roles.AddRange([OrganizationRole.Owner]); if (_role == OrganizationRole.Admin) roles.AddRange([OrganizationRole.Owner, OrganizationRole.Admin]); if (_role == OrganizationRole.Member) roles.AddRange([OrganizationRole.Owner, OrganizationRole.Admin, OrganizationRole.Member]); var result = await _dbContext.OrganizationUsers .AsNoTracking() .Where(organizationUser => organizationUser.OrganizationId == organizationId) .Where(organizationUser => roles.Contains(organizationUser.Role)) .AnyAsync(cancellationToken); return result; } }