line-gestao-api/Services/TenantProvider.cs

55 lines
1.6 KiB
C#

using System.Security.Claims;
using Microsoft.AspNetCore.Http;
namespace line_gestao_api.Services;
public class TenantProvider : ITenantProvider
{
private readonly IHttpContextAccessor _httpContextAccessor;
private static readonly AsyncLocal<Guid?> CurrentTenant = new();
public TenantProvider(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public Guid? ActorTenantId => TenantId;
public Guid? TenantId => CurrentTenant.Value ?? ResolveFromClaims();
public bool HasGlobalViewAccess =>
HasRole(AppRoles.SysAdmin) ||
HasRole(AppRoles.Gestor) ||
HasRole(AppRoles.Financeiro);
public void SetTenantId(Guid? tenantId)
{
CurrentTenant.Value = tenantId;
}
private Guid? ResolveFromClaims()
{
var claim = _httpContextAccessor.HttpContext?.User?.FindFirst("tenantId")?.Value
?? _httpContextAccessor.HttpContext?.User?.FindFirst("tenant")?.Value;
return Guid.TryParse(claim, out var tenantId) ? tenantId : null;
}
private bool HasRole(string role)
{
var principal = _httpContextAccessor.HttpContext?.User;
if (principal?.Identity?.IsAuthenticated != true)
{
return false;
}
var roleClaims = principal.FindAll(ClaimTypes.Role)
.Select(c => c.Value)
.Concat(principal.FindAll("role").Select(c => c.Value))
.Concat(principal.FindAll("roles").Select(c => c.Value))
.Distinct(StringComparer.OrdinalIgnoreCase);
return roleClaims.Any(r => string.Equals(r, role, StringComparison.OrdinalIgnoreCase));
}
}