fix #3065 - redirect user if they are logged in and navigating to Login page

This commit is contained in:
sbwalker 2023-08-03 12:46:42 -04:00
parent cb7fe364bc
commit 93be61e483
3 changed files with 237 additions and 234 deletions

View File

@ -11,9 +11,6 @@
<Authorizing> <Authorizing>
<text>...</text> <text>...</text>
</Authorizing> </Authorizing>
<Authorized>
<div>@Localizer["Info.SignedIn"]</div>
</Authorized>
<NotAuthorized> <NotAuthorized>
@if (!twofactor) @if (!twofactor)
{ {
@ -69,259 +66,265 @@
</AuthorizeView> </AuthorizeView>
@code { @code {
private bool _allowsitelogin = true; private bool _allowsitelogin = true;
private bool _allowexternallogin = false; private bool _allowexternallogin = false;
private ElementReference login; private ElementReference login;
private bool validated = false; private bool validated = false;
private bool twofactor = false; private bool twofactor = false;
private string _username = string.Empty; private string _username = string.Empty;
private ElementReference username; private ElementReference username;
private string _password = string.Empty; private string _password = string.Empty;
private string _passwordtype = "password"; private string _passwordtype = "password";
private string _togglepassword = string.Empty; private string _togglepassword = string.Empty;
private bool _remember = false; private bool _remember = false;
private string _code = string.Empty; private string _code = string.Empty;
private string _returnUrl = string.Empty; private string _returnUrl = string.Empty;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
public override List<Resource> Resources => new List<Resource>() public override List<Resource> Resources => new List<Resource>()
{ {
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" } new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
}; };
protected override async Task OnInitializedAsync() protected override async Task OnInitializedAsync()
{ {
try try
{ {
_togglepassword = SharedLocalizer["ShowPassword"]; _togglepassword = SharedLocalizer["ShowPassword"];
if (PageState.Site.Settings.ContainsKey("LoginOptions:AllowSiteLogin") && !string.IsNullOrEmpty(PageState.Site.Settings["LoginOptions:AllowSiteLogin"])) if (PageState.Site.Settings.ContainsKey("LoginOptions:AllowSiteLogin") && !string.IsNullOrEmpty(PageState.Site.Settings["LoginOptions:AllowSiteLogin"]))
{ {
_allowsitelogin = bool.Parse(PageState.Site.Settings["LoginOptions:AllowSiteLogin"]); _allowsitelogin = bool.Parse(PageState.Site.Settings["LoginOptions:AllowSiteLogin"]);
} }
if (PageState.Site.Settings.ContainsKey("ExternalLogin:ProviderType") && !string.IsNullOrEmpty(PageState.Site.Settings["ExternalLogin:ProviderType"])) if (PageState.Site.Settings.ContainsKey("ExternalLogin:ProviderType") && !string.IsNullOrEmpty(PageState.Site.Settings["ExternalLogin:ProviderType"]))
{ {
_allowexternallogin = true; _allowexternallogin = true;
} }
if (PageState.QueryString.ContainsKey("returnurl")) if (PageState.QueryString.ContainsKey("returnurl"))
{ {
_returnUrl = PageState.QueryString["returnurl"]; _returnUrl = PageState.QueryString["returnurl"];
} }
if (PageState.QueryString.ContainsKey("name")) if (PageState.QueryString.ContainsKey("name"))
{ {
_username = PageState.QueryString["name"]; _username = PageState.QueryString["name"];
} }
if (PageState.QueryString.ContainsKey("token") && !string.IsNullOrEmpty(_username)) if (PageState.QueryString.ContainsKey("token") && !string.IsNullOrEmpty(_username))
{ {
var user = new User(); var user = new User();
user.SiteId = PageState.Site.SiteId; user.SiteId = PageState.Site.SiteId;
user.Username = _username; user.Username = _username;
if (PageState.QueryString.ContainsKey("key")) if (PageState.QueryString.ContainsKey("key"))
{ {
user = await UserService.LinkUserAsync(user, PageState.QueryString["token"], PageState.Site.Settings["ExternalLogin:ProviderType"], PageState.QueryString["key"], PageState.Site.Settings["ExternalLogin:ProviderName"]); user = await UserService.LinkUserAsync(user, PageState.QueryString["token"], PageState.Site.Settings["ExternalLogin:ProviderType"], PageState.QueryString["key"], PageState.Site.Settings["ExternalLogin:ProviderName"]);
if (user != null) if (user != null)
{ {
await logger.LogInformation(LogFunction.Security, "External Login Linkage Successful For Username {Username}", _username); await logger.LogInformation(LogFunction.Security, "External Login Linkage Successful For Username {Username}", _username);
AddModuleMessage(Localizer["Success.Account.Linked"], MessageType.Info); AddModuleMessage(Localizer["Success.Account.Linked"], MessageType.Info);
} }
else else
{ {
await logger.LogError(LogFunction.Security, "External Login Linkage Failed For Username {Username}", _username); await logger.LogError(LogFunction.Security, "External Login Linkage Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Message.Account.NotLinked"], MessageType.Warning); AddModuleMessage(Localizer["Message.Account.NotLinked"], MessageType.Warning);
} }
_username = ""; _username = "";
} }
else else
{ {
user = await UserService.VerifyEmailAsync(user, PageState.QueryString["token"]); user = await UserService.VerifyEmailAsync(user, PageState.QueryString["token"]);
if (user != null) if (user != null)
{ {
await logger.LogInformation(LogFunction.Security, "Email Verified For For Username {Username}", _username); await logger.LogInformation(LogFunction.Security, "Email Verified For For Username {Username}", _username);
AddModuleMessage(Localizer["Success.Account.Verified"], MessageType.Info); AddModuleMessage(Localizer["Success.Account.Verified"], MessageType.Info);
} }
else else
{ {
await logger.LogError(LogFunction.Security, "Email Verification Failed For Username {Username}", _username); await logger.LogError(LogFunction.Security, "Email Verification Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Message.Account.NotVerified"], MessageType.Warning); AddModuleMessage(Localizer["Message.Account.NotVerified"], MessageType.Warning);
} }
} }
} }
else else
{ {
if (PageState.QueryString.ContainsKey("status")) if (PageState.QueryString.ContainsKey("status"))
{ {
AddModuleMessage(Localizer["ExternalLoginStatus." + PageState.QueryString["status"]], MessageType.Info); AddModuleMessage(Localizer["ExternalLoginStatus." + PageState.QueryString["status"]], MessageType.Info);
} }
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
await logger.LogError(ex, "Error Loading Login {Error}", ex.Message); await logger.LogError(ex, "Error Loading Login {Error}", ex.Message);
AddModuleMessage(Localizer["Error.LoadLogin"], MessageType.Error); AddModuleMessage(Localizer["Error.LoadLogin"], MessageType.Error);
} }
} }
protected override async Task OnAfterRenderAsync(bool firstRender) protected override async Task OnAfterRenderAsync(bool firstRender)
{ {
if (firstRender && PageState.User == null) if (firstRender && PageState.User == null)
{ {
await username.FocusAsync(); await username.FocusAsync();
} }
}
private async Task Login() // redirect logged in user to specified page
{ if (PageState.User != null)
try {
{ NavigationManager.NavigateTo(PageState.ReturnUrl);
validated = true; }
var interop = new Interop(JSRuntime); }
if (await interop.FormValid(login))
{
var hybrid = (PageState.Runtime == Shared.Runtime.Hybrid);
var user = new User { SiteId = PageState.Site.SiteId, Username = _username, Password = _password, LastIPAddress = SiteState.RemoteIPAddress};
if (!twofactor) private async Task Login()
{ {
user = await UserService.LoginUserAsync(user, hybrid, _remember); try
} {
else validated = true;
{ var interop = new Interop(JSRuntime);
user = await UserService.VerifyTwoFactorAsync(user, _code); if (await interop.FormValid(login))
} {
var hybrid = (PageState.Runtime == Shared.Runtime.Hybrid);
var user = new User { SiteId = PageState.Site.SiteId, Username = _username, Password = _password, LastIPAddress = SiteState.RemoteIPAddress};
if (user.IsAuthenticated) if (!twofactor)
{ {
await logger.LogInformation(LogFunction.Security, "Login Successful For Username {Username}", _username); user = await UserService.LoginUserAsync(user, hybrid, _remember);
}
else
{
user = await UserService.VerifyTwoFactorAsync(user, _code);
}
if (hybrid) if (user.IsAuthenticated)
{ {
// hybrid apps utilize an interactive login await logger.LogInformation(LogFunction.Security, "Login Successful For Username {Username}", _username);
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider
.GetService(typeof(IdentityAuthenticationStateProvider));
authstateprovider.NotifyAuthenticationChanged();
NavigationManager.NavigateTo(NavigateUrl(WebUtility.UrlDecode(_returnUrl), true));
}
else
{
// post back to the Login page so that the cookies are set correctly
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/");
await interop.SubmitForm(url, fields);
}
}
else
{
if ((PageState.Site.Settings.ContainsKey("LoginOptions:TwoFactor") && PageState.Site.Settings["LoginOptions:TwoFactor"] == "required") || user.TwoFactorRequired)
{
twofactor = true;
validated = false;
AddModuleMessage(Localizer["Message.TwoFactor"], MessageType.Info);
}
else
{
if (!twofactor)
{
await logger.LogInformation(LogFunction.Security, "Login Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Error.Login.Fail"], MessageType.Error);
}
else
{
await logger.LogInformation(LogFunction.Security, "Two Factor Verification Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Error.TwoFactor.Fail"], MessageType.Error);
}
}
}
}
else
{
AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Performing Login {Error}", ex.Message);
AddModuleMessage(Localizer["Error.Login"], MessageType.Error);
}
}
private void Cancel() if (hybrid)
{ {
NavigationManager.NavigateTo(_returnUrl); // hybrid apps utilize an interactive login
} var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider
.GetService(typeof(IdentityAuthenticationStateProvider));
authstateprovider.NotifyAuthenticationChanged();
NavigationManager.NavigateTo(NavigateUrl(WebUtility.UrlDecode(_returnUrl), true));
}
else
{
// post back to the Login page so that the cookies are set correctly
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/");
await interop.SubmitForm(url, fields);
}
}
else
{
if ((PageState.Site.Settings.ContainsKey("LoginOptions:TwoFactor") && PageState.Site.Settings["LoginOptions:TwoFactor"] == "required") || user.TwoFactorRequired)
{
twofactor = true;
validated = false;
AddModuleMessage(Localizer["Message.TwoFactor"], MessageType.Info);
}
else
{
if (!twofactor)
{
await logger.LogInformation(LogFunction.Security, "Login Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Error.Login.Fail"], MessageType.Error);
}
else
{
await logger.LogInformation(LogFunction.Security, "Two Factor Verification Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Error.TwoFactor.Fail"], MessageType.Error);
}
}
}
}
else
{
AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning);
}
}
catch (Exception ex)
{
await logger.LogError(ex, "Error Performing Login {Error}", ex.Message);
AddModuleMessage(Localizer["Error.Login"], MessageType.Error);
}
}
private async Task Forgot() private void Cancel()
{ {
try NavigationManager.NavigateTo(_returnUrl);
{ }
if (_username != string.Empty)
{
var user = await UserService.GetUserAsync(_username, PageState.Site.SiteId);
if (user != null)
{
await UserService.ForgotPasswordAsync(user);
await logger.LogInformation(LogFunction.Security, "Password Reset Notification Sent For Username {Username}", _username);
AddModuleMessage(Localizer["Message.ForgotUser"], MessageType.Info);
}
else
{
AddModuleMessage(Localizer["Message.UserDoesNotExist"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["Message.ForgotPassword"], MessageType.Info);
}
StateHasChanged(); private async Task Forgot()
} {
catch (Exception ex) try
{ {
await logger.LogError(ex, "Error Resetting Password {Error}", ex.Message); if (_username != string.Empty)
AddModuleMessage(Localizer["Error.ResetPassword"], MessageType.Error); {
} var user = await UserService.GetUserAsync(_username, PageState.Site.SiteId);
} if (user != null)
{
await UserService.ForgotPasswordAsync(user);
await logger.LogInformation(LogFunction.Security, "Password Reset Notification Sent For Username {Username}", _username);
AddModuleMessage(Localizer["Message.ForgotUser"], MessageType.Info);
}
else
{
AddModuleMessage(Localizer["Message.UserDoesNotExist"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["Message.ForgotPassword"], MessageType.Info);
}
private void Reset() StateHasChanged();
{ }
twofactor = false; catch (Exception ex)
_username = ""; {
_password = ""; await logger.LogError(ex, "Error Resetting Password {Error}", ex.Message);
ClearModuleMessage(); AddModuleMessage(Localizer["Error.ResetPassword"], MessageType.Error);
StateHasChanged(); }
} }
private async Task KeyPressed(KeyboardEventArgs e) private void Reset()
{ {
if (e.Code == "Enter" || e.Code == "NumpadEnter") twofactor = false;
{ _username = "";
await Login(); _password = "";
} ClearModuleMessage();
} StateHasChanged();
}
private void TogglePassword() private async Task KeyPressed(KeyboardEventArgs e)
{ {
if (_passwordtype == "password") if (e.Code == "Enter" || e.Code == "NumpadEnter")
{ {
_passwordtype = "text"; await Login();
_togglepassword = SharedLocalizer["HidePassword"]; }
} }
else
{
_passwordtype = "password";
_togglepassword = SharedLocalizer["ShowPassword"];
}
}
private void ExternalLogin() private void TogglePassword()
{ {
if (_passwordtype == "password")
{
_passwordtype = "text";
_togglepassword = SharedLocalizer["HidePassword"];
}
else
{
_passwordtype = "password";
_togglepassword = SharedLocalizer["ShowPassword"];
}
}
private void ExternalLogin()
{
NavigationManager.NavigateTo(Utilities.TenantUrl(PageState.Alias, "/pages/external?returnurl=" + _returnUrl), true); NavigationManager.NavigateTo(Utilities.TenantUrl(PageState.Alias, "/pages/external?returnurl=" + _returnUrl), true);
} }
} }

View File

@ -231,7 +231,7 @@ namespace Oqtane.Infrastructure
new Permission(PermissionNames.View, RoleNames.Admin, true), new Permission(PermissionNames.View, RoleNames.Admin, true),
new Permission(PermissionNames.Edit, RoleNames.Admin, true) new Permission(PermissionNames.Edit, RoleNames.Admin, true)
}, },
Content = "<p>The page you requested does not exist.</p>" Content = "<p>The page you requested does not exist or you do not have sufficient rights to view it.</p>"
} }
} }
}); });

View File

@ -640,7 +640,7 @@ namespace Oqtane.Repository
new Permission(PermissionNames.View, RoleNames.Admin, true), new Permission(PermissionNames.View, RoleNames.Admin, true),
new Permission(PermissionNames.Edit, RoleNames.Admin, true) new Permission(PermissionNames.Edit, RoleNames.Admin, true)
}, },
Content = "<p>The page you requested does not exist.</p>" Content = "<p>The page you requested does not exist or you do not have sufficient rights to view it.</p>"
} }
} }
}); });