✨ Magic spell for one time code
🗑️ Drop the usage of casbin ♻️ Refactor the permission service ♻️ Refactor the flow of creating an account 🧱 Email infra structure
This commit is contained in:
126
DysonNetwork.Sphere/Permission/PermissionService.cs
Normal file
126
DysonNetwork.Sphere/Permission/PermissionService.cs
Normal file
@ -0,0 +1,126 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using NodaTime;
|
||||
|
||||
namespace DysonNetwork.Sphere.Permission;
|
||||
|
||||
public class PermissionService(AppDatabase db)
|
||||
{
|
||||
public async Task<T?> GetPermissionAsync<T>(string actor, string area, string key)
|
||||
{
|
||||
var now = SystemClock.Instance.GetCurrentInstant();
|
||||
var groupsId = await db.PermissionGroupMembers
|
||||
.Where(n => n.Actor == actor)
|
||||
.Where(n => n.ExpiredAt == null || n.ExpiredAt < now)
|
||||
.Where(n => n.AffectedAt == null || n.AffectedAt >= now)
|
||||
.Select(e => e.GroupId)
|
||||
.ToListAsync();
|
||||
var permission = await db.PermissionNodes
|
||||
.Where(n => n.GroupId == null || groupsId.Contains(n.GroupId.Value))
|
||||
.Where(n => n.Key == key && n.Actor == actor && n.Area == area)
|
||||
.Where(n => n.ExpiredAt == null || n.ExpiredAt < now)
|
||||
.Where(n => n.AffectedAt == null || n.AffectedAt >= now)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return permission is not null ? _DeserializePermissionValue<T>(permission.Value) : default;
|
||||
}
|
||||
|
||||
public async Task<PermissionNode> AddPermissionNode<T>(
|
||||
string actor,
|
||||
string area,
|
||||
string key,
|
||||
T value,
|
||||
Instant? expiredAt = null,
|
||||
Instant? affectedAt = null
|
||||
)
|
||||
{
|
||||
if (value is null) throw new ArgumentNullException(nameof(value));
|
||||
|
||||
var node = new PermissionNode
|
||||
{
|
||||
Actor = actor,
|
||||
Key = key,
|
||||
Area = area,
|
||||
Value = _SerializePermissionValue(value),
|
||||
ExpiredAt = expiredAt,
|
||||
AffectedAt = affectedAt
|
||||
};
|
||||
|
||||
db.PermissionNodes.Add(node);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public async Task<PermissionNode> AddPermissionNodeToGroup<T>(
|
||||
PermissionGroup group,
|
||||
string actor,
|
||||
string area,
|
||||
string key,
|
||||
T value,
|
||||
Instant? expiredAt = null,
|
||||
Instant? affectedAt = null
|
||||
)
|
||||
{
|
||||
if (value is null) throw new ArgumentNullException(nameof(value));
|
||||
|
||||
var node = new PermissionNode
|
||||
{
|
||||
Actor = actor,
|
||||
Key = key,
|
||||
Area = area,
|
||||
Value = _SerializePermissionValue(value),
|
||||
ExpiredAt = expiredAt,
|
||||
AffectedAt = affectedAt,
|
||||
Group = group,
|
||||
GroupId = group.Id
|
||||
};
|
||||
|
||||
db.PermissionNodes.Add(node);
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
public async Task RemovePermissionNode(string actor, string area, string key)
|
||||
{
|
||||
var node = await db.PermissionNodes
|
||||
.Where(n => n.Actor == actor && n.Area == area && n.Key == key)
|
||||
.FirstOrDefaultAsync();
|
||||
if (node is not null) db.PermissionNodes.Remove(node);
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
public async Task RemovePermissionNodeFromGroup<T>(PermissionGroup group, string actor, string area, string key)
|
||||
{
|
||||
var node = await db.PermissionNodes
|
||||
.Where(n => n.GroupId == group.Id)
|
||||
.Where(n => n.Actor == actor && n.Area == area && n.Key == key)
|
||||
.FirstOrDefaultAsync();
|
||||
if (node is null) return;
|
||||
db.PermissionNodes.Remove(node);
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
private static T? _DeserializePermissionValue<T>(JsonDocument json)
|
||||
{
|
||||
return JsonSerializer.Deserialize<T>(json.RootElement.GetRawText());
|
||||
}
|
||||
|
||||
private static JsonDocument _SerializePermissionValue<T>(T obj)
|
||||
{
|
||||
var str = JsonSerializer.Serialize(obj);
|
||||
return JsonDocument.Parse(str);
|
||||
}
|
||||
|
||||
public static PermissionNode NewPermissionNode<T>(string actor, string area, string key, T value)
|
||||
{
|
||||
return new PermissionNode
|
||||
{
|
||||
Actor = actor,
|
||||
Area = area,
|
||||
Key = key,
|
||||
Value = _SerializePermissionValue(value),
|
||||
};
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user