using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using PSTW_CentralSystem.DBContext; using PSTW_CentralSystem.Models; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Text.Json; namespace PSTW_CentralSystem.Controllers.API { [ApiController] [Route("[controller]")] public class IdentityAPI : Controller { private readonly ILogger _logger; private readonly CentralSystemContext _identityDbContext; private readonly UserManager _userManager; private readonly SignInManager _signInManager; // Communication Key for API. Not API authentication key private readonly string _commKey = "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF4NW42anlkNlpTYzZNSE1Zem9qaApUbldpYTIra2pud2ZNbVhpSWlyK0RadjM2cEVGMGhRUWFLaWpaMWtyMGNiT25Ha2d2QnNwTzNiYkFua0E3SWwzCk4zM3NNYWdQV0JOQzZyVm1jT04zNEhDSWJCM0hvQXFYQUtkSHFUOGZneklMRzFhRzdxK2h4RDZhZzZsemhTMnEKdDA1bHdNc0hONWpOdmVNNnFWalRnTVB4aEFOMUhnUTkrd1lRWFh5bnZYYUo5OUNySHBqS21WdUt2VUh6WXdlRwp6SnBtYXZOclc4bE9oM1lMeVNuUVU5bjRrdURubGc1OWNHeUtKbzJ2YUxZbll4MkR1ZDNabzBXMHRMWGd0dlQyCjVXdVFsY0NVbldvaVpBV1JBTGI3anRpcTF0MGY5eVBiV2gxYXpMMjFoL3QvckJUMXNCL2FQd2kzRCt3MnBUR00KeVFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg=="; public IdentityAPI(ILogger logger, CentralSystemContext authDbContext, UserManager userManager, SignInManager signInManager) { _logger = logger; _identityDbContext = authDbContext; _userManager = userManager; _signInManager = signInManager; } #region User [HttpPost("GetUserInformation")] public async Task GetUserInformation() { try { var user = await _userManager.GetUserAsync(User); var userRole = await _userManager.GetRolesAsync(user!); if (user == null) { return NotFound(new { message = $"Unable to load user with ID '{_userManager.GetUserId(User)}'." }); } var storeId = await _identityDbContext.InventoryMasters.Where(s => s.UserId == user.Id).Select(s => s.StoreId).FirstOrDefaultAsync(); var userInfo = await _identityDbContext.Users.Include(u => u.Department) .Include(u => u.Store) .Select(u => new { id = u.Id, email = u.NormalizedEmail, company = u.Department!.Company!.CompanyName, department = u.Department, role = userRole, store = storeId != 0 ? storeId : (int?)null }).Where(u => u.id == user.Id).FirstOrDefaultAsync(); if (userInfo == null) { return NotFound(new { message = "User not found" }); } return Ok(new { UserInfo = userInfo }); } catch (Exception ex) { return StatusCode(500, $"An error occurred: {ex.Message}"); } } [HttpPost("GetTechnicianUserInformation")] public async Task GetTechnicianUserInformation() { try { var users = await _identityDbContext.Users .Include(u => u.Department) .ToListAsync(); // Retrieve all users with department info var technicianUsers = new List(); foreach (var user in users) { var roles = await _userManager.GetRolesAsync(user); if (roles.Contains("Technician")) { technicianUsers.Add(new { id = user.Id, fullname = user.FullName, department = user.Department }); } } if (!technicianUsers.Any()) { return NotFound(new { message = "No technicians found" }); } return Ok(new { technicianUsers = technicianUsers }); } catch (Exception ex) { return StatusCode(500, new { message = $"An error occurred: {ex.Message}" }); } } #endregion User #region LDAP Login [HttpPost("LdapLogin")] public async Task LdapLogin([FromBody] LdapLoginCredential ldapLoginInfo) { if (!ModelState.IsValid) { return BadRequest(ModelState); } byte[] noFormatString = Convert.FromBase64String(_commKey); string initUrlKey = Encoding.UTF8.GetString(noFormatString); string jsonData = JsonSerializer.Serialize(ldapLoginInfo); RSA rsaBase = RSA.Create(); rsaBase.ImportFromPem(initUrlKey.ToCharArray()); byte[] rsaData = rsaBase.Encrypt(Encoding.UTF8.GetBytes(jsonData), RSAEncryptionPadding.Pkcs1); string rsaDataBase64 = Convert.ToBase64String(rsaData); string ldapUrl = "http://192.168.11.231/api/ldap/"; string ldapUrlResult = ""; using (HttpClient httpClient = new HttpClient()) { try { StringContent rsaDataB64HttpContent = new(rsaDataBase64, Encoding.UTF8); HttpResponseMessage ldapUrlResponse = await httpClient.PostAsync(ldapUrl, rsaDataB64HttpContent); ldapUrlResponse.EnsureSuccessStatusCode(); if (ldapUrlResponse.IsSuccessStatusCode) { ldapUrlResult = await ldapUrlResponse.Content.ReadAsStringAsync(); } } catch (Exception e) { return BadRequest(new { Message = $"Message: {e.Message}\nException Caught!" }); } } userLdapInfo userLdapInfo = JsonSerializer.Deserialize(ldapUrlResult)!; if (!userLdapInfo.Authenticated) { return BadRequest(new { Message = $"Login Failed. {userLdapInfo.Response}" }); } userInfo userInfo = userLdapInfo.UserInfo!; UserModel ldapuser = new UserModel() { FullName = userInfo!.Username, UserName = userInfo.Email, NormalizedUserName = userInfo.Email.ToUpper(), Email = userInfo.Email, NormalizedEmail = userInfo.Email.ToUpper(), EmailConfirmed = true, PhoneNumberConfirmed = false, TwoFactorEnabled = false, LockoutEnabled = false, AccessFailedCount = 0, }; var existUser = await doUserExists(ldapuser.Email); if (existUser == null) { await _userManager.CreateAsync(ldapuser); await _signInManager.SignInAsync(ldapuser, false); return Ok(new { RedirectUrl = Url.Action("ComDeptAssignment", "Identity") }); }; await _signInManager.SignInAsync(existUser, false); if (existUser.UserInfoStatus == null || existUser.UserInfoStatus == 0) { return Ok(new { RedirectUrl = Url.Action("ComDeptAssignment", "Identity") }); } return Ok(new { RedirectUrl = Url.Action("Index", "Home") }); } #endregion LDAP Login #region Company [HttpPost("CompanyDepartmentList")] public async Task CompanyDepartmentList() { var companyList = await _identityDbContext.Companies .Include(c => c.Departments) .Select(c => new { c.CompanyId, c.CompanyName, Departments = c.Departments .OrderBy(d => d.DepartmentId) .Select(d => new { d.DepartmentId, d.DepartmentName }) }) .ToListAsync(); return Json(companyList); } #endregion Company #region Department [HttpPost("DepartmentCompanyList")] public async Task DepartmentCompanyList() { var itemDepartment = await _identityDbContext.Departments .Include(d => d.Company) // Include the related Company entity .Select(d => new { d.DepartmentId, d.DepartmentName, d.CompanyId, d.Company.CompanyName, }) .ToListAsync(); //return Json(await GetDepartmentWithCompanyList()); return Json(itemDepartment); } [HttpPost("UserComptDeptAssignment/{id}")] public async Task UserComptDeptAssignment([FromBody] UserDeptAssignment userDeptAssignment, int id) { var deptId = userDeptAssignment.departmentId; if (deptId <= 0) { return BadRequest(new { message = "Invalid department ID provided." }); } var user = await _userManager.FindByIdAsync(id.ToString()); if(user == null) { return NotFound( new { message = $"Unable to load user with ID '{id}'." }); } user.UserInfoStatus = 0; user.departmentId = deptId; await _userManager.UpdateAsync(user); return Ok( new { message = "User updated successfully", RedirectUrl = Url.Action("Index", "Home") }); } #endregion Department public async Task doUserExists(string username) { var user = await _userManager.FindByNameAsync(username); return user != null ? user : null; } public class LdapLoginCredential { public required string username { get; set; } public required string password { get; set; } } public class UserDeptAssignment() { public required int departmentId { get; set; } } class userLdapInfo() { public required bool Authenticated { get; set; } public userInfo? UserInfo { get; set; } public string? Response { get; set; } } class userInfo() { public required string FirstName { get; set; } public required string LastName { get; set; } public required string DisplayName { get; set; } public required string Description { get; set; } public required string Username { get; set; } public required string Office { get; set; } public required string Email { get; set; } public required string Street { get; set; } public required string City { get; set; } public required string State { get; set; } public required string ZipCode { get; set; } public required string Country { get; set; } public required string Home { get; set; } public required string Mobile { get; set; } } } }