diff --git a/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs b/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs index e294b7f..8785a29 100644 --- a/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs +++ b/Areas/Identity/Pages/Account/ConfirmEmail.cshtml.cs @@ -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 _userManager; + private readonly UserManager _userManager; - public ConfirmEmailModel(UserManager userManager) + public ConfirmEmailModel(UserManager userManager) { _userManager = userManager; } diff --git a/Areas/Identity/Pages/Account/ConfirmEmailChange.cshtml.cs b/Areas/Identity/Pages/Account/ConfirmEmailChange.cshtml.cs index af5ccf0..4394c88 100644 --- a/Areas/Identity/Pages/Account/ConfirmEmailChange.cshtml.cs +++ b/Areas/Identity/Pages/Account/ConfirmEmailChange.cshtml.cs @@ -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 _userManager; - private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; - public ConfirmEmailChangeModel(UserManager userManager, SignInManager signInManager) + public ConfirmEmailChangeModel(UserManager userManager, SignInManager signInManager) { _userManager = userManager; _signInManager = signInManager; diff --git a/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs b/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs index acd19cf..2b965bf 100644 --- a/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs +++ b/Areas/Identity/Pages/Account/ExternalLogin.cshtml.cs @@ -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 _signInManager; - private readonly UserManager _userManager; - private readonly IUserStore _userStore; - private readonly IUserEmailStore _emailStore; + private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly IUserStore _userStore; + private readonly IUserEmailStore _emailStore; private readonly IEmailSender _emailSender; private readonly ILogger _logger; public ExternalLoginModel( - SignInManager signInManager, - UserManager userManager, - IUserStore userStore, + SignInManager signInManager, + UserManager userManager, + IUserStore userStore, ILogger 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(); + return Activator.CreateInstance(); } 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 GetEmailStore() + private IUserEmailStore GetEmailStore() { if (!_userManager.SupportsUserEmail) { throw new NotSupportedException("The default UI requires a user store with email support."); } - return (IUserEmailStore)_userStore; + return (IUserEmailStore)_userStore; } } } diff --git a/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs b/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs index da82592..b57f985 100644 --- a/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs +++ b/Areas/Identity/Pages/Account/ForgotPassword.cshtml.cs @@ -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 _userManager; + private readonly UserManager _userManager; private readonly IEmailSender _emailSender; - public ForgotPasswordModel(UserManager userManager, IEmailSender emailSender) + public ForgotPasswordModel(UserManager userManager, IEmailSender emailSender) { _userManager = userManager; _emailSender = emailSender; diff --git a/Areas/Identity/Pages/Account/Login.cshtml.cs b/Areas/Identity/Pages/Account/Login.cshtml.cs index 76ef970..ae610eb 100644 --- a/Areas/Identity/Pages/Account/Login.cshtml.cs +++ b/Areas/Identity/Pages/Account/Login.cshtml.cs @@ -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 _signInManager; + private readonly SignInManager _signInManager; private readonly ILogger _logger; - public LoginModel(SignInManager signInManager, ILogger logger) + public LoginModel(SignInManager signInManager, ILogger logger) { _signInManager = signInManager; _logger = logger; diff --git a/Areas/Identity/Pages/Account/LoginWith2fa.cshtml.cs b/Areas/Identity/Pages/Account/LoginWith2fa.cshtml.cs index 0e73753..808b2e3 100644 --- a/Areas/Identity/Pages/Account/LoginWith2fa.cshtml.cs +++ b/Areas/Identity/Pages/Account/LoginWith2fa.cshtml.cs @@ -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 _signInManager; - private readonly UserManager _userManager; + private readonly SignInManager _signInManager; + private readonly UserManager _userManager; private readonly ILogger _logger; public LoginWith2faModel( - SignInManager signInManager, - UserManager userManager, + SignInManager signInManager, + UserManager userManager, ILogger logger) { _signInManager = signInManager; diff --git a/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml.cs b/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml.cs index 53b8ee6..043f247 100644 --- a/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml.cs +++ b/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml.cs @@ -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 _signInManager; - private readonly UserManager _userManager; + private readonly SignInManager _signInManager; + private readonly UserManager _userManager; private readonly ILogger _logger; public LoginWithRecoveryCodeModel( - SignInManager signInManager, - UserManager userManager, + SignInManager signInManager, + UserManager userManager, ILogger logger) { _signInManager = signInManager; diff --git a/Areas/Identity/Pages/Account/Logout.cshtml.cs b/Areas/Identity/Pages/Account/Logout.cshtml.cs index 75e87c5..c6a7244 100644 --- a/Areas/Identity/Pages/Account/Logout.cshtml.cs +++ b/Areas/Identity/Pages/Account/Logout.cshtml.cs @@ -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 _signInManager; + private readonly SignInManager _signInManager; private readonly ILogger _logger; - public LogoutModel(SignInManager signInManager, ILogger logger) + public LogoutModel(SignInManager signInManager, ILogger logger) { _signInManager = signInManager; _logger = logger; diff --git a/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml.cs b/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml.cs index f076826..dffc85d 100644 --- a/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml.cs @@ -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 _userManager; - private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; private readonly ILogger _logger; public ChangePasswordModel( - UserManager userManager, - SignInManager signInManager, + UserManager userManager, + SignInManager signInManager, ILogger logger) { _userManager = userManager; diff --git a/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs b/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs index 6181d0a..f23c48d 100644 --- a/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs @@ -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 _userManager; - private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; private readonly ILogger _logger; public DeletePersonalDataModel( - UserManager userManager, - SignInManager signInManager, + UserManager userManager, + SignInManager signInManager, ILogger logger) { _userManager = userManager; diff --git a/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml.cs b/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml.cs index 4b682b0..b399f56 100644 --- a/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml.cs @@ -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 _userManager; + private readonly UserManager _userManager; private readonly ILogger _logger; public Disable2faModel( - UserManager userManager, + UserManager userManager, ILogger logger) { _userManager = userManager; diff --git a/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs b/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs index 3ae8471..0827541 100644 --- a/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs @@ -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 _userManager; + private readonly UserManager _userManager; private readonly ILogger _logger; public DownloadPersonalDataModel( - UserManager userManager, + UserManager userManager, ILogger 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(); - var personalDataProps = typeof(IdentityUser).GetProperties().Where( + var personalDataProps = typeof(UserModel).GetProperties().Where( prop => Attribute.IsDefined(prop, typeof(PersonalDataAttribute))); foreach (var p in personalDataProps) { diff --git a/Areas/Identity/Pages/Account/Manage/Email.cshtml.cs b/Areas/Identity/Pages/Account/Manage/Email.cshtml.cs index dcdd1b9..5613a9e 100644 --- a/Areas/Identity/Pages/Account/Manage/Email.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/Email.cshtml.cs @@ -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 _userManager; - private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; private readonly IEmailSender _emailSender; public EmailModel( - UserManager userManager, - SignInManager signInManager, + UserManager userManager, + SignInManager 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; diff --git a/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs b/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs index 4d010b5..b284ad2 100644 --- a/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml.cs @@ -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 _userManager; + private readonly UserManager _userManager; private readonly ILogger _logger; private readonly UrlEncoder _urlEncoder; private const string AuthenticatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6"; public EnableAuthenticatorModel( - UserManager userManager, + UserManager userManager, ILogger 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); diff --git a/Areas/Identity/Pages/Account/Manage/ExternalLogins.cshtml.cs b/Areas/Identity/Pages/Account/Manage/ExternalLogins.cshtml.cs index 535418e..6e5e14d 100644 --- a/Areas/Identity/Pages/Account/Manage/ExternalLogins.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/ExternalLogins.cshtml.cs @@ -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 _userManager; - private readonly SignInManager _signInManager; - private readonly IUserStore _userStore; + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; + private readonly IUserStore _userStore; public ExternalLoginsModel( - UserManager userManager, - SignInManager signInManager, - IUserStore userStore) + UserManager userManager, + SignInManager signInManager, + IUserStore 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 userPasswordStore) + if (_userStore is IUserPasswordStore userPasswordStore) { passwordHash = await userPasswordStore.GetPasswordHashAsync(user, HttpContext.RequestAborted); } diff --git a/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml.cs b/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml.cs index 588965e..12a17ac 100644 --- a/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml.cs @@ -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 _userManager; + private readonly UserManager _userManager; private readonly ILogger _logger; public GenerateRecoveryCodesModel( - UserManager userManager, + UserManager userManager, ILogger logger) { _userManager = userManager; diff --git a/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs b/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs index 2a00afc..e037385 100644 --- a/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/Index.cshtml.cs @@ -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 _userManager; - private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; public IndexModel( - UserManager userManager, - SignInManager signInManager) + UserManager userManager, + SignInManager 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); diff --git a/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs b/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs index cb8ec56..44415cf 100644 --- a/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs @@ -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 _userManager; + private readonly UserManager _userManager; private readonly ILogger _logger; public PersonalDataModel( - UserManager userManager, + UserManager userManager, ILogger logger) { _userManager = userManager; diff --git a/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml.cs b/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml.cs index 9300f92..a8e7049 100644 --- a/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml.cs @@ -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 _userManager; - private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; private readonly ILogger _logger; public ResetAuthenticatorModel( - UserManager userManager, - SignInManager signInManager, + UserManager userManager, + SignInManager signInManager, ILogger logger) { _userManager = userManager; diff --git a/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml.cs b/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml.cs index 3c33a40..d388548 100644 --- a/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml.cs @@ -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 _userManager; - private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; public SetPasswordModel( - UserManager userManager, - SignInManager signInManager) + UserManager userManager, + SignInManager signInManager) { _userManager = userManager; _signInManager = signInManager; diff --git a/Areas/Identity/Pages/Account/Manage/ShowRecoveryCodes.cshtml.cs b/Areas/Identity/Pages/Account/Manage/ShowRecoveryCodes.cshtml.cs index 09e7bee..051175d 100644 --- a/Areas/Identity/Pages/Account/Manage/ShowRecoveryCodes.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/ShowRecoveryCodes.cshtml.cs @@ -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 { diff --git a/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml.cs b/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml.cs index a1e08c0..6e27cfd 100644 --- a/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml.cs +++ b/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml.cs @@ -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 _userManager; - private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly SignInManager _signInManager; private readonly ILogger _logger; public TwoFactorAuthenticationModel( - UserManager userManager, SignInManager signInManager, ILogger logger) + UserManager userManager, SignInManager signInManager, ILogger logger) { _userManager = userManager; _signInManager = signInManager; diff --git a/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml b/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml index 59b1bb1..3c96f35 100644 --- a/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml +++ b/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml @@ -1,4 +1,4 @@ -@inject SignInManager SignInManager +@inject SignInManager SignInManager @{ var hasExternalLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()).Any(); } diff --git a/Areas/Identity/Pages/Account/Register.cshtml.cs b/Areas/Identity/Pages/Account/Register.cshtml.cs index 1945ef9..7a7da32 100644 --- a/Areas/Identity/Pages/Account/Register.cshtml.cs +++ b/Areas/Identity/Pages/Account/Register.cshtml.cs @@ -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 _signInManager; - private readonly UserManager _userManager; - private readonly IUserStore _userStore; - private readonly IUserEmailStore _emailStore; + private readonly SignInManager _signInManager; + private readonly UserManager _userManager; + private readonly IUserStore _userStore; + private readonly IUserEmailStore _emailStore; private readonly ILogger _logger; private readonly IEmailSender _emailSender; public RegisterModel( - UserManager userManager, - IUserStore userStore, - SignInManager signInManager, + UserManager userManager, + IUserStore userStore, + SignInManager signInManager, ILogger 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(); + return Activator.CreateInstance(); } 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 GetEmailStore() + private IUserEmailStore GetEmailStore() { if (!_userManager.SupportsUserEmail) { throw new NotSupportedException("The default UI requires a user store with email support."); } - return (IUserEmailStore)_userStore; + return (IUserEmailStore)_userStore; } } } diff --git a/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs b/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs index dfceefa..6c4bdc5 100644 --- a/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs +++ b/Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs @@ -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 _userManager; + private readonly UserManager _userManager; private readonly IEmailSender _sender; - public RegisterConfirmationModel(UserManager userManager, IEmailSender sender) + public RegisterConfirmationModel(UserManager userManager, IEmailSender sender) { _userManager = userManager; _sender = sender; diff --git a/Areas/Identity/Pages/Account/ResendEmailConfirmation.cshtml.cs b/Areas/Identity/Pages/Account/ResendEmailConfirmation.cshtml.cs index 65bb3a9..fc0cf77 100644 --- a/Areas/Identity/Pages/Account/ResendEmailConfirmation.cshtml.cs +++ b/Areas/Identity/Pages/Account/ResendEmailConfirmation.cshtml.cs @@ -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 _userManager; + private readonly UserManager _userManager; private readonly IEmailSender _emailSender; - public ResendEmailConfirmationModel(UserManager userManager, IEmailSender emailSender) + public ResendEmailConfirmationModel(UserManager userManager, IEmailSender emailSender) { _userManager = userManager; _emailSender = emailSender; diff --git a/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs b/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs index 6b750a7..f665196 100644 --- a/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs +++ b/Areas/Identity/Pages/Account/ResetPassword.cshtml.cs @@ -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 _userManager; + private readonly UserManager _userManager; - public ResetPasswordModel(UserManager userManager) + public ResetPasswordModel(UserManager userManager) { _userManager = userManager; } diff --git a/Areas/Identity/Pages/_ViewImports.cshtml b/Areas/Identity/Pages/_ViewImports.cshtml index a9632f1..0d94d5d 100644 --- a/Areas/Identity/Pages/_ViewImports.cshtml +++ b/Areas/Identity/Pages/_ViewImports.cshtml @@ -2,3 +2,4 @@ @using PSTW_CentralSystem.Areas.Identity @using PSTW_CentralSystem.Areas.Identity.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@using PSTW_CentralSystem.Models diff --git a/Controllers/API/AdminAPI.cs b/Controllers/API/AdminAPI.cs new file mode 100644 index 0000000..d1e19c5 --- /dev/null +++ b/Controllers/API/AdminAPI.cs @@ -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 _logger; + private readonly AuthDBContext _authDbContext; + + public AdminAPI(ILogger logger, AuthDBContext authDbContext) + { + _logger = logger; + _authDbContext = authDbContext; + } + + [HttpPost("GetModuleInformation")] + public async Task GetModuleInformation() + { + var qcList = await _authDbContext.ModuleSettings.ToListAsync(); + return Json(qcList); + } + + } +} diff --git a/Controllers/AdminController.cs b/Controllers/AdminController.cs new file mode 100644 index 0000000..5a9496a --- /dev/null +++ b/Controllers/AdminController.cs @@ -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 _logger; + + public AdminController(ILogger 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); + } + + } +} diff --git a/CustomPolicy/RoleModulePolicy.cs b/CustomPolicy/RoleModulePolicy.cs index 1a1adbf..2dcee46 100644 --- a/CustomPolicy/RoleModulePolicy.cs +++ b/CustomPolicy/RoleModulePolicy.cs @@ -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 { private readonly AuthDBContext _authDBContext; - private readonly UserManager _userManager; - private readonly RoleManager _roleManager; + private readonly UserManager _userManager; + private readonly RoleManager _roleManager; private readonly IHttpContextAccessor _httpContextAccessor; - public RoleModuleHandler( AuthDBContext authDBContext, UserManager userManager, RoleManager roleManager, IHttpContextAccessor httpContextAccessor) + public RoleModuleHandler( AuthDBContext authDBContext, UserManager userManager, RoleManager 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(); - context.Fail(); + 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(); + 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); + } + } } + } } diff --git a/DBContext/AuthDBContext.cs b/DBContext/AuthDBContext.cs index 31bd505..8b43cf9 100644 --- a/DBContext/AuthDBContext.cs +++ b/DBContext/AuthDBContext.cs @@ -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 + public class AuthDBContext : IdentityDbContext { private readonly IWebHostEnvironment _hostingEnvironment; public AuthDBContext(DbContextOptions options, IWebHostEnvironment hostingEnvironment) : base(options) @@ -16,8 +18,58 @@ namespace PSTW_CentralSystem.DBContext protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); + + modelBuilder.Entity() + .Property(e => e.MethodAllowedUserType) + .HasConversion( + v => JsonConvert.SerializeObject(v), // Convert List to JSON string + v => JsonConvert.DeserializeObject>(v)); + + // Seeding Roles + modelBuilder.Entity().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(); + + 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().HasData(superAdmin, systemAdmin); + + // Seeding AdminRole + modelBuilder.Entity>().HasData( + new IdentityUserRole { UserId = 1, RoleId = 1 }); } - + public new DbSet Users { get; set; } + public new DbSet Roles { get; set; } + public DbSet ModuleSettings { get; set; } } } diff --git a/Migrations/20241114071237_Initiate.Designer.cs b/Migrations/20241120071120_Initiate.Designer.cs similarity index 52% rename from Migrations/20241114071237_Initiate.Designer.cs rename to Migrations/20241120071120_Initiate.Designer.cs index b6b9db5..b66f76a 100644 --- a/Migrations/20241114071237_Initiate.Designer.cs +++ b/Migrations/20241120071120_Initiate.Designer.cs @@ -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 { /// @@ -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", b => { - b.Property("Id") + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") .HasColumnType("varchar(255)"); + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("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", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("PSTW_CentralSystem.Models.ModuleSettingModel", b => + { + b.Property("SettingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("SettingId")); + + b.Property("AllowedUserType") + .HasColumnType("longtext"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("MethodAllowedUserType") + .HasColumnType("json"); + + b.Property("ModuleName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("ModuleStatus") + .HasColumnType("int"); + + b.HasKey("SettingId"); + + b.ToTable("ModuleSettings"); + }); + + modelBuilder.Entity("PSTW_CentralSystem.Models.RoleModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasColumnType("longtext"); + b.Property("Description") + .HasColumnType("longtext"); + b.Property("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", b => + modelBuilder.Entity("PSTW_CentralSystem.Models.UserModel", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("ClaimType") - .HasColumnType("longtext"); - - b.Property("ClaimValue") - .HasColumnType("longtext"); - - b.Property("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("Id") - .HasColumnType("varchar(255)"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); b.Property("AccessFailedCount") .HasColumnType("int"); @@ -90,11 +249,14 @@ namespace PSTW_CentralSystem.Migrations b.Property("EmailConfirmed") .HasColumnType("tinyint(1)"); + b.Property("FullName") + .HasColumnType("longtext"); + b.Property("LockoutEnabled") .HasColumnType("tinyint(1)"); b.Property("LockoutEnd") - .HasColumnType("datetime"); + .HasColumnType("datetime(6)"); b.Property("NormalizedEmail") .HasMaxLength(256) @@ -123,6 +285,9 @@ namespace PSTW_CentralSystem.Migrations .HasMaxLength(256) .HasColumnType("varchar(256)"); + b.Property("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", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("ClaimType") - .HasColumnType("longtext"); - - b.Property("ClaimValue") - .HasColumnType("longtext"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("varchar(255)"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("varchar(255)"); - - b.Property("ProviderKey") - .HasColumnType("varchar(255)"); - - b.Property("ProviderDisplayName") - .HasColumnType("longtext"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("varchar(255)"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("varchar(255)"); - - b.Property("RoleId") - .HasColumnType("varchar(255)"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("varchar(255)"); - - b.Property("LoginProvider") - .HasColumnType("varchar(255)"); - - b.Property("Name") - .HasColumnType("varchar(255)"); - - b.Property("Value") - .HasColumnType("longtext"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", 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", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", 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", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", 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", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", 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", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + b.HasOne("PSTW_CentralSystem.Models.UserModel", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) diff --git a/Migrations/20241114071237_Initiate.cs b/Migrations/20241120071120_Initiate.cs similarity index 53% rename from Migrations/20241114071237_Initiate.cs rename to Migrations/20241120071120_Initiate.cs index a288234..34123e7 100644 --- a/Migrations/20241114071237_Initiate.cs +++ b/Migrations/20241120071120_Initiate.cs @@ -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 { /// @@ -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(type: "varchar(255)", nullable: false), - Name = table.Column(type: "varchar(256)", maxLength: 256, nullable: true), - NormalizedName = table.Column(type: "varchar(256)", maxLength: 256, nullable: true), + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Description = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Name = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + NormalizedName = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), ConcurrencyStamp = table.Column(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(type: "varchar(255)", nullable: false), - UserName = table.Column(type: "varchar(256)", maxLength: 256, nullable: true), - NormalizedUserName = table.Column(type: "varchar(256)", maxLength: 256, nullable: true), - Email = table.Column(type: "varchar(256)", maxLength: 256, nullable: true), - NormalizedEmail = table.Column(type: "varchar(256)", maxLength: 256, nullable: true), + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + FullName = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + UserStatus = table.Column(type: "int", nullable: true), + UserName = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + NormalizedUserName = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + Email = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + NormalizedEmail = table.Column(type: "varchar(256)", maxLength: 256, nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), EmailConfirmed = table.Column(type: "tinyint(1)", nullable: false), - PasswordHash = table.Column(type: "longtext", nullable: true), - SecurityStamp = table.Column(type: "longtext", nullable: true), - ConcurrencyStamp = table.Column(type: "longtext", nullable: true), - PhoneNumber = table.Column(type: "longtext", nullable: true), + PasswordHash = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + SecurityStamp = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ConcurrencyStamp = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + PhoneNumber = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), PhoneNumberConfirmed = table.Column(type: "tinyint(1)", nullable: false), TwoFactorEnabled = table.Column(type: "tinyint(1)", nullable: false), - LockoutEnd = table.Column(type: "datetime", nullable: true), + LockoutEnd = table.Column(type: "datetime(6)", nullable: true), LockoutEnabled = table.Column(type: "tinyint(1)", nullable: false), AccessFailedCount = table.Column(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(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + ModuleName = table.Column(type: "varchar(50)", maxLength: 50, nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + AllowedUserType = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + MethodAllowedUserType = table.Column(type: "json", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + ModuleStatus = table.Column(type: "int", nullable: false), + Description = table.Column(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(type: "int", nullable: false) - .Annotation("MySQL:ValueGenerationStrategy", MySQLValueGenerationStrategy.IdentityColumn), - RoleId = table.Column(type: "varchar(255)", nullable: false), - ClaimType = table.Column(type: "longtext", nullable: true), + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + RoleId = table.Column(type: "int", nullable: false), + ClaimType = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), ClaimValue = table.Column(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(type: "int", nullable: false) - .Annotation("MySQL:ValueGenerationStrategy", MySQLValueGenerationStrategy.IdentityColumn), - UserId = table.Column(type: "varchar(255)", nullable: false), - ClaimType = table.Column(type: "longtext", nullable: true), + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UserId = table.Column(type: "int", nullable: false), + ClaimType = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), ClaimValue = table.Column(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(type: "varchar(255)", nullable: false), - ProviderKey = table.Column(type: "varchar(255)", nullable: false), - ProviderDisplayName = table.Column(type: "longtext", nullable: true), - UserId = table.Column(type: "varchar(255)", nullable: false) + LoginProvider = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ProviderKey = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + ProviderDisplayName = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"), + UserId = table.Column(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(type: "varchar(255)", nullable: false), - RoleId = table.Column(type: "varchar(255)", nullable: false) + UserId = table.Column(type: "int", nullable: false), + RoleId = table.Column(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(type: "varchar(255)", nullable: false), - LoginProvider = table.Column(type: "varchar(255)", nullable: false), - Name = table.Column(type: "varchar(255)", nullable: false), + UserId = table.Column(type: "int", nullable: false), + LoginProvider = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), + Name = table.Column(type: "varchar(255)", nullable: false) + .Annotation("MySql:CharSet", "utf8mb4"), Value = table.Column(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"); diff --git a/Migrations/AuthDBContextModelSnapshot.cs b/Migrations/AuthDBContextModelSnapshot.cs index 8c75195..a06c3a3 100644 --- a/Migrations/AuthDBContextModelSnapshot.cs +++ b/Migrations/AuthDBContextModelSnapshot.cs @@ -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", b => { - b.Property("Id") + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") .HasColumnType("varchar(255)"); + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("int"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("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", b => + { + b.Property("UserId") + .HasColumnType("int"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("PSTW_CentralSystem.Models.ModuleSettingModel", b => + { + b.Property("SettingId") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("SettingId")); + + b.Property("AllowedUserType") + .HasColumnType("longtext"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("MethodAllowedUserType") + .HasColumnType("json"); + + b.Property("ModuleName") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("varchar(50)"); + + b.Property("ModuleStatus") + .HasColumnType("int"); + + b.HasKey("SettingId"); + + b.ToTable("ModuleSettings"); + }); + + modelBuilder.Entity("PSTW_CentralSystem.Models.RoleModel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); + b.Property("ConcurrencyStamp") .IsConcurrencyToken() .HasColumnType("longtext"); + b.Property("Description") + .HasColumnType("longtext"); + b.Property("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", b => + modelBuilder.Entity("PSTW_CentralSystem.Models.UserModel", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("ClaimType") - .HasColumnType("longtext"); - - b.Property("ClaimValue") - .HasColumnType("longtext"); - - b.Property("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("Id") - .HasColumnType("varchar(255)"); + MySqlPropertyBuilderExtensions.UseMySqlIdentityColumn(b.Property("Id")); b.Property("AccessFailedCount") .HasColumnType("int"); @@ -87,11 +246,14 @@ namespace PSTW_CentralSystem.Migrations b.Property("EmailConfirmed") .HasColumnType("tinyint(1)"); + b.Property("FullName") + .HasColumnType("longtext"); + b.Property("LockoutEnabled") .HasColumnType("tinyint(1)"); b.Property("LockoutEnd") - .HasColumnType("datetime"); + .HasColumnType("datetime(6)"); b.Property("NormalizedEmail") .HasMaxLength(256) @@ -120,6 +282,9 @@ namespace PSTW_CentralSystem.Migrations .HasMaxLength(256) .HasColumnType("varchar(256)"); + b.Property("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", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("ClaimType") - .HasColumnType("longtext"); - - b.Property("ClaimValue") - .HasColumnType("longtext"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("varchar(255)"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => - { - b.Property("LoginProvider") - .HasColumnType("varchar(255)"); - - b.Property("ProviderKey") - .HasColumnType("varchar(255)"); - - b.Property("ProviderDisplayName") - .HasColumnType("longtext"); - - b.Property("UserId") - .IsRequired() - .HasColumnType("varchar(255)"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => - { - b.Property("UserId") - .HasColumnType("varchar(255)"); - - b.Property("RoleId") - .HasColumnType("varchar(255)"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => - { - b.Property("UserId") - .HasColumnType("varchar(255)"); - - b.Property("LoginProvider") - .HasColumnType("varchar(255)"); - - b.Property("Name") - .HasColumnType("varchar(255)"); - - b.Property("Value") - .HasColumnType("longtext"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens", (string)null); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", 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", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", 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", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", 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", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", 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", b => + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { - b.HasOne("Microsoft.AspNetCore.Identity.IdentityUser", null) + b.HasOne("PSTW_CentralSystem.Models.UserModel", null) .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) diff --git a/Models/ModuleSettingModel.cs b/Models/ModuleSettingModel.cs index 5d68c6f..7786e3c 100644 --- a/Models/ModuleSettingModel.cs +++ b/Models/ModuleSettingModel.cs @@ -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 { 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; } } } diff --git a/Models/RoleModel.cs b/Models/RoleModel.cs new file mode 100644 index 0000000..ec985d2 --- /dev/null +++ b/Models/RoleModel.cs @@ -0,0 +1,9 @@ +using Microsoft.AspNetCore.Identity; + +namespace PSTW_CentralSystem.Models +{ + public class RoleModel : IdentityRole + { + public string? Description { get; set; } + } +} diff --git a/Models/UserModel.cs b/Models/UserModel.cs new file mode 100644 index 0000000..8943877 --- /dev/null +++ b/Models/UserModel.cs @@ -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 // Specify the type for the primary key + { + // Add custom properties + public string? FullName { get; set; } + public int? UserStatus { get; set; } + } +} diff --git a/PSTW_CentralSystem.csproj b/PSTW_CentralSystem.csproj index 8f86a7d..933f49e 100644 --- a/PSTW_CentralSystem.csproj +++ b/PSTW_CentralSystem.csproj @@ -21,13 +21,14 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + + diff --git a/Program.cs b/Program.cs index bddd51c..4b42c94 100644 --- a/Program.cs +++ b/Program.cs @@ -3,70 +3,80 @@ 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"); - -// Add services to the container. -builder.Services.AddControllersWithViews(); -Log.Logger = new LoggerConfiguration() - .ReadFrom.Configuration(builder.Configuration) - .Enrich.FromLogContext() - .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == Serilog.Events.LogEventLevel.Information) - .WriteTo.File("Logs/info-.txt", rollingInterval: RollingInterval.Day, - outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}")) - .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == Serilog.Events.LogEventLevel.Warning) - .WriteTo.File("Logs/warning-.txt", rollingInterval: RollingInterval.Day, - outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}")) - .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == Serilog.Events.LogEventLevel.Error) - .WriteTo.File("Logs/error-.txt", rollingInterval: RollingInterval.Day, - outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}")) - .WriteTo.Console() - .CreateLogger(); - -builder.Logging.AddSerilog(); - -builder.Services.AddDbContext(options => +internal class Program { - var config = builder.Configuration; - options.UseMySQL(config.GetConnectionString("DefaultConnection") ?? string.Empty, mysqlOptions => mysqlOptions.CommandTimeout(300)); -}); + private static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); -//builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true).AddEntityFrameworkStores(); -builder.Services.AddIdentity(options => options.SignIn.RequireConfirmedAccount = true) - .AddEntityFrameworkStores() - .AddDefaultUI() - .AddDefaultTokenProviders(); + // Add services to the container. + builder.Services.AddControllersWithViews(); + builder.Services.AddRazorPages(); -builder.Services.AddAuthorizationCore(options => -{ - options.AddPolicy("RoleModulePolicy", policy => - policy.Requirements.Add(new RoleModulePolicy())); -}); + Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(builder.Configuration) + .Enrich.FromLogContext() + .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == Serilog.Events.LogEventLevel.Information) + .WriteTo.File("Logs/info-.txt", rollingInterval: RollingInterval.Day, + outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}")) + .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == Serilog.Events.LogEventLevel.Warning) + .WriteTo.File("Logs/warning-.txt", rollingInterval: RollingInterval.Day, + outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}")) + .WriteTo.Logger(l => l.Filter.ByIncludingOnly(e => e.Level == Serilog.Events.LogEventLevel.Error) + .WriteTo.File("Logs/error-.txt", rollingInterval: RollingInterval.Day, + outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level}] {Message}{NewLine}{Exception}")) + .WriteTo.Console() + .CreateLogger(); -// Add scope -builder.Services.AddScoped(); + builder.Logging.AddSerilog(); -var app = builder.Build(); + builder.Services.AddDbContext(options => + { + options.UseMySql(connectionString, new MySqlServerVersion(new Version(8, 0, 39)), + mysqlOptions => mysqlOptions.CommandTimeout(120) + ); + }); -// 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(); -} + //builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true).AddEntityFrameworkStores(); -app.UseHttpsRedirection(); -app.UseStaticFiles(); + builder.Services.AddIdentity(options => options.SignIn.RequireConfirmedAccount = true) + .AddEntityFrameworkStores() + .AddDefaultUI() + .AddDefaultTokenProviders(); -app.UseRouting(); + builder.Services.AddAuthorizationCore(options => + { + options.AddPolicy("RoleModulePolicy", policy => + policy.Requirements.Add(new RoleModulePolicy())); + }); -app.UseAuthorization(); -app.MapRazorPages(); -app.MapControllerRoute( - name: "default", - pattern: "{controller=Home}/{action=Index}/{id?}"); + // Add scope + builder.Services.AddScoped(); + var app = builder.Build(); -app.Run(); + // 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.UseRouting(); + + app.UseAuthorization(); + app.MapRazorPages(); + app.MapControllerRoute( + name: "default", + pattern: "{controller=Home}/{action=Index}/{id?}"); + + app.Run(); + } +} \ No newline at end of file diff --git a/Views/Admin/Index.cshtml b/Views/Admin/Index.cshtml new file mode 100644 index 0000000..53735d9 --- /dev/null +++ b/Views/Admin/Index.cshtml @@ -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"; +} +
+
+
+
+

+ +

+
Dashboard
+
+
+
+
diff --git a/Views/Admin/ModuleAdmin.cshtml b/Views/Admin/ModuleAdmin.cshtml new file mode 100644 index 0000000..8837f3d --- /dev/null +++ b/Views/Admin/ModuleAdmin.cshtml @@ -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"; +} + +

+ Create New +

+
+
+
+
+

Latest Posts

+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ ModuleName + + Access Type + + Configured Page + + Description + + ModuleStatus + + Action +
+ {{module.moduleName}} + + {{module.allowedUserType}} + +
    +
  • + Method Name: {{ method.methodName }}
    + Allowed User Types: + + {{ userType }}, + +
  • +
+
+ {{module.description}} + + + + + + + | + +
+
+

... Loading

+
+
+
+
+
+ + +@section Scripts { + @{ + await Html.RenderPartialAsync("_ValidationScriptsPartial"); + } + +} diff --git a/Views/Admin/ModuleSetting.cshtml b/Views/Admin/ModuleSetting.cshtml new file mode 100644 index 0000000..bd14f62 --- /dev/null +++ b/Views/Admin/ModuleSetting.cshtml @@ -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"; +} + +

+ Create New +

+
+
+
+
+

{{module.moduleName}}

+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ ModuleName + + Access Type + + Configured Page + + Description + + ModuleStatus + + Action +
+ {{module.moduleName}} + + {{module.allowedUserType}} + +
    +
  • + Method Name: {{ method.methodName }}
    + Allowed User Types: + + {{ userType }}, + +
  • +
+
+ {{module.description}} + + + + + + + | + +
+
+

... Loading

+
+
+
+
+
+ + +@section Scripts { + @{ + await Html.RenderPartialAsync("_ValidationScriptsPartial"); + } + +} diff --git a/Views/Home/Index.cshtml b/Views/Home/Index.cshtml index bcfd79a..8ca92a3 100644 --- a/Views/Home/Index.cshtml +++ b/Views/Home/Index.cshtml @@ -1,8 +1,10 @@ @{ - ViewData["Title"] = "Home Page"; + ViewData["Title"] = "PSTW Centralized System"; } -
-

Welcome

-

Learn about building Web apps with ASP.NET Core.

+
+
+

Welcome

+

Learn about building Web apps with ASP.NET Core.

+
diff --git a/Views/Shared/_Layout.cshtml b/Views/Shared/_Layout.cshtml index b93b427..321975b 100644 --- a/Views/Shared/_Layout.cshtml +++ b/Views/Shared/_Layout.cshtml @@ -28,6 +28,11 @@ rel="stylesheet" /> + + + + @* *@ + @@ -202,7 +213,12 @@ aria-expanded="false"> - + @@ -267,7 +303,13 @@
@@ -334,6 +358,25 @@