fix #3108 - raise reload event after user logs out

This commit is contained in:
sbwalker 2023-08-07 09:34:20 -04:00
parent 22cfec9276
commit b5649e2a6f
5 changed files with 61 additions and 48 deletions

View File

@ -98,7 +98,7 @@
User user = null; User user = null;
var editmode = false; var editmode = false;
var refresh = false; var refresh = false;
var lastsyncdate = DateTime.UtcNow.AddHours(-1); var lastsyncdate = DateTime.UtcNow.AddHours(-1); // events in the past hour
var runtime = (Shared.Runtime)Enum.Parse(typeof(Shared.Runtime), Runtime); var runtime = (Shared.Runtime)Enum.Parse(typeof(Shared.Runtime), Runtime);
_error = ""; _error = "";
@ -165,29 +165,6 @@
user = PageState.User; user = PageState.User;
} }
// process any sync events
var sync = await SyncService.GetSyncAsync(lastsyncdate);
lastsyncdate = sync.SyncDate;
if (sync.SyncEvents.Any())
{
// reload client application if server was restarted or site runtime/rendermode was modified
if (PageState != null && sync.SyncEvents.Exists(item => (item.Action == SyncEventActions.Reload)))
{
NavigationManager.NavigateTo(_absoluteUri, true);
return;
}
// when site information has changed the PageState needs to be refreshed
if (sync.SyncEvents.Exists(item => item.EntityName == EntityNames.Site && item.EntityId == SiteState.Alias.SiteId))
{
refresh = true;
}
// when user information has changed the PageState needs to be refreshed as the list of pages/modules may have changed
if (user != null && sync.SyncEvents.Exists(item => item.EntityName == EntityNames.User && item.EntityId == user.UserId))
{
refresh = true;
}
}
if (PageState == null || refresh || PageState.Alias.SiteId != SiteState.Alias.SiteId) if (PageState == null || refresh || PageState.Alias.SiteId != SiteState.Alias.SiteId)
{ {
site = await SiteService.GetSiteAsync(SiteState.Alias.SiteId); site = await SiteService.GetSiteAsync(SiteState.Alias.SiteId);
@ -198,6 +175,28 @@
site = PageState.Site; site = PageState.Site;
} }
// process any sync events
var sync = await SyncService.GetSyncAsync(lastsyncdate);
lastsyncdate = sync.SyncDate;
if (sync.SyncEvents.Any())
{
// reload client application if server was restarted or site runtime/rendermode was modified
if (PageState != null && sync.SyncEvents.Exists(item => item.Action == SyncEventActions.Reload && site != null && ((item.EntityName == EntityNames.Host && site.Runtime != "Server") || (item.EntityName == EntityNames.Site && item.EntityId == site.SiteId))))
{
NavigationManager.NavigateTo(_absoluteUri, true);
}
// when current user auth information has changed the client application needs to be reloaded
if (PageState != null && user != null && sync.SyncEvents.Exists(item => item.Action == SyncEventActions.Reload && item.EntityName == EntityNames.User && item.EntityId == user.UserId))
{
NavigationManager.NavigateTo(_absoluteUri, true);
}
// when site information has changed the PageState needs to be refreshed
if (sync.SyncEvents.Exists(item => item.EntityName == EntityNames.Site && item.EntityId == SiteState.Alias.SiteId))
{
refresh = true;
}
}
if (site != null) if (site != null)
{ {
if (PageState == null || refresh || PageState.Page.Path != route.PagePath) if (PageState == null || refresh || PageState.Page.Path != route.PagePath)

View File

@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Oqtane.Models; using Oqtane.Models;
using Microsoft.AspNetCore.Identity;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
@ -22,23 +21,17 @@ namespace Oqtane.Controllers
public class UserController : Controller public class UserController : Controller
{ {
private readonly IUserRepository _users; private readonly IUserRepository _users;
private readonly UserManager<IdentityUser> _identityUserManager;
private readonly SignInManager<IdentityUser> _identitySignInManager;
private readonly ITenantManager _tenantManager; private readonly ITenantManager _tenantManager;
private readonly INotificationRepository _notifications;
private readonly IUserManager _userManager; private readonly IUserManager _userManager;
private readonly ISiteRepository _sites; private readonly ISiteRepository _sites;
private readonly IUserPermissions _userPermissions; private readonly IUserPermissions _userPermissions;
private readonly IJwtManager _jwtManager; private readonly IJwtManager _jwtManager;
private readonly ILogManager _logger; private readonly ILogManager _logger;
public UserController(IUserRepository users, UserManager<IdentityUser> identityUserManager, SignInManager<IdentityUser> identitySignInManager, ITenantManager tenantManager, INotificationRepository notifications, IUserManager userManager, ISiteRepository sites, IUserPermissions userPermissions, IJwtManager jwtManager, ILogManager logger) public UserController(IUserRepository users, ITenantManager tenantManager, IUserManager userManager, ISiteRepository sites, IUserPermissions userPermissions, IJwtManager jwtManager, ILogManager logger)
{ {
_users = users; _users = users;
_identityUserManager = identityUserManager;
_identitySignInManager = identitySignInManager;
_tenantManager = tenantManager; _tenantManager = tenantManager;
_notifications = notifications;
_userManager = userManager; _userManager = userManager;
_sites = sites; _sites = sites;
_userPermissions = userPermissions; _userPermissions = userPermissions;

View File

@ -131,9 +131,8 @@ namespace Oqtane.Controllers
{ {
userRole = _userRoles.AddUserRole(userRole); userRole = _userRoles.AddUserRole(userRole);
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.UserRole, userRole.UserRoleId, SyncEventActions.Create); _syncManager.AddSyncEvent(_alias.TenantId, EntityNames.UserRole, userRole.UserRoleId, SyncEventActions.Create);
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.User, userRole.UserId, SyncEventActions.Reload);
_logger.Log(LogLevel.Information, this, LogFunction.Create, "User Role Added {UserRole}", userRole); _logger.Log(LogLevel.Information, this, LogFunction.Create, "User Role Added {UserRole}", userRole);
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.User, userRole.UserId, SyncEventActions.Refresh);
} }
else else
{ {
@ -154,7 +153,7 @@ namespace Oqtane.Controllers
{ {
userRole = _userRoles.UpdateUserRole(userRole); userRole = _userRoles.UpdateUserRole(userRole);
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.UserRole, userRole.UserRoleId, SyncEventActions.Update); _syncManager.AddSyncEvent(_alias.TenantId, EntityNames.UserRole, userRole.UserRoleId, SyncEventActions.Update);
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.User, userRole.UserId, SyncEventActions.Refresh); _syncManager.AddSyncEvent(_alias.TenantId, EntityNames.User, userRole.UserId, SyncEventActions.Reload);
_logger.Log(LogLevel.Information, this, LogFunction.Update, "User Role Updated {UserRole}", userRole); _logger.Log(LogLevel.Information, this, LogFunction.Update, "User Role Updated {UserRole}", userRole);
} }
else else
@ -171,25 +170,24 @@ namespace Oqtane.Controllers
[Authorize(Policy = $"{EntityNames.UserRole}:{PermissionNames.Write}:{RoleNames.Admin}")] [Authorize(Policy = $"{EntityNames.UserRole}:{PermissionNames.Write}:{RoleNames.Admin}")]
public void Delete(int id) public void Delete(int id)
{ {
UserRole userrole = _userRoles.GetUserRole(id); UserRole userRole = _userRoles.GetUserRole(id);
if (userrole != null && SiteValid(userrole.Role.SiteId) && RoleValid(userrole.Role.Name)) if (userRole != null && SiteValid(userRole.Role.SiteId) && RoleValid(userRole.Role.Name))
{ {
_userRoles.DeleteUserRole(id); _userRoles.DeleteUserRole(id);
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.UserRole, userrole.UserRoleId, SyncEventActions.Delete); _syncManager.AddSyncEvent(_alias.TenantId, EntityNames.UserRole, userRole.UserRoleId, SyncEventActions.Delete);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Role Deleted {UserRole}", userrole); _syncManager.AddSyncEvent(_alias.TenantId, EntityNames.User, userRole.UserId, SyncEventActions.Reload);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Role Deleted {UserRole}", userRole);
if (userrole.Role.Name == RoleNames.Host) if (userRole.Role.Name == RoleNames.Host)
{ {
// add site specific user roles to preserve user access // add site specific user roles to preserve user access
var role = _roles.GetRoles(_alias.SiteId).FirstOrDefault(item => item.Name == RoleNames.Registered); var role = _roles.GetRoles(_alias.SiteId).FirstOrDefault(item => item.Name == RoleNames.Registered);
userrole = _userRoles.AddUserRole(new UserRole { UserId = userrole.UserId, RoleId = role.RoleId, EffectiveDate = null, ExpiryDate = null }); userRole = _userRoles.AddUserRole(new UserRole { UserId = userRole.UserId, RoleId = role.RoleId, EffectiveDate = null, ExpiryDate = null });
_logger.Log(LogLevel.Information, this, LogFunction.Create, "User Role Added {UserRole}", userrole); _logger.Log(LogLevel.Information, this, LogFunction.Create, "User Role Added {UserRole}", userRole);
role = _roles.GetRoles(_alias.SiteId).FirstOrDefault(item => item.Name == RoleNames.Admin); role = _roles.GetRoles(_alias.SiteId).FirstOrDefault(item => item.Name == RoleNames.Admin);
userrole = _userRoles.AddUserRole(new UserRole { UserId = userrole.UserId, RoleId = role.RoleId, EffectiveDate = null, ExpiryDate = null }); userRole = _userRoles.AddUserRole(new UserRole { UserId = userRole.UserId, RoleId = role.RoleId, EffectiveDate = null, ExpiryDate = null });
_logger.Log(LogLevel.Information, this, LogFunction.Create, "User Role Added {UserRole}", userrole); _logger.Log(LogLevel.Information, this, LogFunction.Create, "User Role Added {UserRole}", userRole);
} }
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.User, userrole.UserId, SyncEventActions.Refresh);
} }
else else
{ {

View File

@ -178,7 +178,7 @@ namespace Oqtane.Managers
user = _users.UpdateUser(user); user = _users.UpdateUser(user);
_syncManager.AddSyncEvent(_tenantManager.GetAlias().TenantId, EntityNames.User, user.UserId, SyncEventActions.Update); _syncManager.AddSyncEvent(_tenantManager.GetAlias().TenantId, EntityNames.User, user.UserId, SyncEventActions.Update);
_syncManager.AddSyncEvent(_tenantManager.GetAlias().TenantId, EntityNames.User, user.UserId, SyncEventActions.Refresh); _syncManager.AddSyncEvent(_tenantManager.GetAlias().TenantId, EntityNames.User, user.UserId, SyncEventActions.Reload);
user.Password = ""; // remove sensitive information user.Password = ""; // remove sensitive information
_logger.Log(LogLevel.Information, this, LogFunction.Update, "User Updated {User}", user); _logger.Log(LogLevel.Information, this, LogFunction.Update, "User Updated {User}", user);
} }
@ -228,6 +228,7 @@ namespace Oqtane.Managers
// delete user // delete user
_users.DeleteUser(userid); _users.DeleteUser(userid);
_syncManager.AddSyncEvent(_tenantManager.GetAlias().TenantId, EntityNames.User, userid, SyncEventActions.Delete); _syncManager.AddSyncEvent(_tenantManager.GetAlias().TenantId, EntityNames.User, userid, SyncEventActions.Delete);
_syncManager.AddSyncEvent(_tenantManager.GetAlias().TenantId, EntityNames.User, userid, SyncEventActions.Reload);
_logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Deleted {UserId}", userid, result.ToString()); _logger.Log(LogLevel.Information, this, LogFunction.Delete, "User Deleted {UserId}", userid, result.ToString());
} }
else else

View File

@ -3,6 +3,9 @@ using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.AspNetCore.Mvc.RazorPages;
using Oqtane.Extensions;
using Oqtane.Infrastructure;
using Oqtane.Managers;
using Oqtane.Shared; using Oqtane.Shared;
namespace Oqtane.Pages namespace Oqtane.Pages
@ -10,9 +13,28 @@ namespace Oqtane.Pages
[Authorize] [Authorize]
public class LogoutModel : PageModel public class LogoutModel : PageModel
{ {
private readonly IUserManager _userManager;
private readonly ISyncManager _syncManager;
public LogoutModel(IUserManager userManager, ISyncManager syncManager)
{
_userManager = userManager;
_syncManager = syncManager;
}
public async Task<IActionResult> OnPostAsync(string returnurl) public async Task<IActionResult> OnPostAsync(string returnurl)
{ {
if (HttpContext.User != null)
{
var alias = HttpContext.GetAlias();
var user = _userManager.GetUser(HttpContext.User.Identity.Name, alias.SiteId);
if (user != null)
{
_syncManager.AddSyncEvent(alias.TenantId, EntityNames.User, user.UserId, SyncEventActions.Reload);
}
await HttpContext.SignOutAsync(Constants.AuthenticationScheme); await HttpContext.SignOutAsync(Constants.AuthenticationScheme);
}
returnurl = (returnurl == null) ? "/" : returnurl; returnurl = (returnurl == null) ? "/" : returnurl;
returnurl = (!returnurl.StartsWith("/")) ? "/" + returnurl : returnurl; returnurl = (!returnurl.StartsWith("/")) ? "/" + returnurl : returnurl;