Browse Source

IdleBusExtesions新增获得租户FreeSql实例
租户设置权限限定租户权限范围,防止租户非法授权
租户管理设置权限,删除租户下关联的角色权限

zhontai 3 years ago
parent
commit
79db2382ff

+ 3 - 3
Admin.Core.Common/Cache/CacheKey.cs

@@ -20,19 +20,19 @@ namespace Admin.Core.Common.Cache
         public const string PassWordEncryptKey = "admin:password:encrypt:{0}";
 
         /// <summary>
-        /// 用户权限 admin:user:用户主键:permissions
+        /// 用户权限 admin:user:permissions:用户主键
         /// </summary>
         [Description("用户权限")]
         public const string UserPermissions = "admin:user:permissions:{0}";
 
         /// <summary>
-        /// 用户信息 admin:user:用户主键:info
+        /// 用户信息 admin:user:info:用户主键
         /// </summary>
         [Description("用户信息")]
         public const string UserInfo = "admin:user:info:{0}";
 
         /// <summary>
-        /// 租户信息 admin:tenant:租户主键:info
+        /// 租户信息 admin:tenant:info:租户主键
         /// </summary>
         [Description("租户信息")]
         public const string TenantInfo = "admin:tenant:info:{0}";

+ 39 - 5
Admin.Core.Repository/Base/IdleBusExtesions.cs

@@ -83,17 +83,18 @@ namespace Admin.Core.Repository
             var user = serviceProvider.GetRequiredService<IUser>();
             var appConfig = serviceProvider.GetRequiredService<AppConfig>();
 
-            if (appConfig.Tenant && user.DataIsolationType == DataIsolationType.OwnDb && user.TenantId.HasValue)
+            var tenantId = user.TenantId;
+            if (appConfig.Tenant && user.DataIsolationType == DataIsolationType.OwnDb && tenantId.HasValue)
             {
-                var tenantName = "tenant_" + user.TenantId.ToString();
+                var tenantName = "tenant_" + tenantId.ToString();
                 var exists = ib.Exists(tenantName);
                 if (!exists)
                 {
                     var dbConfig = serviceProvider.GetRequiredService<DbConfig>();
                     //查询租户数据库信息
-                    var freeSql = serviceProvider.GetRequiredService<IFreeSql>();
-                    var tenantRepository = freeSql.GetRepository<TenantEntity>();
-                    var tenant = tenantRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(user.TenantId).ToOne<CreateFreeSqlTenantDto>();
+                    var masterDb = serviceProvider.GetRequiredService<IFreeSql>();
+                    var tenantRepository = masterDb.GetRepository<TenantEntity>();
+                    var tenant = tenantRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(tenantId).ToOne<CreateFreeSqlTenantDto>();
 
                     var timeSpan = tenant.IdleTime.HasValue && tenant.IdleTime.Value > 0 ? TimeSpan.FromMinutes(tenant.IdleTime.Value) : TimeSpan.MaxValue;
                     ib.TryRegister(tenantName, () => CreateFreeSql(user, appConfig, dbConfig, tenant), timeSpan);
@@ -107,5 +108,38 @@ namespace Admin.Core.Repository
                 return freeSql;
             }
         }
+
+        /// <summary>
+        /// 获得租户FreeSql实例
+        /// </summary>
+        /// <param name="ib"></param>
+        /// <param name="serviceProvider"></param>
+        /// <param name="tenantId"></param>
+        /// <returns></returns>
+        public static IFreeSql GetTenantFreeSql(this IdleBus<IFreeSql> ib, IServiceProvider serviceProvider, long? tenantId = null)
+        {
+            if (tenantId.HasValue)
+            {
+                var user = serviceProvider.GetRequiredService<IUser>();
+                var appConfig = serviceProvider.GetRequiredService<AppConfig>();
+                var tenantName = "tenant_" + tenantId.ToString();
+                var exists = ib.Exists(tenantName);
+                if (!exists)
+                {
+                    var dbConfig = serviceProvider.GetRequiredService<DbConfig>();
+                    //查询租户数据库信息
+                    var masterDb = serviceProvider.GetRequiredService<IFreeSql>();
+                    var tenantRepository = masterDb.GetRepository<TenantEntity>();
+                    var tenant = tenantRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(tenantId).ToOne<CreateFreeSqlTenantDto>();
+
+                    var timeSpan = tenant.IdleTime.HasValue && tenant.IdleTime.Value > 0 ? TimeSpan.FromMinutes(tenant.IdleTime.Value) : TimeSpan.MaxValue;
+                    ib.TryRegister(tenantName, () => CreateFreeSql(user, appConfig, dbConfig, tenant), timeSpan);
+                }
+
+                return ib.Get(tenantName);
+            }
+
+            return null;
+        }
     }
 }

+ 37 - 14
Admin.Core.Service/Admin/Permission/PermissionService.cs

@@ -8,6 +8,7 @@ using Admin.Core.Repository;
 using Admin.Core.Repository.Admin;
 using Admin.Core.Service.Admin.Permission.Input;
 using Admin.Core.Service.Admin.Permission.Output;
+using Microsoft.Extensions.DependencyInjection;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -21,24 +22,27 @@ namespace Admin.Core.Service.Admin.Permission
         private readonly IPermissionRepository _permissionRepository;
         private readonly IRoleRepository _roleRepository;
         private readonly IRolePermissionRepository _rolePermissionRepository;
-        private readonly IRepositoryBase<TenantPermissionEntity> _tenantPermissionRepository;
         private readonly IUserRepository _userRepository;
+        private readonly IRepositoryBase<TenantPermissionEntity> _tenantPermissionRepository;
+        private readonly IRepositoryBase<UserRoleEntity> _userRoleRepository;
 
         public PermissionService(
             AppConfig appConfig,
             IPermissionRepository permissionRepository,
             IRoleRepository roleRepository,
             IRolePermissionRepository rolePermissionRepository,
+            IUserRepository userRepository,
             IRepositoryBase<TenantPermissionEntity> tenantPermissionRepository,
-            IUserRepository userRepository
+            IRepositoryBase<UserRoleEntity> userRoleRepository
         )
         {
             _appConfig = appConfig;
             _permissionRepository = permissionRepository;
             _roleRepository = roleRepository;
             _rolePermissionRepository = rolePermissionRepository;
-            _tenantPermissionRepository = tenantPermissionRepository;
             _userRepository = userRepository;
+            _tenantPermissionRepository = tenantPermissionRepository;
+            _userRoleRepository = userRoleRepository;
         }
 
         public async Task<IResponseOutput> GetAsync(long id)
@@ -205,7 +209,7 @@ namespace Admin.Core.Service.Admin.Permission
 
             //批量删除权限
             var deleteIds = permissionIds.Where(d => !input.PermissionIds.Contains(d));
-            if (deleteIds.Count() > 0)
+            if (deleteIds.Any())
             {
                 await _rolePermissionRepository.DeleteAsync(m => m.RoleId == input.RoleId && deleteIds.Contains(m.PermissionId));
             }
@@ -213,7 +217,16 @@ namespace Admin.Core.Service.Admin.Permission
             //批量插入权限
             var insertRolePermissions = new List<RolePermissionEntity>();
             var insertPermissionIds = input.PermissionIds.Where(d => !permissionIds.Contains(d));
-            if (insertPermissionIds.Count() > 0)
+
+            //防止租户非法授权
+            if (_appConfig.Tenant && User.TenantType == TenantType.Tenant)
+            {
+                var masterDb = ServiceProvider.GetRequiredService<IFreeSql>();
+                var tenantPermissionIds = await masterDb.GetRepository<TenantPermissionEntity>().Select.Where(d => d.TenantId == User.TenantId).ToListAsync(m => m.PermissionId);
+                insertPermissionIds = insertPermissionIds.Where(d => tenantPermissionIds.Contains(d));
+            }
+
+            if (insertPermissionIds.Any())
             {
                 foreach (var permissionId in insertPermissionIds)
                 {
@@ -226,8 +239,12 @@ namespace Admin.Core.Service.Admin.Permission
                 await _rolePermissionRepository.InsertAsync(insertRolePermissions);
             }
 
-            //清除权限
-            await Cache.DelByPatternAsync(CacheKey.UserPermissions);
+            //清除角色下关联的用户权限缓存
+            var userIds = await _userRoleRepository.Select.Where(a => a.RoleId == input.RoleId).ToListAsync(a => a.UserId);
+            foreach (var userId in userIds)
+            {
+                await Cache.DelAsync(string.Format(CacheKey.UserPermissions, userId));
+            }
 
             return ResponseOutput.Ok();
         }
@@ -235,20 +252,26 @@ namespace Admin.Core.Service.Admin.Permission
         [Transaction]
         public async Task<IResponseOutput> SaveTenantPermissionsAsync(PermissionSaveTenantPermissionsInput input)
         {
+            //获得租户db
+            var ib = ServiceProvider.GetRequiredService<IdleBus<IFreeSql>>();
+            var tenantDb = ib.GetTenantFreeSql(ServiceProvider, input.TenantId);
+
             //查询租户权限
             var permissionIds = await _tenantPermissionRepository.Select.Where(d => d.TenantId == input.TenantId).ToListAsync(m => m.PermissionId);
 
             //批量删除租户权限
             var deleteIds = permissionIds.Where(d => !input.PermissionIds.Contains(d));
-            if (deleteIds.Count() > 0)
+            if (deleteIds.Any())
             {
                 await _tenantPermissionRepository.DeleteAsync(m => m.TenantId == input.TenantId && deleteIds.Contains(m.PermissionId));
+                //删除租户下关联的角色权限
+                await tenantDb.GetRepository<RolePermissionEntity>().DeleteAsync(a => deleteIds.Contains(a.PermissionId));
             }
 
             //批量插入租户权限
             var tenatPermissions = new List<TenantPermissionEntity>();
             var insertPermissionIds = input.PermissionIds.Where(d => !permissionIds.Contains(d));
-            if (insertPermissionIds.Count() > 0)
+            if (insertPermissionIds.Any())
             {
                 foreach (var permissionId in insertPermissionIds)
                 {
@@ -261,11 +284,11 @@ namespace Admin.Core.Service.Admin.Permission
                 await _tenantPermissionRepository.InsertAsync(tenatPermissions);
             }
 
-            //清除租户下所有用户权限
-            if (_appConfig.Tenant)
+            //清除租户下所有用户权限缓存
+            var userIds = await tenantDb.GetRepository<UserEntity>().Select.Where(a => a.TenantId == input.TenantId).ToListAsync(a => a.Id);
+            if(userIds.Any())
             {
-                var userIds = await _userRepository.Select.Where(a => a.TenantId == input.TenantId).ToListAsync(a => a.Id);
-                foreach(var userId in userIds)
+                foreach (var userId in userIds)
                 {
                     await Cache.DelAsync(string.Format(CacheKey.UserPermissions, userId));
                 }
@@ -278,7 +301,7 @@ namespace Admin.Core.Service.Admin.Permission
         {
             var permissions = await _permissionRepository.Select
                 .WhereIf(_appConfig.Tenant && User.TenantType == TenantType.Tenant, a =>
-                    _permissionRepository.Orm.Select<TenantPermissionEntity>()
+                    _tenantPermissionRepository
                     .Where(b => b.PermissionId == a.Id && b.TenantId == User.TenantId)
                     .Any()
                 )

+ 1 - 1
Admin.Core.Service/Admin/User/UserService.cs

@@ -45,7 +45,7 @@ namespace Admin.Core.Service.Admin.User
         {
             var output = new ResponseOutput<AuthLoginOutput>();
             var entityDto = await _userRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(id).ToOneAsync<AuthLoginOutput>();
-            if (_appConfig.Tenant)
+            if (_appConfig.Tenant && entityDto?.TenantId.Value > 0)
             {
                 var tenant = await _tenantRepository.Select.DisableGlobalFilter("Tenant").WhereDynamic(entityDto.TenantId).ToOneAsync(a => new { a.TenantType, a.DataIsolationType });
                 output.Data.TenantType = tenant.TenantType;

+ 3 - 3
Admin.Core/Admin.Core.Common.xml

@@ -341,17 +341,17 @@
         </member>
         <member name="F:Admin.Core.Common.Cache.CacheKey.UserPermissions">
             <summary>
-            用户权限 admin:user:用户主键:permissions
+            用户权限 admin:user:permissions:用户主键
             </summary>
         </member>
         <member name="F:Admin.Core.Common.Cache.CacheKey.UserInfo">
             <summary>
-            用户信息 admin:user:用户主键:info
+            用户信息 admin:user:info:用户主键
             </summary>
         </member>
         <member name="F:Admin.Core.Common.Cache.CacheKey.TenantInfo">
             <summary>
-            租户信息 admin:tenant:租户主键:info
+            租户信息 admin:tenant:info:租户主键
             </summary>
         </member>
         <member name="T:Admin.Core.Common.Cache.CacheType">

+ 1 - 1
Admin.Core/Controllers/Admin/AuthController.cs

@@ -183,7 +183,7 @@ namespace Admin.Core.Controllers.Admin
             var userId = userClaims.FirstOrDefault(a => a.Type == ClaimAttributes.UserId)?.Value;
             if (userId.IsNull())
             {
-                return ResponseOutput.NotOk();
+                return ResponseOutput.NotOk("登录信息已失效");
             }
             var output = await _userServices.GetLoginUserAsync(userId.ToLong());