// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Security.Claims; using System.Threading; using System.Threading.Tasks; namespace Microsoft.AspNetCore.Identity { /// /// Creates a new instance of a persistence store for roles that matches . /// /// The type of the class representing a role. /// The type of the primary key for a role. /// The type of the class representing a user role. /// The type of the class representing a role claim. public abstract class RoleStoreBaseV1 : IQueryableRoleStore, IRoleClaimStore where TRole : IdentityRole where TKey : IEquatable where TUserRole : IdentityUserRole, new() where TRoleClaim : IdentityRoleClaim, new() { /// /// Constructs a new instance of . /// /// The . public RoleStoreBaseV1(IdentityErrorDescriber describer) { if (describer == null) { throw new ArgumentNullException(nameof(describer)); } ErrorDescriber = describer; } private bool _disposed; /// /// Gets or sets the for any error that occurred with the current operation. /// public IdentityErrorDescriber ErrorDescriber { get; set; } /// /// Creates a new role in a store as an asynchronous operation. /// /// The role to create in the store. /// The used to propagate notifications that the operation should be canceled. /// A that represents the of the asynchronous query. public abstract Task CreateAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)); /// /// Updates a role in a store as an asynchronous operation. /// /// The role to update in the store. /// The used to propagate notifications that the operation should be canceled. /// A that represents the of the asynchronous query. public abstract Task UpdateAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)); /// /// Deletes a role from the store as an asynchronous operation. /// /// The role to delete from the store. /// The used to propagate notifications that the operation should be canceled. /// A that represents the of the asynchronous query. public abstract Task DeleteAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)); /// /// Gets the ID for a role from the store as an asynchronous operation. /// /// The role whose ID should be returned. /// The used to propagate notifications that the operation should be canceled. /// A that contains the ID of the role. public virtual Task GetRoleIdAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException(nameof(role)); } return Task.FromResult(ConvertIdToString(role.Id)); } /// /// Gets the name of a role from the store as an asynchronous operation. /// /// The role whose name should be returned. /// The used to propagate notifications that the operation should be canceled. /// A that contains the name of the role. public virtual Task GetRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException(nameof(role)); } return Task.FromResult(role.Name); } /// /// Sets the name of a role in the store as an asynchronous operation. /// /// The role whose name should be set. /// The name of the role. /// The used to propagate notifications that the operation should be canceled. /// The that represents the asynchronous operation. public virtual Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException(nameof(role)); } role.Name = roleName; return Task.CompletedTask; } /// /// Converts the provided to a strongly typed key object. /// /// The id to convert. /// An instance of representing the provided . public virtual TKey ConvertIdFromString(string id) { if (id == null) { return default(TKey); } return (TKey)TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString(id); } /// /// Converts the provided to its string representation. /// /// The id to convert. /// An representation of the provided . public virtual string ConvertIdToString(TKey id) { if (id.Equals(default(TKey))) { return null; } return id.ToString(); } /// /// Finds the role who has the specified ID as an asynchronous operation. /// /// The role ID to look for. /// The used to propagate notifications that the operation should be canceled. /// A that result of the look up. public abstract Task FindByIdAsync(string id, CancellationToken cancellationToken = default(CancellationToken)); /// /// Finds the role who has the specified normalized name as an asynchronous operation. /// /// The normalized role name to look for. /// The used to propagate notifications that the operation should be canceled. /// A that result of the look up. public abstract Task FindByNameAsync(string normalizedName, CancellationToken cancellationToken = default(CancellationToken)); /// /// Get a role's normalized name as an asynchronous operation. /// /// The role whose normalized name should be retrieved. /// The used to propagate notifications that the operation should be canceled. /// A that contains the name of the role. public virtual Task GetNormalizedRoleNameAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException(nameof(role)); } return Task.FromResult(role.NormalizedName); } /// /// Set a role's normalized name as an asynchronous operation. /// /// The role whose normalized name should be set. /// The normalized name to set /// The used to propagate notifications that the operation should be canceled. /// The that represents the asynchronous operation. public virtual Task SetNormalizedRoleNameAsync(TRole role, string normalizedName, CancellationToken cancellationToken = default(CancellationToken)) { cancellationToken.ThrowIfCancellationRequested(); ThrowIfDisposed(); if (role == null) { throw new ArgumentNullException(nameof(role)); } role.NormalizedName = normalizedName; return Task.CompletedTask; } /// /// Throws if this class has been disposed. /// protected void ThrowIfDisposed() { if (_disposed) { throw new ObjectDisposedException(GetType().Name); } } /// /// Dispose the stores /// public void Dispose() { _disposed = true; } /// /// Get the claims associated with the specified as an asynchronous operation. /// /// The role whose claims should be retrieved. /// The used to propagate notifications that the operation should be canceled. /// A that contains the claims granted to a role. public abstract Task> GetClaimsAsync(TRole role, CancellationToken cancellationToken = default(CancellationToken)); /// /// Adds the given to the specified . /// /// The role to add the claim to. /// The claim to add to the role. /// The used to propagate notifications that the operation should be canceled. /// The that represents the asynchronous operation. public abstract Task AddClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken)); /// /// Removes the given from the specified . /// /// The role to remove the claim from. /// The claim to remove from the role. /// The used to propagate notifications that the operation should be canceled. /// The that represents the asynchronous operation. public abstract Task RemoveClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default(CancellationToken)); /// /// A navigation property for the roles the store contains. /// public abstract IQueryable Roles { get; } /// /// Creates a entity representing a role claim. /// /// The associated role. /// The associated claim. /// The role claim entity. public virtual TRoleClaim CreateRoleClaim(TRole role, Claim claim) { return new TRoleClaim { RoleId = role.Id, ClaimType = claim.Type, ClaimValue = claim.Value }; } } }