using System; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace Microsoft.AspNet.Identity { /// /// Exposes role related api which will automatically save changes to the RoleStore /// /// public class RoleManager : IDisposable where TRole : class { private bool _disposed; /// /// Constructor /// /// The IRoleStore is responsible for commiting changes via the UpdateAsync/CreateAsync methods public RoleManager(IRoleStore store) { if (store == null) { throw new ArgumentNullException("store"); } Store = store; RoleValidator = new RoleValidator(); } /// /// Persistence abstraction that the Manager operates against /// protected IRoleStore Store { get; private set; } /// /// Used to validate roles before persisting changes /// public IRoleValidator RoleValidator { get; set; } /// /// Returns an IQueryable of roles if the store is an IQueryableRoleStore /// public virtual IQueryable Roles { get { var queryableStore = Store as IQueryableRoleStore; if (queryableStore == null) { throw new NotSupportedException(Resources.StoreNotIQueryableRoleStore); } return queryableStore.Roles; } } /// /// Returns true if the store is an IQueryableRoleStore /// public virtual bool SupportsQueryableRoles { get { ThrowIfDisposed(); return Store is IQueryableRoleStore; } } /// /// Dispose this object /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private async Task ValidateRoleInternal(TRole role, CancellationToken cancellationToken) { return (RoleValidator == null) ? IdentityResult.Success : await RoleValidator.Validate(this, role, cancellationToken); } /// /// Create a role /// /// /// /// public virtual async Task Create(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException("role"); } var result = await ValidateRoleInternal(role, cancellationToken); if (!result.Succeeded) { return result; } await Store.Create(role, cancellationToken); return IdentityResult.Success; } /// /// Update an existing role /// /// /// /// public virtual async Task Update(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException("role"); } var result = await ValidateRoleInternal(role, cancellationToken); if (!result.Succeeded) { return result; } await Store.Update(role, cancellationToken); return IdentityResult.Success; } /// /// Delete a role /// /// /// /// public virtual async Task Delete(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException("role"); } await Store.Delete(role, cancellationToken); return IdentityResult.Success; } /// /// Returns true if the role exists /// /// /// /// public virtual async Task RoleExists(string roleName, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); if (roleName == null) { throw new ArgumentNullException("roleName"); } return await FindByName(roleName, cancellationToken) != null; } /// /// Find a role by id /// /// /// /// public virtual async Task FindById(string roleId, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); return await Store.FindById(roleId, cancellationToken); } /// /// Return the name of the role /// /// /// /// public virtual async Task GetRoleName(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); return await Store.GetRoleName(role, cancellationToken); } /// /// Return the role id for a role /// /// /// /// public virtual async Task GetRoleId(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); return await Store.GetRoleId(role, cancellationToken); } /// /// Find a role by name /// /// /// /// public virtual async Task FindByName(string roleName, CancellationToken cancellationToken = default(CancellationToken)) { ThrowIfDisposed(); if (roleName == null) { throw new ArgumentNullException("roleName"); } return await Store.FindByName(roleName, cancellationToken); } private void ThrowIfDisposed() { if (_disposed) { throw new ObjectDisposedException(GetType().Name); } } /// /// When disposing, actually dipose the store /// /// protected virtual void Dispose(bool disposing) { if (disposing && !_disposed) { Store.Dispose(); } _disposed = true; } } }