mirror of
https://github.com/opelly27/WinStudentGoalTracker.git
synced 2026-05-20 11:07:41 +00:00
latest
This commit is contained in:
@@ -0,0 +1,273 @@
|
||||
using WinStudentGoalTracker.Models;
|
||||
|
||||
namespace WinStudentGoalTracker.Services;
|
||||
|
||||
public readonly record struct PermissionRule(bool Mine, bool Others);
|
||||
|
||||
public static class PermissionMatrix
|
||||
{
|
||||
private static readonly PermissionRule Allow = new(true, true);
|
||||
private static readonly PermissionRule MineOnly = new(true, false);
|
||||
private static readonly PermissionRule Deny = new(false, false);
|
||||
|
||||
// _rules[role][entity][action] → PermissionRule
|
||||
private static readonly Dictionary<string, Dictionary<string, Dictionary<string, PermissionRule>>> _rules = new()
|
||||
{
|
||||
// ──────────────────────────────────────────────
|
||||
// Super Admin — full access to everything
|
||||
// ──────────────────────────────────────────────
|
||||
[UserRoles.SuperAdmin] = new()
|
||||
{
|
||||
[EntityType.SchoolDistrict] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = Allow,
|
||||
},
|
||||
[EntityType.Program] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = Allow,
|
||||
},
|
||||
[EntityType.User] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = Allow,
|
||||
},
|
||||
[EntityType.Student] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = Allow,
|
||||
},
|
||||
[EntityType.Goal] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = Allow,
|
||||
},
|
||||
[EntityType.ProgressEvent] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = Allow,
|
||||
},
|
||||
},
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// District Admin
|
||||
// ──────────────────────────────────────────────
|
||||
[UserRoles.DistrictAdmin] = new()
|
||||
{
|
||||
[EntityType.SchoolDistrict] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = MineOnly,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.Program] = new()
|
||||
{
|
||||
[PermissionAction.Create] = MineOnly,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = MineOnly,
|
||||
},
|
||||
[EntityType.User] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = Allow,
|
||||
},
|
||||
[EntityType.Student] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = Allow,
|
||||
},
|
||||
[EntityType.Goal] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = Allow,
|
||||
},
|
||||
[EntityType.ProgressEvent] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = Allow,
|
||||
},
|
||||
},
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// Program Admin
|
||||
// ──────────────────────────────────────────────
|
||||
[UserRoles.ProgramAdmin] = new()
|
||||
{
|
||||
[EntityType.SchoolDistrict] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = Deny,
|
||||
[PermissionAction.Update] = Deny,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.Program] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = MineOnly,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.User] = new()
|
||||
{
|
||||
[PermissionAction.Create] = MineOnly,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = MineOnly,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.Student] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = MineOnly,
|
||||
},
|
||||
[EntityType.Goal] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = MineOnly,
|
||||
},
|
||||
[EntityType.ProgressEvent] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Allow,
|
||||
[PermissionAction.Read] = Allow,
|
||||
[PermissionAction.Update] = Allow,
|
||||
[PermissionAction.Delete] = MineOnly,
|
||||
},
|
||||
},
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// Teacher
|
||||
// ──────────────────────────────────────────────
|
||||
[UserRoles.Teacher] = new()
|
||||
{
|
||||
[EntityType.SchoolDistrict] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = Deny,
|
||||
[PermissionAction.Update] = Deny,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.Program] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = Deny,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.User] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = MineOnly,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.Student] = new()
|
||||
{
|
||||
[PermissionAction.Create] = MineOnly,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = MineOnly,
|
||||
[PermissionAction.Delete] = MineOnly,
|
||||
},
|
||||
[EntityType.Goal] = new()
|
||||
{
|
||||
[PermissionAction.Create] = MineOnly,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = MineOnly,
|
||||
[PermissionAction.Delete] = MineOnly,
|
||||
},
|
||||
[EntityType.ProgressEvent] = new()
|
||||
{
|
||||
[PermissionAction.Create] = MineOnly,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = MineOnly,
|
||||
[PermissionAction.Delete] = MineOnly,
|
||||
},
|
||||
},
|
||||
|
||||
// ──────────────────────────────────────────────
|
||||
// Paraeducator
|
||||
// ──────────────────────────────────────────────
|
||||
[UserRoles.Paraeducator] = new()
|
||||
{
|
||||
[EntityType.SchoolDistrict] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = Deny,
|
||||
[PermissionAction.Update] = Deny,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.Program] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = Deny,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.User] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = MineOnly,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.Student] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = Deny,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.Goal] = new()
|
||||
{
|
||||
[PermissionAction.Create] = Deny,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = Deny,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
[EntityType.ProgressEvent] = new()
|
||||
{
|
||||
[PermissionAction.Create] = MineOnly,
|
||||
[PermissionAction.Read] = MineOnly,
|
||||
[PermissionAction.Update] = MineOnly,
|
||||
[PermissionAction.Delete] = Deny,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
public static PermissionRule? GetRule(string role, string entity, string action)
|
||||
{
|
||||
if (_rules.TryGetValue(role, out var entities)
|
||||
&& entities.TryGetValue(entity, out var actions)
|
||||
&& actions.TryGetValue(action, out var rule))
|
||||
{
|
||||
return rule;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using WinStudentGoalTracker.Models;
|
||||
|
||||
namespace WinStudentGoalTracker.Services;
|
||||
|
||||
public class PermissionService
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks whether the given role is allowed to perform the specified action
|
||||
/// on the specified entity, considering ownership.
|
||||
/// </summary>
|
||||
/// <param name="role">The user's role (use UserRoles constants)</param>
|
||||
/// <param name="entity">The entity being acted on (use EntityType constants)</param>
|
||||
/// <param name="action">The action being performed (use PermissionAction constants)</param>
|
||||
/// <param name="isMine">Whether the resource belongs to the requesting user.
|
||||
/// For Create actions this parameter is ignored.</param>
|
||||
/// <returns>True if the action is permitted, false otherwise.</returns>
|
||||
public bool IsAllowed(string role, string entity, string action, bool isMine = true)
|
||||
{
|
||||
var rule = PermissionMatrix.GetRule(role, entity, action);
|
||||
|
||||
if (rule is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Create has no ownership concept — use the Mine field as a general "can create" flag
|
||||
if (action == PermissionAction.Create)
|
||||
{
|
||||
return rule.Value.Mine;
|
||||
}
|
||||
|
||||
|
||||
return isMine ? rule.Value.Mine : rule.Value.Others;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user