Api/Netina.Core/EntityServices/UserService.cs

435 lines
18 KiB
C#

namespace Netina.Core.EntityServices;
public class UserService(
ICurrentUserService currentUserService,
UserManager<ApplicationUser> userManager,
RoleManager<ApplicationRole> roleManager,
IExternalFilesService externalFilesService,
IRepositoryWrapper repositoryWrapper)
: IUserService
{
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();
response.User = new ApplicationUserSDto();
var userRoles = await userManager.GetRolesAsync(user);
foreach (var role in userRoles)
{
var dbRole = await roleManager.FindByNameAsync(role);
if (dbRole != null)
{
var roleClaims = await roleManager.GetClaimsAsync(dbRole);
response.Permissions.AddRange(roleClaims.Where(c => c.Type == "Permission").Select(c => c.Value).ToList());
}
}
response.Roles = userRoles.ToList();
return response;
}
public async Task<List<ApplicationUserSDto>> GetUsersAsync(int page = 0, string? phoneNumber = null, CancellationToken cancellationToken = default)
{
List<ApplicationUserSDto> users;
if (phoneNumber == null || phoneNumber.IsNullOrEmpty())
users = await userManager.Users
.Where(u => u.UserName != "09214802813")
.Skip(page * 15).Take(15)
.Select(ApplicationUserMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
else
users = await userManager.Users
.Where(a => a.PhoneNumber == phoneNumber && a.UserName != "09214802813")
.Skip(page * 15).Take(15)
.Select(ApplicationUserMapper.ProjectToSDto)
.ToListAsync(cancellationToken);
foreach (var user in users)
{
var roles = await userManager.GetRolesAsync(user.AdaptToApplicationUser());
foreach (var roleName in roles)
{
var role = await roleManager.FindByNameAsync(roleName);
if (role != null)
user.RoleName += role.PersianName + " ";
}
}
var returnUser = users.Where(r => r.FullName.Trim() != "همه کاره سیستم").ToList();
return returnUser;
}
public async Task<ApplicationUserSDto> GetUserAsync(Guid userId, CancellationToken cancellationToken = default)
{
var user = await userManager.FindByIdAsync(userId.ToString());
if (user == null)
throw new AppException("User not found", ApiResultStatusCode.NotFound);
var dto = user.AdaptToSDto();
dto.IsMarketer = await repositoryWrapper.SetRepository<Marketer>()
.TableNoTracking
.AnyAsync(m => m.UserId == userId, cancellationToken);
dto.IsManager = await repositoryWrapper.SetRepository<Manager>()
.TableNoTracking
.AnyAsync(m => m.UserId == userId, cancellationToken);
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, CancellationToken cancellationToken = default)
{
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)
{
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)));
}
if (request.RoleIds.Count > 0)
{
foreach (var roleId in request.RoleIds)
{
var role = await roleManager.FindByIdAsync(roleId.ToString());
if (role is { Name: not null })
await userManager.AddToRoleAsync(user, role.Name);
}
}
var customer = await repositoryWrapper.SetRepository<Customer>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == user.Id, cancellationToken);
if (customer != null)
{
repositoryWrapper.SetRepository<Customer>()
.Add(new Customer
{
UserId = user.Id
});
await repositoryWrapper.SaveChangesAsync(default);
}
repositoryWrapper.SetRepository<Manager>()
.Add(new Manager
{
UserId = user.Id
});
await repositoryWrapper.SaveChangesAsync(default);
}
return user;
}
public async Task<bool> EditUserAsync(UserActionRequestDto request, CancellationToken cancellationToken)
{
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)));
}
if (request.RoleIds.Count > 0)
{
var userRoles = await userManager.GetRolesAsync(user);
await userManager.RemoveFromRolesAsync(user, userRoles);
foreach (var roleId in request.RoleIds)
{
var role = await roleManager.FindByIdAsync(roleId.ToString());
if (role is { Name: not null })
{
await userManager.AddToRoleAsync(user, role.Name);
}
}
}
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)
{
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);
var removeResult = await userManager.DeleteAsync(user);
if (!removeResult.Succeeded)
throw new AppException(string.Join('|', removeResult.Errors.Select(e => e.Description)));
var customer = await repositoryWrapper.SetRepository<Customer>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken);
if (customer != null)
{
repositoryWrapper.SetRepository<Customer>()
.Delete(customer);
await repositoryWrapper.SaveChangesAsync(default);
}
var manager = await repositoryWrapper.SetRepository<Manager>()
.TableNoTracking
.FirstOrDefaultAsync(c => c.UserId == userId, cancellationToken);
if (manager != null)
{
repositoryWrapper.SetRepository<Manager>()
.Delete(manager);
await repositoryWrapper.SaveChangesAsync(default);
}
return true;
}
public async Task<AdminChangeLogResponseDto> GetAdminChangeLogAsync(CancellationToken cancellationToken = default)
{
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 manager = await repositoryWrapper.SetRepository<Manager>()
.TableNoTracking
.FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken);
var currentVersion = await externalFilesService.GetAdminChangeLogAsync(cancellationToken);
if (manager != null)
{
if (!(manager.LatestVersionUsed < currentVersion.VersionNumber)) return currentVersion;
currentVersion.IsNewVersion = true;
manager.LatestVersionUsed = currentVersion.VersionNumber;
repositoryWrapper.SetRepository<Manager>()
.Update(manager);
await repositoryWrapper.SaveChangesAsync(cancellationToken);
}
return currentVersion;
}
public async Task<List<ApplicationRole>> GetRolesAsync(int page = 0, CancellationToken cancellationToken = default)
{
var roles = await roleManager.Roles
.Where(r => r.Name != "RootAdmin")
.Skip(page * 15)
.Take(15)
.ToListAsync(cancellationToken);
return roles;
}
public async Task<List<ApplicationRole>> GetRolesAsync(int? page, string? roleName, CancellationToken cancellationToken = default)
{
IQueryable<ApplicationRole> roles;
if (roleName != null)
roles = roleManager.Roles.Where(r => r.Name != "RootAdmin" && r.Name != "Customer" && r.PersianName.Trim().ToLower().Contains(roleName));
else
roles = roleManager.Roles.Where(r => r.Name != "RootAdmin" && r.Name != "Customer");
if (page != null)
roles = roles.Skip(page.Value * 15).Take(15);
else
roles = roles;
return await roles.ToListAsync(cancellationToken);
}
public async Task<RoleActionRequestDto> GetRoleAsync(Guid roleId, CancellationToken cancellationToken = default)
{
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, CancellationToken cancellationToken = default)
{
if (request.EnglishName.IsNullOrEmpty())
throw new AppException("لطفا نام انگلیسی را وارد کنید");
var applicationRole = new ApplicationRole
{
EnglishName = request.EnglishName,
PersianName = request.PersianName,
Description = request.Description,
Name = $"{request.EnglishName}"
};
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, CancellationToken cancellationToken = default)
{
if (request.EnglishName.IsNullOrEmpty())
throw new AppException("لطفا نام انگلیسی را وارد کنید");
var applicationRole = await roleManager.FindByIdAsync(request.RoleId.ToString());
if (applicationRole == null)
throw new AppException("نقش پیدا نشد");
applicationRole.EnglishName = request.EnglishName;
applicationRole.PersianName = request.PersianName;
applicationRole.Description = request.Description;
applicationRole.Name = $"{request.EnglishName}";
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())
{
var removeResult = await roleManager.RemoveClaimAsync(applicationRole, roleClaim);
if (!removeResult.Succeeded)
throw new AppException(string.Join(" | ", removeResult.Errors.Select(e => e.Description)));
}
foreach (var claim in request.Permissions)
{
var addResult = await roleManager.AddClaimAsync(applicationRole, new Claim(CustomClaimType.Permission, claim));
if (!addResult.Succeeded)
throw new AppException(string.Join(" | ", addResult.Errors.Select(e => e.Description)));
}
return true;
}
public async Task<bool> RemoveRoleAsync(Guid roleId, CancellationToken cancellationToken = default)
{
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 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;
}
}