This commit is contained in:
MOHD ARIFF 2024-11-20 16:27:35 +08:00
parent 8dc8dd90da
commit 3f3ad980b9
46 changed files with 1570 additions and 493 deletions

View File

@ -11,14 +11,15 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
public class ConfirmEmailModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly UserManager<UserModel> _userManager;
public ConfirmEmailModel(UserManager<IdentityUser> userManager)
public ConfirmEmailModel(UserManager<UserModel> userManager)
{
_userManager = userManager;
}

View File

@ -10,15 +10,16 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
public class ConfirmEmailChangeModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager;
public ConfirmEmailChangeModel(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager)
public ConfirmEmailChangeModel(UserManager<UserModel> userManager, SignInManager<UserModel> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;

View File

@ -17,23 +17,24 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class ExternalLoginModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly IUserStore<IdentityUser> _userStore;
private readonly IUserEmailStore<IdentityUser> _emailStore;
private readonly SignInManager<UserModel> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly IUserStore<UserModel> _userStore;
private readonly IUserEmailStore<UserModel> _emailStore;
private readonly IEmailSender _emailSender;
private readonly ILogger<ExternalLoginModel> _logger;
public ExternalLoginModel(
SignInManager<IdentityUser> signInManager,
UserManager<IdentityUser> userManager,
IUserStore<IdentityUser> userStore,
SignInManager<UserModel> signInManager,
UserManager<UserModel> userManager,
IUserStore<UserModel> userStore,
ILogger<ExternalLoginModel> logger,
IEmailSender emailSender)
{
@ -197,27 +198,27 @@ namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
return Page();
}
private IdentityUser CreateUser()
private UserModel CreateUser()
{
try
{
return Activator.CreateInstance<IdentityUser>();
return Activator.CreateInstance<UserModel>();
}
catch
{
throw new InvalidOperationException($"Can't create an instance of '{nameof(IdentityUser)}'. " +
$"Ensure that '{nameof(IdentityUser)}' is not an abstract class and has a parameterless constructor, or alternatively " +
throw new InvalidOperationException($"Can't create an instance of '{nameof(UserModel)}'. " +
$"Ensure that '{nameof(UserModel)}' is not an abstract class and has a parameterless constructor, or alternatively " +
$"override the external login page in /Areas/Identity/Pages/Account/ExternalLogin.cshtml");
}
}
private IUserEmailStore<IdentityUser> GetEmailStore()
private IUserEmailStore<UserModel> GetEmailStore()
{
if (!_userManager.SupportsUserEmail)
{
throw new NotSupportedException("The default UI requires a user store with email support.");
}
return (IUserEmailStore<IdentityUser>)_userStore;
return (IUserEmailStore<UserModel>)_userStore;
}
}
}

View File

@ -13,15 +13,16 @@ using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
public class ForgotPasswordModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly UserManager<UserModel> _userManager;
private readonly IEmailSender _emailSender;
public ForgotPasswordModel(UserManager<IdentityUser> userManager, IEmailSender emailSender)
public ForgotPasswordModel(UserManager<UserModel> userManager, IEmailSender emailSender)
{
_userManager = userManager;
_emailSender = emailSender;

View File

@ -14,15 +14,16 @@ using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
public class LoginModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly SignInManager<UserModel> _signInManager;
private readonly ILogger<LoginModel> _logger;
public LoginModel(SignInManager<IdentityUser> signInManager, ILogger<LoginModel> logger)
public LoginModel(SignInManager<UserModel> signInManager, ILogger<LoginModel> logger)
{
_signInManager = signInManager;
_logger = logger;

View File

@ -11,18 +11,19 @@ using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
public class LoginWith2faModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<UserModel> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly ILogger<LoginWith2faModel> _logger;
public LoginWith2faModel(
SignInManager<IdentityUser> signInManager,
UserManager<IdentityUser> userManager,
SignInManager<UserModel> signInManager,
UserManager<UserModel> userManager,
ILogger<LoginWith2faModel> logger)
{
_signInManager = signInManager;

View File

@ -10,17 +10,18 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
public class LoginWithRecoveryCodeModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<UserModel> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly ILogger<LoginWithRecoveryCodeModel> _logger;
public LoginWithRecoveryCodeModel(
SignInManager<IdentityUser> signInManager,
UserManager<IdentityUser> userManager,
SignInManager<UserModel> signInManager,
UserManager<UserModel> userManager,
ILogger<LoginWithRecoveryCodeModel> logger)
{
_signInManager = signInManager;

View File

@ -9,15 +9,16 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
public class LogoutModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly SignInManager<UserModel> _signInManager;
private readonly ILogger<LogoutModel> _logger;
public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger)
public LogoutModel(SignInManager<UserModel> signInManager, ILogger<LogoutModel> logger)
{
_signInManager = signInManager;
_logger = logger;

View File

@ -9,18 +9,19 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class ChangePasswordModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager;
private readonly ILogger<ChangePasswordModel> _logger;
public ChangePasswordModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
UserManager<UserModel> userManager,
SignInManager<UserModel> signInManager,
ILogger<ChangePasswordModel> logger)
{
_userManager = userManager;

View File

@ -9,18 +9,19 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class DeletePersonalDataModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager;
private readonly ILogger<DeletePersonalDataModel> _logger;
public DeletePersonalDataModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
UserManager<UserModel> userManager,
SignInManager<UserModel> signInManager,
ILogger<DeletePersonalDataModel> logger)
{
_userManager = userManager;

View File

@ -8,16 +8,17 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class Disable2faModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly UserManager<UserModel> _userManager;
private readonly ILogger<Disable2faModel> _logger;
public Disable2faModel(
UserManager<IdentityUser> userManager,
UserManager<UserModel> userManager,
ILogger<Disable2faModel> logger)
{
_userManager = userManager;

View File

@ -12,16 +12,17 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class DownloadPersonalDataModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly UserManager<UserModel> _userManager;
private readonly ILogger<DownloadPersonalDataModel> _logger;
public DownloadPersonalDataModel(
UserManager<IdentityUser> userManager,
UserManager<UserModel> userManager,
ILogger<DownloadPersonalDataModel> logger)
{
_userManager = userManager;
@ -45,7 +46,7 @@ namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
// Only include personal data for download
var personalData = new Dictionary<string, string>();
var personalDataProps = typeof(IdentityUser).GetProperties().Where(
var personalDataProps = typeof(UserModel).GetProperties().Where(
prop => Attribute.IsDefined(prop, typeof(PersonalDataAttribute)));
foreach (var p in personalDataProps)
{

View File

@ -12,18 +12,19 @@ using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class EmailModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager;
private readonly IEmailSender _emailSender;
public EmailModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
UserManager<UserModel> userManager,
SignInManager<UserModel> signInManager,
IEmailSender emailSender)
{
_userManager = userManager;
@ -73,7 +74,7 @@ namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
public string NewEmail { get; set; }
}
private async Task LoadAsync(IdentityUser user)
private async Task LoadAsync(UserModel user)
{
var email = await _userManager.GetEmailAsync(user);
Email = email;

View File

@ -13,19 +13,20 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class EnableAuthenticatorModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly UserManager<UserModel> _userManager;
private readonly ILogger<EnableAuthenticatorModel> _logger;
private readonly UrlEncoder _urlEncoder;
private const string AuthenticatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6";
public EnableAuthenticatorModel(
UserManager<IdentityUser> userManager,
UserManager<UserModel> userManager,
ILogger<EnableAuthenticatorModel> logger,
UrlEncoder urlEncoder)
{
@ -142,7 +143,7 @@ namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
}
}
private async Task LoadSharedKeyAndQrCodeUriAsync(IdentityUser user)
private async Task LoadSharedKeyAndQrCodeUriAsync(UserModel user)
{
// Load the authenticator key & QR code URI to display on the form
var unformattedKey = await _userManager.GetAuthenticatorKeyAsync(user);

View File

@ -11,19 +11,20 @@ using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class ExternalLoginsModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly IUserStore<IdentityUser> _userStore;
private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager;
private readonly IUserStore<UserModel> _userStore;
public ExternalLoginsModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
IUserStore<IdentityUser> userStore)
UserManager<UserModel> userManager,
SignInManager<UserModel> signInManager,
IUserStore<UserModel> userStore)
{
_userManager = userManager;
_signInManager = signInManager;
@ -69,7 +70,7 @@ namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
.ToList();
string passwordHash = null;
if (_userStore is IUserPasswordStore<IdentityUser> userPasswordStore)
if (_userStore is IUserPasswordStore<UserModel> userPasswordStore)
{
passwordHash = await userPasswordStore.GetPasswordHashAsync(user, HttpContext.RequestAborted);
}

View File

@ -9,16 +9,17 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class GenerateRecoveryCodesModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly UserManager<UserModel> _userManager;
private readonly ILogger<GenerateRecoveryCodesModel> _logger;
public GenerateRecoveryCodesModel(
UserManager<IdentityUser> userManager,
UserManager<UserModel> userManager,
ILogger<GenerateRecoveryCodesModel> logger)
{
_userManager = userManager;

View File

@ -9,17 +9,18 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class IndexModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager;
public IndexModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager)
UserManager<UserModel> userManager,
SignInManager<UserModel> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;
@ -60,7 +61,7 @@ namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
public string PhoneNumber { get; set; }
}
private async Task LoadAsync(IdentityUser user)
private async Task LoadAsync(UserModel user)
{
var userName = await _userManager.GetUserNameAsync(user);
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);

View File

@ -6,16 +6,17 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class PersonalDataModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly UserManager<UserModel> _userManager;
private readonly ILogger<PersonalDataModel> _logger;
public PersonalDataModel(
UserManager<IdentityUser> userManager,
UserManager<UserModel> userManager,
ILogger<PersonalDataModel> logger)
{
_userManager = userManager;

View File

@ -8,18 +8,19 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class ResetAuthenticatorModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager;
private readonly ILogger<ResetAuthenticatorModel> _logger;
public ResetAuthenticatorModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager,
UserManager<UserModel> userManager,
SignInManager<UserModel> signInManager,
ILogger<ResetAuthenticatorModel> logger)
{
_userManager = userManager;

View File

@ -8,17 +8,18 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class SetPasswordModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager;
public SetPasswordModel(
UserManager<IdentityUser> userManager,
SignInManager<IdentityUser> signInManager)
UserManager<UserModel> userManager,
SignInManager<UserModel> signInManager)
{
_userManager = userManager;
_signInManager = signInManager;

View File

@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{

View File

@ -8,17 +8,18 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account.Manage
{
public class TwoFactorAuthenticationModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly SignInManager<UserModel> _signInManager;
private readonly ILogger<TwoFactorAuthenticationModel> _logger;
public TwoFactorAuthenticationModel(
UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager, ILogger<TwoFactorAuthenticationModel> logger)
UserManager<UserModel> userManager, SignInManager<UserModel> signInManager, ILogger<TwoFactorAuthenticationModel> logger)
{
_userManager = userManager;
_signInManager = signInManager;

View File

@ -1,4 +1,4 @@
@inject SignInManager<IdentityUser> SignInManager
@inject SignInManager<UserModel> SignInManager
@{
var hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any();
}

View File

@ -18,22 +18,23 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Logging;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
public class RegisterModel : PageModel
{
private readonly SignInManager<IdentityUser> _signInManager;
private readonly UserManager<IdentityUser> _userManager;
private readonly IUserStore<IdentityUser> _userStore;
private readonly IUserEmailStore<IdentityUser> _emailStore;
private readonly SignInManager<UserModel> _signInManager;
private readonly UserManager<UserModel> _userManager;
private readonly IUserStore<UserModel> _userStore;
private readonly IUserEmailStore<UserModel> _emailStore;
private readonly ILogger<RegisterModel> _logger;
private readonly IEmailSender _emailSender;
public RegisterModel(
UserManager<IdentityUser> userManager,
IUserStore<IdentityUser> userStore,
SignInManager<IdentityUser> signInManager,
UserManager<UserModel> userManager,
IUserStore<UserModel> userStore,
SignInManager<UserModel> signInManager,
ILogger<RegisterModel> logger,
IEmailSender emailSender)
{
@ -154,27 +155,27 @@ namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
return Page();
}
private IdentityUser CreateUser()
private UserModel CreateUser()
{
try
{
return Activator.CreateInstance<IdentityUser>();
return Activator.CreateInstance<UserModel>();
}
catch
{
throw new InvalidOperationException($"Can't create an instance of '{nameof(IdentityUser)}'. " +
$"Ensure that '{nameof(IdentityUser)}' is not an abstract class and has a parameterless constructor, or alternatively " +
throw new InvalidOperationException($"Can't create an instance of '{nameof(UserModel)}'. " +
$"Ensure that '{nameof(UserModel)}' is not an abstract class and has a parameterless constructor, or alternatively " +
$"override the register page in /Areas/Identity/Pages/Account/Register.cshtml");
}
}
private IUserEmailStore<IdentityUser> GetEmailStore()
private IUserEmailStore<UserModel> GetEmailStore()
{
if (!_userManager.SupportsUserEmail)
{
throw new NotSupportedException("The default UI requires a user store with email support.");
}
return (IUserEmailStore<IdentityUser>)_userStore;
return (IUserEmailStore<UserModel>)_userStore;
}
}
}

View File

@ -11,16 +11,17 @@ using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly UserManager<UserModel> _userManager;
private readonly IEmailSender _sender;
public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
public RegisterConfirmationModel(UserManager<UserModel> userManager, IEmailSender sender)
{
_userManager = userManager;
_sender = sender;

View File

@ -13,16 +13,17 @@ using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
[AllowAnonymous]
public class ResendEmailConfirmationModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly UserManager<UserModel> _userManager;
private readonly IEmailSender _emailSender;
public ResendEmailConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender emailSender)
public ResendEmailConfirmationModel(UserManager<UserModel> userManager, IEmailSender emailSender)
{
_userManager = userManager;
_emailSender = emailSender;

View File

@ -11,14 +11,15 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.WebUtilities;
using PSTW_CentralSystem.Models;
namespace PSTW_CentralSystem.Areas.Identity.Pages.Account
{
public class ResetPasswordModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly UserManager<UserModel> _userManager;
public ResetPasswordModel(UserManager<IdentityUser> userManager)
public ResetPasswordModel(UserManager<UserModel> userManager)
{
_userManager = userManager;
}

View File

@ -2,3 +2,4 @@
@using PSTW_CentralSystem.Areas.Identity
@using PSTW_CentralSystem.Areas.Identity.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using PSTW_CentralSystem.Models

View File

@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PSTW_CentralSystem.DBContext;
using PSTW_CentralSystem.Models;
using System.Diagnostics;
namespace PSTW_CentralSystem.Controllers.API
{
[ApiController]
[Route("[controller]")]
public class AdminAPI : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly AuthDBContext _authDbContext;
public AdminAPI(ILogger<HomeController> logger, AuthDBContext authDbContext)
{
_logger = logger;
_authDbContext = authDbContext;
}
[HttpPost("GetModuleInformation")]
public async Task<IActionResult> GetModuleInformation()
{
var qcList = await _authDbContext.ModuleSettings.ToListAsync();
return Json(qcList);
}
}
}

View File

@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using PSTW_CentralSystem.DBContext;
using PSTW_CentralSystem.Models;
using System.Diagnostics;
namespace PSTW_CentralSystem.Controllers
{
[Authorize(Policy = "RoleModulePolicy")]
public class AdminController : Controller
{
private readonly AuthDBContext _authDbContext;
private readonly ILogger<HomeController> _logger;
public AdminController(ILogger<HomeController> logger, AuthDBContext authDbContext)
{
_logger = logger;
_authDbContext = authDbContext;
}
public IActionResult Index()
{
return View();
}
public IActionResult ModuleAdmin()
{
return View();
}
public IActionResult ModuleSetting(int? id)
{
if (id == null)
{
return NotFound();
}
var moduleSettings = _authDbContext.ModuleSettings.Find(id);
if (moduleSettings == null)
{
return NotFound();
}
return View(moduleSettings);
}
}
}

View File

@ -1,6 +1,10 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using PSTW_CentralSystem.DBContext;
using PSTW_CentralSystem.Models;
using Newtonsoft.Json;
using System.Text.Json;
using System.Data;
namespace PSTW_CentralSystem.CustomPolicy
{
@ -11,10 +15,10 @@ namespace PSTW_CentralSystem.CustomPolicy
public class RoleModuleHandler : AuthorizationHandler<RoleModulePolicy>
{
private readonly AuthDBContext _authDBContext;
private readonly UserManager<IdentityUser> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly UserManager<UserModel> _userManager;
private readonly RoleManager<RoleModel> _roleManager;
private readonly IHttpContextAccessor _httpContextAccessor;
public RoleModuleHandler( AuthDBContext authDBContext, UserManager<IdentityUser> userManager, RoleManager<IdentityRole> roleManager, IHttpContextAccessor httpContextAccessor)
public RoleModuleHandler( AuthDBContext authDBContext, UserManager<UserModel> userManager, RoleManager<RoleModel> roleManager, IHttpContextAccessor httpContextAccessor)
{
_authDBContext = authDBContext;
_userManager = userManager;
@ -25,10 +29,105 @@ namespace PSTW_CentralSystem.CustomPolicy
{
// Get the current user
var currentUser = await _userManager.GetUserAsync(context.User);
var userRole = await _userManager.GetRolesAsync(currentUser ?? new IdentityUser());
var userRole = await _userManager.GetRolesAsync(currentUser ?? new UserModel());
var moduleName = _httpContextAccessor.HttpContext?.GetRouteData().Values["controller"]?.ToString();
var regModule = _httpContextAccessor.HttpContext?.GetRouteData().Values["page"]?.ToString();
var pageName = _httpContextAccessor.HttpContext?.GetRouteData().Values["action"]?.ToString();
var registeredModule = _authDBContext.ModuleSettings.FirstOrDefault(x => x.ModuleName == moduleName);
if (checkIfSuperAdmin())
{
context.Succeed(requirement);
}
else {
checkModuleExistOrNot();
checkModuleHaveRoleOrNot();
}
bool checkIfSuperAdmin()
{
var superAdminRole = _authDBContext.Roles.Where(r => r.Name == "SuperAdmin").FirstOrDefault();
var sysAdminRole = _authDBContext.Roles.Where(r => r.Name == "SystemAdmin").FirstOrDefault();
if (userRole.ToString() != null && userRole.Contains("SuperAdmin") && superAdminRole?.Id == 1)
{
return true;
}
else if (userRole.ToString() != null && userRole.Contains("SystemAdmin") && sysAdminRole?.Id == 2)
{
return true;
}
else
{
return false;
}
}
void checkModuleExistOrNot()
{
if (registeredModule == null)
{
context.Fail();
}
else
{
checkModuleActiveOrNot();
}
}
void checkModuleActiveOrNot()
{
if (registeredModule.ModuleStatus == 0)
{
context.Fail();
}
}
void checkModuleHaveRoleOrNot()
{
var allowedUserTypes = registeredModule?.AllowedUserType ?? "";
if (allowedUserTypes == "Public" || userRole.Any(role => allowedUserTypes.Contains(role)))
{
context.Succeed(requirement);
}
else if (currentUser != null && allowedUserTypes == "Registered User" )
{
checkMethodAndRole();
}
else
{
context.Fail();
}
}
void checkMethodAndRole()
{
// Load all ModuleSettings and process them in memory
var moduleSettings = _authDBContext.ModuleSettings.AsEnumerable();
// Check if the method exists in the module settings
// Check if the method exists in the module settings
var isMethodExist = moduleSettings
.FirstOrDefault(m => m.MethodAllowedUserType?.Any(mt => mt.MethodName == pageName) == true);
if (isMethodExist != null) // Check if the method exists which means method is registered
{
var registeredMethod = moduleSettings.Where(m => m.MethodAllowedUserType != null && m.MethodAllowedUserType.Any(mt => mt.MethodName == pageName)).FirstOrDefault();
var allowedUserTypes = registeredMethod?.MethodAllowedUserType?.Where(mt => mt.MethodName == pageName).Select(mt => mt.AllowedUserTypesArray).FirstOrDefault() ?? Array.Empty<string>();
if (userRole.Any(role => allowedUserTypes.Contains(role)) || allowedUserTypes.Contains("All")) // Check if the user role is allowed, allowing only registered user to access.
{
context.Succeed(requirement);
}
else
{
context.Fail();
}
}
else // No method is registered to allow all method to be accessed
{
context.Succeed(requirement);
}
}
}
}
}

View File

@ -2,10 +2,12 @@
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using PSTW_CentralSystem.Models;
using System.Text.Json;
namespace PSTW_CentralSystem.DBContext
{
public class AuthDBContext : IdentityDbContext<IdentityUser, IdentityRole, string>
public class AuthDBContext : IdentityDbContext<UserModel, RoleModel, int>
{
private readonly IWebHostEnvironment _hostingEnvironment;
public AuthDBContext(DbContextOptions<AuthDBContext> options, IWebHostEnvironment hostingEnvironment) : base(options)
@ -16,8 +18,58 @@ namespace PSTW_CentralSystem.DBContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ModuleSettingModel>()
.Property(e => e.MethodAllowedUserType)
.HasConversion(
v => JsonConvert.SerializeObject(v), // Convert List<MethodAllowedUserType> to JSON string
v => JsonConvert.DeserializeObject<List<MethodAllowedUserType>>(v));
// Seeding Roles
modelBuilder.Entity<RoleModel>().HasData(
new RoleModel { Id = 1, Name = "SuperAdmin", NormalizedName = "SuperAdmin".ToUpper(), Description = "Can access all pages" },
new RoleModel { Id = 2, Name = "SystemAdmin", NormalizedName = "SystemAdmin".ToUpper(), Description = "Can access some admin pages" },
new RoleModel { Id = 3, Name = "Engineer", NormalizedName = "Engineer".ToUpper(), Description = "Can access operation pages" },
new RoleModel { Id = 4, Name = "Observer", NormalizedName = "Observer".ToUpper(), Description = "Can access data viewer pages" });
var passwordHasher = new PasswordHasher<UserModel>();
var superAdmin = new UserModel
{
Id = 1, // Use `Guid.NewGuid().ToString()` if the Id is a string.
FullName = "MAAdmin",
UserName = "admin@pstw.com.my",
NormalizedUserName = "ADMIN@PSTW.COM.MY",
Email = "admin@pstw.com.my",
NormalizedEmail = "ADMIN@PSTW.COM.MY",
SecurityStamp = Guid.NewGuid().ToString(),
EmailConfirmed = true
};
var systemAdmin = new UserModel
{
Id = 2, // Use `Guid.NewGuid().ToString()` if the Id is a string.
FullName = "SysAdmin",
UserName = "sysadmin@pstw.com.my",
NormalizedUserName = "SYSADMIN@PSTW.COM.MY",
Email = "sysadmin@pstw.com.my",
NormalizedEmail = "SYSADMIN@PSTW.COM.MY",
SecurityStamp = Guid.NewGuid().ToString(),
EmailConfirmed = true
};
// Hash the password
superAdmin.PasswordHash = passwordHasher.HashPassword(superAdmin, "5u@Dmin12345678");
systemAdmin.PasswordHash = passwordHasher.HashPassword(systemAdmin, "5ys@Dmin12345678");
modelBuilder.Entity<UserModel>().HasData(superAdmin, systemAdmin);
// Seeding AdminRole
modelBuilder.Entity<IdentityUserRole<int>>().HasData(
new IdentityUserRole<int> { UserId = 1, RoleId = 1 });
}
public new DbSet<UserModel> Users { get; set; }
public new DbSet<RoleModel> Roles { get; set; }
public DbSet<ModuleSettingModel> ModuleSettings { get; set; }
}
}

View File

@ -2,6 +2,7 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using PSTW_CentralSystem.DBContext;
@ -11,7 +12,7 @@ using PSTW_CentralSystem.DBContext;
namespace PSTW_CentralSystem.Migrations
{
[DbContext(typeof(AuthDBContext))]
[Migration("20241114071237_Initiate")]
[Migration("20241120071120_Initiate")]
partial class Initiate
{
/// <inheritdoc />
@ -22,15 +23,163 @@ namespace PSTW_CentralSystem.Migrations
.HasAnnotation("ProductVersion", "8.0.11")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
{
b.Property<string>("Id")
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<int>("RoleId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<int>", b =>
{
b.Property<int>("UserId")
.HasColumnType("int");
b.Property<int>("RoleId")
.HasColumnType("int");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
b.HasData(
new
{
UserId = 1,
RoleId = 1
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
{
b.Property<int>("UserId")
.HasColumnType("int");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("PSTW_CentralSystem.Models.ModuleSettingModel", b =>
{
b.Property<int>("SettingId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("SettingId"));
b.Property<string>("AllowedUserType")
.HasColumnType("longtext");
b.Property<string>("Description")
.HasColumnType("longtext");
b.Property<string>("MethodAllowedUserType")
.HasColumnType("json");
b.Property<string>("ModuleName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<int>("ModuleStatus")
.HasColumnType("int");
b.HasKey("SettingId");
b.ToTable("ModuleSettings");
});
modelBuilder.Entity("PSTW_CentralSystem.Models.RoleModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Description")
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
@ -46,35 +195,45 @@ namespace PSTW_CentralSystem.Migrations
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
b.HasData(
new
{
Id = 1,
Description = "Can access all pages",
Name = "SuperAdmin",
NormalizedName = "SUPERADMIN"
},
new
{
Id = 2,
Description = "Can access some admin pages",
Name = "SystemAdmin",
NormalizedName = "SYSTEMADMIN"
},
new
{
Id = 3,
Description = "Can access operation pages",
Name = "Engineer",
NormalizedName = "ENGINEER"
},
new
{
Id = 4,
Description = "Can access data viewer pages",
Name = "Observer",
NormalizedName = "OBSERVER"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
modelBuilder.Entity("PSTW_CentralSystem.Models.UserModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
@ -90,11 +249,14 @@ namespace PSTW_CentralSystem.Migrations
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("FullName")
.HasColumnType("longtext");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime");
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
@ -123,6 +285,9 @@ namespace PSTW_CentralSystem.Migrations
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<int?>("UserStatus")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
@ -133,132 +298,89 @@ namespace PSTW_CentralSystem.Migrations
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
b.HasData(
new
{
Id = 1,
AccessFailedCount = 0,
ConcurrencyStamp = "e4431078-c853-410b-8369-eba4c21937f0",
Email = "admin@pstw.com.my",
EmailConfirmed = true,
FullName = "MAAdmin",
LockoutEnabled = false,
NormalizedEmail = "ADMIN@PSTW.COM.MY",
NormalizedUserName = "ADMIN@PSTW.COM.MY",
PasswordHash = "AQAAAAIAAYagAAAAENdEN8F2O8D9gJofhSQV6UDhcjh2+C7TvjAC+KgJMUbFJbGBNXPvOORKISb0jRhftA==",
PhoneNumberConfirmed = false,
SecurityStamp = "bce6229e-4b74-4324-a89d-5f3210daccfb",
TwoFactorEnabled = false,
UserName = "admin@pstw.com.my"
},
new
{
Id = 2,
AccessFailedCount = 0,
ConcurrencyStamp = "94504423-6916-4a9e-baf2-271beb3b3f2a",
Email = "sysadmin@pstw.com.my",
EmailConfirmed = true,
FullName = "SysAdmin",
LockoutEnabled = false,
NormalizedEmail = "SYSADMIN@PSTW.COM.MY",
NormalizedUserName = "SYSADMIN@PSTW.COM.MY",
PasswordHash = "AQAAAAIAAYagAAAAEApFYVWK3qRpzEM6jFFw5EDohJ+xHCxX2EDABsUg65pa0iA1h54wp9yf/gp2qVxvVg==",
PhoneNumberConfirmed = false,
SecurityStamp = "0d07b058-1d11-40a9-875e-6631d26702cb",
TwoFactorEnabled = false,
UserName = "sysadmin@pstw.com.my"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
b.HasOne("PSTW_CentralSystem.Models.RoleModel", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
b.HasOne("PSTW_CentralSystem.Models.UserModel", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
b.HasOne("PSTW_CentralSystem.Models.UserModel", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<int>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
b.HasOne("PSTW_CentralSystem.Models.RoleModel", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
b.HasOne("PSTW_CentralSystem.Models.UserModel", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
b.HasOne("PSTW_CentralSystem.Models.UserModel", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)

View File

@ -1,9 +1,11 @@
using System;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using MySql.EntityFrameworkCore.Metadata;
#nullable disable
#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional
namespace PSTW_CentralSystem.Migrations
{
/// <inheritdoc />
@ -13,40 +15,58 @@ namespace PSTW_CentralSystem.Migrations
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.Annotation("MySQL:Charset", "utf8mb4");
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<string>(type: "varchar(255)", nullable: false),
Name = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
Description = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Name = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
NormalizedName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
})
.Annotation("MySQL:Charset", "utf8mb4");
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
Id = table.Column<string>(type: "varchar(255)", nullable: false),
UserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
Email = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true),
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
FullName = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
UserStatus = table.Column<int>(type: "int", nullable: true),
UserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
NormalizedUserName = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
Email = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
NormalizedEmail = table.Column<string>(type: "varchar(256)", maxLength: 256, nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
EmailConfirmed = table.Column<bool>(type: "tinyint(1)", nullable: false),
PasswordHash = table.Column<string>(type: "longtext", nullable: true),
SecurityStamp = table.Column<string>(type: "longtext", nullable: true),
ConcurrencyStamp = table.Column<string>(type: "longtext", nullable: true),
PhoneNumber = table.Column<string>(type: "longtext", nullable: true),
PasswordHash = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
SecurityStamp = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ConcurrencyStamp = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
PhoneNumber = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
PhoneNumberConfirmed = table.Column<bool>(type: "tinyint(1)", nullable: false),
TwoFactorEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(type: "datetime", nullable: true),
LockoutEnd = table.Column<DateTimeOffset>(type: "datetime(6)", nullable: true),
LockoutEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
AccessFailedCount = table.Column<int>(type: "int", nullable: false)
},
@ -54,17 +74,41 @@ namespace PSTW_CentralSystem.Migrations
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
})
.Annotation("MySQL:Charset", "utf8mb4");
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "ModuleSettings",
columns: table => new
{
SettingId = table.Column<int>(type: "int", nullable: false)
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
ModuleName = table.Column<string>(type: "varchar(50)", maxLength: 50, nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
AllowedUserType = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
MethodAllowedUserType = table.Column<string>(type: "json", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ModuleStatus = table.Column<int>(type: "int", nullable: false),
Description = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
table.PrimaryKey("PK_ModuleSettings", x => x.SettingId);
})
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySQL:ValueGenerationStrategy", MySQLValueGenerationStrategy.IdentityColumn),
RoleId = table.Column<string>(type: "varchar(255)", nullable: false),
ClaimType = table.Column<string>(type: "longtext", nullable: true),
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
RoleId = table.Column<int>(type: "int", nullable: false),
ClaimType = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ClaimValue = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
@ -76,17 +120,19 @@ namespace PSTW_CentralSystem.Migrations
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySQL:Charset", "utf8mb4");
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("MySQL:ValueGenerationStrategy", MySQLValueGenerationStrategy.IdentityColumn),
UserId = table.Column<string>(type: "varchar(255)", nullable: false),
ClaimType = table.Column<string>(type: "longtext", nullable: true),
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
UserId = table.Column<int>(type: "int", nullable: false),
ClaimType = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
ClaimValue = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
@ -98,16 +144,19 @@ namespace PSTW_CentralSystem.Migrations
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySQL:Charset", "utf8mb4");
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(type: "varchar(255)", nullable: false),
ProviderKey = table.Column<string>(type: "varchar(255)", nullable: false),
ProviderDisplayName = table.Column<string>(type: "longtext", nullable: true),
UserId = table.Column<string>(type: "varchar(255)", nullable: false)
LoginProvider = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ProviderKey = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
ProviderDisplayName = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4"),
UserId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
@ -119,14 +168,14 @@ namespace PSTW_CentralSystem.Migrations
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySQL:Charset", "utf8mb4");
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<string>(type: "varchar(255)", nullable: false),
RoleId = table.Column<string>(type: "varchar(255)", nullable: false)
UserId = table.Column<int>(type: "int", nullable: false),
RoleId = table.Column<int>(type: "int", nullable: false)
},
constraints: table =>
{
@ -144,16 +193,19 @@ namespace PSTW_CentralSystem.Migrations
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySQL:Charset", "utf8mb4");
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<string>(type: "varchar(255)", nullable: false),
LoginProvider = table.Column<string>(type: "varchar(255)", nullable: false),
Name = table.Column<string>(type: "varchar(255)", nullable: false),
UserId = table.Column<int>(type: "int", nullable: false),
LoginProvider = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Name = table.Column<string>(type: "varchar(255)", nullable: false)
.Annotation("MySql:CharSet", "utf8mb4"),
Value = table.Column<string>(type: "longtext", nullable: true)
.Annotation("MySql:CharSet", "utf8mb4")
},
constraints: table =>
{
@ -165,7 +217,32 @@ namespace PSTW_CentralSystem.Migrations
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
})
.Annotation("MySQL:Charset", "utf8mb4");
.Annotation("MySql:CharSet", "utf8mb4");
migrationBuilder.InsertData(
table: "AspNetRoles",
columns: new[] { "Id", "ConcurrencyStamp", "Description", "Name", "NormalizedName" },
values: new object[,]
{
{ 1, null, "Can access all pages", "SuperAdmin", "SUPERADMIN" },
{ 2, null, "Can access some admin pages", "SystemAdmin", "SYSTEMADMIN" },
{ 3, null, "Can access operation pages", "Engineer", "ENGINEER" },
{ 4, null, "Can access data viewer pages", "Observer", "OBSERVER" }
});
migrationBuilder.InsertData(
table: "AspNetUsers",
columns: new[] { "Id", "AccessFailedCount", "ConcurrencyStamp", "Email", "EmailConfirmed", "FullName", "LockoutEnabled", "LockoutEnd", "NormalizedEmail", "NormalizedUserName", "PasswordHash", "PhoneNumber", "PhoneNumberConfirmed", "SecurityStamp", "TwoFactorEnabled", "UserName", "UserStatus" },
values: new object[,]
{
{ 1, 0, "e4431078-c853-410b-8369-eba4c21937f0", "admin@pstw.com.my", true, "MAAdmin", false, null, "ADMIN@PSTW.COM.MY", "ADMIN@PSTW.COM.MY", "AQAAAAIAAYagAAAAENdEN8F2O8D9gJofhSQV6UDhcjh2+C7TvjAC+KgJMUbFJbGBNXPvOORKISb0jRhftA==", null, false, "bce6229e-4b74-4324-a89d-5f3210daccfb", false, "admin@pstw.com.my", null },
{ 2, 0, "94504423-6916-4a9e-baf2-271beb3b3f2a", "sysadmin@pstw.com.my", true, "SysAdmin", false, null, "SYSADMIN@PSTW.COM.MY", "SYSADMIN@PSTW.COM.MY", "AQAAAAIAAYagAAAAEApFYVWK3qRpzEM6jFFw5EDohJ+xHCxX2EDABsUg65pa0iA1h54wp9yf/gp2qVxvVg==", null, false, "0d07b058-1d11-40a9-875e-6631d26702cb", false, "sysadmin@pstw.com.my", null }
});
migrationBuilder.InsertData(
table: "AspNetUserRoles",
columns: new[] { "RoleId", "UserId" },
values: new object[] { 1, 1 });
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
@ -223,6 +300,9 @@ namespace PSTW_CentralSystem.Migrations
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable(
name: "ModuleSettings");
migrationBuilder.DropTable(
name: "AspNetRoles");

View File

@ -2,6 +2,7 @@
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using PSTW_CentralSystem.DBContext;
@ -19,15 +20,163 @@ namespace PSTW_CentralSystem.Migrations
.HasAnnotation("ProductVersion", "8.0.11")
.HasAnnotation("Relational:MaxIdentifierLength", 64);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
{
b.Property<string>("Id")
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<int>("RoleId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<int>("UserId")
.HasColumnType("int");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<int>", b =>
{
b.Property<int>("UserId")
.HasColumnType("int");
b.Property<int>("RoleId")
.HasColumnType("int");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
b.HasData(
new
{
UserId = 1,
RoleId = 1
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
{
b.Property<int>("UserId")
.HasColumnType("int");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("PSTW_CentralSystem.Models.ModuleSettingModel", b =>
{
b.Property<int>("SettingId")
.ValueGeneratedOnAdd()
.HasColumnType("int");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("SettingId"));
b.Property<string>("AllowedUserType")
.HasColumnType("longtext");
b.Property<string>("Description")
.HasColumnType("longtext");
b.Property<string>("MethodAllowedUserType")
.HasColumnType("json");
b.Property<string>("ModuleName")
.IsRequired()
.HasMaxLength(50)
.HasColumnType("varchar(50)");
b.Property<int>("ModuleStatus")
.HasColumnType("int");
b.HasKey("SettingId");
b.ToTable("ModuleSettings");
});
modelBuilder.Entity("PSTW_CentralSystem.Models.RoleModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasColumnType("longtext");
b.Property<string>("Description")
.HasColumnType("longtext");
b.Property<string>("Name")
.HasMaxLength(256)
.HasColumnType("varchar(256)");
@ -43,35 +192,45 @@ namespace PSTW_CentralSystem.Migrations
.HasDatabaseName("RoleNameIndex");
b.ToTable("AspNetRoles", (string)null);
b.HasData(
new
{
Id = 1,
Description = "Can access all pages",
Name = "SuperAdmin",
NormalizedName = "SUPERADMIN"
},
new
{
Id = 2,
Description = "Can access some admin pages",
Name = "SystemAdmin",
NormalizedName = "SYSTEMADMIN"
},
new
{
Id = 3,
Description = "Can access operation pages",
Name = "Engineer",
NormalizedName = "ENGINEER"
},
new
{
Id = 4,
Description = "Can access data viewer pages",
Name = "Observer",
NormalizedName = "OBSERVER"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
modelBuilder.Entity("PSTW_CentralSystem.Models.UserModel", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("RoleId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUser", b =>
{
b.Property<string>("Id")
.HasColumnType("varchar(255)");
MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property<int>("Id"));
b.Property<int>("AccessFailedCount")
.HasColumnType("int");
@ -87,11 +246,14 @@ namespace PSTW_CentralSystem.Migrations
b.Property<bool>("EmailConfirmed")
.HasColumnType("tinyint(1)");
b.Property<string>("FullName")
.HasColumnType("longtext");
b.Property<bool>("LockoutEnabled")
.HasColumnType("tinyint(1)");
b.Property<DateTimeOffset?>("LockoutEnd")
.HasColumnType("datetime");
.HasColumnType("datetime(6)");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256)
@ -120,6 +282,9 @@ namespace PSTW_CentralSystem.Migrations
.HasMaxLength(256)
.HasColumnType("varchar(256)");
b.Property<int?>("UserStatus")
.HasColumnType("int");
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
@ -130,132 +295,89 @@ namespace PSTW_CentralSystem.Migrations
.HasDatabaseName("UserNameIndex");
b.ToTable("AspNetUsers", (string)null);
b.HasData(
new
{
Id = 1,
AccessFailedCount = 0,
ConcurrencyStamp = "e4431078-c853-410b-8369-eba4c21937f0",
Email = "admin@pstw.com.my",
EmailConfirmed = true,
FullName = "MAAdmin",
LockoutEnabled = false,
NormalizedEmail = "ADMIN@PSTW.COM.MY",
NormalizedUserName = "ADMIN@PSTW.COM.MY",
PasswordHash = "AQAAAAIAAYagAAAAENdEN8F2O8D9gJofhSQV6UDhcjh2+C7TvjAC+KgJMUbFJbGBNXPvOORKISb0jRhftA==",
PhoneNumberConfirmed = false,
SecurityStamp = "bce6229e-4b74-4324-a89d-5f3210daccfb",
TwoFactorEnabled = false,
UserName = "admin@pstw.com.my"
},
new
{
Id = 2,
AccessFailedCount = 0,
ConcurrencyStamp = "94504423-6916-4a9e-baf2-271beb3b3f2a",
Email = "sysadmin@pstw.com.my",
EmailConfirmed = true,
FullName = "SysAdmin",
LockoutEnabled = false,
NormalizedEmail = "SYSADMIN@PSTW.COM.MY",
NormalizedUserName = "SYSADMIN@PSTW.COM.MY",
PasswordHash = "AQAAAAIAAYagAAAAEApFYVWK3qRpzEM6jFFw5EDohJ+xHCxX2EDABsUg65pa0iA1h54wp9yf/gp2qVxvVg==",
PhoneNumberConfirmed = false,
SecurityStamp = "0d07b058-1d11-40a9-875e-6631d26702cb",
TwoFactorEnabled = false,
UserName = "sysadmin@pstw.com.my"
});
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<int>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int");
b.Property<string>("ClaimType")
.HasColumnType("longtext");
b.Property<string>("ClaimValue")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderKey")
.HasColumnType("varchar(255)");
b.Property<string>("ProviderDisplayName")
.HasColumnType("longtext");
b.Property<string>("UserId")
.IsRequired()
.HasColumnType("varchar(255)");
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("RoleId")
.HasColumnType("varchar(255)");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId")
.HasColumnType("varchar(255)");
b.Property<string>("LoginProvider")
.HasColumnType("varchar(255)");
b.Property<string>("Name")
.HasColumnType("varchar(255)");
b.Property<string>("Value")
.HasColumnType("longtext");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens", (string)null);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
b.HasOne("PSTW_CentralSystem.Models.RoleModel", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<int>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
b.HasOne("PSTW_CentralSystem.Models.UserModel", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<int>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
b.HasOne("PSTW_CentralSystem.Models.UserModel", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<int>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
b.HasOne("PSTW_CentralSystem.Models.RoleModel", null)
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
b.HasOne("PSTW_CentralSystem.Models.UserModel", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<int>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null)
b.HasOne("PSTW_CentralSystem.Models.UserModel", null)
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)

View File

@ -12,13 +12,16 @@ namespace PSTW_CentralSystem.Models
[Required]
[MaxLength(50)]
public string ModuleName { get; set; }
public string? ModuleName { get; set; }
public string? AllowedUserType { get; set; }
[Column(TypeName = "json")]
public string? AllowedUsertype { get; set; }
public List<MethodAllowedUserType>? MethodAllowedUserType { get; set; }
public int ModuleStatus { get; set; }
public string? Description { get; set; }
[NotMapped] // This property will not be mapped to the database
public string[]? AllowedUsertypesArray { get; set; }
}
public class MethodAllowedUserType
{
public string? MethodName { get; set; }
public string[]? AllowedUserTypesArray { get; set; }
}
}

9
Models/RoleModel.cs Normal file
View File

@ -0,0 +1,9 @@
using Microsoft.AspNetCore.Identity;
namespace PSTW_CentralSystem.Models
{
public class RoleModel : IdentityRole<int>
{
public string? Description { get; set; }
}
}

13
Models/UserModel.cs Normal file
View File

@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Identity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PSTW_CentralSystem.Models
{
public class UserModel : IdentityUser<int> // Specify the type for the primary key
{
// Add custom properties
public string? FullName { get; set; }
public int? UserStatus { get; set; }
}
}

View File

@ -21,13 +21,14 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.7" />
<PackageReference Include="MySql.EntityFrameworkCore" Version="8.0.8" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="8.0.2" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.3" />
</ItemGroup>
<ItemGroup>
<Folder Include="Logs\" />
<Folder Include="Migrations\" />
</ItemGroup>
</Project>

View File

@ -3,14 +3,21 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using PSTW_CentralSystem.CustomPolicy;
using PSTW_CentralSystem.DBContext;
using PSTW_CentralSystem.Models;
using Serilog;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
internal class Program
{
private static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
// Add services to the container.
builder.Services.AddControllersWithViews();
Log.Logger = new LoggerConfiguration()
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddRazorPages();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Configuration)
.Enrich.FromLogContext()
.WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == Serilog.Events.LogEventLevel.Information)
@ -25,48 +32,51 @@ Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
builder.Logging.AddSerilog();
builder.Logging.AddSerilog();
builder.Services.AddDbContext<AuthDBContext>(options =>
{
var config = builder.Configuration;
options.UseMySQL(config.GetConnectionString("DefaultConnection") ?? string.Empty, mysqlOptions => mysqlOptions.CommandTimeout(300));
});
builder.Services.AddDbContext<AuthDBContext>(options =>
{
options.UseMySql(connectionString, new MySqlServerVersion(new Version(8, 0, 39)),
mysqlOptions => mysqlOptions.CommandTimeout(120)
);
});
//builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true).AddEntityFrameworkStores<AuthDBContext>();
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
//builder.Services.AddDefaultIdentity<UserModel>(options => options.SignIn.RequireConfirmedAccount = true).AddEntityFrameworkStores<AuthDBContext>();
builder.Services.AddIdentity<UserModel, RoleModel>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<AuthDBContext>()
.AddDefaultUI()
.AddDefaultTokenProviders();
builder.Services.AddAuthorizationCore(options =>
{
builder.Services.AddAuthorizationCore(options =>
{
options.AddPolicy("RoleModulePolicy", policy =>
policy.Requirements.Add(new RoleModulePolicy()));
});
});
// Add scope
builder.Services.AddScoped<IAuthorizationHandler, RoleModuleHandler>();
// Add scope
builder.Services.AddScoped<IAuthorizationHandler, RoleModuleHandler>();
var app = builder.Build();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseRouting();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllerRoute(
app.UseAuthorization();
app.MapRazorPages();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
app.Run();
app.Run();
}
}

19
Views/Admin/Index.cshtml Normal file
View File

@ -0,0 +1,19 @@
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
ViewData["Title"] = "Admin Dashboard";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="row">
<div class="col-md-6 col-lg-3">
<div class="card card-hover">
<div class="box bg-cyan text-center">
<h1 class="font-light text-white">
<i class="mdi mdi-view-dashboard"></i>
</h1>
<h6 class="text-white">Dashboard</h6>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,177 @@
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@{
ViewData["Title"] = "Module Administration";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<p>
<a asp-action="CreateModule">Create New</a>
</p>
<div class="row" id="app">
<div class="col-md-12 col-lg-12">
<div class="card">
<div class="card-body">
<h4 class="card-title">Latest Posts</h4>
<div class="col-md-12 col-lg-12">
<div v-if="moduleData">
<table class="table table-bordered border-primary">
<thead>
<tr>
<th>
ModuleName
</th>
<th>
Access Type
</th>
<th>
Configured Page
</th>
<th>
Description
</th>
<th>
ModuleStatus
</th>
<th>
Action
</th>
</tr>
</thead>
<tbody>
<tr v-for="module in moduleData">
<td class="align-middle">
{{module.moduleName}}
</td>
<td class="align-middle">
{{module.allowedUserType}}
</td>
<td class="align-middle">
<ul>
<li v-for="(method, index) in module.methodAllowedUserType" :key="index">
<strong>Method Name:</strong> {{ method.methodName }}<br>
<strong>Allowed User Types:</strong>
<span v-for="(userType, idx) in method.allowedUserTypesArray" :key="idx">
{{ userType }}<span v-if="idx < method.allowedUserTypesArray.length - 1">, </span>
</span>
</li>
</ul>
</td>
<td class="align-middle">
{{module.description}}
</td>
<td class="align-middle">
<span>
<i :class="{'far fa-lg fa-times-circle': module.moduleStatus === 0, 'far fa-lg fa-check-circle': module.moduleStatus === 1}"
:style="{color: (module.moduleStatus === 0 ? 'red' : 'limegreen')}">
</i>
</span>
</td>
<td class="align-middle">
<button class="btn btn-primary" v-on:click="editModule(module)">Edit</button> |
<button class="btn btn-danger delete-button" v-on:click="deleteModule(module)">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
<div v-else><p>... Loading</p></div>
</div>
</div>
</div>
</div>
</div>
<!-- MODAL -->
<div class="modal fade" id="confirm-dialog" tabindex="-1" role="dialog" aria-labelledby="confirm-dialog-title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirm-dialog-title">Confirmation</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div v-if="selectedModule">
<div class="modal-body">
<p>Are you sure you want to delete module {{ selectedModule.moduleName }}?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<input type="hidden" id="delete-id">
<a id="confirmButton" href="#" class="btn btn-danger" v-on:click="confirmDelete(selectedModule)">Confirm</a>
</div>
</div>
<div v-else><p>Loading...</p></div>
</div>
</div>
</div>
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
<script>
const app = Vue.createApp({
data() {
return {
moduleData: null,
selectedModule: null
};
},
mounted() {
this.fetchModule();
},
methods: {
fetchModule() {
fetch('/AdminAPI/GetModuleInformation', {
method: 'POST'
})
.then(response => response.json())
.then(data => {
console.log(data);
if (data.length > 0) {
this.moduleData = data.length ? data : [];
}
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
},
editModule(module) {
// Check if the user ID exists
if (module.settingId) {
// Redirect the user to the edit user page
window.location.href = 'ModuleSetting/' + module.settingId;
} else {
console.error('Module ID not found');
}
},
deleteModule(module) {
this.selectedModule = module; // Set selected user
$('#confirm-dialog').modal('show'); // Show the modal
},
confirmDelete(module) {
fetch('/AdminAPI/DeleteModule/' + module.settingId, {
method: 'POST'
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to delete module');
}
// Remove the deleted user from the userData array
const index = this.moduleData.findIndex(u => u.settingId === module.settingId);
if (index !== -1) {
alert("Module deleted successfully");
this.moduleData.splice(index, 1);
}
$('#confirm-dialog').modal('hide'); // Hide the modal after deletion
})
.catch(error => {
console.error('Failed to delete module with status:', error);
});
}
}
})
app.mount('#app');
</script>
}

View File

@ -0,0 +1,178 @@
@*
For more information on enabling MVC for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860
*@
@model PSTW_CentralSystem.Models.ModuleSettingModel
@{
ViewData["Title"] = "Module Setting";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<p>
<a asp-action="CreateModule">Create New</a>
</p>
<div class="row" id="app">
<div class="col-md-12 col-lg-12">
<div class="card">
<div class="card-body">
<h4 class="card-title">{{module.moduleName}}</h4>
<div class="col-md-12 col-lg-12">
<div v-if="moduleData">
<table class="table table-bordered border-primary">
<thead>
<tr>
<th>
ModuleName
</th>
<th>
Access Type
</th>
<th>
Configured Page
</th>
<th>
Description
</th>
<th>
ModuleStatus
</th>
<th>
Action
</th>
</tr>
</thead>
<tbody>
<tr v-for="module in moduleData">
<td class="align-middle">
{{module.moduleName}}
</td>
<td class="align-middle">
{{module.allowedUserType}}
</td>
<td class="align-middle">
<ul>
<li v-for="(method, index) in module.methodAllowedUserType" :key="index">
<strong>Method Name:</strong> {{ method.methodName }}<br>
<strong>Allowed User Types:</strong>
<span v-for="(userType, idx) in method.allowedUserTypesArray" :key="idx">
{{ userType }}<span v-if="idx < method.allowedUserTypesArray.length - 1">, </span>
</span>
</li>
</ul>
</td>
<td class="align-middle">
{{module.description}}
</td>
<td class="align-middle">
<span>
<i :class="{'far fa-lg fa-times-circle': module.moduleStatus === 0, 'far fa-lg fa-check-circle': module.moduleStatus === 1}"
:style="{color: (module.moduleStatus === 0 ? 'red' : 'limegreen')}">
</i>
</span>
</td>
<td class="align-middle">
<button class="btn btn-primary" v-on:click="editModule(module)">Edit</button> |
<button class="btn btn-danger delete-button" v-on:click="deleteModule(module)">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
<div v-else><p>... Loading</p></div>
</div>
</div>
</div>
</div>
</div>
<!-- MODAL -->
<div class="modal fade" id="confirm-dialog" tabindex="-1" role="dialog" aria-labelledby="confirm-dialog-title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="confirm-dialog-title">Confirmation</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div v-if="selectedModule">
<div class="modal-body">
<p>Are you sure you want to delete module {{ selectedModule.moduleName }}?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<input type="hidden" id="delete-id">
<a id="confirmButton" href="#" class="btn btn-danger" @@click="confirmDelete(selectedModule)">Confirm</a>
</div>
</div>
<div v-else><p>Loading...</p></div>
</div>
</div>
</div>
@section Scripts {
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
<script>
const app = Vue.createApp({
data() {
return {
moduleData: null,
selectedModule: null
};
},
mounted() {
this.fetchModule();
},
methods: {
fetchModule() {
fetch('/AdminAPI/GetModuleInformation', {
method: 'POST'
})
.then(response => response.json())
.then(data => {
console.log(data);
if (data.length > 0) {
this.moduleData = data.length ? data : [];
}
})
.catch(error => {
console.error('There was a problem with the fetch operation:', error);
});
},
editModule(module) {
// Check if the user ID exists
if (module.settingId) {
// Redirect the user to the edit user page
window.location.href = 'EditModule/' + module.settingId;
} else {
console.error('Module ID not found');
}
},
deleteModule(module) {
this.selectedModule = module; // Set selected user
$('#confirm-dialog').modal('show'); // Show the modal
},
confirmDelete(module) {
fetch('/AdminAPI/DeleteModule/' + module.settingId, {
method: 'POST'
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to delete module');
}
// Remove the deleted user from the userData array
const index = this.moduleData.findIndex(u => u.settingId === module.settingId);
if (index !== -1) {
alert("Module deleted successfully");
this.moduleData.splice(index, 1);
}
$('#confirm-dialog').modal('hide'); // Hide the modal after deletion
})
.catch(error => {
console.error('Failed to delete module with status:', error);
});
}
}
})
app.mount('#app');
</script>
}

View File

@ -1,8 +1,10 @@
@{
ViewData["Title"] = "Home Page";
ViewData["Title"] = "PSTW Centralized System";
}
<div class="text-center">
<div class="row">
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
</div>

View File

@ -28,6 +28,11 @@
rel="stylesheet" />
<link href="/assets/extra-libs/calendar/calendar.css" rel="stylesheet" />
<link href="/dist/css/style.min.css" rel="stylesheet" />
<!-- Vue Js CSS -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
@* <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> *@
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
@ -119,6 +124,12 @@
<i class="mdi mdi-menu font-24"></i>
</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
<!-- ============================================================== -->
<!-- create new -->
<!-- ============================================================== -->
@ -202,7 +213,12 @@
aria-expanded="false">
<i class="font-24 mdi mdi-comment-processing"></i>
</a>
<div class=" dropdown-menu dropdown-menu-end mailbox animated bounceInDown "
<ul class="
dropdown-menu dropdown-menu-end
mailbox
animated
bounceInDown
"
aria-labelledby="2">
<ul class="list-style-none">
<li>
@ -210,7 +226,12 @@
<!-- Message -->
<a href="javascript:void(0)" class="link border-top">
<div class="d-flex no-block align-items-center p-10">
<span class=" btn btn-success btn-circle d-flex align-items-center justify-content-center ">
<span class="
btn btn-success btn-circle
d-flex
align-items-center
justify-content-center
">
<i class="mdi mdi-calendar text-white fs-4"></i>
</span>
<div class="ms-2">
@ -222,7 +243,12 @@
<!-- Message -->
<a href="javascript:void(0)" class="link border-top">
<div class="d-flex no-block align-items-center p-10">
<span class=" btn btn-info btn-circle d-flex align-items-center justify-content-center ">
<span class="
btn btn-info btn-circle
d-flex
align-items-center
justify-content-center
">
<i class="mdi mdi-settings fs-4"></i>
</span>
<div class="ms-2">
@ -234,7 +260,12 @@
<!-- Message -->
<a href="javascript:void(0)" class="link border-top">
<div class="d-flex no-block align-items-center p-10">
<span class="btn btn-primary btn-circle d-flex align-items-center justify-content-center ">
<span class="
btn btn-primary btn-circle
d-flex
align-items-center
justify-content-center
">
<i class="mdi mdi-account fs-4"></i>
</span>
<div class="ms-2">
@ -246,7 +277,12 @@
<!-- Message -->
<a href="javascript:void(0)" class="link border-top">
<div class="d-flex no-block align-items-center p-10">
<span class="btn btn-danger btn-circle d-flex align-items-center justify-content-center ">
<span class="
btn btn-danger btn-circle
d-flex
align-items-center
justify-content-center
">
<i class="mdi mdi-link fs-4"></i>
</span>
<div class="ms-2">
@ -258,7 +294,7 @@
</div>
</li>
</ul>
</div>
</ul>
</li>
<!-- ============================================================== -->
<!-- End Messages -->
@ -267,7 +303,13 @@
<!-- User profile and search -->
<!-- ============================================================== -->
<li class="nav-item dropdown">
<a class=" nav-link dropdown-toggle text-muted waves-effect waves-dark pro-pic "
<a class="
nav-link
dropdown-toggle
text-muted
waves-effect waves-dark
pro-pic
"
href="#"
id="navbarDropdown"
role="button"
@ -280,39 +322,21 @@
</a>
<ul class="dropdown-menu dropdown-menu-end user-dd animated"
aria-labelledby="navbarDropdown">
<li>
<a class="dropdown-item" href="javascript:void(0)"><i class="mdi mdi-account me-1 ms-1"></i> My Profile</a>
</li>
<li>
<a class="dropdown-item" href="javascript:void(0)"><i class="mdi mdi-wallet me-1 ms-1"></i> My Balance</a>
</li>
<li>
<a class="dropdown-item" href="javascript:void(0)"><i class="mdi mdi-email me-1 ms-1"></i> Inbox</a>
</li>
<li>
<div class="dropdown-divider"></div>
</li>
<li>
<a class="dropdown-item" href="javascript:void(0)">
<i class="mdi mdi-settings me-1 ms-1"></i> Account
Setting
</a>
</li>
<li>
<div class="dropdown-divider"></div>
</li>
<li>
<a class="dropdown-item" href="javascript:void(0)"><i class="fa fa-power-off me-1 ms-1"></i> Logout</a>
</li>
<li>
<div class="dropdown-divider"></div>
</li>
<li>
<div class="ps-4 p-10">
<a href="javascript:void(0)"
class="btn btn-sm btn-success btn-rounded text-white">View Profile</a>
</div>
</li>
</ul>
</li>
<!-- ============================================================== -->
@ -334,6 +358,25 @@
<!-- Sidebar navigation-->
<nav class="sidebar-nav">
<ul id="sidebarnav" class="pt-4">
<li class="sidebar-item">
<a class="sidebar-link has-arrow waves-effect waves-dark"
href="javascript:void(0)"
aria-expanded="false">
<i class="mdi mdi-receipt"></i><span class="hide-menu">Administrator </span>
</a>
<ul aria-expanded="false" class="collapse first-level">
<li class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" asp-area="" asp-controller="Admin" asp-action="Index" aria-expanded="false">
<i class="mdi mdi-view-dashboard"></i><span class="hide-menu">Admin Dashboard</span>
</a>
</li>
<li class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link" asp-area="" asp-controller="Admin" asp-action="ModuleAdmin" aria-expanded="false">
<i class="mdi mdi-view-dashboard"></i><span class="hide-menu">Module Administration</span>
</a>
</li>
</ul>
</li>
<li class="sidebar-item">
<a class="sidebar-link waves-effect waves-dark sidebar-link"
href="index.html"
@ -506,8 +549,15 @@
<li class="sidebar-item p-3">
<a href="https://github.com/wrappixel/matrix-admin-bt5"
target="_blank"
class=" w-100 btn btn-cyan d-flex align-items-center text-white ">
<i class="mdi mdi-cloud-download font-20 me-2"></i>Download Free
class="
w-100
btn btn-cyan
d-flex
align-items-center
text-white
">
<i class="mdi mdi-cloud-download font-20 me-2"></i>Download
Free
</a>
</li>
</ul>
@ -522,14 +572,23 @@
<!-- ============================================================== -->
<!-- Page wrapper -->
<!-- ============================================================== -->
<div class="container-fluid page-wrapper">
<div class="page-wrapper">
<!-- ============================================================== -->
<!-- Bread crumb and right sidebar toggle -->
<!-- ============================================================== -->
<div class="page-breadcrumb">
<div class="row">
<div class="col-12 d-flex no-block align-items-center">
<h4 class="page-title">Dashboard-2</h4>
@{
if (ViewBag.Title != null || ViewBag.Title != "")
{
<h1 class="m-0 page-title">@ViewBag.Title</h1>
}
else
{
<h1 class="m-0 page-title">PSTW-Centralized System</h1>
}
}
<div class="ms-auto text-end">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
@ -559,7 +618,13 @@
<!-- ============================================================== -->
<!-- End PAge Content -->
<!-- ============================================================== -->
<!-- ============================================================== -->
<!-- Right sidebar -->
<!-- ============================================================== -->
<!-- .right-sidebar -->
<!-- ============================================================== -->
<!-- End Right sidebar -->
<!-- ============================================================== -->
</div>
<!-- ============================================================== -->
<!-- End Container fluid -->

View File

@ -1,19 +1,39 @@
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
@inject SignInManager<UserModel> SignInManager
@inject UserManager<UserModel> UserManager
@* <ul class="navbar-nav"> *@
@if (SignInManager.IsSignedIn(User))
{
<li class="nav-item">
<a id="manage" class="nav-link " asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
<li class="nav-item d-inline">
<a id="manage" class="nav-link" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">
Hello @UserManager.GetUserName(User)!
</a>
</li>
<li class="nav-item">
<form id="logoutForm" class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })">
<button id="logout" type="submit" class="nav-link btn btn-link border-0">Logout</button>
</form>
<li class="nav-item d-inline">
<a id="logout" class="nav-link" href="javascript:void(0);" onclick="logout()">Logout</a>
</li>
@Html.AntiForgeryToken()
<script>
function logout() {
const returnUrl = '@Url.Action("Index", "Home", new { area = "" })';
fetch('@Url.Page("/Account/Logout", new { area = "Identity" })', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: `__RequestVerificationToken=${document.querySelector('input[name="__RequestVerificationToken"]').value}&returnUrl=${encodeURIComponent(returnUrl)}`
}).then(response => {
if (response.ok) {
window.location.href = returnUrl;
} else {
alert('Logout failed.');
}
}).catch(error => {
console.error('Logout error:', error);
});
}
</script>
}
else
{
@ -24,4 +44,3 @@ else
<a class="nav-link " id="login" asp-area="Identity" asp-page="/Account/Login">Login</a>
</li>
}
@* </ul> *@