This commit is contained in:
MOHD ARIFF 2024-12-09 16:28:42 +08:00
parent 907a171616
commit 7cbc870f78
4 changed files with 192 additions and 52 deletions

View File

@ -46,6 +46,26 @@
</form> </form>
</section> </section>
</div> </div>
<div class="col-md-4" id="ldapLogin">
<form v-on:submit.prevent="ldapLogin" id="login" method="post">
<h2>Use a local 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>
<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"> <div class="col-md-6 col-md-offset-2">
<section> <section>
<h3>Use another service to log in.</h3> <h3>Use another service to log in.</h3>
@ -80,4 +100,64 @@
@section Scripts { @section Scripts {
<partial name="_ValidationScriptsPartial" /> <partial name="_ValidationScriptsPartial" />
<script>
$(function () {
app.mount('#ldapLogin');
});
const app = Vue.createApp({
data() {
return {
ldapLoginInfo: {
username: '',
password: '',
},
};
},
mounted() {
},
watch: {
},
methods: {
ldapLogin() {
console.log(JSON.stringify(this.ldapLoginInfo))
fetch('/AdminAPI/LdapLogin', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(this.ldapLoginInfo)
})
.then(response => {
if (!response.ok) {
throw new Error('Name module already exist');
}
alert('Module information saved successfully');
})
.catch(error => {
console.error('There was a problem with the update operation:', error);
alert('Failed to save data: ' + error.message);
});
},
fetchControllerMethodList() {
fetch('/AdminAPI/GetListClassAndMethodInformation', {
method: 'POST'
})
.then(response => response.json())
.then(data => {
if (data != null) {
this.controllerMethodData = data;
}
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
},
},
});
</script>
} }

View File

@ -4,6 +4,10 @@ using Microsoft.EntityFrameworkCore;
using PSTW_CentralSystem.DBContext; using PSTW_CentralSystem.DBContext;
using PSTW_CentralSystem.Models; using PSTW_CentralSystem.Models;
using System.Reflection; using System.Reflection;
using static System.Runtime.InteropServices.JavaScript.JSType;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
namespace PSTW_CentralSystem.Controllers.API namespace PSTW_CentralSystem.Controllers.API
{ {
@ -15,6 +19,8 @@ namespace PSTW_CentralSystem.Controllers.API
private readonly ILogger<HomeController> _logger; private readonly ILogger<HomeController> _logger;
private readonly IdentityDBContext _authDbContext; private readonly IdentityDBContext _authDbContext;
private readonly UserManager<UserModel> _userManager; private readonly UserManager<UserModel> _userManager;
// Communication Key for API. Not API authentication key
private readonly string _commKey = "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF4NW42anlkNlpTYzZNSE1Zem9qaApUbldpYTIra2pud2ZNbVhpSWlyK0RadjM2cEVGMGhRUWFLaWpaMWtyMGNiT25Ha2d2QnNwTzNiYkFua0E3SWwzCk4zM3NNYWdQV0JOQzZyVm1jT04zNEhDSWJCM0hvQXFYQUtkSHFUOGZneklMRzFhRzdxK2h4RDZhZzZsemhTMnEKdDA1bHdNc0hONWpOdmVNNnFWalRnTVB4aEFOMUhnUTkrd1lRWFh5bnZYYUo5OUNySHBqS21WdUt2VUh6WXdlRwp6SnBtYXZOclc4bE9oM1lMeVNuUVU5bjRrdURubGc1OWNHeUtKbzJ2YUxZbll4MkR1ZDNabzBXMHRMWGd0dlQyCjVXdVFsY0NVbldvaVpBV1JBTGI3anRpcTF0MGY5eVBiV2gxYXpMMjFoL3QvckJUMXNCL2FQd2kzRCt3MnBUR00KeVFJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==";
public AdminAPI(ILogger<HomeController> logger, IdentityDBContext authDbContext, UserManager<UserModel> userManager) public AdminAPI(ILogger<HomeController> logger, IdentityDBContext authDbContext, UserManager<UserModel> userManager)
{ {
@ -117,6 +123,93 @@ 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);
Console.WriteLine("Sending data (RSA-Encrypted JSON as Base64)");
Console.WriteLine(rsaDataBase64);
Console.WriteLine("");
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 = httpClient.PostAsync(ldapUrl, rsaDataB64HttpContent).Result;
ldapUrlResponse.EnsureSuccessStatusCode();
if (ldapUrlResponse.IsSuccessStatusCode)
{
ldapUrlResult = ldapUrlResponse.Content.ReadAsStringAsync().Result;
}
}
catch (Exception e)
{
return BadRequest(new { Message = $"Message: {e.Message}\nException Caught!" });
}
}
userLdapInfo userInfo = JsonSerializer.Deserialize<userLdapInfo>(ldapUrlResult)!;
if (userInfo.Authenticated != "True")
{
return BadRequest(new { Message = "Login Failed" });
}
UserModel ldapuser = new UserModel()
{
UserName = userInfo.UserInfo.Email,
Email = userInfo.UserInfo.Email,
};
return Json(userInfo);
}
class userLdapInfo()
{
public required string 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; }
} }
}
} }

View File

@ -35,11 +35,12 @@ namespace PSTW_CentralSystem.Controllers.API
var userInfo = await _authDbContext.Users.Include(u => u.Department).Select(u => new var userInfo = await _authDbContext.Users.Include(u => u.Department).Select(u => new
{ {
u.Id, id = u.Id,
u.NormalizedEmail, email = u.NormalizedEmail,
u.Department, company = u.Department!.Company!.CompanyName,
userRole, department =u.Department,
}).Where(u => u.Id == user.Id).FirstOrDefaultAsync(); role = userRole,
}).Where(u => u.id == user.Id).FirstOrDefaultAsync();
if (userInfo == null) if (userInfo == null)
{ {

View File

@ -7,7 +7,7 @@
} }
<p> <p>
<a asp-action="UserCreate">Create New</a> @* <a asp-action="UserCreate">Create New</a> *@
</p> </p>
<div id="app"> <div id="app">
<div class="row"> <div class="row">
@ -122,69 +122,35 @@
initiateTable() { initiateTable() {
self = this; self = this;
this.itemDatatable = $('#userDatatable').DataTable({ this.itemDatatable = $('#userDatatable').DataTable({
"data": this.items, "data": this.userList,
"columns": [ "columns": [
{ {
"title": "Unique Id", "title": "UID",
"data": "uniqueID", "data": "id",
"createdCell": function (td, cellData, rowData, row, col) { "createdCell": function (td, cellData, rowData, row, col) {
// Assign a unique ID to the <td> element // Assign a unique ID to the <td> element
$(td).attr('id', `qr${cellData}`); $(td).attr('id', `qr${cellData}`);
}, },
}, },
{ {
"title": "Serial Number", "title": "Email",
"data": "serialNumber", "data": "email",
}, },
{ {
"title": "Quantity", "title": "Company Name",
"data": "quantity", "data": "company",
}, },
{ {
"title": "Supplier", "title": "Department",
"data": "supplier", "data": "department",
}, },
{ {
"title": "Purchase Date", "title": "Role",
"data": "purchaseDate", "data": "role",
},
{
"title": "Price After Convert(RM)",
"data": "convertPrice",
},
{
"title": "Invoice Date",
"data": "invoiceDate",
},
{
"title": "Warranty Until",
"data": "warranty",
"render": function (data, type, full, meta) {
if (data > 0) { return full.endWDate }
else { return data }
}
},
// {
// "title": "Image",
// "data": "imageProduct",
// "render": function (data, type, full, meta) {
// var image = `<a href="${data}" target="_blank" data-lightbox="image-1">
// <img src="${data}" alt="Image" class="img-thumbnail" style="width: 100px; height: 100px;" />
// </a>`;
// return image;
// },
// },
{
"title": "Print",
"data": "uniqueID",
"render": function (data) {
var printButton = `<button type="button" class="btn btn-success print-btn" data-id="${data}">Print</button>`;
return printButton;
},
}, },
{ {
"title": "Delete", "title": "Delete",
"data": "productId", "data": "id",
"render": function (data) { "render": function (data) {
var deleteButton = `<button type="button" class="btn btn-danger delete-btn" data-id="${data}">Delete</button>`; var deleteButton = `<button type="button" class="btn btn-danger delete-btn" data-id="${data}">Delete</button>`;
return deleteButton; return deleteButton;