Update
This commit is contained in:
parent
45a94c99fc
commit
3cfcfd7a3a
@ -2,9 +2,82 @@
|
|||||||
@model AccessDeniedModel
|
@model AccessDeniedModel
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Access denied";
|
ViewData["Title"] = "Access denied";
|
||||||
|
@inject UserManager<UserModel> _userManager
|
||||||
|
var user = await _userManager.GetUserAsync(User);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
var userComDept = user.departmentId;
|
||||||
|
var userRole = await _userManager.GetRolesAsync(user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
<header>
|
<header id="deniedHeader">
|
||||||
<h1 class="text-danger">@ViewData["Title"]</h1>
|
<template v-if="ldapUserInfo.role.length == 0"><p class="text-danger">You do not have access to this resource because you have no role. Please contact the system administrator.</p></template>
|
||||||
<p class="text-danger">You do not have access to this resource.</p>
|
<template v-else><p class="text-danger">You do not have access to this resource.</p></template>
|
||||||
</header>
|
</header>
|
||||||
|
@section Scripts {
|
||||||
|
<script>
|
||||||
|
if (typeof jQuery === 'undefined') {
|
||||||
|
console.error('jQuery is not loaded.');
|
||||||
|
}
|
||||||
|
$(function () {
|
||||||
|
app.mount('#deniedHeader');
|
||||||
|
});
|
||||||
|
|
||||||
|
const app = Vue.createApp({
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
ldapUserInfo: {
|
||||||
|
role: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getUserInfo();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async getUserInfo() {
|
||||||
|
try {
|
||||||
|
// Show the loading modal
|
||||||
|
$('#loadingModal').modal('show');
|
||||||
|
|
||||||
|
// Perform the fetch request
|
||||||
|
const response = await fetch('/IdentityAPI/GetUserInformation', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check if the response is OK
|
||||||
|
if (!response.ok) {
|
||||||
|
const errorData = await response.json();
|
||||||
|
throw new Error(errorData.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.userInfo) {
|
||||||
|
console.log(data.userInfo)
|
||||||
|
this.ldapUserInfo = data.userInfo
|
||||||
|
} else {
|
||||||
|
console.error('Get user failed:', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('Error getting user information:', error);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
await new Promise(resolve => {
|
||||||
|
$('#loadingModal').on('shown.bs.modal', resolve);
|
||||||
|
});
|
||||||
|
$('#loadingModal').modal('hide');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|||||||
@ -5,10 +5,19 @@
|
|||||||
ViewData["Title"] = "Log in";
|
ViewData["Title"] = "Log in";
|
||||||
}
|
}
|
||||||
|
|
||||||
<h1>@ViewData["Title"]</h1>
|
<div class="row" id="systemLogin">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4">
|
<h2><label class="col-md-2">Login Type</label></h2>
|
||||||
<section>
|
<div class="btn-group col-md-4" role="group" aria-label="Login type">
|
||||||
|
<input type="radio" class="btn-check" name="loginType" id="local-login" value="Local" v-model="loginType">
|
||||||
|
<label class="btn btn-outline-primary" for="local-login">Local</label>
|
||||||
|
|
||||||
|
<input type="radio" class="btn-check" name="loginType" id="ad-login" value="AD" v-model="loginType" checked>
|
||||||
|
<label class="btn btn-outline-primary" for="ad-login">AD</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4" v-if="loginType == 'Local'">
|
||||||
<form id="account" method="post">
|
<form id="account" method="post">
|
||||||
<h2>Use a local account to log in.</h2>
|
<h2>Use a local account to log in.</h2>
|
||||||
<hr />
|
<hr />
|
||||||
@ -23,78 +32,61 @@
|
|||||||
<label asp-for="Input.Password" class="form-label">Password</label>
|
<label asp-for="Input.Password" class="form-label">Password</label>
|
||||||
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
<span asp-validation-for="Input.Password" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="checkbox mb-3">
|
|
||||||
<label asp-for="Input.RememberMe" class="form-label">
|
|
||||||
<input class="form-check-input" asp-for="Input.RememberMe" />
|
|
||||||
@Html.DisplayNameFor(m => m.Input.RememberMe)
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<button id="login-submit" type="submit" class="w-100 btn btn-lg btn-primary">Log in</button>
|
<button id="login-submit" type="submit" class="w-100 btn btn-lg btn-primary">Log in</button>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4" v-if="loginType == 'AD'">
|
||||||
|
<form v-on:submit.prevent="ldapLogin" id="login" method="post">
|
||||||
|
<h2>Use a AD account to log in.</h2>
|
||||||
|
<hr />
|
||||||
|
<div class="text-danger" role="alert"></div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input v-model="ldapLoginInfo.username" id="ldapUsername" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" />
|
||||||
|
<label id="ldapEmailLabel" class="form-label">Email</label>
|
||||||
|
<span id="ldapEmailError" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input v-model="ldapLoginInfo.password" id="ldapPassword" class="form-control" type="password" autocomplete="current-password" aria-required="true" placeholder="password" />
|
||||||
|
<label id="ldapPasswordLabel" class="form-label">Password</label>
|
||||||
|
<span id="ldapPasswordError" class="text-danger"></span>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<button id="ldap-login-submit" type="submit" class="w-100 btn btn-lg btn-primary">Log in</button>
|
||||||
<a id="forgot-password" asp-page="./ForgotPassword">Forgot your password?</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a asp-page="./Register" asp-route-returnUrl="@Model.ReturnUrl">Register as a new user</a>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<a id="resend-confirmation" asp-page="./ResendEmailConfirmation">Resend email confirmation</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</section>
|
</div>
|
||||||
</div>
|
<div class="col-md-6 col-md-offset-2">
|
||||||
<div class="col-md-4" id="ldapLogin">
|
<section>
|
||||||
<form v-on:submit.prevent="ldapLogin" id="login" method="post">
|
<h3>Use another service to log in.</h3>
|
||||||
<h2>Use a local account to log in.</h2>
|
<hr />
|
||||||
<hr />
|
@{
|
||||||
<div class="text-danger" role="alert"></div>
|
if ((Model.ExternalLogins?.Count ?? 0) == 0)
|
||||||
<div class="form-floating mb-3">
|
{
|
||||||
<input v-model="ldapLoginInfo.username" id="ldapUsername" class="form-control" autocomplete="username" aria-required="true" placeholder="name@example.com" />
|
|
||||||
<label id="ldapEmailLabel" class="form-label">Email</label>
|
|
||||||
<span id="ldapEmailError" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
<div class="form-floating mb-3">
|
|
||||||
<input v-model="ldapLoginInfo.password" id="ldapPassword" class="form-control" type="password" autocomplete="current-password" aria-required="true" placeholder="password" />
|
|
||||||
<label id="ldapPasswordLabel" class="form-label">Password</label>
|
|
||||||
<span id="ldapPasswordError" class="text-danger"></span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<button id="ldap-login-submit" type="submit" class="w-100 btn btn-lg btn-primary">Log in</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 col-md-offset-2">
|
|
||||||
<section>
|
|
||||||
<h3>Use another service to log in.</h3>
|
|
||||||
<hr />
|
|
||||||
@{
|
|
||||||
if ((Model.ExternalLogins?.Count ?? 0) == 0)
|
|
||||||
{
|
|
||||||
<div>
|
|
||||||
<p>
|
|
||||||
There are no external authentication services configured. See this <a href="https://go.microsoft.com/fwlink/?LinkID=532715">article
|
|
||||||
about setting up this ASP.NET application to support logging in via external services</a>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
|
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
@foreach (var provider in Model.ExternalLogins!)
|
There are no external authentication services configured. See this <a href="https://go.microsoft.com/fwlink/?LinkID=532715">article
|
||||||
{
|
about setting up this ASP.NET application to support logging in via external services</a>.
|
||||||
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
|
|
||||||
}
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="@Model.ReturnUrl" method="post" class="form-horizontal">
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
@foreach (var provider in Model.ExternalLogins!)
|
||||||
|
{
|
||||||
|
<button type="submit" class="btn btn-primary" name="provider" value="@provider.Name" title="Log in using your @provider.DisplayName account">@provider.DisplayName</button>
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
</section>
|
||||||
</section>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -104,12 +96,13 @@
|
|||||||
<script>
|
<script>
|
||||||
|
|
||||||
$(function () {
|
$(function () {
|
||||||
app.mount('#ldapLogin');
|
app.mount('#systemLogin');
|
||||||
});
|
});
|
||||||
|
|
||||||
const app = Vue.createApp({
|
const app = Vue.createApp({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
loginType: 'AD',
|
||||||
ldapLoginInfo: {
|
ldapLoginInfo: {
|
||||||
username: '',
|
username: '',
|
||||||
password: '',
|
password: '',
|
||||||
@ -123,50 +116,68 @@
|
|||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
ldapLogin() {
|
async ldapLogin() {
|
||||||
console.log(JSON.stringify(this.ldapLoginInfo))
|
try {
|
||||||
fetch('/AdminAPI/LdapLogin', {
|
// Show the loading modal
|
||||||
method: 'POST',
|
$('#loadingModal').modal('show');
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
// Perform the fetch request
|
||||||
},
|
const response = await fetch('/IdentityAPI/LdapLogin', {
|
||||||
body: JSON.stringify(this.ldapLoginInfo)
|
method: 'POST',
|
||||||
})
|
headers: {
|
||||||
.then(response => {
|
'Content-Type': 'application/json',
|
||||||
if (!response.ok) {
|
},
|
||||||
throw new Error('Name module already exist');
|
body: JSON.stringify(this.ldapLoginInfo),
|
||||||
}
|
|
||||||
return response.json();
|
|
||||||
})
|
|
||||||
.then(data => {
|
|
||||||
console.log(data);
|
|
||||||
if (data.redirectUrl) {
|
|
||||||
window.location.href = data.redirectUrl;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
console.error('Login failed:', data);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error during LDAP login:', error);
|
|
||||||
alert('Failed to login: ' + error.message);
|
|
||||||
});
|
});
|
||||||
},
|
|
||||||
fetchControllerMethodList() {
|
// Check if the response is OK
|
||||||
fetch('/AdminAPI/GetListClassAndMethodInformation', {
|
if (!response.ok) {
|
||||||
method: 'POST'
|
const errorData = await response.json();
|
||||||
})
|
throw new Error(errorData.message);
|
||||||
.then(response => response.json())
|
}
|
||||||
.then(data => {
|
|
||||||
if (data != null) {
|
const data = await response.json();
|
||||||
this.controllerMethodData = data;
|
|
||||||
}
|
// Redirect if a URL is provided
|
||||||
})
|
if (data.redirectUrl) {
|
||||||
.catch(error => {
|
window.location.href = data.redirectUrl;
|
||||||
console.error('There was a problem with the fetch operation:', error);
|
} else {
|
||||||
|
console.error('Login failed:', data);
|
||||||
|
alert('Login failed.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.error('Error during LDAP login:', error);
|
||||||
|
alert(error.message);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
await new Promise(resolve => {
|
||||||
|
$('#loadingModal').on('shown.bs.modal', resolve);
|
||||||
});
|
});
|
||||||
|
$('#loadingModal').modal('hide');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
async fetchControllerMethodList() {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/AdminAPI/GetListClassAndMethodInformation', {
|
||||||
|
method: 'POST',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
// Assign data if it exists
|
||||||
|
if (data) {
|
||||||
|
this.controllerMethodData = data;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('There was a problem with the fetch operation:', error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -20,8 +20,6 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
private readonly IdentityDBContext _authDbContext;
|
private readonly IdentityDBContext _authDbContext;
|
||||||
private readonly UserManager<UserModel> _userManager;
|
private readonly UserManager<UserModel> _userManager;
|
||||||
private readonly SignInManager<UserModel> _signInManager;
|
private readonly SignInManager<UserModel> _signInManager;
|
||||||
// Communication Key for API. Not API authentication key
|
|
||||||
private readonly string _commKey = "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF4NW42anlkNlpTYzZNSE1Zem9qaApUbldpYTIra2pud2ZNbVhpSWlyK0RadjM2cEVGMGhRUWFLaWpaMWtyMGNiT25Ha2d2QnNwTzNiYkFua0E3SWwzCk4zM3NNYWdQV0JOQzZyVm1jT04zNEhDSWJCM0hvQXFYQUtkSHFUOGZneklMRzFhRzdxK2h4RDZhZzZsemhTMnEKdDA1bHdNc0hONWpOdmVNNnFWalRnTVB4aEFOMUhnUTkrd1lRWFh5bnZYYUo5OUNySHBqS21WdUt2VUh6WXdlRwp6SnBtYXZOclc4bE9oM1lMeVNuUVU5bjRrdURubGc1OWNHeUtKbzJ2YUxZbll4MkR1ZDNabzBXMHRMWGd0dlQyCjVXdVFsY0NVbldvaVpBV1JBTGI3anRpcTF0MGY5eVBiV2gxYXpMMjFoL3QvckJUMXNCL2FQd2kzRCt3MnBUR00KeVFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==";
|
|
||||||
|
|
||||||
public AdminAPI(ILogger<AdminAPI> logger, IdentityDBContext authDbContext, UserManager<UserModel> userManager, SignInManager<UserModel> signInManager)
|
public AdminAPI(ILogger<AdminAPI> logger, IdentityDBContext authDbContext, UserManager<UserModel> userManager, SignInManager<UserModel> signInManager)
|
||||||
{
|
{
|
||||||
@ -97,13 +95,13 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
var userRole = await _userManager.GetRolesAsync(user??new UserModel());
|
var userRole = await _userManager.GetRolesAsync(user??new UserModel());
|
||||||
List<UserModel> userInfo = new List<UserModel>();
|
List<UserModel> userInfo = new List<UserModel>();
|
||||||
|
|
||||||
if (userRole == null || userRole.Count == 0)
|
|
||||||
{
|
|
||||||
// Fetch all users excluding those with roles SuperAdmin or SystemAdmin
|
// Fetch all users excluding those with roles SuperAdmin or SystemAdmin
|
||||||
var allUsers = await _authDbContext.Users
|
var allUsers = await _authDbContext.Users
|
||||||
.Include(u => u.Department).ThenInclude(d => d!.Company)
|
.Include(u => u.Department)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
if (userRole == null || userRole.Count == 0)
|
||||||
|
{
|
||||||
foreach (var u in allUsers)
|
foreach (var u in allUsers)
|
||||||
{
|
{
|
||||||
var roles = await _userManager.GetRolesAsync(u);
|
var roles = await _userManager.GetRolesAsync(u);
|
||||||
@ -115,126 +113,22 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
userInfo = await _authDbContext.Users.Include(u => u.Department).ThenInclude(d => d!.Company).ToListAsync();
|
userInfo = await _authDbContext.Users.Include(u => u.Department).ToListAsync();
|
||||||
}
|
}
|
||||||
|
var userList = userInfo.Select(u => new
|
||||||
return Ok(new { UserInfo = userInfo });
|
{
|
||||||
|
id = u.Id,
|
||||||
|
email = u.NormalizedEmail,
|
||||||
|
company = u.Department?.Company?.CompanyName,
|
||||||
|
department = u.Department,
|
||||||
|
role = _userManager.GetRolesAsync(u).Result
|
||||||
|
}).ToList();
|
||||||
|
return Ok(new { UserInfo = userList });
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
return StatusCode(500, $"An error occurred: {ex.Message}");
|
return StatusCode(500, $"An error occurred: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public class LdapLoginCredential
|
|
||||||
{
|
|
||||||
public required string username { get; set; }
|
|
||||||
public required string password { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
[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)!;
|
|
||||||
userInfo userInfo = userLdapInfo.UserInfo;
|
|
||||||
|
|
||||||
if (!userLdapInfo.Authenticated)
|
|
||||||
{
|
|
||||||
return BadRequest(new { Message = "Login Failed" });
|
|
||||||
}
|
|
||||||
|
|
||||||
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 _userManager.SetLockoutEnabledAsync(ldapuser, false);
|
|
||||||
//return RedirectToAction("AssignRoleAfterLdap", "IdentityController");
|
|
||||||
return Ok(new { RedirectUrl = Url.Action("RoleAssignment", "Identity") });
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
await _signInManager.SignInAsync(existUser, false);
|
|
||||||
//return RedirectToAction("Index", "HomeController");
|
|
||||||
return Ok(new { RedirectUrl = Url.Action("Index", "Home") });
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<UserModel?> doUserExists(string username)
|
|
||||||
{
|
|
||||||
var user = await _userManager.FindByNameAsync(username);
|
|
||||||
return user != null ? user : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
class userLdapInfo()
|
|
||||||
{
|
|
||||||
public required bool Authenticated { get; set; }
|
|
||||||
public required userInfo UserInfo { 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; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,9 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using PSTW_CentralSystem.DBContext;
|
using PSTW_CentralSystem.DBContext;
|
||||||
using PSTW_CentralSystem.Models;
|
using PSTW_CentralSystem.Models;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
namespace PSTW_CentralSystem.Controllers.API
|
namespace PSTW_CentralSystem.Controllers.API
|
||||||
{
|
{
|
||||||
[ApiController]
|
[ApiController]
|
||||||
@ -13,15 +16,20 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
private readonly ILogger<IdentityAPI> _logger;
|
private readonly ILogger<IdentityAPI> _logger;
|
||||||
private readonly IdentityDBContext _authDbContext;
|
private readonly IdentityDBContext _authDbContext;
|
||||||
private readonly UserManager<UserModel> _userManager;
|
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, IdentityDBContext authDbContext, UserManager<UserModel> userManager)
|
|
||||||
|
public IdentityAPI(ILogger<IdentityAPI> logger, IdentityDBContext authDbContext, UserManager<UserModel> userManager, SignInManager<UserModel> signInManager)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_authDbContext = authDbContext;
|
_authDbContext = authDbContext;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
|
_signInManager = signInManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost("GetUserInformation/")]
|
[HttpPost("GetUserInformation")]
|
||||||
public async Task<IActionResult> GetUserInformation()
|
public async Task<IActionResult> GetUserInformation()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -30,7 +38,7 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
var userRole = await _userManager.GetRolesAsync(user!);
|
var userRole = await _userManager.GetRolesAsync(user!);
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
|
return NotFound(new { message = $"Unable to load user with ID '{_userManager.GetUserId(User)}'."});
|
||||||
}
|
}
|
||||||
|
|
||||||
var userInfo = await _authDbContext.Users.Include(u => u.Department).Select(u => new
|
var userInfo = await _authDbContext.Users.Include(u => u.Department).Select(u => new
|
||||||
@ -44,7 +52,7 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
|
|
||||||
if (userInfo == null)
|
if (userInfo == null)
|
||||||
{
|
{
|
||||||
return NotFound("User not found");
|
return NotFound(new { message = "User not found" });
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(new { UserInfo = userInfo });
|
return Ok(new { UserInfo = userInfo });
|
||||||
@ -54,5 +62,118 @@ namespace PSTW_CentralSystem.Controllers.API
|
|||||||
return StatusCode(500, $"An error occurred: {ex.Message}");
|
return StatusCode(500, $"An error occurred: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public class LdapLoginCredential
|
||||||
|
{
|
||||||
|
public required string username { get; set; }
|
||||||
|
public required string password { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[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 _userManager.SetLockoutEnabledAsync(ldapuser, false);
|
||||||
|
//return RedirectToAction("AssignRoleAfterLdap", "IdentityController");
|
||||||
|
return Ok(new { RedirectUrl = Url.Action("ComDeptAssignment", "Identity") });
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
await _signInManager.SignInAsync(existUser, false);
|
||||||
|
//return RedirectToAction("Index", "HomeController");
|
||||||
|
return Ok(new { RedirectUrl = Url.Action("Index", "Home") });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<UserModel?> doUserExists(string username)
|
||||||
|
{
|
||||||
|
var user = await _userManager.FindByNameAsync(username);
|
||||||
|
return user != null ? user : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
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; }
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ using System.Diagnostics;
|
|||||||
|
|
||||||
namespace PSTW_CentralSystem.Controllers
|
namespace PSTW_CentralSystem.Controllers
|
||||||
{
|
{
|
||||||
//[Authorize(Policy = "RoleModulePolicy")]
|
[Authorize(Policy = "RoleModulePolicy")]
|
||||||
public class AdminController : Controller
|
public class AdminController : Controller
|
||||||
{
|
{
|
||||||
private readonly IdentityDBContext _authDbContext;
|
private readonly IdentityDBContext _authDbContext;
|
||||||
|
|||||||
@ -2,6 +2,9 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using PSTW_CentralSystem.DBContext;
|
using PSTW_CentralSystem.DBContext;
|
||||||
using PSTW_CentralSystem.Models;
|
using PSTW_CentralSystem.Models;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace PSTW_CentralSystem.Controllers
|
namespace PSTW_CentralSystem.Controllers
|
||||||
{
|
{
|
||||||
@ -19,7 +22,7 @@ namespace PSTW_CentralSystem.Controllers
|
|||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IActionResult> RoleAssignment()
|
public async Task<IActionResult> ComDeptAssignment()
|
||||||
{
|
{
|
||||||
var thisUser = await _userManager.GetUserAsync(User);
|
var thisUser = await _userManager.GetUserAsync(User);
|
||||||
return View(thisUser.Id);
|
return View(thisUser.Id);
|
||||||
|
|||||||
@ -17,8 +17,7 @@
|
|||||||
<h4 class="card-title">Latest Posts</h4>
|
<h4 class="card-title">Latest Posts</h4>
|
||||||
<div class="col-md-12 col-lg-12">
|
<div class="col-md-12 col-lg-12">
|
||||||
<div>
|
<div>
|
||||||
<table class="table table-bordered border-primary" id="userDatatable">
|
<table class="table table-bordered table-hover table-striped no-wrap" id="userDatatable" style="width:100%;border-style: solid; border-width: 1px"></table>
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -157,27 +156,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
responsive: true,
|
responsive: true,
|
||||||
drawCallback: function (settings) {
|
|
||||||
// Generate QR codes after rows are rendered
|
|
||||||
const api = this.api();
|
|
||||||
api.rows().every(function () {
|
|
||||||
const data = this.data(); // Row data
|
|
||||||
const containerId = `qr${data.uniqueID}`;
|
|
||||||
const container = $(`#${containerId}`);
|
|
||||||
// console.log(container[0]);
|
|
||||||
if (container) {
|
|
||||||
// Generate QR code only if not already generated
|
|
||||||
new QRCode(container[0], {
|
|
||||||
text: data.qrString,
|
|
||||||
width: 150,
|
|
||||||
height: 150,
|
|
||||||
colorDark: "#000000",
|
|
||||||
colorLight: "#ffffff",
|
|
||||||
correctLevel: QRCode.CorrectLevel.H
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Attach click event listener to the delete buttons
|
// Attach click event listener to the delete buttons
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
|
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
|
||||||
*@
|
*@
|
||||||
@{
|
@{
|
||||||
ViewData["Title"] = "Role Assignment";
|
ViewData["Title"] = "Company & Department Assignment";
|
||||||
Layout = "~/Views/Shared/_Layout.cshtml";
|
Layout = "~/Views/Shared/_Layout.cshtml";
|
||||||
int userId = ViewBag.UserId;
|
int userId = ViewBag.UserId;
|
||||||
}
|
}
|
||||||
@ -19,8 +19,7 @@
|
|||||||
<h4 class="card-title">Latest Posts</h4>
|
<h4 class="card-title">Latest Posts</h4>
|
||||||
<div class="col-md-12 col-lg-12">
|
<div class="col-md-12 col-lg-12">
|
||||||
<div>
|
<div>
|
||||||
<table class="table table-bordered border-primary" id="userDatatable">
|
<table class="table table-bordered border-primary" id="userDatatable"></table>
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -70,6 +70,18 @@
|
|||||||
<div class="lds-pos"></div>
|
<div class="lds-pos"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal fade" id="loadingModal" data-bs-backdrop="static" tabindex="-1" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-body text-center">
|
||||||
|
<div class="spinner-border text-primary" role="status">
|
||||||
|
<span class="visually-hidden">Loading...</span>
|
||||||
|
</div>
|
||||||
|
<p class="mt-3">Please wait while we process your request...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- ============================================================== -->
|
<!-- ============================================================== -->
|
||||||
<!-- Main wrapper - style you can find in pages.scss -->
|
<!-- Main wrapper - style you can find in pages.scss -->
|
||||||
<!-- ============================================================== -->
|
<!-- ============================================================== -->
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user