Skip to content

Commit

Permalink
feat: 完善授权管理
Browse files Browse the repository at this point in the history
  • Loading branch information
uyoufu committed Jul 23, 2024
1 parent 97440e5 commit 44139b1
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
using UZonMailService.Models.SQL;
using UZonMailService.Models.SQL.Permission;
using UZonMailService.Models.Validators;
using UZonMailService.Services.Permission;
using UZonMailService.Services.Settings;
using UZonMailService.Utils.ASPNETCore.PagingQuery;
using UZonMailService.Utils.Database;
using UZonMailService.Utils.Extensions;

namespace UZonMailService.Controllers.Permission
{
public class RoleController(TokenService tokenService, SqlContext db) : PermissionControllerBase
public class RoleController(TokenService tokenService, SqlContext db, PermissionService permission) : PermissionControllerBase
{
/// <summary>
/// 获取角色数量
Expand Down Expand Up @@ -123,12 +124,26 @@ public async Task<ResponseResult<Role>> UpsertRole([FromBody] Role role)
public async Task<ResponseResult<bool>> DeleteRole(long roleId)
{
// 删除角色
var role = await db.Roles.Where(x => x.Id == roleId)
.Include(x => x.UserRoles)
.Include(x=>x.PermissionCodes)
.FirstOrDefaultAsync();
if (role == null) return true.ToSuccessResponse();

var userRoles = role.UserRoles?.ToList() ?? [];
// 删除用户与角色关联表
role.UserRoles?.Clear();
role.PermissionCodes?.Clear();
// 删除角色
db.Roles.Remove(role);
await db.SaveChangesAsync();

// 重新计算受影响的用户的权限

// 通知用户更新权限
// 更新权限缓存
var userIds = userRoles.Select(x => x.UserId).ToList();
var permissionCodesDic = await permission.UpdateUserPermissionsCache(userIds);
// 通知权限更新
await permission.NotifyPermissionUpdate(permissionCodesDic);

return true.ToSuccessResponse();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
using UZonMailService.Models.SQL;
using UZonMailService.Models.SQL.Permission;
using UZonMailService.Models.Validators;
using UZonMailService.Services.Permission;
using UZonMailService.Services.Settings;
using UZonMailService.Utils.ASPNETCore.PagingQuery;
using UZonMailService.Utils.Database;
using UZonMailService.Utils.Extensions;

namespace UZonMailService.Controllers.Permission
{
public class UserRoleController(SqlContext db) : PermissionControllerBase
public class UserRoleController(SqlContext db, PermissionService permission) : PermissionControllerBase
{
/// <summary>
/// 创建或者更新角色
Expand Down Expand Up @@ -42,7 +43,7 @@ public async Task<ResponseResult<UserRole>> UpsertUserRole([FromBody] UserRole u
userRole = existOne;
}
else
{
{
db.UserRoles.Add(userRole);
}

Expand All @@ -58,7 +59,7 @@ public async Task<ResponseResult<UserRole>> UpsertUserRole([FromBody] UserRole u
[HttpGet("filtered-count")]
public async Task<ResponseResult<int>> GetRolesCount(string filter)
{
var dbSet = db.UserRoles.AsNoTracking();
var dbSet = db.UserRoles.AsNoTracking();
if (!string.IsNullOrEmpty(filter))
{
dbSet = dbSet.Where(x => x.User.UserName.Contains(filter) || x.User.UserName.Contains(filter));
Expand All @@ -82,7 +83,7 @@ public async Task<ResponseResult<List<UserRole>>> GetRolesData(string filter, [F
}
var results = await dbSet.Page(pagination)
.Include(x => x.User)
.Include(x=>x.Roles)
.Include(x => x.Roles)
.ToListAsync();

return results.ToSuccessResponse();
Expand All @@ -96,11 +97,23 @@ public async Task<ResponseResult<List<UserRole>>> GetRolesData(string filter, [F
[HttpDelete("{userRoleId:long}")]
public async Task<ResponseResult<bool>> DeleteUserRole(long userRoleId)
{
// 先移除关联的角色
// 先移除关联的角色
var userRole = await db.UserRoles.Where(x => x.Id == userRoleId)
.Include(x => x.Roles)
.FirstOrDefaultAsync();
if (userRole == null) return false.ToErrorResponse("未找到对应的用户角色");
userRole.Roles.Clear();

// 删除本身
db.UserRoles.Remove(userRole);
await db.SaveChangesAsync();

// 更新权限缓存
var permissionCodesDic = await permission.UpdateUserPermissionsCache([userRole.UserId]);
// 通知权限更新
await permission.NotifyPermissionUpdate(permissionCodesDic);

// 返回结果
return true.ToSuccessResponse();
}
}
Expand Down
12 changes: 12 additions & 0 deletions backend-src/UZonMailService/Models/SQL/Permission/License.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using UZonMailService.Models.SQL.Base;

namespace UZonMailService.Models.SQL.Permission
{
/// <summary>
/// 授权验证
/// </summary>
public class License : SqlId
{

}
}
44 changes: 44 additions & 0 deletions backend-src/UZonMailService/Services/License/LicenseManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Uamazing.Utils.Web.Service;

namespace UZonMailService.Services.License
{
/// <summary>
/// 授权管理
/// </summary>
public class LicenseManager(IServiceScopeFactory ssf) : ISingletonService
{
/// <summary>
/// 上一次授权更新日期
/// </summary>
private DateTime _lastUpdateDate;

/// <summary>
/// 更新间隔
/// </summary>
private double _updateIntervalHours = 24;

/// <summary>
/// 获取授权类型
/// </summary>
/// <returns></returns>
public LicenseType GetLicenseType()
{
// 判断是否需要更新
var timespan = DateTime.Now - _lastUpdateDate;
if (timespan.TotalHours > _updateIntervalHours)
{
// 更新授权
UpdateLicense();
}

return _licenseType;
}

private LicenseType _licenseType = LicenseType.Community;
private void UpdateLicense()
{
// 从数据库读取授权文件
_licenseType = LicenseType.Community;
}
}
}
23 changes: 23 additions & 0 deletions backend-src/UZonMailService/Services/License/LicenseType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace UZonMailService.Services.License
{
/// <summary>
/// 授权类型
/// </summary>
public enum LicenseType
{
/// <summary>
/// 社区版本,免费
/// </summary>
Community = 1 << 0,

/// <summary>
/// 专业版
/// </summary>
Professional = 1 << 1,

/// <summary>
/// 企业版
/// </summary>
Enterprise = 1 << 2,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;
using Uamazing.Utils.Web.Service;
using UZonMailService.Cache;
using UZonMailService.Models.SQL;
using UZonMailService.Models.SQL.MultiTenant;
using UZonMailService.SignalRHubs;
using UZonMailService.SignalRHubs.Extensions;

namespace UZonMailService.Services.Permission
{
/// <summary>
/// 权限服务
/// </summary>
public class PermissionService(SqlContext db, CacheService cache, IHubContext<UzonMailHub, IUzonMailClient> hub) : IScopedService
{
/// <summary>
/// 更新用户的权限缓存
/// </summary>
/// <param name="userIds"></param>
/// <returns>返回权限码</returns>
public async Task<Dictionary<long,List<string>>> UpdateUserPermissionsCache(List<long> userIds)
{
if (userIds.Count == 0) return [];

var userRoles = await db.UserRoles.AsNoTracking()
.Where(x => userIds.Contains(x.UserId))
.Include(x => x.Roles)
.ThenInclude(x => x.PermissionCodes)
.GroupBy(x=>x.UserId)
.ToListAsync();

Dictionary<long, List<string>> results = [];
foreach (var item in userRoles)
{
var permissionCodes = item.SelectMany(x=>x.Roles).SelectMany(x=>x.PermissionCodes).Select(x => x.Code).Distinct().ToList();
results.Add(item.Key, permissionCodes);
// 更新缓存
await cache.SetAsync($"permissions/{item.Key}", permissionCodes);
}
return results;
}

/// <summary>
/// 通知用户权限更新
/// </summary>
/// <param name="userPermissionCodes"></param>
/// <returns></returns>
public async Task NotifyPermissionUpdate(Dictionary<long,List<string>> userPermissionCodes)
{
if(userPermissionCodes.Count == 0) return;

foreach (var item in userPermissionCodes)
{
await hub.GetUserClient(item.Key).PermissionUpdated(item.Value);
}
}
}
}
3 changes: 2 additions & 1 deletion backend-src/UZonMailService/SignalRHubs/IUzonMailClient.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using UZonMailService.SignalRHubs.Notify;
using UZonMailService.SignalRHubs.Permission;
using UZonMailService.SignalRHubs.SendEmail;

namespace UZonMailService.SignalRHubs
{
/// <summary>
/// 客户端的方法
/// </summary>
public interface IUzonMailClient: ISendEmailClient, INotifyClient
public interface IUzonMailClient: ISendEmailClient, INotifyClient,IPermissionClient
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace UZonMailService.SignalRHubs.Permission
{
public interface IPermissionClient
{
/// <summary>
/// 通知权限更新
/// </summary>
/// <param name="permissions"></param>
/// <returns></returns>
Task PermissionUpdated(List<string> permissions);
}
}
2 changes: 1 addition & 1 deletion backend-src/UZonMailService/UZonMailService.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<ServerGarbageCollection>false</ServerGarbageCollection>
<ConcurrentGarbageCollection>true</ConcurrentGarbageCollection>
<Platforms>x64</Platforms>
<FileVersion>0.8.7.0</FileVersion>
<FileVersion>0.8.9.0</FileVersion>
</PropertyGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions backend-src/UzonMailDesktop/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.8.7.0")]
[assembly: AssemblyFileVersion("0.8.7.0")]
[assembly: AssemblyVersion("0.8.9.0")]
[assembly: AssemblyFileVersion("0.8.9.0")]

0 comments on commit 44139b1

Please sign in to comment.