using CPRNIMS.Domain.Contracts.Account; using CPRNIMS.Domain.Services; using CPRNIMS.Domain.Services.Account; using CPRNIMS.Infrastructure.Dto.Account; using CPRNIMS.Infrastructure.Entities.Account; using CPRNIMS.Infrastructure.Entities.Common; using CPRNIMS.Infrastructure.Models; using CPRNIMS.Infrastructure.Models.Account; using CPRNIMS.Infrastructure.Models.Common; using CPRNIMS.Infrastructure.Security; using CPRNIMS.Infrastructure.ViewModel.Account; using CPRNIMS.WebApi.Security; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; namespace CPRNIMS.WebApi.Controllers.Account { [AuthorizeRoles("Account")] public class AccountController : Base.BaseController { private readonly ErrorMessageService _errorMessageService; private readonly IAttachment _attachment; private readonly IAccount _account; private readonly IDepartment _department; private readonly IControllerAccess _controllerAccess; private readonly UserManager _userManager; private readonly UserClaimsManager _userClaimsManager; private readonly RoleManager _roleManager; public AccountController(ErrorMessageService errorMessageService, IWebHostEnvironment webHostEnvironment, IConfiguration configuration, IAttachment attachment, IAccount account, IDepartment department, IControllerAccess controllerAccess, UserManager userManager, SignInManager signInManager, UserClaimsManager userClaimsManager, RoleManager roleManager ) : base(errorMessageService, webHostEnvironment, configuration) { _errorMessageService = errorMessageService; _attachment = attachment; _department = department; _controllerAccess = controllerAccess; _userManager = userManager; _userClaimsManager = userClaimsManager; _roleManager = roleManager; _account= account; } [HttpPost("RefreshToken")] public async Task RefreshToken() { var currentUser = User.ToUserClaims(); if (currentUser == null) return Unauthorized(); var user = new ApplicationUser { UserName = currentUser.UserName, }; var token = await _account.CreateToken(user); return Ok(new { token, expiresAt = DateTime.UtcNow.AddMinutes(30) }); } [HttpPut("UpdateUser")] public async Task UpdateUserProfile([FromBody] RegisterModel model) { try { var userCurrentDetails = await _userManager.FindByIdAsync(model.Id); // Check if the Password field is not empty if (!string.IsNullOrEmpty(model.PasswordHash)) { // Change the user's password var token = await _userManager.GeneratePasswordResetTokenAsync(userCurrentDetails); var passwordChangeResult = await _userManager.ResetPasswordAsync(userCurrentDetails, token, model.PasswordHash); if (!passwordChangeResult.Succeeded) { string passwordErrorMessage = passwordChangeResult.Errors?.FirstOrDefault().Description; return StatusCode(StatusCodes.Status500InternalServerError, new ResponseObject { statusResponse = "Error", message = passwordErrorMessage }); } } // Update other user details as needed, but exclude UserName userCurrentDetails.Email = model.Email; userCurrentDetails.UpdatedDate = DateTime.Now; userCurrentDetails.Company = model.Company; userCurrentDetails.FullName = model.FullName; userCurrentDetails.PhoneNumber = model.PhoneNumber; userCurrentDetails.Address = model.Address; userCurrentDetails.LockoutEnabled = model.LockoutEnabled; userCurrentDetails.UpdatedBy = model.UpdatedBy; //string myCurrentRole = userCurrentDetails.Role; //if (!String.IsNullOrEmpty(model.Role)) //{ // userCurrentDetails.Role = model.Role; //} var result = await _userManager.UpdateAsync(userCurrentDetails); if (!result.Succeeded) { string errorMessage = result.Errors.FirstOrDefault()?.Description; return StatusCode(StatusCodes.Status500InternalServerError, new ResponseObject { statusResponse = "Error", message = errorMessage }); } if (model.Attachment != null && !String.IsNullOrEmpty(model.Attachment.FileName) && !String.IsNullOrEmpty(model.Attachment.URL)) { var attachment = new Infrastructure.Entities.Account.Attachment { FileName = model.Attachment.FileName, URL = model.Attachment.URL, AttachmentId = model.Id, //ExtensionId = model.Attachment.ExtensionId, CreatedBy = model.UpdatedBy, CreatedDate = DateTime.Now, UpdatedBy = model.UpdatedBy, UpdatedDate = DateTime.Now, }; await _attachment.CreateUpdateAttachment(attachment, model.Id); } // Only Admin if (model.Role == "Admin" && !String.IsNullOrEmpty(model.Role)) { if (await _roleManager.RoleExistsAsync(model.Role)) { await _userManager.AddToRoleAsync(userCurrentDetails, model.Role); } await _userClaimsManager.UpdateCustomClaim(model, model.Role); } return Ok(new ResponseObject { statusResponse = "Success", message = "User updated successfully!" }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); await PostErrorMessage(message, "WebApi"); throw; } } [HttpGet("GetUserById/{userId}")] public async Task GetUserProfileById(string userId) { var userWithUrl = await _userManager.Users .Include(u => u.Attachment) .Where(u => u.Id == userId) .Select(u => new { u.Id, u.UserName, u.FullName, u.Email, u.Department, u.Company, u.LockoutEnabled, u.CreatedBy, u.PhoneNumber, u.Address, u.UpdatedBy, u.CreatedDate, u.UpdatedDate, URL = u.Attachment != null ? u.Attachment.URL : string.Empty }) .ToListAsync(); if (userWithUrl == null) { return NotFound(); } return Ok(userWithUrl); } [HttpGet("GetAllUser")] public async Task GetAllUsers() { var usersWithUrl = await _userClaimsManager.GetAllUsersProfile(); if (usersWithUrl == null) { return NotFound(); } return Ok(usersWithUrl); } [HttpPost("GetUserRolesClaims")] public async Task GetUserRolesClaims([FromBody] LoginModel model) { var user = await _userManager.Users .Include(u => u.Department) .SingleOrDefaultAsync(u => u.UserName == model.Username.ToLower()); if (user != null && await _userManager.CheckPasswordAsync(user, model.Password)) { var userRoles = await _userManager.GetRolesAsync(user); var roleDetails = await _roleManager.Roles .Where(r => userRoles.Contains(r.Name)) .Select(r => new { r.Id, r.Name }) .ToListAsync(); var myClaims = await _userManager.GetClaimsAsync(user); var authClaims = new List { new Claim(ClaimTypes.Name, user.UserName), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), }; var response = new UserClaimsResponse { UserId = user.Id, UserRoles = roleDetails.Select(r => new UserRoleData { RoleId = r.Id, RoleName = r.Name }).ToList(), OtherClaims = myClaims.Select(claim => new UserClaimData { issuer = claim.Issuer, originalIssuer = claim.OriginalIssuer, properties = claim.Properties.ToDictionary(p => p.Key, p => p.Value), subject = claim.Subject?.Name, type = claim.Type, value = claim.Value, valueType = claim.ValueType, company = user.Company, FullName = user.FullName, Department = user.Department?.Department, }).ToList() }; return Ok(response); } return Unauthorized(); } [HttpPost("GetTClaim")] public async Task GetTClaim([FromBody] LoginModel model) { var user = await _userManager.FindByNameAsync(model.Username.ToLower()); if (user != null && await _userManager.CheckPasswordAsync(user, model.Password)) { var userRoles = await _userManager.GetRolesAsync(user); try { var authClaims = new List { new Claim(ClaimTypes.Name, user.UserName), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), }; foreach (var userRole in userRoles) { authClaims.Add(new Claim(ClaimTypes.Role, userRole)); } var token = GetToken(authClaims); var roles = token.Claims .Where(c => c.Type == ClaimTypes.Role) .Select(c => c.Value) .ToList(); return Ok(new { roles }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); var error = new ErrorMessage { Application = "WebApi", Message = message, CreatedDate = DateTime.Now, CreatedBy = "Approval", }; await _errorMessageService.PostErrorMessage(error); throw; } } return Unauthorized(); } [HttpPost("register")] public async Task Register([FromBody] RegisterModel model) { var userExists = await _userManager.FindByNameAsync(model.UserName); if (userExists != null) { await UpdateUserProfile(model); return Ok(new ResponseObject { statusResponse = "Success", message = "User updated successfully!" }); } try { ApplicationUser user = new() { Email = model.Email, SecurityStamp = Guid.NewGuid().ToString(), UserName = model.UserName, CreatedBy = model.CreatedBy, CreatedDate = DateTime.Now, UpdatedBy = model.UpdatedBy, UpdatedDate = DateTime.Now, Company = model.Company, DepartmentId = model.DepartmentId, FullName = model.FullName, }; var result = await _userManager.CreateAsync(user, model.Password); if (!result.Succeeded) { string errorMessage = result.Errors.FirstOrDefault()?.Description; return StatusCode(StatusCodes.Status500InternalServerError, new ResponseObject { statusResponse = "Error", message = errorMessage }); } model.Id = user.Id; await _userClaimsManager.AssignUserRole(model); //Insert customClaim await _userClaimsManager.AddCustomClaim(model); return Ok(new ResponseObject { statusResponse = "Success", message = "User created successfully!" }); } catch (Exception ex) { var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); await PostErrorMessage(message, "WebApi"); throw; } } [HttpPost("GetLandingPageByUserId")] public async Task GetLandingPageByUserId(ControllerAccessVM model) { return await ExecuteWithErrorHandling( () => _controllerAccess.GetControllerAccessByUserId(model.UserId), nameof(GetLandingPageByUserId), false); } [HttpGet("GetAllRoles")] public async Task GetAllRoles() { var roles = await _roleManager.Roles.ToListAsync(); return Ok(roles); } [HttpGet("GetRoles")] public async Task GetRoles() { var roles = await _roleManager.Roles.Select(r => r.Name).ToListAsync(); return Ok(roles); } [HttpPost("GetDepartment")] public async Task GetDepartment() { var user = await _department.GetDepartment(); if (user != null) return Ok(user); else return NotFound(); } [HttpPost("GetUserRights")] public async Task GetUserRights(AccountDto accountDto) { var user = await _account.GetUserRights(accountDto); if (user != null) return Ok(user); else return NotFound(); } [HttpPost("PutPostUserAccess")] public async Task PutPostUserAccess([FromBody] UserRightsVM viewModel) { var itemDto = new AccountDto(); if (viewModel.UserRightsList != null) { foreach (var itemList in viewModel.UserRightsList.ContAccId) { var index = viewModel.UserRightsList.ContAccId.IndexOf(itemList); itemDto = new AccountDto { ContAccId = viewModel.UserRightsList.ContAccId[index], UserAccessId = viewModel.UserRightsList.UserAccessId[index], AccessTypeId = viewModel.UserRightsList.AccessTypeId[index], IsActive = viewModel.UserRightsList.IsActive[index], AdminUserId = viewModel.AdminUserId, UserId = viewModel.UserId }; await _account.PutPostUserAccess(itemDto); } return Ok(itemDto); } return BadRequest(new { success = false, messCode = 0, message = "Your email has not yet been configured. Please go to the SMTP page." }); } [HttpPost("CreateUpdateRole")] public async Task CreateUpdateRole([FromBody] UserRoleModel model) { var existingRole = await _roleManager.FindByIdAsync(model.Id); if (existingRole != null) { existingRole.Name = model.Name; // Update the role name var result = await _roleManager.UpdateAsync(existingRole); if (!result.Succeeded) { string errorMessage = result.Errors.FirstOrDefault()?.Description; return StatusCode(StatusCodes.Status500InternalServerError, new ResponseObject { statusResponse = "Error", message = errorMessage }); } return Ok(new ResponseObject { statusResponse = "Success", message = "Role updated successfully!" }); } else { var result = await _roleManager.CreateAsync(new IdentityRole(model.Name)); if (!result.Succeeded) { string errorMessage = result.Errors.FirstOrDefault()?.Description; return StatusCode(StatusCodes.Status500InternalServerError, new ResponseObject { statusResponse = "Error", message = errorMessage }); } } return Ok(new ResponseObject { statusResponse = "Success", message = "Role created successfully!" }); } } }