Api/Brizco.Core/EntityServices/UserService.cs

485 lines
21 KiB
C#

using System.Security.Claims;
using Brizco.Domain.CommandQueries.Queries;
using Brizco.Domain.Mappers;
using Mapster;
namespace Brizco.Core.EntityServices;
public class UserService : IUserService
{
private readonly ICurrentUserService _currentUserService;
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<ApplicationRole> _roleManager;
private readonly ISender _sender;
private readonly IRepositoryWrapper _repositoryWrapper;
private readonly IJwtService _jwtService;
public UserService(ICurrentUserService currentUserService,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
ISender sender,
IRepositoryWrapper repositoryWrapper,
IJwtService jwtService)
{
_currentUserService = currentUserService;
_userManager = userManager;
_roleManager = roleManager;
_sender = sender;
_repositoryWrapper = repositoryWrapper;
_jwtService = jwtService;
}
public async Task<ProfileResponseDto> GetUserProfileAsync(CancellationToken cancellationToken)
{
if (!Guid.TryParse(_currentUserService.UserId, out var userId))
throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized);
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User NotFound", ApiResultStatusCode.NotFound);
var response = new ProfileResponseDto();
var userSDto = user.AdaptToSDto();
var complexUsers = await GetUserRolesAsync(cancellationToken);
response.User = userSDto;
if (user.SelectedComplexUserRoleId != Guid.Empty)
{
var complexUserRole = complexUsers.FirstOrDefault(cu => cu.Id == user.SelectedComplexUserRoleId);
userSDto.SelectedComplexName = complexUserRole!.ComplexName;
userSDto.SelectedRoleName = complexUserRole!.RoleName;
response.User.SelectedRoleId = complexUserRole!.Id;
var role = await _roleManager.FindByIdAsync(complexUserRole.RoleId.ToString());
if (role != null)
{
var roleClaims = await _roleManager.GetClaimsAsync(role);
response.Permissions = roleClaims.Where(c => c.Type == "Permission").Select(c => c.Value).ToList();
}
}
response.Roles = complexUsers;
return response;
}
public async Task<AccessToken<ApplicationUserSDto, ComplexUserRoleSDto>> ChangeUserRoleAsync(Guid roleId, CancellationToken cancellationToken)
{
if (!Guid.TryParse(_currentUserService.UserId, out var userId))
throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized);
AccessToken<ApplicationUserSDto, ComplexUserRoleSDto> jwt;
var complexUserRole = await _repositoryWrapper.SetRepository<ComplexUserRole>()
.TableNoTracking
.Where(c => c.Id == roleId)
.Select(ComplexUserRoleMapper.ProjectToSDto)
.FirstOrDefaultAsync(cancellationToken);
if (complexUserRole == null)
throw new AppException("Role not found", ApiResultStatusCode.NotFound);
var complexUser = await _repositoryWrapper.SetRepository<ComplexUser>()
.TableNoTracking
.Where(mcu => mcu.Id == complexUserRole.ComplexUserId)
.Select(ComplexUserMapper.ProjectToSDto)
.FirstOrDefaultAsync(cancellationToken);
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
if (complexUser?.UserId != user.Id)
throw new AppException("User role is wrong", ApiResultStatusCode.BadRequest);
user.SelectedComplexUserRoleId = complexUserRole.Id;
await _userManager.UpdateAsync(user);
jwt = (await _jwtService.Generate<ApplicationUserSDto, ApplicationUser>(user, complexUser.ComplexId, complexUserRole.RoleId)).Adapt<AccessToken<ApplicationUserSDto, ComplexUserRoleSDto>>();
jwt.User.SelectedComplexName = complexUser.ComplexName;
jwt.User.SelectedRoleName = complexUserRole.RoleName;
jwt.User.SelectedRoleId = complexUserRole.Id;
jwt.Roles = await GetUserRolesAsync(cancellationToken);
return jwt;
}
public async Task<List<ComplexUserRoleSDto>> GetUserRolesAsync(CancellationToken cancellationToken)
{
if (!Guid.TryParse(_currentUserService.UserId, out var userId))
throw new AppException("Wrong Token", ApiResultStatusCode.UnAuthorized);
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User NotFound", ApiResultStatusCode.NotFound);
var response = new List<ComplexUserRoleSDto>();
var complexUsers = await _repositoryWrapper.SetRepository<ComplexUser>()
.TableNoTracking
.Where(mcu => mcu.UserId == user.Id)
.Select(ComplexUserMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
if (complexUsers.Count == 0)
return response;
foreach (var complexUser in complexUsers)
{
var complexUserRoles = await _repositoryWrapper.SetRepository<ComplexUserRole>()
.TableNoTracking
.Where(c => c.ComplexUserId == complexUser.Id)
.Select(ComplexUserRoleMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
foreach (var userRole in complexUserRoles)
{
userRole.ComplexName = complexUser.ComplexName;
response.Add(userRole);
}
}
return response;
}
public async Task<List<ComplexUserRoleSDto>> GetUserRolesAsync(Guid userId,CancellationToken cancellationToken)
{
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User NotFound", ApiResultStatusCode.NotFound);
var response = new List<ComplexUserRoleSDto>();
var complexUsers = await _repositoryWrapper.SetRepository<ComplexUser>()
.TableNoTracking
.Where(mcu => mcu.UserId == user.Id)
.Select(ComplexUserMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
if (complexUsers.Count == 0)
return response;
foreach (var complexUser in complexUsers)
{
var complexUserRoles = await _repositoryWrapper.SetRepository<ComplexUserRole>()
.TableNoTracking
.Where(c => c.ComplexUserId == complexUser.Id)
.Select(ComplexUserRoleMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
foreach (var userRole in complexUserRoles)
{
userRole.ComplexName = complexUser.ComplexName;
response.Add(userRole);
}
}
return response;
}
public async Task<List<ComplexUserSDto>> GetUsersAsync(int page = 0, CancellationToken cancellationToken = default)
{
if (_currentUserService.ComplexId.IsNullOrEmpty())
throw new AppException("Wrong authorize token , ComplexId needed");
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("Wrong authorize token , ComplexId needed");
var complexUsers = await _sender.Send(new GetComplexUsersQuery(complexId.ToString(), page), cancellationToken);
return complexUsers;
}
public async Task<ApplicationUserSDto> GetUserAsync(Guid userId)
{
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
var dto = user.AdaptToSDto();
var roles = await _userManager.GetRolesAsync(user);
foreach (var roleName in roles)
{
var role = await _roleManager.FindByNameAsync(roleName);
if (role != null)
dto.RoleIds.Add(role.Id);
}
return dto;
}
public async Task<ApplicationUser> CreateUserAsync(string phoneNumber)
{
var user = new ApplicationUser
{
UserName = phoneNumber,
PhoneNumber = phoneNumber,
SignUpStatus = SignUpStatus.StartSignOn
};
var result = await _userManager.CreateAsync(user);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors));
return user;
}
public async Task<ApplicationUser> CreateUserAsync(UserActionRequestDto request, CancellationToken cancellationToken)
{
if (_currentUserService.ComplexId.IsNullOrEmpty())
throw new AppException("Wrong authorize token , ComplexId needed");
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("Wrong authorize token , ComplexId needed");
var user = await _userManager.FindByNameAsync(request.PhoneNumber);
if (user == null)
{
user = new ApplicationUser
{
UserName = request.PhoneNumber,
PhoneNumber = request.PhoneNumber,
FirstName = request.FirstName,
LastName = request.LastName,
NationalId = request.NationalId,
BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDateTimeStamp),
Gender = request.Gender,
SignUpStatus = SignUpStatus.SignUpCompleted,
PhoneNumberConfirmed = true
};
if (!request.Password.IsNullOrEmpty())
{
var result = await _userManager.CreateAsync(user, request.Password);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
}
else
{
var result = await _userManager.CreateAsync(user);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
}
}
await _sender.Send(new CreateComplexUserCommand(complexId, user.Id, request.RoleIds), cancellationToken);
return user;
}
public async Task<bool> EditUserAsync(UserActionRequestDto request, CancellationToken cancellationToken)
{
if (_currentUserService.ComplexId.IsNullOrEmpty())
throw new AppException("Wrong authorize token , ComplexId needed");
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("Wrong authorize token , ComplexId needed");
if (request.UserId == Guid.Empty)
throw new AppException("Wrong authorize token , UserId needed");
var user = await _userManager.FindByIdAsync(request.UserId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
user.LastName = request.LastName;
user.FirstName = request.FirstName;
user.UserName = request.PhoneNumber;
user.PhoneNumber = request.PhoneNumber;
user.FirstName = request.FirstName;
user.LastName = request.LastName;
user.NationalId = request.NationalId;
user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDateTimeStamp);
user.Gender = request.Gender;
var result = await _userManager.UpdateAsync(user);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
if (!request.Password.IsNullOrEmpty())
{
if (await _userManager.HasPasswordAsync(user))
await _userManager.RemovePasswordAsync(user);
var addPassResult = await _userManager.AddPasswordAsync(user, request.Password);
if (!addPassResult.Succeeded)
throw new AppException(string.Join('|', addPassResult.Errors.Select(e => e.Description)));
}
await _sender.Send(new UpdateComplexUserCommand(user.Id, complexId, request.RoleIds), cancellationToken);
return true;
}
public async Task<bool> EditUserProfileAsync(UserActionRequestDto request, CancellationToken cancellationToken)
{
if (_currentUserService.UserId == null)
throw new AppException("Wrong authorize token , UserId needed");
var user = await _userManager.FindByIdAsync(_currentUserService.UserId);
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
user.LastName = request.LastName;
user.FirstName = request.FirstName;
user.UserName = request.PhoneNumber;
user.PhoneNumber = request.PhoneNumber;
user.FirstName = request.FirstName;
user.LastName = request.LastName;
user.NationalId = request.NationalId;
user.BirthDate = DateTimeExtensions.UnixTimeStampToDateTime(request.BirthDateTimeStamp);
user.Gender = request.Gender;
var result = await _userManager.UpdateAsync(user);
if (!result.Succeeded)
throw new AppException(string.Join('|', result.Errors.Select(e => e.Description)));
if (!request.Password.IsNullOrEmpty())
{
if (await _userManager.HasPasswordAsync(user))
await _userManager.RemovePasswordAsync(user);
var addPassResult = await _userManager.AddPasswordAsync(user, request.Password);
if (!addPassResult.Succeeded)
throw new AppException(string.Join('|', addPassResult.Errors.Select(e => e.Description)));
}
return true;
}
public async Task<bool> RemoveUserAsync(Guid userId, CancellationToken cancellationToken)
{
if (_currentUserService.ComplexId.IsNullOrEmpty())
throw new AppException("Wrong authorize token , ComplexId needed");
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("Wrong authorize token , ComplexId needed");
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
var roles = await _userManager.GetRolesAsync(user);
await _userManager.RemoveFromRolesAsync(user, roles);
await _sender.Send(new DeleteComplexUserCommand(userId, complexId), cancellationToken);
var removeResult = await _userManager.DeleteAsync(user);
if (!removeResult.Succeeded)
throw new AppException(string.Join('|', removeResult.Errors.Select(e => e.Description)));
return true;
}
public async Task<bool> RemoveUserFromComplexAsync(Guid userId, CancellationToken cancellationToken)
{
if (_currentUserService.ComplexId.IsNullOrEmpty())
throw new AppException("Wrong authorize token , ComplexId needed");
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("Wrong authorize token , ComplexId needed");
var user = await _userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
await _sender.Send(new DeleteComplexUserCommand(userId, complexId), cancellationToken);
return true;
}
public async Task<List<ApplicationRole>> GetRolesAsync(int page = 0, CancellationToken cancellationToken = default)
{
if (_currentUserService.ComplexId.IsNullOrEmpty())
throw new AppException("Wrong authorize token , ComplexId needed");
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("Wrong authorize token , ComplexId needed");
var roles = await _roleManager.Roles
.Where(r => r.ComplexId == complexId)
.Skip(page * 15)
.Take(15)
.ToListAsync(cancellationToken);
return roles;
}
public async Task<RoleActionRequestDto> GetRoleAsync(Guid roleId)
{
var role = (await _roleManager.FindByIdAsync(roleId.ToString()));
if (role == null)
throw new AppException("نقش پیدا نشد", ApiResultStatusCode.NotFound);
var roleDto = role.Adapt<RoleActionRequestDto>();
roleDto.RoleId = roleId;
roleDto.Permissions = (await _roleManager.GetClaimsAsync(role))
.Where(c => c.Type == CustomClaimType.Permission)
.Select(c => c.Value)
.ToList();
return roleDto;
}
public async Task<ApplicationRole> CreateRoleAsync(RoleActionRequestDto request)
{
if (_currentUserService.ComplexId.IsNullOrEmpty())
throw new AppException("Wrong authorize token , ComplexId needed");
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("Wrong authorize token , ComplexId wrong");
if (request.EnglishName.IsNullOrEmpty())
throw new AppException("لطفا نام انگلیسی را وارد کنید");
var applicationRole = new ApplicationRole
{
ComplexId = complexId,
EnglishName = request.EnglishName,
PersianName = request.PersianName,
Description = request.Description,
Name = $"{request.EnglishName}_{complexId.ToString()}"
};
var createRoleResult = await _roleManager.CreateAsync(applicationRole);
if (!createRoleResult.Succeeded)
throw new AppException(string.Join('|', createRoleResult.Errors));
foreach (var claim in request.Permissions)
await _roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim));
return applicationRole;
}
public async Task<bool> EditRoleAsync(RoleActionRequestDto request)
{
if (_currentUserService.ComplexId.IsNullOrEmpty())
throw new AppException("Wrong authorize token , ComplexId needed");
if (!Guid.TryParse(_currentUserService.ComplexId, out Guid complexId))
throw new AppException("Wrong authorize token , ComplexId wrong");
if (request.EnglishName.IsNullOrEmpty())
throw new AppException("لطفا نام انگلیسی را وارد کنید");
var applicationRole = await _roleManager.FindByIdAsync(request.RoleId.ToString());
if (applicationRole == null)
throw new AppException("نقش پیدا نشد");
applicationRole.ComplexId = complexId;
applicationRole.EnglishName = request.EnglishName;
applicationRole.PersianName = request.PersianName;
applicationRole.Description = request.Description;
applicationRole.Name = $"{request.EnglishName}_{complexId.ToString()}";
var createRoleResult = await _roleManager.UpdateAsync(applicationRole);
if (!createRoleResult.Succeeded)
throw new AppException(string.Join('|', createRoleResult.Errors));
var roleClaims = (await _roleManager.GetClaimsAsync(applicationRole)).Where(c => c.Type == CustomClaimType.Permission).ToList();
foreach (var roleClaim in roleClaims.ToList())
{
if (request.Permissions.Contains(roleClaim.Value))
{
roleClaims.Remove(roleClaim);
request.Permissions.Remove(roleClaim.Value);
}
}
foreach (var claim in request.Permissions)
await _roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim));
foreach (var claim in roleClaims)
await _roleManager.RemoveClaimAsync(applicationRole, claim);
return true;
}
public async Task<bool> RemoveRoleAsync(Guid roleId)
{
var applicationRole = await _roleManager.FindByIdAsync(roleId.ToString());
if (applicationRole == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
var claims = await _roleManager.GetClaimsAsync(applicationRole);
foreach (var claim in claims)
await _roleManager.RemoveClaimAsync(applicationRole, claim);
var users = await _userManager.GetUsersInRoleAsync(applicationRole.Name);
foreach (var user in users)
await _userManager.RemoveFromRoleAsync(user, applicationRole.Name);
var complexRoles = await _repositoryWrapper.SetRepository<ComplexUserRole>()
.TableNoTracking
.Where(r => r.RoleId == applicationRole.Id)
.ToListAsync();
foreach (var complexRole in complexRoles)
{
_repositoryWrapper.SetRepository<ComplexUserRole>()
.HardDelete(complexRole);
await _repositoryWrapper.SaveChangesAsync(default);
}
var removeResult = await _roleManager.DeleteAsync(applicationRole);
if (!removeResult.Succeeded)
throw new AppException(string.Join('|', removeResult.Errors.Select(e => e.Description)));
return true;
}
public List<ClaimDto> GetPermissions()
{
return ApplicationClaims.AllClaimDtos;
}
}