using Microsoft.AspNetCore.Identity;
using Raven.Client.Documents;
using Raven.Client.Documents.Session;
using Raven.Client.Exceptions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using zero.Core.Entities;
namespace zero.Web.Identity
{
///
/// Provides an abstraction for a store of role specific claims.
///
public class BackofficeUserRoleStore : IRoleClaimStore
where TClaim : class, IUserClaim, new()
where TRole : class, IUserRole, new()
{
///
/// Gets the database context for this store.
///
IDocumentStore Raven { get; set; }
///
/// Gets or sets the for any error that occurred with the current operation.
///
public IdentityErrorDescriber ErrorDescriber { get; set; }
public BackofficeUserRoleStore(IDocumentStore raven, IdentityErrorDescriber describer = null)
{
Raven = raven ?? throw new ArgumentNullException(nameof(raven));
ErrorDescriber = describer ?? new IdentityErrorDescriber();
}
///
async Task SaveChangesAsync(TRole role, CancellationToken cancellationToken)
{
using (IAsyncDocumentSession session = Raven.OpenAsyncSession())
{
await session.StoreAsync(role, cancellationToken);
}
}
///
public async Task CreateAsync(TRole role, CancellationToken cancellationToken)
{
await SaveChangesAsync(role, cancellationToken);
return IdentityResult.Success;
}
///
public async Task DeleteAsync(TRole role, CancellationToken cancellationToken)
{
using (IAsyncDocumentSession session = Raven.OpenAsyncSession())
{
try
{
session.Delete(role.Id);
await session.SaveChangesAsync(cancellationToken);
}
catch (ConcurrencyException)
{
return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure());
}
return IdentityResult.Success;
}
}
///
public Task FindByIdAsync(string roleId, CancellationToken cancellationToken)
{
using (IAsyncDocumentSession session = Raven.OpenAsyncSession())
{
return session.LoadAsync(roleId, cancellationToken);
}
}
///
public Task FindByNameAsync(string normalizedRoleName, CancellationToken cancellationToken)
{
using (IAsyncDocumentSession session = Raven.OpenAsyncSession())
{
return session.Query().FirstOrDefaultAsync(x => x.Name == normalizedRoleName);
}
}
///
public Task GetNormalizedRoleNameAsync(TRole role, CancellationToken cancellationToken)
{
return Task.FromResult(role.Name.ToLowerInvariant());
}
///
public Task GetRoleIdAsync(TRole role, CancellationToken cancellationToken)
{
return Task.FromResult(role.Id);
}
///
public Task GetRoleNameAsync(TRole role, CancellationToken cancellationToken)
{
return Task.FromResult(role.Name);
}
///
public Task SetNormalizedRoleNameAsync(TRole role, string normalizedName, CancellationToken cancellationToken)
{
return Task.FromResult(0);
}
///
public async Task SetRoleNameAsync(TRole role, string roleName, CancellationToken cancellationToken)
{
role.Name = roleName;
await SaveChangesAsync(role, cancellationToken);
}
///
public async Task UpdateAsync(TRole role, CancellationToken cancellationToken)
{
try
{
await SaveChangesAsync(role, cancellationToken);
}
catch (ConcurrencyException)
{
return IdentityResult.Failed(ErrorDescriber.ConcurrencyFailure());
}
return IdentityResult.Success;
}
///
public async Task AddClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default)
{
role.Claims.Add(new TClaim().FromClaim(claim));
await SaveChangesAsync(role, cancellationToken);
}
///
public Task> GetClaimsAsync(TRole role, CancellationToken cancellationToken = default)
{
return Task.FromResult>(role.Claims.Select(c => c.ToClaim()).ToList());
}
///
public async Task RemoveClaimAsync(TRole role, Claim claim, CancellationToken cancellationToken = default)
{
role.Claims = role.Claims.Where(c => c.Type == claim.Type).ToList();
await SaveChangesAsync(role, cancellationToken);
}
///
public void Dispose() { }
}
}