mirror of https://github.com/abpframework/abp.git
12 changed files with 411 additions and 29 deletions
@ -0,0 +1,333 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Security.Claims; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Microsoft.AspNetCore.Identity; |
|||
using Volo.Abp.Uow; |
|||
using Volo.DependencyInjection; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
/// <summary>
|
|||
/// Creates a new instance of a persistence store for roles.
|
|||
/// </summary>
|
|||
public class RoleStore : |
|||
IRoleStore<IdentityRole>, |
|||
IRoleClaimStore<IdentityRole>, |
|||
ITransientDependency |
|||
{ |
|||
private readonly IIdentityRoleRepository _roleRepository; |
|||
private readonly IUnitOfWorkManager _unitOfWorkManager; |
|||
|
|||
/// <summary>
|
|||
/// Constructs a new instance of <see cref="RoleStore"/>.
|
|||
/// </summary>
|
|||
public RoleStore( |
|||
IIdentityRoleRepository roleRepository, |
|||
IUnitOfWorkManager unitOfWorkManager, |
|||
IdentityErrorDescriber describer = null) |
|||
{ |
|||
_roleRepository = roleRepository; |
|||
_unitOfWorkManager = unitOfWorkManager; |
|||
|
|||
ErrorDescriber = describer ?? new IdentityErrorDescriber(); |
|||
} |
|||
|
|||
private bool _disposed; //TODO: Remove!
|
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the <see cref="IdentityErrorDescriber"/> for any error that occurred with the current operation.
|
|||
/// </summary>
|
|||
public IdentityErrorDescriber ErrorDescriber { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets a flag indicating if changes should be persisted after CreateAsync, UpdateAsync and DeleteAsync are called.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// True if changes should be automatically persisted, otherwise false.
|
|||
/// </value>
|
|||
public bool AutoSaveChanges { get; set; } = true; |
|||
|
|||
/// <summary>Saves the current store.</summary>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
|||
protected Task SaveChanges(CancellationToken cancellationToken) |
|||
{ |
|||
if (!AutoSaveChanges || _unitOfWorkManager.Current == null) |
|||
{ |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
return _unitOfWorkManager.Current.SaveChangesAsync(cancellationToken); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Creates a new role in a store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role to create in the store.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="IdentityResult"/> of the asynchronous query.</returns>
|
|||
public virtual async Task<IdentityResult> CreateAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
await _roleRepository.InsertAsync(role); |
|||
await SaveChanges(cancellationToken); |
|||
|
|||
return IdentityResult.Success; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Updates a role in a store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role to update in the store.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="IdentityResult"/> of the asynchronous query.</returns>
|
|||
public virtual async Task<IdentityResult> UpdateAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
await _roleRepository.UpdateAsync(role); |
|||
|
|||
try |
|||
{ |
|||
await SaveChanges(cancellationToken); |
|||
} |
|||
catch (AbpDbConcurrencyException ex) |
|||
{ |
|||
//TODO: Log...?
|
|||
return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure()); |
|||
} |
|||
|
|||
return IdentityResult.Success; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Deletes a role from the store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role to delete from the store.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that represents the <see cref="IdentityResult"/> of the asynchronous query.</returns>
|
|||
public virtual async Task<IdentityResult> DeleteAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
try |
|||
{ |
|||
await _roleRepository.DeleteAsync(role); |
|||
await SaveChanges(cancellationToken); |
|||
} |
|||
catch (AbpDbConcurrencyException ex) |
|||
{ |
|||
//TODO: Log...
|
|||
return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure()); |
|||
} |
|||
|
|||
return IdentityResult.Success; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the ID for a role from the store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose ID should be returned.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that contains the ID of the role.</returns>
|
|||
public Task<string> GetRoleIdAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
return Task.FromResult(role.Id); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the name of a role from the store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose name should be returned.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that contains the name of the role.</returns>
|
|||
public Task<string> GetRoleNameAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
return Task.FromResult(role.Name); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Sets the name of a role in the store as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose name should be set.</param>
|
|||
/// <param name="roleName">The name of the role.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
|||
public Task SetRoleNameAsync([NotNull] IdentityRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
role.Name = roleName; |
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Finds the role who has the specified ID as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="id">The role ID to look for.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that result of the look up.</returns>
|
|||
public virtual Task<IdentityRole> FindByIdAsync([NotNull] string id, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(id, nameof(id)); |
|||
|
|||
//TODO: Add cancellationToken to Repository.FindAsync method as overload
|
|||
return _roleRepository.FindAsync(id); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Finds the role who has the specified normalized name as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="normalizedName">The normalized role name to look for.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that result of the look up.</returns>
|
|||
public virtual Task<IdentityRole> FindByNameAsync([NotNull] string normalizedName, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(normalizedName, nameof(normalizedName)); |
|||
|
|||
return _roleRepository.FindByNormalizedNameAsync(normalizedName, cancellationToken); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Get a role's normalized name as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose normalized name should be retrieved.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that contains the name of the role.</returns>
|
|||
public virtual Task<string> GetNormalizedRoleNameAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
return Task.FromResult(role.NormalizedName); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Set a role's normalized name as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose normalized name should be set.</param>
|
|||
/// <param name="normalizedName">The normalized name to set</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
|||
public virtual Task SetNormalizedRoleNameAsync([NotNull] IdentityRole role, string normalizedName, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
role.NormalizedName = normalizedName; |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Throws if this class has been disposed.
|
|||
/// </summary>
|
|||
protected void ThrowIfDisposed() |
|||
{ |
|||
if (_disposed) |
|||
{ |
|||
throw new ObjectDisposedException(GetType().Name); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Dispose the stores
|
|||
/// </summary>
|
|||
public void Dispose() |
|||
{ |
|||
_disposed = true; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Get the claims associated with the specified <paramref name="role"/> as an asynchronous operation.
|
|||
/// </summary>
|
|||
/// <param name="role">The role whose claims should be retrieved.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>A <see cref="Task{TResult}"/> that contains the claims granted to a role.</returns>
|
|||
public Task<IList<Claim>> GetClaimsAsync([NotNull] IdentityRole role, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
|
|||
return Task.FromResult<IList<Claim>>(role.Claims.Select(c => c.ToClaim()).ToList()); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Adds the <paramref name="claim"/> given to the specified <paramref name="role"/>.
|
|||
/// </summary>
|
|||
/// <param name="role">The role to add the claim to.</param>
|
|||
/// <param name="claim">The claim to add to the role.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
|||
public Task AddClaimAsync([NotNull] IdentityRole role, [NotNull] Claim claim, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
cancellationToken.ThrowIfCancellationRequested(); |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
Check.NotNull(claim, nameof(claim)); |
|||
|
|||
role.AddClaim(claim); |
|||
|
|||
return Task.FromResult(false); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Removes the <paramref name="claim"/> given from the specified <paramref name="role"/>.
|
|||
/// </summary>
|
|||
/// <param name="role">The role to remove the claim from.</param>
|
|||
/// <param name="claim">The claim to remove from the role.</param>
|
|||
/// <param name="cancellationToken">The <see cref="CancellationToken"/> used to propagate notifications that the operation should be canceled.</param>
|
|||
/// <returns>The <see cref="Task"/> that represents the asynchronous operation.</returns>
|
|||
public Task RemoveClaimAsync([NotNull] IdentityRole role, [NotNull] Claim claim, CancellationToken cancellationToken = default(CancellationToken)) |
|||
{ |
|||
ThrowIfDisposed(); |
|||
|
|||
Check.NotNull(role, nameof(role)); |
|||
Check.NotNull(claim, nameof(claim)); |
|||
|
|||
role.RemoveClaim(claim); |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue