mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-09-30 11:53:12 +00:00
96 lines
3.6 KiB
C#
96 lines
3.6 KiB
C#
using Data.SeaHavenIndustries.Enums;
|
|
using SeaHaven.DataServices.Dto;
|
|
using SeaHaven.DataServices.Interfaces;
|
|
using SeaHaven.Services.Constants;
|
|
using SeaHaven.Services.DTOs;
|
|
using SeaHaven.Services.Interfaces;
|
|
using System.Security.Claims;
|
|
|
|
namespace SeaHaven.Services.Implementation;
|
|
|
|
public sealed class TeamPermissionService : ITeamPermissionService
|
|
{
|
|
private readonly ITeamPermissionOverrideDataService _dataService;
|
|
private readonly ITeamPermissionPolicy _policy;
|
|
|
|
public TeamPermissionService(
|
|
ITeamPermissionOverrideDataService dataService,
|
|
ITeamPermissionPolicy policy)
|
|
{
|
|
_dataService = dataService;
|
|
_policy = policy;
|
|
}
|
|
|
|
public async Task<TeamPermissionResult<TeamPermissionProfileDTO>> GetProfileAsync(
|
|
string userId,
|
|
ClaimsPrincipal caller,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
if (!IsAdmin(caller))
|
|
return TeamPermissionResult<TeamPermissionProfileDTO>.Failure(TeamPermissionResultStatus.Forbidden);
|
|
|
|
var user = await _dataService.GetUserAsync(userId, cancellationToken);
|
|
return user is null
|
|
? TeamPermissionResult<TeamPermissionProfileDTO>.Failure(TeamPermissionResultStatus.NotFound)
|
|
: TeamPermissionResult<TeamPermissionProfileDTO>.Success(BuildProfile(user));
|
|
}
|
|
|
|
public async Task<TeamPermissionResult<TeamPermissionProfileDTO>> SetOverrideAsync(
|
|
string userId,
|
|
string permissionKey,
|
|
UserPermissionState state,
|
|
ClaimsPrincipal caller,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
if (!IsAdmin(caller))
|
|
return TeamPermissionResult<TeamPermissionProfileDTO>.Failure(TeamPermissionResultStatus.Forbidden);
|
|
|
|
var canonicalKey = TeamPermissionKeys.All.FirstOrDefault(
|
|
key => string.Equals(key, permissionKey, StringComparison.OrdinalIgnoreCase));
|
|
if (canonicalKey is null)
|
|
return TeamPermissionResult<TeamPermissionProfileDTO>.Failure(
|
|
TeamPermissionResultStatus.InvalidPermissionKey);
|
|
|
|
var user = await _dataService.GetUserAsync(userId, cancellationToken);
|
|
if (user is null)
|
|
return TeamPermissionResult<TeamPermissionProfileDTO>.Failure(TeamPermissionResultStatus.NotFound);
|
|
|
|
await _dataService.SetOverrideAsync(userId, canonicalKey, state, cancellationToken);
|
|
|
|
var updatedOverrides = user.Overrides.ToDictionary(
|
|
pair => pair.Key,
|
|
pair => pair.Value,
|
|
StringComparer.OrdinalIgnoreCase);
|
|
updatedOverrides[canonicalKey] = state;
|
|
|
|
return TeamPermissionResult<TeamPermissionProfileDTO>.Success(
|
|
BuildProfile(new TeamPermissionUserData
|
|
{
|
|
UserId = user.UserId,
|
|
RoleName = user.RoleName,
|
|
Overrides = updatedOverrides
|
|
}));
|
|
}
|
|
|
|
private TeamPermissionProfileDTO BuildProfile(TeamPermissionUserData user)
|
|
{
|
|
return new TeamPermissionProfileDTO
|
|
{
|
|
UserId = user.UserId,
|
|
RoleName = user.RoleName,
|
|
Permissions = TeamPermissionKeys.All
|
|
.Select(key => new TeamPermissionValueDTO
|
|
{
|
|
PermissionKey = key,
|
|
OverrideState = user.Overrides.TryGetValue(key, out var state)
|
|
? state
|
|
: UserPermissionState.Unset,
|
|
IsGranted = _policy.IsAllowed(user.RoleName, key, user.Overrides)
|
|
})
|
|
.ToList()
|
|
};
|
|
}
|
|
|
|
private static bool IsAdmin(ClaimsPrincipal? caller) =>
|
|
caller?.IsInRole("Admin") == true;
|
|
}
|