| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466 |
- using Abp;
- using Abp.Dependency;
- using Abp.Domain.Repositories;
- using Abp.Domain.Uow;
- using Abp.Extensions;
- using Castle.Core.Logging;
- using Microsoft.AspNetCore.Identity;
- using System.Security.Claims;
- using VberZero.BaseSystem.Roles;
- using VberZero.Tools;
- using ILogger = Castle.Core.Logging.ILogger;
- namespace VberZero.Authorization.Roles;
- /// <summary>
- /// 为角色创建持久性存储的新实例
- /// </summary>
- public class VzRoleStore :
- IRoleStore<Role>,
- IRoleClaimStore<Role>,
- IRolePermissionStore<Role>,
- IQueryableRoleStore<Role>,
- ITransientDependency
- {
- public ILogger Logger { get; set; }
- /// <summary>
- /// 获取或设置当前操作发生的任何错误的 <see cref="IdentityErrorDescriber"/>
- /// </summary>
- public IdentityErrorDescriber ErrorDescriber { get; set; }
- /// <summary>
- /// 获取或设置一个标志,该标志指示在调用 CreateAsync、UpdateAsync 和 DeleteAsync 后是否应保存。
- /// </summary>
- /// <value>
- /// 如果应自动保存,则为 true,否则为 false。
- /// </value>
- public bool AutoSaveChanges { get; set; } = true;
- public IQueryable<Role> Roles => _roleRepository.GetAll();
- private readonly IRepository<Role> _roleRepository;
- private readonly IUnitOfWorkManager _unitOfWorkManager;
- private readonly IRepository<RolePermissionSetting, long> _rolePermissionSettingRepository;
- public VzRoleStore(
- IUnitOfWorkManager unitOfWorkManager,
- IRepository<Role> roleRepository,
- IRepository<RolePermissionSetting, long> rolePermissionSettingRepository)
- {
- _unitOfWorkManager = unitOfWorkManager;
- _roleRepository = roleRepository;
- _rolePermissionSettingRepository = rolePermissionSettingRepository;
- ErrorDescriber = new IdentityErrorDescriber();
- Logger = NullLogger.Instance;
- }
- /// <summary>
- /// 保存当前库
- /// </summary>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- protected Task SaveChanges(CancellationToken cancellationToken)
- {
- if (!AutoSaveChanges || _unitOfWorkManager.Current == null)
- {
- return Task.CompletedTask;
- }
- return _unitOfWorkManager.Current.SaveChangesAsync();
- }
- /// <summary>
- /// 创建一个新角色
- /// </summary>
- /// <param name="role"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public virtual async Task<IdentityResult> CreateAsync(Role role, CancellationToken cancellationToken = default)
- {
- return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(role, nameof(role));
- await _roleRepository.InsertAsync(role);
- await SaveChanges(cancellationToken);
- return IdentityResult.Success;
- });
- }
- /// <summary>
- /// 更新一个新角色
- /// </summary>
- /// <param name="role"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public virtual async Task<IdentityResult> UpdateAsync(Role role, CancellationToken cancellationToken = default)
- {
- return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(role, nameof(role));
- role.ConcurrencyStamp = Guid.NewGuid().ToString();
- await _roleRepository.UpdateAsync(role);
- try
- {
- await SaveChanges(cancellationToken);
- }
- catch (AbpDbConcurrencyException ex)
- {
- Logger.Warn(ex.ToString(), ex);
- return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure());
- }
- await SaveChanges(cancellationToken);
- return IdentityResult.Success;
- });
- }
- /// <summary>
- /// 删除一个新角色
- /// </summary>
- /// <param name="role"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public virtual async Task<IdentityResult> DeleteAsync(Role role, CancellationToken cancellationToken = default)
- {
- return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(role, nameof(role));
- await _roleRepository.DeleteAsync(role);
- try
- {
- await SaveChanges(cancellationToken);
- }
- catch (AbpDbConcurrencyException ex)
- {
- Logger.Warn(ex.ToString(), ex);
- return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure());
- }
- await SaveChanges(cancellationToken);
- return IdentityResult.Success;
- });
- }
- /// <summary>
- /// 获取角色的 ID
- /// </summary>
- /// <param name="role"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public Task<string> GetRoleIdAsync(Role role, CancellationToken cancellationToken = default)
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(role, nameof(role));
- return Task.FromResult(role.Id.ToString());
- }
- /// <summary>
- /// 获取角色的 Name
- /// </summary>
- /// <param name="role"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public Task<string> GetRoleNameAsync(Role role, CancellationToken cancellationToken = default)
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(role, nameof(role));
- return Task.FromResult(role.Name);
- }
- /// <summary>
- /// 设置角色名称
- /// </summary>
- /// <param name="role"></param>
- /// <param name="roleName"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public Task SetRoleNameAsync(Role role, string roleName, CancellationToken cancellationToken = default)
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(role, nameof(role));
- role.Name = roleName;
- return Task.CompletedTask;
- }
- /// <summary>
- /// 查询指定 ID 的角色
- /// </summary>
- /// <param name="id"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public virtual async Task<Role> FindByIdAsync(string id, CancellationToken cancellationToken = default)
- {
- return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- cancellationToken.ThrowIfCancellationRequested();
- return await _roleRepository.FirstOrDefaultAsync(id.To<int>());
- });
- }
- /// <summary>
- /// 查询指定 ID 的角色
- /// </summary>
- /// <param name="id"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public virtual Role FindById(string id, CancellationToken cancellationToken = default)
- {
- return _unitOfWorkManager.WithUnitOfWork(() =>
- {
- cancellationToken.ThrowIfCancellationRequested();
- return _roleRepository.FirstOrDefault(id.To<int>());
- });
- }
- /// <summary>
- /// 查询指定 Name 的角色
- /// </summary>
- /// <param name="normalizedName"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public virtual async Task<Role> FindByNameAsync(string normalizedName, CancellationToken cancellationToken = default)
- {
- return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(normalizedName, nameof(normalizedName));
- return await _roleRepository.FirstOrDefaultAsync(r => r.NormalizedName == normalizedName);
- });
- }
- /// <summary>
- /// 查询指定 Name 的角色
- /// </summary>
- /// <param name="normalizedName"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public virtual Role FindByName(string normalizedName, CancellationToken cancellationToken = default)
- {
- return _unitOfWorkManager.WithUnitOfWork(() =>
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(normalizedName, nameof(normalizedName));
- return _roleRepository.FirstOrDefault(r => r.NormalizedName == normalizedName);
- });
- }
- /// <summary>
- /// 获取角色的规范化名称
- /// </summary>
- /// <param name="role"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public virtual Task<string> GetNormalizedRoleNameAsync(Role role, CancellationToken cancellationToken = default)
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(role, nameof(role));
- return Task.FromResult(role.NormalizedName);
- }
- /// <summary>
- /// 设置角色的规范化名称
- /// </summary>
- /// <param name="role"></param>
- /// <param name="normalizedName">The normalized name to set</param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public virtual Task SetNormalizedRoleNameAsync(Role role, string normalizedName, CancellationToken cancellationToken = default)
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(role, nameof(role));
- role.NormalizedName = normalizedName;
- return Task.CompletedTask;
- }
- /// <summary>
- /// Dispose
- /// </summary>
- public void Dispose()
- {
- }
- /// <summary>
- /// 获取与指定的 <paramref name="role"/> 关联的声明
- /// </summary>
- /// <param name="role"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public virtual async Task<IList<Claim>> GetClaimsAsync(Role role, CancellationToken cancellationToken = default)
- {
- return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(role, nameof(role));
- await _roleRepository.EnsureCollectionLoadedAsync(role, u => u.Claims, cancellationToken);
- return role.Claims.Select(c => new Claim(c.ClaimType, c.ClaimValue)).ToList();
- });
- }
- /// <summary>
- /// 将给定的 <paramref name="claim"/> 添加到指定的 <paramref name="role"/>
- /// </summary>
- /// <param name="role"></param>
- /// <param name="claim"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public async Task AddClaimAsync(Role role, Claim claim, CancellationToken cancellationToken = default)
- {
- await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- cancellationToken.ThrowIfCancellationRequested();
- Check.NotNull(role, nameof(role));
- Check.NotNull(claim, nameof(claim));
- await _roleRepository.EnsureCollectionLoadedAsync(role, u => u.Claims, cancellationToken);
- role.Claims.Add(new RoleClaim(role, claim));
- });
- }
- /// <summary>
- /// 从指定的 <paramref name="role"/> 中移除给定的 <paramref name="claim"/>
- /// </summary>
- /// <param name="role"></param>
- /// <param name="claim"></param>
- /// <param name="cancellationToken"><see cref="CancellationToken"/> 取消操作的通知</param>
- /// <returns></returns>
- public async Task RemoveClaimAsync(Role role, Claim claim, CancellationToken cancellationToken = default)
- {
- await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- Check.NotNull(role, nameof(role));
- Check.NotNull(claim, nameof(claim));
- await _roleRepository.EnsureCollectionLoadedAsync(role, u => u.Claims, cancellationToken);
- role.Claims.RemoveAll(c => c.ClaimValue == claim.Value && c.ClaimType == claim.Type);
- });
- }
- public virtual async Task<Role> FindByDisplayNameAsync(string displayName)
- {
- return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- return await _roleRepository.FirstOrDefaultAsync(
- role => role.DisplayName == displayName
- );
- });
- }
- public virtual async Task AddPermissionAsync(Role role, PermissionGrantInfo permissionGrant)
- {
- await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- if (await HasPermissionAsync(role.Id, permissionGrant))
- {
- return;
- }
- await _rolePermissionSettingRepository.InsertAsync(
- new RolePermissionSetting(role.Id)
- {
- TenantId = role.TenantId,
- //RoleId = role.Id,
- Name = permissionGrant.Name,
- IsGranted = permissionGrant.IsGranted
- });
- });
- }
- /// <inheritdoc/>
- public virtual async Task RemovePermissionAsync(Role role, PermissionGrantInfo permissionGrant)
- {
- await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- await _rolePermissionSettingRepository.DeleteAsync(
- permissionSetting => permissionSetting.RoleId == role.Id &&
- permissionSetting.Name == permissionGrant.Name &&
- permissionSetting.IsGranted == permissionGrant.IsGranted
- );
- });
- }
- /// <inheritdoc/>
- public virtual Task<IList<PermissionGrantInfo>> GetPermissionsAsync(Role role)
- {
- return GetPermissionsAsync(role.Id);
- }
- /// <inheritdoc/>
- public virtual IList<PermissionGrantInfo> GetPermissions(Role role)
- {
- return GetPermissions(role.Id);
- }
- public async Task<IList<PermissionGrantInfo>> GetPermissionsAsync(int roleId)
- {
- return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- return (await _rolePermissionSettingRepository.GetAllListAsync(p => p.RoleId == roleId))
- .Select(p => new PermissionGrantInfo(p.Name, p.IsGranted))
- .ToList();
- });
- }
- public IList<PermissionGrantInfo> GetPermissions(int roleId)
- {
- return _unitOfWorkManager.WithUnitOfWork(() =>
- {
- return (_rolePermissionSettingRepository.GetAllList(p => p.RoleId == roleId))
- .Select(p => new PermissionGrantInfo(p.Name, p.IsGranted))
- .ToList();
- });
- }
- /// <inheritdoc/>
- public virtual async Task<bool> HasPermissionAsync(int roleId, PermissionGrantInfo permissionGrant)
- {
- return await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- return await _rolePermissionSettingRepository.FirstOrDefaultAsync(
- p => p.RoleId == roleId &&
- p.Name == permissionGrant.Name &&
- p.IsGranted == permissionGrant.IsGranted
- ) != null;
- });
- }
- /// <inheritdoc/>
- public virtual async Task RemoveAllPermissionSettingsAsync(Role role)
- {
- await _unitOfWorkManager.WithUnitOfWorkAsync(async () =>
- {
- await _rolePermissionSettingRepository.DeleteAsync(s => s.RoleId == role.Id);
- });
- }
- }
|