Commit ecca1f88 authored by Marko Matic's avatar Marko Matic
Browse files

Make line endings same, and format documents using VS ctrl+e,d

parent 49d4e92b
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Identity;
using Skoruba.AuditLogging.Services;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Resources;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services.Interfaces;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.ExceptionHandling;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common;
using Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories.Interfaces;
namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services
{
public class IdentityService<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole,
TUserLogin, TRoleClaim, TUserToken,
TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto> : IIdentityService<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole,
TUserLogin, TRoleClaim, TUserToken,
TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto>
where TUserDto : UserDto<TKey>
where TRoleDto : RoleDto<TKey>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
where TUsersDto : UsersDto<TUserDto, TKey>
where TRolesDto : RolesDto<TRoleDto, TKey>
where TUserRolesDto : UserRolesDto<TRoleDto, TKey>
where TUserClaimsDto : UserClaimsDto<TUserClaimDto, TKey>
where TUserProviderDto : UserProviderDto<TKey>
where TUserProvidersDto : UserProvidersDto<TKey>
where TUserChangePasswordDto : UserChangePasswordDto<TKey>
where TRoleClaimsDto : RoleClaimsDto<TKey>
where TUserClaimDto : UserClaimDto<TKey>
{
protected readonly IIdentityRepository<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> IdentityRepository;
protected readonly IIdentityServiceResources IdentityServiceResources;
protected readonly IMapper Mapper;
protected readonly IAuditEventLogger AuditEventLogger;
public IdentityService(IIdentityRepository<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> identityRepository,
IIdentityServiceResources identityServiceResources,
IMapper mapper,
IAuditEventLogger auditEventLogger)
{
IdentityRepository = identityRepository;
IdentityServiceResources = identityServiceResources;
Mapper = mapper;
AuditEventLogger = auditEventLogger;
}
public virtual async Task<bool> ExistsUserAsync(string userId)
{
var exists = await IdentityRepository.ExistsUserAsync(userId);
if (!exists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
return true;
}
public virtual async Task<bool> ExistsRoleAsync(string roleId)
{
var exists = await IdentityRepository.ExistsRoleAsync(roleId);
if (!exists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description);
return true;
}
public virtual async Task<TUsersDto> GetUsersAsync(string search, int page = 1, int pageSize = 10)
{
var pagedList = await IdentityRepository.GetUsersAsync(search, page, pageSize);
var usersDto = Mapper.Map<TUsersDto>(pagedList);
await AuditEventLogger.LogEventAsync(new UsersRequestedEvent<TUsersDto>(usersDto));
return usersDto;
}
public virtual async Task<TUsersDto> GetRoleUsersAsync(string roleId, string search, int page = 1, int pageSize = 10)
{
var roleKey = ConvertToKeyFromString(roleId);
var userIdentityRole = await IdentityRepository.GetRoleAsync(roleKey);
if (userIdentityRole == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description);
var pagedList = await IdentityRepository.GetRoleUsersAsync(roleId, search, page, pageSize);
var usersDto = Mapper.Map<TUsersDto>(pagedList);
await AuditEventLogger.LogEventAsync(new RoleUsersRequestedEvent<TUsersDto>(usersDto));
return usersDto;
}
public virtual async Task<TUsersDto> GetClaimUsersAsync(string claimType, string claimValue, int page = 1, int pageSize = 10)
{
var pagedList = await IdentityRepository.GetClaimUsersAsync(claimType, claimValue, page, pageSize);
var usersDto = Mapper.Map<TUsersDto>(pagedList);
await AuditEventLogger.LogEventAsync(new ClaimUsersRequestedEvent<TUsersDto>(usersDto));
return usersDto;
}
public virtual async Task<TRolesDto> GetRolesAsync(string search, int page = 1, int pageSize = 10)
{
PagedList<TRole> pagedList = await IdentityRepository.GetRolesAsync(search, page, pageSize);
var rolesDto = Mapper.Map<TRolesDto>(pagedList);
await AuditEventLogger.LogEventAsync(new RolesRequestedEvent<TRolesDto>(rolesDto));
return rolesDto;
}
public virtual async Task<(IdentityResult identityResult, TKey roleId)> CreateRoleAsync(TRoleDto role)
{
var roleEntity = Mapper.Map<TRole>(role);
var (identityResult, roleId) = await IdentityRepository.CreateRoleAsync(roleEntity);
var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.RoleCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role);
await AuditEventLogger.LogEventAsync(new RoleAddedEvent<TRoleDto>(role));
return (handleIdentityError, roleId);
}
private IdentityResult HandleIdentityError(IdentityResult identityResult, string errorMessage, string errorKey, object model)
{
if (!identityResult.Errors.Any()) return identityResult;
var viewErrorMessages = Mapper.Map<List<ViewErrorMessage>>(identityResult.Errors);
throw new UserFriendlyViewException(errorMessage, errorKey, viewErrorMessages, model);
}
public virtual async Task<TRoleDto> GetRoleAsync(string roleId)
{
var roleKey = ConvertToKeyFromString(roleId);
var userIdentityRole = await IdentityRepository.GetRoleAsync(roleKey);
if (userIdentityRole == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description);
var roleDto = Mapper.Map<TRoleDto>(userIdentityRole);
await AuditEventLogger.LogEventAsync(new RoleRequestedEvent<TRoleDto>(roleDto));
return roleDto;
}
public virtual async Task<List<TRoleDto>> GetRolesAsync()
{
var roles = await IdentityRepository.GetRolesAsync();
var roleDtos = Mapper.Map<List<TRoleDto>>(roles);
await AuditEventLogger.LogEventAsync(new AllRolesRequestedEvent<TRoleDto>(roleDtos));
return roleDtos;
}
public virtual async Task<(IdentityResult identityResult, TKey roleId)> UpdateRoleAsync(TRoleDto role)
{
var userIdentityRole = Mapper.Map<TRole>(role);
var originalRole = await GetRoleAsync(role.Id.ToString());
var (identityResult, roleId) = await IdentityRepository.UpdateRoleAsync(userIdentityRole);
await AuditEventLogger.LogEventAsync(new RoleUpdatedEvent<TRoleDto>(originalRole, role));
var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.RoleUpdateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role);
return (handleIdentityError, roleId);
}
public virtual async Task<TUserDto> GetUserAsync(string userId)
{
var identity = await IdentityRepository.GetUserAsync(userId);
if (identity == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var userDto = Mapper.Map<TUserDto>(identity);
await AuditEventLogger.LogEventAsync(new UserRequestedEvent<TUserDto>(userDto));
return userDto;
}
public virtual async Task<(IdentityResult identityResult, TKey userId)> CreateUserAsync(TUserDto user)
{
var userIdentity = Mapper.Map<TUser>(user);
var (identityResult, userId) = await IdentityRepository.CreateUserAsync(userIdentity);
var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.UserCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, user);
await AuditEventLogger.LogEventAsync(new UserSavedEvent<TUserDto>(user));
return (handleIdentityError, userId);
}
/// <summary>
/// Updates the specified user, but without updating the password hash value
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public virtual async Task<(IdentityResult identityResult, TKey userId)> UpdateUserAsync(TUserDto user)
{
var userIdentity = Mapper.Map<TUser>(user);
await MapOriginalPasswordHashAsync(userIdentity);
var originalUser = await GetUserAsync(user.Id.ToString());
var (identityResult, userId) = await IdentityRepository.UpdateUserAsync(userIdentity);
var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.UserUpdateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, user);
await AuditEventLogger.LogEventAsync(new UserUpdatedEvent<TUserDto>(originalUser, user));
return (handleIdentityError, userId);
}
/// <summary>
/// Get original password hash and map password hash to user
/// </summary>
/// <param name="userIdentity"></param>
/// <returns></returns>
private async Task MapOriginalPasswordHashAsync(TUser userIdentity)
{
var identity = await IdentityRepository.GetUserAsync(userIdentity.Id.ToString());
userIdentity.PasswordHash = identity.PasswordHash;
}
public virtual async Task<IdentityResult> DeleteUserAsync(string userId, TUserDto user)
{
var identityResult = await IdentityRepository.DeleteUserAsync(userId);
await AuditEventLogger.LogEventAsync(new UserDeletedEvent<TUserDto>(user));
return HandleIdentityError(identityResult, IdentityServiceResources.UserDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, user);
}
public virtual async Task<IdentityResult> CreateUserRoleAsync(TUserRolesDto role)
{
var identityResult = await IdentityRepository.CreateUserRoleAsync(role.UserId.ToString(), role.RoleId.ToString());
await AuditEventLogger.LogEventAsync(new UserRoleSavedEvent<TUserRolesDto>(role));
if (!identityResult.Errors.Any()) return identityResult;
var userRolesDto = await BuildUserRolesViewModel(role.UserId, 1);
return HandleIdentityError(identityResult, IdentityServiceResources.UserRoleCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, userRolesDto);
}
public virtual async Task<TUserRolesDto> BuildUserRolesViewModel(TKey id, int? page)
{
var roles = await GetRolesAsync();
var userRoles = await GetUserRolesAsync(id.ToString(), page ?? 1);
userRoles.UserId = id;
userRoles.RolesList = roles.Select(x => new SelectItemDto(x.Id.ToString(), x.Name)).ToList();
return userRoles;
}
public virtual async Task<TUserRolesDto> GetUserRolesAsync(string userId, int page = 1, int pageSize = 10)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var userIdentityRoles = await IdentityRepository.GetUserRolesAsync(userId, page, pageSize);
var roleDtos = Mapper.Map<TUserRolesDto>(userIdentityRoles);
var user = await IdentityRepository.GetUserAsync(userId);
roleDtos.UserName = user.UserName;
await AuditEventLogger.LogEventAsync(new UserRolesRequestedEvent<TUserRolesDto>(roleDtos));
return roleDtos;
}
public virtual async Task<IdentityResult> DeleteUserRoleAsync(TUserRolesDto role)
{
var identityResult = await IdentityRepository.DeleteUserRoleAsync(role.UserId.ToString(), role.RoleId.ToString());
await AuditEventLogger.LogEventAsync(new UserRoleDeletedEvent<TUserRolesDto>(role));
return HandleIdentityError(identityResult, IdentityServiceResources.UserRoleDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role);
}
public virtual async Task<TUserClaimsDto> GetUserClaimsAsync(string userId, int page = 1, int pageSize = 10)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var identityUserClaims = await IdentityRepository.GetUserClaimsAsync(userId, page, pageSize);
var claimDtos = Mapper.Map<TUserClaimsDto>(identityUserClaims);
var user = await IdentityRepository.GetUserAsync(userId);
claimDtos.UserName = user.UserName;
await AuditEventLogger.LogEventAsync(new UserClaimsRequestedEvent<TUserClaimsDto>(claimDtos));
return claimDtos;
}
public virtual async Task<TUserClaimsDto> GetUserClaimAsync(string userId, int claimId)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var identityUserClaim = await IdentityRepository.GetUserClaimAsync(userId, claimId);
if (identityUserClaim == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserClaimDoesNotExist().Description, userId), IdentityServiceResources.UserClaimDoesNotExist().Description);
var userClaimsDto = Mapper.Map<TUserClaimsDto>(identityUserClaim);
await AuditEventLogger.LogEventAsync(new UserClaimRequestedEvent<TUserClaimsDto>(userClaimsDto));
return userClaimsDto;
}
public virtual async Task<IdentityResult> CreateUserClaimsAsync(TUserClaimsDto claimsDto)
{
var userIdentityUserClaim = Mapper.Map<TUserClaim>(claimsDto);
var identityResult = await IdentityRepository.CreateUserClaimsAsync(userIdentityUserClaim);
await AuditEventLogger.LogEventAsync(new UserClaimsSavedEvent<TUserClaimsDto>(claimsDto));
return HandleIdentityError(identityResult, IdentityServiceResources.UserClaimsCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, claimsDto);
}
public virtual async Task<IdentityResult> UpdateUserClaimsAsync(TUserClaimsDto claimsDto)
{
var userIdentityUserClaim = Mapper.Map<TUserClaim>(claimsDto);
var identityResult = await IdentityRepository.UpdateUserClaimsAsync(userIdentityUserClaim);
await AuditEventLogger.LogEventAsync(new UserClaimsSavedEvent<TUserClaimsDto>(claimsDto));
return HandleIdentityError(identityResult, IdentityServiceResources.UserClaimsUpdateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, claimsDto);
}
public virtual async Task<IdentityResult> DeleteUserClaimAsync(TUserClaimsDto claim)
{
var deleted = await IdentityRepository.DeleteUserClaimAsync(claim.UserId.ToString(), claim.ClaimId);
await AuditEventLogger.LogEventAsync(new UserClaimsDeletedEvent<TUserClaimsDto>(claim));
return deleted;
}
public virtual TKey ConvertToKeyFromString(string id)
{
if (id == null)
{
return default(TKey);
}
return (TKey)TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString(id);
}
public virtual async Task<TUserProvidersDto> GetUserProvidersAsync(string userId)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var userLoginInfos = await IdentityRepository.GetUserProvidersAsync(userId);
var providersDto = Mapper.Map<TUserProvidersDto>(userLoginInfos);
providersDto.UserId = ConvertToKeyFromString(userId);
var user = await IdentityRepository.GetUserAsync(userId);
providersDto.UserName = user.UserName;
await AuditEventLogger.LogEventAsync(new UserProvidersRequestedEvent<TUserProvidersDto>(providersDto));
return providersDto;
}
public virtual async Task<IdentityResult> DeleteUserProvidersAsync(TUserProviderDto provider)
{
var identityResult = await IdentityRepository.DeleteUserProvidersAsync(provider.UserId.ToString(), provider.ProviderKey, provider.LoginProvider);
await AuditEventLogger.LogEventAsync(new UserProvidersDeletedEvent<TUserProviderDto>(provider));
return HandleIdentityError(identityResult, IdentityServiceResources.UserProviderDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, provider);
}
public virtual async Task<TUserProviderDto> GetUserProviderAsync(string userId, string providerKey)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var identityUserLogin = await IdentityRepository.GetUserProviderAsync(userId, providerKey);
if (identityUserLogin == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserProviderDoesNotExist().Description, providerKey), IdentityServiceResources.UserProviderDoesNotExist().Description);
var userProviderDto = Mapper.Map<TUserProviderDto>(identityUserLogin);
var user = await GetUserAsync(userId);
userProviderDto.UserName = user.UserName;
await AuditEventLogger.LogEventAsync(new UserProviderRequestedEvent<TUserProviderDto>(userProviderDto));
return userProviderDto;
}
public virtual async Task<IdentityResult> UserChangePasswordAsync(TUserChangePasswordDto userPassword)
{
var userExists = await IdentityRepository.ExistsUserAsync(userPassword.UserId.ToString());
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userPassword.UserId), IdentityServiceResources.UserDoesNotExist().Description);
var identityResult = await IdentityRepository.UserChangePasswordAsync(userPassword.UserId.ToString(), userPassword.Password);
await AuditEventLogger.LogEventAsync(new UserPasswordChangedEvent(userPassword.UserName));
return HandleIdentityError(identityResult, IdentityServiceResources.UserChangePasswordFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, userPassword);
}
public virtual async Task<IdentityResult> CreateRoleClaimsAsync(TRoleClaimsDto claimsDto)
{
var identityRoleClaim = Mapper.Map<TRoleClaim>(claimsDto);
var identityResult = await IdentityRepository.CreateRoleClaimsAsync(identityRoleClaim);
await AuditEventLogger.LogEventAsync(new RoleClaimsSavedEvent<TRoleClaimsDto>(claimsDto));
return HandleIdentityError(identityResult, IdentityServiceResources.RoleClaimsCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, claimsDto);
}
public virtual async Task<IdentityResult> UpdateRoleClaimsAsync(TRoleClaimsDto claimsDto)
{
var identityRoleClaim = Mapper.Map<TRoleClaim>(claimsDto);
var identityResult = await IdentityRepository.UpdateRoleClaimsAsync(identityRoleClaim);
await AuditEventLogger.LogEventAsync(new RoleClaimsSavedEvent<TRoleClaimsDto>(claimsDto));
return HandleIdentityError(identityResult, IdentityServiceResources.RoleClaimsUpdateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, claimsDto);
}
public virtual async Task<TRoleClaimsDto> GetRoleClaimsAsync(string roleId, int page = 1, int pageSize = 10)
{
var roleExists = await IdentityRepository.ExistsRoleAsync(roleId);
if (!roleExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description);
var identityRoleClaims = await IdentityRepository.GetRoleClaimsAsync(roleId, page, pageSize);
var roleClaimDtos = Mapper.Map<TRoleClaimsDto>(identityRoleClaims);
var roleDto = await GetRoleAsync(roleId);
roleClaimDtos.RoleName = roleDto.Name;
await AuditEventLogger.LogEventAsync(new RoleClaimsRequestedEvent<TRoleClaimsDto>(roleClaimDtos));
return roleClaimDtos;
}
public virtual async Task<TRoleClaimsDto> GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var identityRoleClaims = await IdentityRepository.GetUserRoleClaimsAsync(userId, claimSearchText, page, pageSize);
var roleClaimDtos = Mapper.Map<TRoleClaimsDto>(identityRoleClaims);
return roleClaimDtos;
}
public virtual async Task<TRoleClaimsDto> GetRoleClaimAsync(string roleId, int claimId)
{
var roleExists = await IdentityRepository.ExistsRoleAsync(roleId);
if (!roleExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description);
var identityRoleClaim = await IdentityRepository.GetRoleClaimAsync(roleId, claimId);
if (identityRoleClaim == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleClaimDoesNotExist().Description, claimId), IdentityServiceResources.RoleClaimDoesNotExist().Description);
var roleClaimsDto = Mapper.Map<TRoleClaimsDto>(identityRoleClaim);
var roleDto = await GetRoleAsync(roleId);
roleClaimsDto.RoleName = roleDto.Name;
await AuditEventLogger.LogEventAsync(new RoleClaimRequestedEvent<TRoleClaimsDto>(roleClaimsDto));
return roleClaimsDto;
}
public virtual async Task<IdentityResult> DeleteRoleClaimAsync(TRoleClaimsDto role)
{
var deleted = await IdentityRepository.DeleteRoleClaimAsync(role.RoleId.ToString(), role.ClaimId);
await AuditEventLogger.LogEventAsync(new RoleClaimsDeletedEvent<TRoleClaimsDto>(role));
return deleted;
}
public virtual async Task<IdentityResult> DeleteRoleAsync(TRoleDto role)
{
var userIdentityRole = Mapper.Map<TRole>(role);
var identityResult = await IdentityRepository.DeleteRoleAsync(userIdentityRole);
await AuditEventLogger.LogEventAsync(new RoleDeletedEvent<TRoleDto>(role));
return HandleIdentityError(identityResult, IdentityServiceResources.RoleDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role);
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Identity;
using Skoruba.AuditLogging.Services;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Events.Identity;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Resources;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services.Interfaces;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.Dtos.Common;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Shared.ExceptionHandling;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common;
using Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories.Interfaces;
namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services
{
public class IdentityService<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole,
TUserLogin, TRoleClaim, TUserToken,
TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto> : IIdentityService<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole,
TUserLogin, TRoleClaim, TUserToken,
TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto>
where TUserDto : UserDto<TKey>
where TRoleDto : RoleDto<TKey>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
where TUsersDto : UsersDto<TUserDto, TKey>
where TRolesDto : RolesDto<TRoleDto, TKey>
where TUserRolesDto : UserRolesDto<TRoleDto, TKey>
where TUserClaimsDto : UserClaimsDto<TUserClaimDto, TKey>
where TUserProviderDto : UserProviderDto<TKey>
where TUserProvidersDto : UserProvidersDto<TKey>
where TUserChangePasswordDto : UserChangePasswordDto<TKey>
where TRoleClaimsDto : RoleClaimsDto<TKey>
where TUserClaimDto : UserClaimDto<TKey>
{
protected readonly IIdentityRepository<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> IdentityRepository;
protected readonly IIdentityServiceResources IdentityServiceResources;
protected readonly IMapper Mapper;
protected readonly IAuditEventLogger AuditEventLogger;
public IdentityService(IIdentityRepository<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> identityRepository,
IIdentityServiceResources identityServiceResources,
IMapper mapper,
IAuditEventLogger auditEventLogger)
{
IdentityRepository = identityRepository;
IdentityServiceResources = identityServiceResources;
Mapper = mapper;
AuditEventLogger = auditEventLogger;
}
public virtual async Task<bool> ExistsUserAsync(string userId)
{
var exists = await IdentityRepository.ExistsUserAsync(userId);
if (!exists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
return true;
}
public virtual async Task<bool> ExistsRoleAsync(string roleId)
{
var exists = await IdentityRepository.ExistsRoleAsync(roleId);
if (!exists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description);
return true;
}
public virtual async Task<TUsersDto> GetUsersAsync(string search, int page = 1, int pageSize = 10)
{
var pagedList = await IdentityRepository.GetUsersAsync(search, page, pageSize);
var usersDto = Mapper.Map<TUsersDto>(pagedList);
await AuditEventLogger.LogEventAsync(new UsersRequestedEvent<TUsersDto>(usersDto));
return usersDto;
}
public virtual async Task<TUsersDto> GetRoleUsersAsync(string roleId, string search, int page = 1, int pageSize = 10)
{
var roleKey = ConvertToKeyFromString(roleId);
var userIdentityRole = await IdentityRepository.GetRoleAsync(roleKey);
if (userIdentityRole == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description);
var pagedList = await IdentityRepository.GetRoleUsersAsync(roleId, search, page, pageSize);
var usersDto = Mapper.Map<TUsersDto>(pagedList);
await AuditEventLogger.LogEventAsync(new RoleUsersRequestedEvent<TUsersDto>(usersDto));
return usersDto;
}
public virtual async Task<TUsersDto> GetClaimUsersAsync(string claimType, string claimValue, int page = 1, int pageSize = 10)
{
var pagedList = await IdentityRepository.GetClaimUsersAsync(claimType, claimValue, page, pageSize);
var usersDto = Mapper.Map<TUsersDto>(pagedList);
await AuditEventLogger.LogEventAsync(new ClaimUsersRequestedEvent<TUsersDto>(usersDto));
return usersDto;
}
public virtual async Task<TRolesDto> GetRolesAsync(string search, int page = 1, int pageSize = 10)
{
PagedList<TRole> pagedList = await IdentityRepository.GetRolesAsync(search, page, pageSize);
var rolesDto = Mapper.Map<TRolesDto>(pagedList);
await AuditEventLogger.LogEventAsync(new RolesRequestedEvent<TRolesDto>(rolesDto));
return rolesDto;
}
public virtual async Task<(IdentityResult identityResult, TKey roleId)> CreateRoleAsync(TRoleDto role)
{
var roleEntity = Mapper.Map<TRole>(role);
var (identityResult, roleId) = await IdentityRepository.CreateRoleAsync(roleEntity);
var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.RoleCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role);
await AuditEventLogger.LogEventAsync(new RoleAddedEvent<TRoleDto>(role));
return (handleIdentityError, roleId);
}
private IdentityResult HandleIdentityError(IdentityResult identityResult, string errorMessage, string errorKey, object model)
{
if (!identityResult.Errors.Any()) return identityResult;
var viewErrorMessages = Mapper.Map<List<ViewErrorMessage>>(identityResult.Errors);
throw new UserFriendlyViewException(errorMessage, errorKey, viewErrorMessages, model);
}
public virtual async Task<TRoleDto> GetRoleAsync(string roleId)
{
var roleKey = ConvertToKeyFromString(roleId);
var userIdentityRole = await IdentityRepository.GetRoleAsync(roleKey);
if (userIdentityRole == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description);
var roleDto = Mapper.Map<TRoleDto>(userIdentityRole);
await AuditEventLogger.LogEventAsync(new RoleRequestedEvent<TRoleDto>(roleDto));
return roleDto;
}
public virtual async Task<List<TRoleDto>> GetRolesAsync()
{
var roles = await IdentityRepository.GetRolesAsync();
var roleDtos = Mapper.Map<List<TRoleDto>>(roles);
await AuditEventLogger.LogEventAsync(new AllRolesRequestedEvent<TRoleDto>(roleDtos));
return roleDtos;
}
public virtual async Task<(IdentityResult identityResult, TKey roleId)> UpdateRoleAsync(TRoleDto role)
{
var userIdentityRole = Mapper.Map<TRole>(role);
var originalRole = await GetRoleAsync(role.Id.ToString());
var (identityResult, roleId) = await IdentityRepository.UpdateRoleAsync(userIdentityRole);
await AuditEventLogger.LogEventAsync(new RoleUpdatedEvent<TRoleDto>(originalRole, role));
var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.RoleUpdateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role);
return (handleIdentityError, roleId);
}
public virtual async Task<TUserDto> GetUserAsync(string userId)
{
var identity = await IdentityRepository.GetUserAsync(userId);
if (identity == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var userDto = Mapper.Map<TUserDto>(identity);
await AuditEventLogger.LogEventAsync(new UserRequestedEvent<TUserDto>(userDto));
return userDto;
}
public virtual async Task<(IdentityResult identityResult, TKey userId)> CreateUserAsync(TUserDto user)
{
var userIdentity = Mapper.Map<TUser>(user);
var (identityResult, userId) = await IdentityRepository.CreateUserAsync(userIdentity);
var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.UserCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, user);
await AuditEventLogger.LogEventAsync(new UserSavedEvent<TUserDto>(user));
return (handleIdentityError, userId);
}
/// <summary>
/// Updates the specified user, but without updating the password hash value
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public virtual async Task<(IdentityResult identityResult, TKey userId)> UpdateUserAsync(TUserDto user)
{
var userIdentity = Mapper.Map<TUser>(user);
await MapOriginalPasswordHashAsync(userIdentity);
var originalUser = await GetUserAsync(user.Id.ToString());
var (identityResult, userId) = await IdentityRepository.UpdateUserAsync(userIdentity);
var handleIdentityError = HandleIdentityError(identityResult, IdentityServiceResources.UserUpdateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, user);
await AuditEventLogger.LogEventAsync(new UserUpdatedEvent<TUserDto>(originalUser, user));
return (handleIdentityError, userId);
}
/// <summary>
/// Get original password hash and map password hash to user
/// </summary>
/// <param name="userIdentity"></param>
/// <returns></returns>
private async Task MapOriginalPasswordHashAsync(TUser userIdentity)
{
var identity = await IdentityRepository.GetUserAsync(userIdentity.Id.ToString());
userIdentity.PasswordHash = identity.PasswordHash;
}
public virtual async Task<IdentityResult> DeleteUserAsync(string userId, TUserDto user)
{
var identityResult = await IdentityRepository.DeleteUserAsync(userId);
await AuditEventLogger.LogEventAsync(new UserDeletedEvent<TUserDto>(user));
return HandleIdentityError(identityResult, IdentityServiceResources.UserDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, user);
}
public virtual async Task<IdentityResult> CreateUserRoleAsync(TUserRolesDto role)
{
var identityResult = await IdentityRepository.CreateUserRoleAsync(role.UserId.ToString(), role.RoleId.ToString());
await AuditEventLogger.LogEventAsync(new UserRoleSavedEvent<TUserRolesDto>(role));
if (!identityResult.Errors.Any()) return identityResult;
var userRolesDto = await BuildUserRolesViewModel(role.UserId, 1);
return HandleIdentityError(identityResult, IdentityServiceResources.UserRoleCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, userRolesDto);
}
public virtual async Task<TUserRolesDto> BuildUserRolesViewModel(TKey id, int? page)
{
var roles = await GetRolesAsync();
var userRoles = await GetUserRolesAsync(id.ToString(), page ?? 1);
userRoles.UserId = id;
userRoles.RolesList = roles.Select(x => new SelectItemDto(x.Id.ToString(), x.Name)).ToList();
return userRoles;
}
public virtual async Task<TUserRolesDto> GetUserRolesAsync(string userId, int page = 1, int pageSize = 10)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var userIdentityRoles = await IdentityRepository.GetUserRolesAsync(userId, page, pageSize);
var roleDtos = Mapper.Map<TUserRolesDto>(userIdentityRoles);
var user = await IdentityRepository.GetUserAsync(userId);
roleDtos.UserName = user.UserName;
await AuditEventLogger.LogEventAsync(new UserRolesRequestedEvent<TUserRolesDto>(roleDtos));
return roleDtos;
}
public virtual async Task<IdentityResult> DeleteUserRoleAsync(TUserRolesDto role)
{
var identityResult = await IdentityRepository.DeleteUserRoleAsync(role.UserId.ToString(), role.RoleId.ToString());
await AuditEventLogger.LogEventAsync(new UserRoleDeletedEvent<TUserRolesDto>(role));
return HandleIdentityError(identityResult, IdentityServiceResources.UserRoleDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role);
}
public virtual async Task<TUserClaimsDto> GetUserClaimsAsync(string userId, int page = 1, int pageSize = 10)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var identityUserClaims = await IdentityRepository.GetUserClaimsAsync(userId, page, pageSize);
var claimDtos = Mapper.Map<TUserClaimsDto>(identityUserClaims);
var user = await IdentityRepository.GetUserAsync(userId);
claimDtos.UserName = user.UserName;
await AuditEventLogger.LogEventAsync(new UserClaimsRequestedEvent<TUserClaimsDto>(claimDtos));
return claimDtos;
}
public virtual async Task<TUserClaimsDto> GetUserClaimAsync(string userId, int claimId)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var identityUserClaim = await IdentityRepository.GetUserClaimAsync(userId, claimId);
if (identityUserClaim == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserClaimDoesNotExist().Description, userId), IdentityServiceResources.UserClaimDoesNotExist().Description);
var userClaimsDto = Mapper.Map<TUserClaimsDto>(identityUserClaim);
await AuditEventLogger.LogEventAsync(new UserClaimRequestedEvent<TUserClaimsDto>(userClaimsDto));
return userClaimsDto;
}
public virtual async Task<IdentityResult> CreateUserClaimsAsync(TUserClaimsDto claimsDto)
{
var userIdentityUserClaim = Mapper.Map<TUserClaim>(claimsDto);
var identityResult = await IdentityRepository.CreateUserClaimsAsync(userIdentityUserClaim);
await AuditEventLogger.LogEventAsync(new UserClaimsSavedEvent<TUserClaimsDto>(claimsDto));
return HandleIdentityError(identityResult, IdentityServiceResources.UserClaimsCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, claimsDto);
}
public virtual async Task<IdentityResult> UpdateUserClaimsAsync(TUserClaimsDto claimsDto)
{
var userIdentityUserClaim = Mapper.Map<TUserClaim>(claimsDto);
var identityResult = await IdentityRepository.UpdateUserClaimsAsync(userIdentityUserClaim);
await AuditEventLogger.LogEventAsync(new UserClaimsSavedEvent<TUserClaimsDto>(claimsDto));
return HandleIdentityError(identityResult, IdentityServiceResources.UserClaimsUpdateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, claimsDto);
}
public virtual async Task<IdentityResult> DeleteUserClaimAsync(TUserClaimsDto claim)
{
var deleted = await IdentityRepository.DeleteUserClaimAsync(claim.UserId.ToString(), claim.ClaimId);
await AuditEventLogger.LogEventAsync(new UserClaimsDeletedEvent<TUserClaimsDto>(claim));
return deleted;
}
public virtual TKey ConvertToKeyFromString(string id)
{
if (id == null)
{
return default(TKey);
}
return (TKey)TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString(id);
}
public virtual async Task<TUserProvidersDto> GetUserProvidersAsync(string userId)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var userLoginInfos = await IdentityRepository.GetUserProvidersAsync(userId);
var providersDto = Mapper.Map<TUserProvidersDto>(userLoginInfos);
providersDto.UserId = ConvertToKeyFromString(userId);
var user = await IdentityRepository.GetUserAsync(userId);
providersDto.UserName = user.UserName;
await AuditEventLogger.LogEventAsync(new UserProvidersRequestedEvent<TUserProvidersDto>(providersDto));
return providersDto;
}
public virtual async Task<IdentityResult> DeleteUserProvidersAsync(TUserProviderDto provider)
{
var identityResult = await IdentityRepository.DeleteUserProvidersAsync(provider.UserId.ToString(), provider.ProviderKey, provider.LoginProvider);
await AuditEventLogger.LogEventAsync(new UserProvidersDeletedEvent<TUserProviderDto>(provider));
return HandleIdentityError(identityResult, IdentityServiceResources.UserProviderDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, provider);
}
public virtual async Task<TUserProviderDto> GetUserProviderAsync(string userId, string providerKey)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var identityUserLogin = await IdentityRepository.GetUserProviderAsync(userId, providerKey);
if (identityUserLogin == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserProviderDoesNotExist().Description, providerKey), IdentityServiceResources.UserProviderDoesNotExist().Description);
var userProviderDto = Mapper.Map<TUserProviderDto>(identityUserLogin);
var user = await GetUserAsync(userId);
userProviderDto.UserName = user.UserName;
await AuditEventLogger.LogEventAsync(new UserProviderRequestedEvent<TUserProviderDto>(userProviderDto));
return userProviderDto;
}
public virtual async Task<IdentityResult> UserChangePasswordAsync(TUserChangePasswordDto userPassword)
{
var userExists = await IdentityRepository.ExistsUserAsync(userPassword.UserId.ToString());
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userPassword.UserId), IdentityServiceResources.UserDoesNotExist().Description);
var identityResult = await IdentityRepository.UserChangePasswordAsync(userPassword.UserId.ToString(), userPassword.Password);
await AuditEventLogger.LogEventAsync(new UserPasswordChangedEvent(userPassword.UserName));
return HandleIdentityError(identityResult, IdentityServiceResources.UserChangePasswordFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, userPassword);
}
public virtual async Task<IdentityResult> CreateRoleClaimsAsync(TRoleClaimsDto claimsDto)
{
var identityRoleClaim = Mapper.Map<TRoleClaim>(claimsDto);
var identityResult = await IdentityRepository.CreateRoleClaimsAsync(identityRoleClaim);
await AuditEventLogger.LogEventAsync(new RoleClaimsSavedEvent<TRoleClaimsDto>(claimsDto));
return HandleIdentityError(identityResult, IdentityServiceResources.RoleClaimsCreateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, claimsDto);
}
public virtual async Task<IdentityResult> UpdateRoleClaimsAsync(TRoleClaimsDto claimsDto)
{
var identityRoleClaim = Mapper.Map<TRoleClaim>(claimsDto);
var identityResult = await IdentityRepository.UpdateRoleClaimsAsync(identityRoleClaim);
await AuditEventLogger.LogEventAsync(new RoleClaimsSavedEvent<TRoleClaimsDto>(claimsDto));
return HandleIdentityError(identityResult, IdentityServiceResources.RoleClaimsUpdateFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, claimsDto);
}
public virtual async Task<TRoleClaimsDto> GetRoleClaimsAsync(string roleId, int page = 1, int pageSize = 10)
{
var roleExists = await IdentityRepository.ExistsRoleAsync(roleId);
if (!roleExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description);
var identityRoleClaims = await IdentityRepository.GetRoleClaimsAsync(roleId, page, pageSize);
var roleClaimDtos = Mapper.Map<TRoleClaimsDto>(identityRoleClaims);
var roleDto = await GetRoleAsync(roleId);
roleClaimDtos.RoleName = roleDto.Name;
await AuditEventLogger.LogEventAsync(new RoleClaimsRequestedEvent<TRoleClaimsDto>(roleClaimDtos));
return roleClaimDtos;
}
public virtual async Task<TRoleClaimsDto> GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10)
{
var userExists = await IdentityRepository.ExistsUserAsync(userId);
if (!userExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.UserDoesNotExist().Description, userId), IdentityServiceResources.UserDoesNotExist().Description);
var identityRoleClaims = await IdentityRepository.GetUserRoleClaimsAsync(userId, claimSearchText, page, pageSize);
var roleClaimDtos = Mapper.Map<TRoleClaimsDto>(identityRoleClaims);
return roleClaimDtos;
}
public virtual async Task<TRoleClaimsDto> GetRoleClaimAsync(string roleId, int claimId)
{
var roleExists = await IdentityRepository.ExistsRoleAsync(roleId);
if (!roleExists) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleDoesNotExist().Description, roleId), IdentityServiceResources.RoleDoesNotExist().Description);
var identityRoleClaim = await IdentityRepository.GetRoleClaimAsync(roleId, claimId);
if (identityRoleClaim == null) throw new UserFriendlyErrorPageException(string.Format(IdentityServiceResources.RoleClaimDoesNotExist().Description, claimId), IdentityServiceResources.RoleClaimDoesNotExist().Description);
var roleClaimsDto = Mapper.Map<TRoleClaimsDto>(identityRoleClaim);
var roleDto = await GetRoleAsync(roleId);
roleClaimsDto.RoleName = roleDto.Name;
await AuditEventLogger.LogEventAsync(new RoleClaimRequestedEvent<TRoleClaimsDto>(roleClaimsDto));
return roleClaimsDto;
}
public virtual async Task<IdentityResult> DeleteRoleClaimAsync(TRoleClaimsDto role)
{
var deleted = await IdentityRepository.DeleteRoleClaimAsync(role.RoleId.ToString(), role.ClaimId);
await AuditEventLogger.LogEventAsync(new RoleClaimsDeletedEvent<TRoleClaimsDto>(role));
return deleted;
}
public virtual async Task<IdentityResult> DeleteRoleAsync(TRoleDto role)
{
var userIdentityRole = Mapper.Map<TRole>(role);
var identityResult = await IdentityRepository.DeleteRoleAsync(userIdentityRole);
await AuditEventLogger.LogEventAsync(new RoleDeletedEvent<TRoleDto>(role));
return HandleIdentityError(identityResult, IdentityServiceResources.RoleDeleteFailed().Description, IdentityServiceResources.IdentityErrorKey().Description, role);
}
public async Task<string> GeneratePasswordResetTokenAsync(TUserDto userDto)
......@@ -500,6 +500,6 @@ namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services
var user = Mapper.Map<TUser>(userDto);
return await IdentityRepository.GeneratePasswordResetTokenAsync(user);
}
}
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity;
namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services.Interfaces
{
public interface IIdentityService<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole,
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Dtos.Identity;
namespace Skoruba.IdentityServer4.Admin.BusinessLogic.Identity.Services.Interfaces
{
public interface IIdentityService<TUserDto, TRoleDto, TUser, TRole, TKey, TUserClaim, TUserRole,
TUserLogin, TRoleClaim, TUserToken,
TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
TUsersDto, TRolesDto, TUserRolesDto, TUserClaimsDto,
TUserProviderDto, TUserProvidersDto, TUserChangePasswordDto, TRoleClaimsDto, TUserClaimDto>
where TUserDto : UserDto<TKey>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
where TRoleDto : RoleDto<TKey>
where TUsersDto : UsersDto<TUserDto, TKey>
where TRolesDto : RolesDto<TRoleDto, TKey>
where TUserRolesDto : UserRolesDto<TRoleDto, TKey>
where TUserClaimsDto : UserClaimsDto<TUserClaimDto, TKey>
where TUserProviderDto : UserProviderDto<TKey>
where TUserProvidersDto : UserProvidersDto<TKey>
where TUserChangePasswordDto : UserChangePasswordDto<TKey>
where TRoleClaimsDto : RoleClaimsDto<TKey>
where TUserClaimDto : UserClaimDto<TKey>
{
Task<bool> ExistsUserAsync(string userId);
Task<bool> ExistsRoleAsync(string roleId);
Task<TUsersDto> GetUsersAsync(string search, int page = 1, int pageSize = 10);
where TUserDto : UserDto<TKey>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
where TRoleDto : RoleDto<TKey>
where TUsersDto : UsersDto<TUserDto, TKey>
where TRolesDto : RolesDto<TRoleDto, TKey>
where TUserRolesDto : UserRolesDto<TRoleDto, TKey>
where TUserClaimsDto : UserClaimsDto<TUserClaimDto, TKey>
where TUserProviderDto : UserProviderDto<TKey>
where TUserProvidersDto : UserProvidersDto<TKey>
where TUserChangePasswordDto : UserChangePasswordDto<TKey>
where TRoleClaimsDto : RoleClaimsDto<TKey>
where TUserClaimDto : UserClaimDto<TKey>
{
Task<bool> ExistsUserAsync(string userId);
Task<bool> ExistsRoleAsync(string roleId);
Task<TUsersDto> GetUsersAsync(string search, int page = 1, int pageSize = 10);
Task<TUsersDto> GetRoleUsersAsync(string roleId, string search, int page = 1, int pageSize = 10);
Task<TUsersDto> GetClaimUsersAsync(string claimType, string claimValue, int page = 1, int pageSize = 10);
Task<TRolesDto> GetRolesAsync(string search, int page = 1, int pageSize = 10);
Task<(IdentityResult identityResult, TKey roleId)> CreateRoleAsync(TRoleDto role);
Task<TRoleDto> GetRoleAsync(string roleId);
Task<List<TRoleDto>> GetRolesAsync();
Task<(IdentityResult identityResult, TKey roleId)> UpdateRoleAsync(TRoleDto role);
Task<TUserDto> GetUserAsync(string userId);
Task<(IdentityResult identityResult, TKey userId)> CreateUserAsync(TUserDto user);
Task<(IdentityResult identityResult, TKey userId)> UpdateUserAsync(TUserDto user);
Task<IdentityResult> DeleteUserAsync(string userId, TUserDto user);
Task<IdentityResult> CreateUserRoleAsync(TUserRolesDto role);
Task<TUserRolesDto> BuildUserRolesViewModel(TKey id, int? page);
Task<TUserRolesDto> GetUserRolesAsync(string userId, int page = 1,
int pageSize = 10);
Task<IdentityResult> DeleteUserRoleAsync(TUserRolesDto role);
Task<TUserClaimsDto> GetUserClaimsAsync(string userId, int page = 1,
int pageSize = 10);
Task<TUserClaimsDto> GetUserClaimAsync(string userId, int claimId);
Task<TUsersDto> GetClaimUsersAsync(string claimType, string claimValue, int page = 1, int pageSize = 10);
Task<TRolesDto> GetRolesAsync(string search, int page = 1, int pageSize = 10);
Task<(IdentityResult identityResult, TKey roleId)> CreateRoleAsync(TRoleDto role);
Task<TRoleDto> GetRoleAsync(string roleId);
Task<List<TRoleDto>> GetRolesAsync();
Task<(IdentityResult identityResult, TKey roleId)> UpdateRoleAsync(TRoleDto role);
Task<TUserDto> GetUserAsync(string userId);
Task<(IdentityResult identityResult, TKey userId)> CreateUserAsync(TUserDto user);
Task<(IdentityResult identityResult, TKey userId)> UpdateUserAsync(TUserDto user);
Task<IdentityResult> DeleteUserAsync(string userId, TUserDto user);
Task<IdentityResult> CreateUserRoleAsync(TUserRolesDto role);
Task<TUserRolesDto> BuildUserRolesViewModel(TKey id, int? page);
Task<TUserRolesDto> GetUserRolesAsync(string userId, int page = 1,
int pageSize = 10);
Task<IdentityResult> DeleteUserRoleAsync(TUserRolesDto role);
Task<TUserClaimsDto> GetUserClaimsAsync(string userId, int page = 1,
int pageSize = 10);
Task<TUserClaimsDto> GetUserClaimAsync(string userId, int claimId);
Task<IdentityResult> CreateUserClaimsAsync(TUserClaimsDto claimsDto);
Task<IdentityResult> UpdateUserClaimsAsync(TUserClaimsDto claimsDto);
Task<IdentityResult> DeleteUserClaimAsync(TUserClaimsDto claim);
Task<TUserProvidersDto> GetUserProvidersAsync(string userId);
TKey ConvertToKeyFromString(string id);
Task<IdentityResult> DeleteUserProvidersAsync(TUserProviderDto provider);
Task<TUserProviderDto> GetUserProviderAsync(string userId, string providerKey);
Task<IdentityResult> UserChangePasswordAsync(TUserChangePasswordDto userPassword);
Task<IdentityResult> UpdateUserClaimsAsync(TUserClaimsDto claimsDto);
Task<IdentityResult> DeleteUserClaimAsync(TUserClaimsDto claim);
Task<TUserProvidersDto> GetUserProvidersAsync(string userId);
TKey ConvertToKeyFromString(string id);
Task<IdentityResult> DeleteUserProvidersAsync(TUserProviderDto provider);
Task<TUserProviderDto> GetUserProviderAsync(string userId, string providerKey);
Task<IdentityResult> UserChangePasswordAsync(TUserChangePasswordDto userPassword);
Task<IdentityResult> CreateRoleClaimsAsync(TRoleClaimsDto claimsDto);
Task<IdentityResult> UpdateRoleClaimsAsync(TRoleClaimsDto claimsDto);
Task<IdentityResult> UpdateRoleClaimsAsync(TRoleClaimsDto claimsDto);
Task<TRoleClaimsDto> GetRoleClaimsAsync(string roleId, int page = 1, int pageSize = 10);
Task<TRoleClaimsDto> GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10);
Task<TRoleClaimsDto> GetRoleClaimAsync(string roleId, int claimId);
Task<IdentityResult> DeleteRoleClaimAsync(TRoleClaimsDto role);
Task<TRoleClaimsDto> GetRoleClaimAsync(string roleId, int claimId);
Task<IdentityResult> DeleteRoleClaimAsync(TRoleClaimsDto role);
Task<IdentityResult> DeleteRoleAsync(TRoleDto role);
Task<string> GeneratePasswordResetTokenAsync(TUserDto user);
}
Task<string> GeneratePasswordResetTokenAsync(TUserDto user);
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Enums;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Extensions;
using Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories.Interfaces;
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories
{
public class IdentityRepository<TIdentityDbContext, TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
: IIdentityRepository<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
where TIdentityDbContext : IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
{
protected readonly TIdentityDbContext DbContext;
protected readonly UserManager<TUser> UserManager;
protected readonly RoleManager<TRole> RoleManager;
protected readonly IMapper Mapper;
public bool AutoSaveChanges { get; set; } = true;
public IdentityRepository(TIdentityDbContext dbContext,
UserManager<TUser> userManager,
RoleManager<TRole> roleManager,
IMapper mapper)
{
DbContext = dbContext;
UserManager = userManager;
RoleManager = roleManager;
Mapper = mapper;
}
public virtual TKey ConvertKeyFromString(string id)
{
if (id == null)
{
return default;
}
return (TKey)TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString(id);
}
public virtual Task<bool> ExistsUserAsync(string userId)
{
var id = ConvertKeyFromString(userId);
return UserManager.Users.AnyAsync(x => x.Id.Equals(id));
}
public virtual Task<bool> ExistsRoleAsync(string roleId)
{
var id = ConvertKeyFromString(roleId);
return RoleManager.Roles.AnyAsync(x => x.Id.Equals(id));
}
public virtual async Task<PagedList<TUser>> GetUsersAsync(string search, int page = 1, int pageSize = 10)
{
var pagedList = new PagedList<TUser>();
Expression<Func<TUser, bool>> searchCondition = x => x.UserName.Contains(search) || x.Email.Contains(search);
var users = await UserManager.Users.WhereIf(!string.IsNullOrEmpty(search), searchCondition).PageBy(x => x.Id, page, pageSize).ToListAsync();
pagedList.Data.AddRange(users);
pagedList.TotalCount = await UserManager.Users.WhereIf(!string.IsNullOrEmpty(search), searchCondition).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TUser>> GetRoleUsersAsync(string roleId, string search, int page = 1, int pageSize = 10)
{
var id = ConvertKeyFromString(roleId);
var pagedList = new PagedList<TUser>();
var users = DbContext.Set<TUser>()
.Join(DbContext.Set<TUserRole>(), u => u.Id, ur => ur.UserId, (u, ur) => new {u, ur})
.Where(t => t.ur.RoleId.Equals(id))
.WhereIf(!string.IsNullOrEmpty(search), t => t.u.UserName.Contains(search) || t.u.Email.Contains(search))
.Select(t => t.u);
var pagedUsers = await users.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(pagedUsers);
pagedList.TotalCount = await users.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TUser>> GetClaimUsersAsync(string claimType, string claimValue, int page = 1, int pageSize = 10)
{
var pagedList = new PagedList<TUser>();
var users = DbContext.Set<TUser>()
.Join(DbContext.Set<TUserClaim>(), u => u.Id, uc => uc.UserId, (u, uc) => new { u, uc })
.Where(t => t.uc.ClaimType.Equals(claimType))
.WhereIf(!string.IsNullOrEmpty(claimValue), t => t.uc.ClaimValue.Equals(claimValue))
.Select(t => t.u).Distinct();
var pagedUsers = await users.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(pagedUsers);
pagedList.TotalCount = await users.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual Task<List<TRole>> GetRolesAsync()
{
return RoleManager.Roles.ToListAsync();
}
public virtual async Task<PagedList<TRole>> GetRolesAsync(string search, int page = 1, int pageSize = 10)
{
var pagedList = new PagedList<TRole>();
Expression<Func<TRole, bool>> searchCondition = x => x.Name.Contains(search);
var roles = await RoleManager.Roles.WhereIf(!string.IsNullOrEmpty(search), searchCondition).PageBy(x => x.Id, page, pageSize).ToListAsync();
pagedList.Data.AddRange(roles);
pagedList.TotalCount = await RoleManager.Roles.WhereIf(!string.IsNullOrEmpty(search), searchCondition).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual Task<TRole> GetRoleAsync(TKey roleId)
{
return RoleManager.Roles.Where(x => x.Id.Equals(roleId)).SingleOrDefaultAsync();
}
public virtual async Task<(IdentityResult identityResult, TKey roleId)> CreateRoleAsync(TRole role)
{
var identityResult = await RoleManager.CreateAsync(role);
return (identityResult, role.Id);
}
public virtual async Task<(IdentityResult identityResult, TKey roleId)> UpdateRoleAsync(TRole role)
{
var existingRole = await RoleManager.FindByIdAsync(role.Id.ToString());
Mapper.Map(role, existingRole);
var identityResult = await RoleManager.UpdateAsync(existingRole);
return (identityResult, role.Id);
}
public virtual async Task<IdentityResult> DeleteRoleAsync(TRole role)
{
var thisRole = await RoleManager.FindByIdAsync(role.Id.ToString());
return await RoleManager.DeleteAsync(thisRole);
}
public virtual Task<TUser> GetUserAsync(string userId)
{
return UserManager.FindByIdAsync(userId);
}
/// <summary>
/// Create a new user
/// </summary>
/// <param name="user"></param>
/// <returns>This method returns identity result and new user id</returns>
public virtual async Task<(IdentityResult identityResult, TKey userId)> CreateUserAsync(TUser user)
{
var identityResult = await UserManager.CreateAsync(user);
return (identityResult, user.Id);
}
public virtual async Task<(IdentityResult identityResult, TKey userId)> UpdateUserAsync(TUser user)
{
var userIdentity = await UserManager.FindByIdAsync(user.Id.ToString());
Mapper.Map(user, userIdentity);
var identityResult = await UserManager.UpdateAsync(userIdentity);
return (identityResult, user.Id);
}
public virtual async Task<IdentityResult> CreateUserRoleAsync(string userId, string roleId)
{
var user = await UserManager.FindByIdAsync(userId);
var selectRole = await RoleManager.FindByIdAsync(roleId);
return await UserManager.AddToRoleAsync(user, selectRole.Name);
}
public virtual async Task<PagedList<TRole>> GetUserRolesAsync(string userId, int page = 1, int pageSize = 10)
{
var id = ConvertKeyFromString(userId);
var pagedList = new PagedList<TRole>();
var roles = from r in DbContext.Set<TRole>()
join ur in DbContext.Set<TUserRole>() on r.Id equals ur.RoleId
where ur.UserId.Equals(id)
select r;
var userIdentityRoles = await roles.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(userIdentityRoles);
pagedList.TotalCount = await roles.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<IdentityResult> DeleteUserRoleAsync(string userId, string roleId)
{
var role = await RoleManager.FindByIdAsync(roleId);
var user = await UserManager.FindByIdAsync(userId);
return await UserManager.RemoveFromRoleAsync(user, role.Name);
}
public virtual async Task<PagedList<TUserClaim>> GetUserClaimsAsync(string userId, int page, int pageSize)
{
var id = ConvertKeyFromString(userId);
var pagedList = new PagedList<TUserClaim>();
var claims = await DbContext.Set<TUserClaim>().Where(x => x.UserId.Equals(id))
.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(claims);
pagedList.TotalCount = await DbContext.Set<TUserClaim>().Where(x => x.UserId.Equals(id)).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TRoleClaim>> GetRoleClaimsAsync(string roleId, int page = 1, int pageSize = 10)
{
var id = ConvertKeyFromString(roleId);
var pagedList = new PagedList<TRoleClaim>();
var claims = await DbContext.Set<TRoleClaim>().Where(x => x.RoleId.Equals(id))
.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(claims);
pagedList.TotalCount = await DbContext.Set<TRoleClaim>().Where(x => x.RoleId.Equals(id)).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TRoleClaim>> GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10)
{
var id = ConvertKeyFromString(userId);
Expression<Func<TRoleClaim, bool>> searchCondition = x => x.ClaimType.Contains(claimSearchText);
var claimsQ = DbContext.Set<TUserRole>().Where(x => x.UserId.Equals(id))
.Join(DbContext.Set<TRoleClaim>().WhereIf(!string.IsNullOrEmpty(claimSearchText), searchCondition), ur => ur.RoleId, rc => rc.RoleId, (ur, rc) => rc);
var claims= await claimsQ.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
var pagedList = new PagedList<TRoleClaim>();
pagedList.Data.AddRange(claims);
pagedList.TotalCount = await claimsQ.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual Task<TUserClaim> GetUserClaimAsync(string userId, int claimId)
{
var userIdConverted = ConvertKeyFromString(userId);
return DbContext.Set<TUserClaim>().Where(x => x.UserId.Equals(userIdConverted) && x.Id == claimId)
.SingleOrDefaultAsync();
}
public virtual Task<TRoleClaim> GetRoleClaimAsync(string roleId, int claimId)
{
var roleIdConverted = ConvertKeyFromString(roleId);
return DbContext.Set<TRoleClaim>().Where(x => x.RoleId.Equals(roleIdConverted) && x.Id == claimId)
.SingleOrDefaultAsync();
}
public virtual async Task<IdentityResult> CreateUserClaimsAsync(TUserClaim claims)
{
var user = await UserManager.FindByIdAsync(claims.UserId.ToString());
return await UserManager.AddClaimAsync(user, new Claim(claims.ClaimType, claims.ClaimValue));
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Security.Claims;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Enums;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Extensions;
using Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories.Interfaces;
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories
{
public class IdentityRepository<TIdentityDbContext, TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
: IIdentityRepository<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
where TIdentityDbContext : IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
{
protected readonly TIdentityDbContext DbContext;
protected readonly UserManager<TUser> UserManager;
protected readonly RoleManager<TRole> RoleManager;
protected readonly IMapper Mapper;
public bool AutoSaveChanges { get; set; } = true;
public IdentityRepository(TIdentityDbContext dbContext,
UserManager<TUser> userManager,
RoleManager<TRole> roleManager,
IMapper mapper)
{
DbContext = dbContext;
UserManager = userManager;
RoleManager = roleManager;
Mapper = mapper;
}
public virtual TKey ConvertKeyFromString(string id)
{
if (id == null)
{
return default;
}
return (TKey)TypeDescriptor.GetConverter(typeof(TKey)).ConvertFromInvariantString(id);
}
public virtual Task<bool> ExistsUserAsync(string userId)
{
var id = ConvertKeyFromString(userId);
return UserManager.Users.AnyAsync(x => x.Id.Equals(id));
}
public virtual Task<bool> ExistsRoleAsync(string roleId)
{
var id = ConvertKeyFromString(roleId);
return RoleManager.Roles.AnyAsync(x => x.Id.Equals(id));
}
public virtual async Task<PagedList<TUser>> GetUsersAsync(string search, int page = 1, int pageSize = 10)
{
var pagedList = new PagedList<TUser>();
Expression<Func<TUser, bool>> searchCondition = x => x.UserName.Contains(search) || x.Email.Contains(search);
var users = await UserManager.Users.WhereIf(!string.IsNullOrEmpty(search), searchCondition).PageBy(x => x.Id, page, pageSize).ToListAsync();
pagedList.Data.AddRange(users);
pagedList.TotalCount = await UserManager.Users.WhereIf(!string.IsNullOrEmpty(search), searchCondition).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TUser>> GetRoleUsersAsync(string roleId, string search, int page = 1, int pageSize = 10)
{
var id = ConvertKeyFromString(roleId);
var pagedList = new PagedList<TUser>();
var users = DbContext.Set<TUser>()
.Join(DbContext.Set<TUserRole>(), u => u.Id, ur => ur.UserId, (u, ur) => new { u, ur })
.Where(t => t.ur.RoleId.Equals(id))
.WhereIf(!string.IsNullOrEmpty(search), t => t.u.UserName.Contains(search) || t.u.Email.Contains(search))
.Select(t => t.u);
var pagedUsers = await users.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(pagedUsers);
pagedList.TotalCount = await users.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TUser>> GetClaimUsersAsync(string claimType, string claimValue, int page = 1, int pageSize = 10)
{
var pagedList = new PagedList<TUser>();
var users = DbContext.Set<TUser>()
.Join(DbContext.Set<TUserClaim>(), u => u.Id, uc => uc.UserId, (u, uc) => new { u, uc })
.Where(t => t.uc.ClaimType.Equals(claimType))
.WhereIf(!string.IsNullOrEmpty(claimValue), t => t.uc.ClaimValue.Equals(claimValue))
.Select(t => t.u).Distinct();
var pagedUsers = await users.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(pagedUsers);
pagedList.TotalCount = await users.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual Task<List<TRole>> GetRolesAsync()
{
return RoleManager.Roles.ToListAsync();
}
public virtual async Task<PagedList<TRole>> GetRolesAsync(string search, int page = 1, int pageSize = 10)
{
var pagedList = new PagedList<TRole>();
Expression<Func<TRole, bool>> searchCondition = x => x.Name.Contains(search);
var roles = await RoleManager.Roles.WhereIf(!string.IsNullOrEmpty(search), searchCondition).PageBy(x => x.Id, page, pageSize).ToListAsync();
pagedList.Data.AddRange(roles);
pagedList.TotalCount = await RoleManager.Roles.WhereIf(!string.IsNullOrEmpty(search), searchCondition).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual Task<TRole> GetRoleAsync(TKey roleId)
{
return RoleManager.Roles.Where(x => x.Id.Equals(roleId)).SingleOrDefaultAsync();
}
public virtual async Task<(IdentityResult identityResult, TKey roleId)> CreateRoleAsync(TRole role)
{
var identityResult = await RoleManager.CreateAsync(role);
return (identityResult, role.Id);
}
public virtual async Task<(IdentityResult identityResult, TKey roleId)> UpdateRoleAsync(TRole role)
{
var existingRole = await RoleManager.FindByIdAsync(role.Id.ToString());
Mapper.Map(role, existingRole);
var identityResult = await RoleManager.UpdateAsync(existingRole);
return (identityResult, role.Id);
}
public virtual async Task<IdentityResult> DeleteRoleAsync(TRole role)
{
var thisRole = await RoleManager.FindByIdAsync(role.Id.ToString());
return await RoleManager.DeleteAsync(thisRole);
}
public virtual Task<TUser> GetUserAsync(string userId)
{
return UserManager.FindByIdAsync(userId);
}
/// <summary>
/// Create a new user
/// </summary>
/// <param name="user"></param>
/// <returns>This method returns identity result and new user id</returns>
public virtual async Task<(IdentityResult identityResult, TKey userId)> CreateUserAsync(TUser user)
{
var identityResult = await UserManager.CreateAsync(user);
return (identityResult, user.Id);
}
public virtual async Task<(IdentityResult identityResult, TKey userId)> UpdateUserAsync(TUser user)
{
var userIdentity = await UserManager.FindByIdAsync(user.Id.ToString());
Mapper.Map(user, userIdentity);
var identityResult = await UserManager.UpdateAsync(userIdentity);
return (identityResult, user.Id);
}
public virtual async Task<IdentityResult> CreateUserRoleAsync(string userId, string roleId)
{
var user = await UserManager.FindByIdAsync(userId);
var selectRole = await RoleManager.FindByIdAsync(roleId);
return await UserManager.AddToRoleAsync(user, selectRole.Name);
}
public virtual async Task<PagedList<TRole>> GetUserRolesAsync(string userId, int page = 1, int pageSize = 10)
{
var id = ConvertKeyFromString(userId);
var pagedList = new PagedList<TRole>();
var roles = from r in DbContext.Set<TRole>()
join ur in DbContext.Set<TUserRole>() on r.Id equals ur.RoleId
where ur.UserId.Equals(id)
select r;
var userIdentityRoles = await roles.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(userIdentityRoles);
pagedList.TotalCount = await roles.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<IdentityResult> DeleteUserRoleAsync(string userId, string roleId)
{
var role = await RoleManager.FindByIdAsync(roleId);
var user = await UserManager.FindByIdAsync(userId);
return await UserManager.RemoveFromRoleAsync(user, role.Name);
}
public virtual async Task<PagedList<TUserClaim>> GetUserClaimsAsync(string userId, int page, int pageSize)
{
var id = ConvertKeyFromString(userId);
var pagedList = new PagedList<TUserClaim>();
var claims = await DbContext.Set<TUserClaim>().Where(x => x.UserId.Equals(id))
.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(claims);
pagedList.TotalCount = await DbContext.Set<TUserClaim>().Where(x => x.UserId.Equals(id)).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TRoleClaim>> GetRoleClaimsAsync(string roleId, int page = 1, int pageSize = 10)
{
var id = ConvertKeyFromString(roleId);
var pagedList = new PagedList<TRoleClaim>();
var claims = await DbContext.Set<TRoleClaim>().Where(x => x.RoleId.Equals(id))
.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
pagedList.Data.AddRange(claims);
pagedList.TotalCount = await DbContext.Set<TRoleClaim>().Where(x => x.RoleId.Equals(id)).CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual async Task<PagedList<TRoleClaim>> GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10)
{
var id = ConvertKeyFromString(userId);
Expression<Func<TRoleClaim, bool>> searchCondition = x => x.ClaimType.Contains(claimSearchText);
var claimsQ = DbContext.Set<TUserRole>().Where(x => x.UserId.Equals(id))
.Join(DbContext.Set<TRoleClaim>().WhereIf(!string.IsNullOrEmpty(claimSearchText), searchCondition), ur => ur.RoleId, rc => rc.RoleId, (ur, rc) => rc);
var claims = await claimsQ.PageBy(x => x.Id, page, pageSize)
.ToListAsync();
var pagedList = new PagedList<TRoleClaim>();
pagedList.Data.AddRange(claims);
pagedList.TotalCount = await claimsQ.CountAsync();
pagedList.PageSize = pageSize;
return pagedList;
}
public virtual Task<TUserClaim> GetUserClaimAsync(string userId, int claimId)
{
var userIdConverted = ConvertKeyFromString(userId);
return DbContext.Set<TUserClaim>().Where(x => x.UserId.Equals(userIdConverted) && x.Id == claimId)
.SingleOrDefaultAsync();
}
public virtual Task<TRoleClaim> GetRoleClaimAsync(string roleId, int claimId)
{
var roleIdConverted = ConvertKeyFromString(roleId);
return DbContext.Set<TRoleClaim>().Where(x => x.RoleId.Equals(roleIdConverted) && x.Id == claimId)
.SingleOrDefaultAsync();
}
public virtual async Task<IdentityResult> CreateUserClaimsAsync(TUserClaim claims)
{
var user = await UserManager.FindByIdAsync(claims.UserId.ToString());
return await UserManager.AddClaimAsync(user, new Claim(claims.ClaimType, claims.ClaimValue));
}
public virtual async Task<IdentityResult> UpdateUserClaimsAsync(TUserClaim claims)
{
var user = await UserManager.FindByIdAsync(claims.UserId.ToString());
......@@ -316,12 +316,12 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories
await UserManager.RemoveClaimAsync(user, new Claim(userClaim.ClaimType, userClaim.ClaimValue));
return await UserManager.AddClaimAsync(user, new Claim(claims.ClaimType, claims.ClaimValue));
}
public virtual async Task<IdentityResult> CreateRoleClaimsAsync(TRoleClaim claims)
{
var role = await RoleManager.FindByIdAsync(claims.RoleId.ToString());
return await RoleManager.AddClaimAsync(role, new Claim(claims.ClaimType, claims.ClaimValue));
}
public virtual async Task<IdentityResult> CreateRoleClaimsAsync(TRoleClaim claims)
{
var role = await RoleManager.FindByIdAsync(claims.RoleId.ToString());
return await RoleManager.AddClaimAsync(role, new Claim(claims.ClaimType, claims.ClaimValue));
}
public virtual async Task<IdentityResult> UpdateRoleClaimsAsync(TRoleClaim claims)
......@@ -333,77 +333,77 @@ namespace Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories
return await RoleManager.AddClaimAsync(role, new Claim(claims.ClaimType, claims.ClaimValue));
}
public virtual async Task<IdentityResult> DeleteUserClaimAsync(string userId, int claimId)
{
var user = await UserManager.FindByIdAsync(userId);
var userClaim = await DbContext.Set<TUserClaim>().Where(x => x.Id == claimId).SingleOrDefaultAsync();
return await UserManager.RemoveClaimAsync(user, new Claim(userClaim.ClaimType, userClaim.ClaimValue));
}
public virtual async Task<IdentityResult> DeleteRoleClaimAsync(string roleId, int claimId)
{
var role = await RoleManager.FindByIdAsync(roleId);
var roleClaim = await DbContext.Set<TRoleClaim>().Where(x => x.Id == claimId).SingleOrDefaultAsync();
return await RoleManager.RemoveClaimAsync(role, new Claim(roleClaim.ClaimType, roleClaim.ClaimValue));
}
public virtual async Task<List<UserLoginInfo>> GetUserProvidersAsync(string userId)
{
var user = await UserManager.FindByIdAsync(userId);
var userLoginInfos = await UserManager.GetLoginsAsync(user);
return userLoginInfos.ToList();
}
public virtual Task<TUserLogin> GetUserProviderAsync(string userId, string providerKey)
{
var userIdConverted = ConvertKeyFromString(userId);
return DbContext.Set<TUserLogin>().Where(x => x.UserId.Equals(userIdConverted) && x.ProviderKey == providerKey)
.SingleOrDefaultAsync();
}
public virtual async Task<IdentityResult> DeleteUserProvidersAsync(string userId, string providerKey, string loginProvider)
{
var userIdConverted = ConvertKeyFromString(userId);
var user = await UserManager.FindByIdAsync(userId);
var login = await DbContext.Set<TUserLogin>().Where(x => x.UserId.Equals(userIdConverted) && x.ProviderKey == providerKey && x.LoginProvider == loginProvider).SingleOrDefaultAsync();
return await UserManager.RemoveLoginAsync(user, login.LoginProvider, login.ProviderKey);
}
public virtual async Task<IdentityResult> UserChangePasswordAsync(string userId, string password)
{
var user = await UserManager.FindByIdAsync(userId);
var token = await UserManager.GeneratePasswordResetTokenAsync(user);
return await UserManager.ResetPasswordAsync(user, token, password);
}
public virtual async Task<IdentityResult> DeleteUserAsync(string userId)
{
var userIdentity = await UserManager.FindByIdAsync(userId);
return await UserManager.DeleteAsync(userIdentity);
public virtual async Task<IdentityResult> DeleteUserClaimAsync(string userId, int claimId)
{
var user = await UserManager.FindByIdAsync(userId);
var userClaim = await DbContext.Set<TUserClaim>().Where(x => x.Id == claimId).SingleOrDefaultAsync();
return await UserManager.RemoveClaimAsync(user, new Claim(userClaim.ClaimType, userClaim.ClaimValue));
}
public virtual async Task<IdentityResult> DeleteRoleClaimAsync(string roleId, int claimId)
{
var role = await RoleManager.FindByIdAsync(roleId);
var roleClaim = await DbContext.Set<TRoleClaim>().Where(x => x.Id == claimId).SingleOrDefaultAsync();
return await RoleManager.RemoveClaimAsync(role, new Claim(roleClaim.ClaimType, roleClaim.ClaimValue));
}
public virtual async Task<List<UserLoginInfo>> GetUserProvidersAsync(string userId)
{
var user = await UserManager.FindByIdAsync(userId);
var userLoginInfos = await UserManager.GetLoginsAsync(user);
return userLoginInfos.ToList();
}
public virtual Task<TUserLogin> GetUserProviderAsync(string userId, string providerKey)
{
var userIdConverted = ConvertKeyFromString(userId);
return DbContext.Set<TUserLogin>().Where(x => x.UserId.Equals(userIdConverted) && x.ProviderKey == providerKey)
.SingleOrDefaultAsync();
}
public virtual async Task<IdentityResult> DeleteUserProvidersAsync(string userId, string providerKey, string loginProvider)
{
var userIdConverted = ConvertKeyFromString(userId);
var user = await UserManager.FindByIdAsync(userId);
var login = await DbContext.Set<TUserLogin>().Where(x => x.UserId.Equals(userIdConverted) && x.ProviderKey == providerKey && x.LoginProvider == loginProvider).SingleOrDefaultAsync();
return await UserManager.RemoveLoginAsync(user, login.LoginProvider, login.ProviderKey);
}
public virtual async Task<IdentityResult> UserChangePasswordAsync(string userId, string password)
{
var user = await UserManager.FindByIdAsync(userId);
var token = await UserManager.GeneratePasswordResetTokenAsync(user);
return await UserManager.ResetPasswordAsync(user, token, password);
}
public virtual async Task<IdentityResult> DeleteUserAsync(string userId)
{
var userIdentity = await UserManager.FindByIdAsync(userId);
return await UserManager.DeleteAsync(userIdentity);
}
public async Task<string> GeneratePasswordResetTokenAsync(TUser user)
{
return await UserManager.GeneratePasswordResetTokenAsync(user);
}
private async Task<int> AutoSaveChangesAsync()
{
return AutoSaveChanges ? await DbContext.SaveChangesAsync() : (int)SavedStatus.WillBeSavedExplicitly;
}
public virtual async Task<int> SaveAllChangesAsync()
{
return await DbContext.SaveChangesAsync();
}
}
}
private async Task<int> AutoSaveChangesAsync()
{
return AutoSaveChanges ? await DbContext.SaveChangesAsync() : (int)SavedStatus.WillBeSavedExplicitly;
}
public virtual async Task<int> SaveAllChangesAsync()
{
return await DbContext.SaveChangesAsync();
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common;
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories.Interfaces
{
public interface IIdentityRepository<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
{
Task<bool> ExistsUserAsync(string userId);
Task<bool> ExistsRoleAsync(string roleId);
Task<PagedList<TUser>> GetUsersAsync(string search, int page = 1, int pageSize = 10);
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Skoruba.IdentityServer4.Admin.EntityFramework.Extensions.Common;
namespace Skoruba.IdentityServer4.Admin.EntityFramework.Identity.Repositories.Interfaces
{
public interface IIdentityRepository<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
{
Task<bool> ExistsUserAsync(string userId);
Task<bool> ExistsRoleAsync(string roleId);
Task<PagedList<TUser>> GetUsersAsync(string search, int page = 1, int pageSize = 10);
Task<PagedList<TUser>> GetRoleUsersAsync(string roleId, string search, int page = 1, int pageSize = 10);
Task<PagedList<TUser>> GetClaimUsersAsync(string claimType, string claimValue, int page = 1, int pageSize = 10);
Task<PagedList<TRole>> GetRolesAsync(string search, int page = 1, int pageSize = 10);
Task<(IdentityResult identityResult, TKey roleId)> CreateRoleAsync(TRole role);
Task<TRole> GetRoleAsync(TKey roleId);
Task<List<TRole>> GetRolesAsync();
Task<(IdentityResult identityResult, TKey roleId)> UpdateRoleAsync(TRole role);
Task<TUser> GetUserAsync(string userId);
Task<(IdentityResult identityResult, TKey userId)> CreateUserAsync(TUser user);
Task<(IdentityResult identityResult, TKey userId)> UpdateUserAsync(TUser user);
Task<IdentityResult> DeleteUserAsync(string userId);
Task<IdentityResult> CreateUserRoleAsync(string userId, string roleId);
Task<PagedList<TRole>> GetUserRolesAsync(string userId, int page = 1, int pageSize = 10);
Task<IdentityResult> DeleteUserRoleAsync(string userId, string roleId);
Task<PagedList<TUserClaim>> GetUserClaimsAsync(string userId, int page = 1, int pageSize = 10);
Task<TUserClaim> GetUserClaimAsync(string userId, int claimId);
Task<IdentityResult> CreateUserClaimsAsync(TUserClaim claims);
Task<IdentityResult> UpdateUserClaimsAsync(TUserClaim claims);
Task<IdentityResult> DeleteUserClaimAsync(string userId, int claimId);
Task<List<UserLoginInfo>> GetUserProvidersAsync(string userId);
Task<IdentityResult> DeleteUserProvidersAsync(string userId, string providerKey, string loginProvider);
Task<TUserLogin> GetUserProviderAsync(string userId, string providerKey);
Task<IdentityResult> UserChangePasswordAsync(string userId, string password);
Task<IdentityResult> CreateRoleClaimsAsync(TRoleClaim claims);
Task<IdentityResult> UpdateRoleClaimsAsync(TRoleClaim claims);
Task<PagedList<TRoleClaim>> GetRoleClaimsAsync(string roleId, int page = 1, int pageSize = 10);
Task<PagedList<TRoleClaim>> GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10);
Task<TRoleClaim> GetRoleClaimAsync(string roleId, int claimId);
Task<IdentityResult> DeleteRoleClaimAsync(string roleId, int claimId);
Task<PagedList<TUser>> GetClaimUsersAsync(string claimType, string claimValue, int page = 1, int pageSize = 10);
Task<PagedList<TRole>> GetRolesAsync(string search, int page = 1, int pageSize = 10);
Task<(IdentityResult identityResult, TKey roleId)> CreateRoleAsync(TRole role);
Task<TRole> GetRoleAsync(TKey roleId);
Task<List<TRole>> GetRolesAsync();
Task<(IdentityResult identityResult, TKey roleId)> UpdateRoleAsync(TRole role);
Task<TUser> GetUserAsync(string userId);
Task<(IdentityResult identityResult, TKey userId)> CreateUserAsync(TUser user);
Task<(IdentityResult identityResult, TKey userId)> UpdateUserAsync(TUser user);
Task<IdentityResult> DeleteUserAsync(string userId);
Task<IdentityResult> CreateUserRoleAsync(string userId, string roleId);
Task<PagedList<TRole>> GetUserRolesAsync(string userId, int page = 1, int pageSize = 10);
Task<IdentityResult> DeleteUserRoleAsync(string userId, string roleId);
Task<PagedList<TUserClaim>> GetUserClaimsAsync(string userId, int page = 1, int pageSize = 10);
Task<TUserClaim> GetUserClaimAsync(string userId, int claimId);
Task<IdentityResult> CreateUserClaimsAsync(TUserClaim claims);
Task<IdentityResult> UpdateUserClaimsAsync(TUserClaim claims);
Task<IdentityResult> DeleteUserClaimAsync(string userId, int claimId);
Task<List<UserLoginInfo>> GetUserProvidersAsync(string userId);
Task<IdentityResult> DeleteUserProvidersAsync(string userId, string providerKey, string loginProvider);
Task<TUserLogin> GetUserProviderAsync(string userId, string providerKey);
Task<IdentityResult> UserChangePasswordAsync(string userId, string password);
Task<IdentityResult> CreateRoleClaimsAsync(TRoleClaim claims);
Task<IdentityResult> UpdateRoleClaimsAsync(TRoleClaim claims);
Task<PagedList<TRoleClaim>> GetRoleClaimsAsync(string roleId, int page = 1, int pageSize = 10);
Task<PagedList<TRoleClaim>> GetUserRoleClaimsAsync(string userId, string claimSearchText, int page = 1, int pageSize = 10);
Task<TRoleClaim> GetRoleClaimAsync(string roleId, int claimId);
Task<IdentityResult> DeleteRoleClaimAsync(string roleId, int claimId);
Task<IdentityResult> DeleteRoleAsync(TRole role);
Task<string> GeneratePasswordResetTokenAsync(TUser user);
bool AutoSaveChanges { get; set; }
Task<int> SaveAllChangesAsync();
}
bool AutoSaveChanges { get; set; }
Task<int> SaveAllChangesAsync();
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment