dotnet-digital-ops/DigitalOps.Authority/Validators/HasAccessToOrganizationValidator.cs

51 lines
1.8 KiB
C#

using DigitalOps.Authority.Services;
using DigitalOps.Dal;
using DigitalOps.Dal.DbEntity;
using FluentValidation;
using Microsoft.EntityFrameworkCore;
namespace DigitalOps.Authority.Validators;
public class HasAccessToOrganizationValidator : AbstractValidator<long>
{
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<bool> 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<OrganizationRole>();
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;
}
}