PSTW_CentralizeSystem/Controllers/API/IdentityAPI.cs
2024-12-23 16:30:34 +08:00

253 lines
9.8 KiB
C#

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PSTW_CentralSystem.DBContext;
using PSTW_CentralSystem.Models;
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<IdentityAPI> _logger;
private readonly CentralSystemContext _identityDbContext;
private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager;
// Communication Key for API. Not API authentication key
private readonly string _commKey = "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF4NW42anlkNlpTYzZNSE1Zem9qaApUbldpYTIra2pud2ZNbVhpSWlyK0RadjM2cEVGMGhRUWFLaWpaMWtyMGNiT25Ha2d2QnNwTzNiYkFua0E3SWwzCk4zM3NNYWdQV0JOQzZyVm1jT04zNEhDSWJCM0hvQXFYQUtkSHFUOGZneklMRzFhRzdxK2h4RDZhZzZsemhTMnEKdDA1bHdNc0hONWpOdmVNNnFWalRnTVB4aEFOMUhnUTkrd1lRWFh5bnZYYUo5OUNySHBqS21WdUt2VUh6WXdlRwp6SnBtYXZOclc4bE9oM1lMeVNuUVU5bjRrdURubGc1OWNHeUtKbzJ2YUxZbll4MkR1ZDNabzBXMHRMWGd0dlQyCjVXdVFsY0NVbldvaVpBV1JBTGI3anRpcTF0MGY5eVBiV2gxYXpMMjFoL3QvckJUMXNCL2FQd2kzRCt3MnBUR00KeVFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==";
public IdentityAPI(ILogger<IdentityAPI> logger, CentralSystemContext authDbContext, UserManager<UserModel> userManager, SignInManager<UserModel> signInManager)
{
_logger = logger;
_identityDbContext = authDbContext;
_userManager = userManager;
_signInManager = signInManager;
}
#region User
[HttpPost("GetUserInformation")]
public async Task<IActionResult> 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 userInfo = await _identityDbContext.Users.Include(u => u.Department).Select(u => new
{
id = u.Id,
email = u.NormalizedEmail,
company = u.Department!.Company!.CompanyName,
department = u.Department,
role = userRole,
}).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}");
}
}
#endregion User
#region LDAP Login
[HttpPost("LdapLogin")]
public async Task<IActionResult> 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<userLdapInfo>(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<IActionResult> 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<IActionResult> 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<IActionResult> 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<UserModel?> 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; }
}
}
}