RoleManager.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using IwbZero.IdentityFramework;
  4. using System.Threading.Tasks;
  5. using Abp;
  6. using Abp.Application.Features;
  7. using Abp.Authorization;
  8. using Abp.Collections.Extensions;
  9. using Abp.Domain.Services;
  10. using Abp.Domain.Uow;
  11. using Abp.Localization;
  12. using Abp.MultiTenancy;
  13. using Abp.Runtime.Caching;
  14. using Abp.Runtime.Session;
  15. using IwbZero.Authorization.Permissions;
  16. using IwbZero.Authorization.Users;
  17. using IwbZero.Caching;
  18. using IwbZero.Configuration;
  19. using Microsoft.AspNet.Identity;
  20. namespace IwbZero.Authorization.Roles
  21. {
  22. public abstract class IwbRoleManager<TRole, TUser> : RoleManager<TRole, int>,
  23. IDomainService
  24. where TRole : IwbSysRole<TUser>,new()
  25. where TUser : IwbSysUser<TUser>
  26. {
  27. public ILocalizationManager LocalizationManager { get; set; }
  28. public IAbpSession AbpSession { get; set; }
  29. public IIwbRoleManagementConfig IwbRoleManagementConfig { get; private set; }
  30. public FeatureDependencyContext FeatureDependencyContext { get; set; }
  31. private IIwbRolePermissionStore<TRole> IwbRolePermissionStore
  32. {
  33. get
  34. {
  35. if (!(Store is IIwbRolePermissionStore<TRole>))
  36. {
  37. throw new AbpException("Store is not IRolePermissionStore");
  38. }
  39. return Store as IIwbRolePermissionStore<TRole>;
  40. }
  41. }
  42. protected string LocalizationSourceName { get; set; }
  43. protected IwbRoleStore<TRole, TUser> AbpStore { get; private set; }
  44. protected IIwbPermissionManager PermissionManager { get; }
  45. protected ICacheManager CacheManager { get; }
  46. protected IUnitOfWorkManager UnitOfWorkManager { get; }
  47. /// <summary>
  48. /// Constructor.
  49. /// </summary>
  50. public IwbRoleManager(
  51. IwbRoleStore<TRole, TUser> store,
  52. IIwbPermissionManager permissionManager,
  53. IIwbRoleManagementConfig iwbRoleManagementConfig,
  54. ICacheManager cacheManager,
  55. IUnitOfWorkManager unitOfWorkManager,
  56. string localizationSourceName = null)
  57. : base(store)
  58. {
  59. PermissionManager = permissionManager;
  60. CacheManager = cacheManager;
  61. UnitOfWorkManager = unitOfWorkManager;
  62. IwbRoleManagementConfig = iwbRoleManagementConfig;
  63. AbpStore = store;
  64. AbpSession = NullAbpSession.Instance;
  65. LocalizationManager = NullLocalizationManager.Instance;
  66. LocalizationSourceName = localizationSourceName ?? IwbZeroConsts.IwbZeroLocalizationSourceName;
  67. }
  68. /// <summary>
  69. /// Checks if a role is granted for a permission.
  70. /// </summary>
  71. /// <param name="roleName">The role's name to check it's permission</param>
  72. /// <param name="permissionName">Name of the permission</param>
  73. /// <returns>True, if the role has the permission</returns>
  74. public virtual async Task<bool> IsGrantedAsync(string roleName, string permissionName)
  75. {
  76. return await IsGrantedAsync((await GetRoleByNameAsync(roleName)).Id, PermissionManager.GetPermission(permissionName));
  77. }
  78. /// <summary>
  79. /// Checks if a role has a permission.
  80. /// </summary>
  81. /// <param name="roleId">The role's id to check it's permission</param>
  82. /// <param name="permissionName">Name of the permission</param>
  83. /// <returns>True, if the role has the permission</returns>
  84. public virtual async Task<bool> IsGrantedAsync(int roleId, string permissionName)
  85. {
  86. return await IsGrantedAsync(roleId, PermissionManager.GetPermission(permissionName));
  87. }
  88. /// <summary>
  89. /// Checks if a role is granted for a permission.
  90. /// </summary>
  91. /// <param name="role">The role</param>
  92. /// <param name="permission">The permission</param>
  93. /// <returns>True, if the role has the permission</returns>
  94. public Task<bool> IsGrantedAsync(TRole role, Permission permission)
  95. {
  96. return IsGrantedAsync(role.Id, permission);
  97. }
  98. /// <summary>
  99. /// Checks if a role is granted for a permission.
  100. /// </summary>
  101. /// <param name="roleId">role id</param>
  102. /// <param name="permission">The permission</param>
  103. /// <returns>True, if the role has the permission</returns>
  104. public virtual async Task<bool> IsGrantedAsync(int roleId, Permission permission)
  105. {
  106. //Get cached role permissions
  107. var cacheItem = await GetRolePermissionCacheItemAsync(roleId);
  108. //Check the permission
  109. return cacheItem.GrantedPermissions.Contains(permission.Name);
  110. }
  111. /// <summary>
  112. /// Gets granted permission names for a role.
  113. /// </summary>
  114. /// <param name="roleId">Role id</param>
  115. /// <returns>List of granted permissions</returns>
  116. public virtual async Task<IReadOnlyList<Permission>> GetGrantedPermissionsAsync(int roleId)
  117. {
  118. return await GetGrantedPermissionsAsync(await GetRoleByIdAsync(roleId));
  119. }
  120. /// <summary>
  121. /// Gets granted permission names for a role.
  122. /// </summary>
  123. /// <param name="roleName">Role name</param>
  124. /// <returns>List of granted permissions</returns>
  125. public virtual async Task<IReadOnlyList<Permission>> GetGrantedPermissionsAsync(string roleName)
  126. {
  127. return await GetGrantedPermissionsAsync(await GetRoleByNameAsync(roleName));
  128. }
  129. /// <summary>
  130. /// Gets granted permissions for a role.
  131. /// </summary>
  132. /// <param name="role">Role</param>
  133. /// <returns>List of granted permissions</returns>
  134. public virtual async Task<IReadOnlyList<Permission>> GetGrantedPermissionsAsync(TRole role)
  135. {
  136. var permissionList = new List<Permission>();
  137. foreach (var permission in PermissionManager.GetAllPermissions())
  138. {
  139. if (await IsGrantedAsync(role.Id, permission))
  140. {
  141. permissionList.Add(permission);
  142. }
  143. }
  144. return permissionList;
  145. }
  146. /// <summary>
  147. /// Sets all granted permissions of a role at once.
  148. /// Prohibits all other permissions.
  149. /// </summary>
  150. /// <param name="roleId">Role id</param>
  151. /// <param name="permissions">Permissions</param>
  152. public virtual async Task SetGrantedPermissionsAsync(int roleId, IEnumerable<Permission> permissions)
  153. {
  154. await SetGrantedPermissionsAsync(await GetRoleByIdAsync(roleId), permissions);
  155. }
  156. /// <summary>
  157. /// Sets all granted permissions of a role at once.
  158. /// Prohibits all other permissions.
  159. /// </summary>
  160. /// <param name="role">The role</param>
  161. /// <param name="permissions">Permissions</param>
  162. public virtual async Task SetGrantedPermissionsAsync(TRole role, IEnumerable<Permission> permissions)
  163. {
  164. var oldPermissions = await GetGrantedPermissionsAsync(role);
  165. var newPermissions = permissions.ToArray();
  166. foreach (var permission in oldPermissions.Where(p => !newPermissions.Contains(p, IwbPermissionEqualityComparer.Instance)))
  167. {
  168. await ProhibitPermissionAsync(role, permission);
  169. }
  170. foreach (var permission in newPermissions.Where(p => !oldPermissions.Contains(p, IwbPermissionEqualityComparer.Instance)))
  171. {
  172. await GrantPermissionAsync(role, permission);
  173. }
  174. }
  175. /// <summary>
  176. /// Grants a permission for a role.
  177. /// </summary>
  178. /// <param name="role">Role</param>
  179. /// <param name="permission">Permission</param>
  180. public async Task GrantPermissionAsync(TRole role, Permission permission)
  181. {
  182. if (await IsGrantedAsync(role.Id, permission))
  183. {
  184. return;
  185. }
  186. await IwbRolePermissionStore.RemovePermissionAsync(role, new IwbPermissionGrantInfo(permission.Name, false));
  187. await IwbRolePermissionStore.AddPermissionAsync(role, new IwbPermissionGrantInfo(permission.Name, true));
  188. await SetRoleGrantedPermissionCacheItem(role.Id, permission.Name);
  189. }
  190. /// <summary>
  191. /// Prohibits a permission for a role.
  192. /// </summary>
  193. /// <param name="role">Role</param>
  194. /// <param name="permission">Permission</param>
  195. public async Task ProhibitPermissionAsync(TRole role, Permission permission)
  196. {
  197. if (!await IsGrantedAsync(role.Id, permission))
  198. {
  199. return;
  200. }
  201. await IwbRolePermissionStore.RemovePermissionAsync(role, new IwbPermissionGrantInfo(permission.Name, true));
  202. await IwbRolePermissionStore.AddPermissionAsync(role, new IwbPermissionGrantInfo(permission.Name, false));
  203. await SetRoleGrantedPermissionCacheItem(role.Id, permission.Name, false);
  204. }
  205. private Task SetRoleGrantedPermissionCacheItem(int roleId, string permissionName, bool isAdded = true)
  206. {
  207. var cacheKey = roleId + "@" + (GetCurrentTenantId() ?? 0);
  208. IwbRolePermissionCacheItem cacheItem = CacheManager.GetRolePermissionCache().Get(cacheKey, () => null) ?? new IwbRolePermissionCacheItem(roleId);
  209. if (isAdded)
  210. {
  211. cacheItem.GrantedPermissions.AddIfNotContains(permissionName);
  212. }
  213. else
  214. {
  215. cacheItem.GrantedPermissions.Remove(permissionName);
  216. }
  217. return CacheManager.GetRolePermissionCache().SetAsync(cacheKey, cacheItem);
  218. }
  219. //private Task SetRoleProhibitedPermissionCacheItem(int roleId, string permissionName, bool isAdded = true)
  220. //{
  221. // var cacheKey = roleId + "@" + (GetCurrentTenantId() ?? 0);
  222. // RolePermissionCacheItem cacheItem = CacheManager.GetRolePermissionCache().Get(cacheKey, () => null) ?? new RolePermissionCacheItem(roleId);
  223. // if (isAdded)
  224. // {
  225. // cacheItem.ProhibitedPermissions.Add(permissionName);
  226. // }
  227. // else
  228. // {
  229. // cacheItem.ProhibitedPermissions.Remove(permissionName);
  230. // }
  231. // return CacheManager.GetRolePermissionCache().SetAsync(cacheKey, cacheItem);
  232. //}
  233. /// <summary>
  234. /// Prohibits all permissions for a role.
  235. /// </summary>
  236. /// <param name="role">Role</param>
  237. public async Task ProhibitAllPermissionsAsync(TRole role)
  238. {
  239. foreach (var permission in PermissionManager.GetAllPermissions())
  240. {
  241. await ProhibitPermissionAsync(role, permission);
  242. }
  243. }
  244. /// <summary>
  245. /// Resets all permission settings for a role.
  246. /// It removes all permission settings for the role.
  247. /// </summary>
  248. /// <param name="role">Role</param>
  249. public async Task ResetAllPermissionsAsync(TRole role)
  250. {
  251. await IwbRolePermissionStore.RemoveAllPermissionSettingsAsync(role);
  252. }
  253. /// <summary>
  254. /// Creates a role.
  255. /// </summary>
  256. /// <param name="role">Role</param>
  257. public override async Task<IdentityResult> CreateAsync(TRole role)
  258. {
  259. var result = await CheckDuplicateRoleNameAsync(role.Id, role.Name, role.RoleDisplayName);
  260. if (!result.Succeeded)
  261. {
  262. return result;
  263. }
  264. //var tenantId = GetCurrentTenantId();
  265. //if (tenantId.HasValue && !role.TenantId.HasValue)
  266. //{
  267. // role.TenantId = tenantId.Value;
  268. //}
  269. return await base.CreateAsync(role);
  270. }
  271. public override async Task<IdentityResult> UpdateAsync(TRole role)
  272. {
  273. var result = await CheckDuplicateRoleNameAsync(role.Id, role.Name, role.RoleDisplayName);
  274. if (!result.Succeeded)
  275. {
  276. return result;
  277. }
  278. return await base.UpdateAsync(role);
  279. }
  280. /// <summary>
  281. /// Deletes a role.
  282. /// </summary>
  283. /// <param name="role">Role</param>
  284. public override async Task<IdentityResult> DeleteAsync(TRole role)
  285. {
  286. if (role.IsStatic)
  287. {
  288. return IwbIdentityResult.Failed(string.Format(L("CanNotDeleteStaticRole"), role.Name));
  289. }
  290. return await base.DeleteAsync(role);
  291. }
  292. public override async Task<TRole> FindByIdAsync(int roleId)
  293. {
  294. return await AbpStore.FindByIdAsync(roleId);
  295. }
  296. /// <summary>
  297. /// Gets a role by given id.
  298. /// Throws exception if no role with given id.
  299. /// </summary>
  300. /// <param name="roleId">Role id</param>
  301. /// <returns>Role</returns>
  302. /// <exception cref="AbpException">Throws exception if no role with given id</exception>
  303. public virtual async Task<TRole> GetRoleByIdAsync(int roleId)
  304. {
  305. var role = await FindByIdAsync(roleId);
  306. if (role == null)
  307. {
  308. throw new AbpException("There is no role with id: " + roleId);
  309. }
  310. return role;
  311. }
  312. /// <summary>
  313. /// Gets a role by given name.
  314. /// Throws exception if no role with given roleName.
  315. /// </summary>
  316. /// <param name="roleName">Role name</param>
  317. /// <returns>Role</returns>
  318. /// <exception cref="AbpException">Throws exception if no role with given roleName</exception>
  319. public virtual async Task<TRole> GetRoleByNameAsync(string roleName)
  320. {
  321. var role = await FindByNameAsync(roleName);
  322. if (role == null)
  323. {
  324. throw new AbpException("There is no role with name: " + roleName);
  325. }
  326. return role;
  327. }
  328. public async Task GrantAllPermissionsAsync(TRole role)
  329. {
  330. //FeatureDependencyContext.TenantId = role.TenantId;
  331. var permissions = PermissionManager.GetAllPermissions()
  332. .Where(permission =>
  333. permission.FeatureDependency == null ||
  334. permission.FeatureDependency.IsSatisfied(FeatureDependencyContext)
  335. );
  336. await SetGrantedPermissionsAsync(role, permissions);
  337. }
  338. [UnitOfWork]
  339. public virtual async Task<IdentityResult> CreateStaticRoles(int tenantId)
  340. {
  341. var staticRoleDefinitions = IwbRoleManagementConfig.StaticRoles.Where(sr => sr.Side == MultiTenancySides.Tenant);
  342. using (UnitOfWorkManager.Current.SetTenantId(tenantId))
  343. {
  344. foreach (var staticRoleDefinition in staticRoleDefinitions)
  345. {
  346. var role = new TRole
  347. {
  348. //TenantId = tenantId,
  349. Name = staticRoleDefinition.RoleName,
  350. RoleDisplayName = staticRoleDefinition.RoleName,
  351. IsStatic = true
  352. };
  353. var identityResult = await CreateAsync(role);
  354. if (!identityResult.Succeeded)
  355. {
  356. return identityResult;
  357. }
  358. }
  359. }
  360. return IdentityResult.Success;
  361. }
  362. public virtual async Task<IdentityResult> CheckDuplicateRoleNameAsync(int? expectedRoleId, string name, string displayName)
  363. {
  364. var role = await FindByNameAsync(name);
  365. if (role != null && role.Id != expectedRoleId)
  366. {
  367. return IwbIdentityResult.Failed(string.Format(L("RoleNameIsAlreadyTaken"), name));
  368. }
  369. role = await FindByDisplayNameAsync(displayName);
  370. if (role != null && role.Id != expectedRoleId)
  371. {
  372. return IwbIdentityResult.Failed(string.Format(L("RoleDisplayNameIsAlreadyTaken"), displayName));
  373. }
  374. return IdentityResult.Success;
  375. }
  376. private Task<TRole> FindByDisplayNameAsync(string displayName)
  377. {
  378. return AbpStore.FindByDisplayNameAsync(displayName);
  379. }
  380. private async Task<IwbRolePermissionCacheItem> GetRolePermissionCacheItemAsync(int roleId)
  381. {
  382. var cacheKey = roleId + "@" + (GetCurrentTenantId() ?? 0);
  383. return await CacheManager.GetRolePermissionCache().GetAsync(cacheKey, async () =>
  384. {
  385. var newCacheItem = new IwbRolePermissionCacheItem(roleId);
  386. var role = await Store.FindByIdAsync(roleId);
  387. if (role == null)
  388. {
  389. throw new AbpException("There is no role with given id: " + roleId);
  390. }
  391. var staticRoleDefinition = IwbRoleManagementConfig.StaticRoles.FirstOrDefault(r =>
  392. r.RoleName == role.Name);
  393. if (staticRoleDefinition != null)
  394. {
  395. foreach (var permission in PermissionManager.GetAllPermissions())
  396. {
  397. if (staticRoleDefinition.IsGrantedByDefault(permission))
  398. {
  399. newCacheItem.GrantedPermissions.Add(permission.Name);
  400. }
  401. }
  402. }
  403. foreach (var permissionInfo in await IwbRolePermissionStore.GetPermissionsAsync(roleId))
  404. {
  405. if (permissionInfo.IsGranted)
  406. {
  407. newCacheItem.GrantedPermissions.AddIfNotContains(permissionInfo.Name);
  408. }
  409. else
  410. {
  411. newCacheItem.GrantedPermissions.Remove(permissionInfo.Name);
  412. }
  413. }
  414. return newCacheItem;
  415. });
  416. }
  417. private string L(string name)
  418. {
  419. return LocalizationManager.GetString(LocalizationSourceName, name);
  420. }
  421. private int? GetCurrentTenantId()
  422. {
  423. if (UnitOfWorkManager.Current != null)
  424. {
  425. return UnitOfWorkManager.Current.GetTenantId();
  426. }
  427. return AbpSession.TenantId;
  428. }
  429. }
  430. }