158 lines
5.0 KiB
C#
158 lines
5.0 KiB
C#
using System.Text.Json;
|
|
using Backend.Data;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Backend.Security;
|
|
|
|
public static class AdminPermissionCatalog
|
|
{
|
|
public const string Dashboard = "dashboard";
|
|
public const string Years = "years";
|
|
public const string Nominations = "nominations";
|
|
public const string Categories = "categories";
|
|
public const string Candidates = "candidates";
|
|
public const string Clips = "clips";
|
|
public const string Risk = "risk";
|
|
public const string Audit = "audit";
|
|
public const string Analytics = "analytics";
|
|
public const string Voting = "voting";
|
|
public const string Winners = "winners";
|
|
public const string Content = "content";
|
|
public const string Settings = "settings";
|
|
public const string Team = "team";
|
|
|
|
public static readonly string[] AllPermissionKeys =
|
|
[
|
|
Dashboard,
|
|
Years,
|
|
Nominations,
|
|
Categories,
|
|
Candidates,
|
|
Clips,
|
|
Risk,
|
|
Audit,
|
|
Analytics,
|
|
Voting,
|
|
Winners,
|
|
Content,
|
|
Settings,
|
|
Team,
|
|
];
|
|
|
|
public static readonly string[] SeasonReadPermissionKeys =
|
|
[
|
|
Dashboard,
|
|
Years,
|
|
Nominations,
|
|
Categories,
|
|
Candidates,
|
|
Clips,
|
|
Analytics,
|
|
Voting,
|
|
Winners,
|
|
];
|
|
|
|
public static bool IsKnownPermission(string permissionKey) =>
|
|
AllPermissionKeys.Contains(permissionKey, StringComparer.OrdinalIgnoreCase);
|
|
|
|
public static string[] DefaultPermissionKeys(string? role)
|
|
{
|
|
return AdminRoles.Normalize(role) switch
|
|
{
|
|
AdminRoles.Owner => AllPermissionKeys,
|
|
AdminRoles.Creator => AllPermissionKeys,
|
|
AdminRoles.Admin => AllPermissionKeys,
|
|
AdminRoles.Member => [Dashboard, Nominations, Categories, Candidates, Clips, Voting, Content],
|
|
AdminRoles.Reviewer => [Dashboard, Nominations, Clips, Risk, Audit],
|
|
AdminRoles.OrganizationTeam => [Dashboard, Content, Analytics, Voting, Winners, Settings],
|
|
AdminRoles.ContentAdmin => [Content, Settings],
|
|
_ => [],
|
|
};
|
|
}
|
|
|
|
public static string[] NormalizePermissionKeys(string? role, IEnumerable<string> permissionKeys)
|
|
{
|
|
var normalizedRole = AdminRoles.Normalize(role);
|
|
var permissions = permissionKeys
|
|
.Where(IsKnownPermission)
|
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
|
.ToList();
|
|
|
|
if (normalizedRole is AdminRoles.Owner or AdminRoles.Creator)
|
|
{
|
|
return AllPermissionKeys;
|
|
}
|
|
|
|
if (DefaultPermissionKeys(normalizedRole).Contains(Settings, StringComparer.OrdinalIgnoreCase)
|
|
&& !permissions.Contains(Settings, StringComparer.OrdinalIgnoreCase))
|
|
{
|
|
permissions.Add(Settings);
|
|
}
|
|
|
|
var hasAnalytics = permissions.Contains(Analytics, StringComparer.OrdinalIgnoreCase);
|
|
var hasWinners = permissions.Contains(Winners, StringComparer.OrdinalIgnoreCase);
|
|
if ((hasAnalytics || hasWinners)
|
|
&& !permissions.Contains(Voting, StringComparer.OrdinalIgnoreCase))
|
|
{
|
|
permissions.Add(Voting);
|
|
}
|
|
|
|
return permissions
|
|
.OrderBy(item => item)
|
|
.ToArray();
|
|
}
|
|
|
|
public static async Task<string[]> GetPermissionKeysAsync(
|
|
AwardsDbContext db,
|
|
string? role,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var normalizedRole = AdminRoles.Normalize(role);
|
|
if (normalizedRole is AdminRoles.Owner or AdminRoles.Creator)
|
|
{
|
|
return AllPermissionKeys;
|
|
}
|
|
|
|
var fallback = DefaultPermissionKeys(normalizedRole);
|
|
var overrideJson = await db.TeamRolePermissions
|
|
.AsNoTracking()
|
|
.Where(item => item.Role == normalizedRole)
|
|
.Select(item => item.PermissionsJson)
|
|
.FirstOrDefaultAsync(cancellationToken);
|
|
|
|
if (string.IsNullOrWhiteSpace(overrideJson))
|
|
{
|
|
return fallback;
|
|
}
|
|
|
|
try
|
|
{
|
|
return NormalizePermissionKeys(normalizedRole, JsonSerializer.Deserialize<string[]>(overrideJson) ?? fallback);
|
|
}
|
|
catch (JsonException)
|
|
{
|
|
return fallback;
|
|
}
|
|
}
|
|
|
|
public static async Task<bool> HasPermissionAsync(
|
|
AwardsDbContext db,
|
|
string? role,
|
|
string permissionKey,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var permissions = await GetPermissionKeysAsync(db, role, cancellationToken);
|
|
return permissions.Contains(permissionKey, StringComparer.OrdinalIgnoreCase);
|
|
}
|
|
|
|
public static async Task<bool> HasAnyPermissionAsync(
|
|
AwardsDbContext db,
|
|
string? role,
|
|
IEnumerable<string> permissionKeys,
|
|
CancellationToken cancellationToken = default)
|
|
{
|
|
var permissions = await GetPermissionKeysAsync(db, role, cancellationToken);
|
|
return permissionKeys.Any(permission => permissions.Contains(permission, StringComparer.OrdinalIgnoreCase));
|
|
}
|
|
}
|