diff --git a/Oqtane.Client/Modules/Controls/TabStrip.razor b/Oqtane.Client/Modules/Controls/TabStrip.razor
index a8402d86..53cd6e11 100644
--- a/Oqtane.Client/Modules/Controls/TabStrip.razor
+++ b/Oqtane.Client/Modules/Controls/TabStrip.razor
@@ -86,11 +86,19 @@
///
/// Determines if a tab should be visible based on user permissions.
- /// Authorization hierarchy:
- /// 1. Host and Admin roles ALWAYS have access (bypass all checks)
- /// 2. Check standard SecurityAccessLevel (View, Edit, etc.)
- /// 3. If RoleName specified AND user is not Admin/Host, check RoleName
- /// 4. If PermissionName specified AND user is not Admin/Host, check PermissionName
+ /// Authorization follows this hierarchy:
+ /// 1. Host tabs (Security == Host): Only users with Host role can access (Admins excluded)
+ /// 2. Admin users: Bypass all other checks (except Host restrictions)
+ /// 3. SecurityAccessLevel check (null/Anonymous/View/Edit/Host):
+ /// - null: No security level restriction (proceeds to step 4)
+ /// - Anonymous: No authentication required
+ /// - View/Edit: Requires corresponding module permission
+ /// - Host: Only Host role can access
+ /// 4. Additional RoleName requirement (if specified)
+ /// 5. Additional PermissionName requirement (if specified)
+ ///
+ /// Important: When Security is null, RoleName and PermissionName checks STILL apply
+ /// (Security = null doesn't mean unrestricted, it means "no security level required")
///
/// The tab panel to check authorization for
/// True if user is authorized to see this tab, false otherwise
@@ -99,24 +107,40 @@
// Step 1: Check for Host-only restriction
if (tabPanel.Security == SecurityAccessLevel.Host)
{
- // Only Host users can access Host-level security tabs (Admin users are excluded)
return UserSecurity.IsAuthorized(PageState.User, RoleNames.Host);
}
- // Step 2: Admin bypass all other restrictions
+ // Step 2: Admin bypass all restrictions except Host
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
{
return true;
}
- var authorized = false;
+ // Step 3: If Security is null, check only RoleName and PermissionName
+ if (tabPanel.Security == null)
+ {
+ // Start with authorized = true for null security
+ bool isAuthorized = true;
- // Step 3: Check standard SecurityAccessLevel
+ // Only apply RoleName check if provided
+ if (!string.IsNullOrEmpty(tabPanel.RoleName))
+ {
+ isAuthorized = UserSecurity.IsAuthorized(PageState.User, tabPanel.RoleName);
+ }
+
+ // Only apply PermissionName check if provided
+ if (isAuthorized && !string.IsNullOrEmpty(tabPanel.PermissionName))
+ {
+ isAuthorized = UserSecurity.IsAuthorized(PageState.User, tabPanel.PermissionName, ModuleState.PermissionList);
+ }
+
+ return isAuthorized;
+ }
+
+ // Handle other SecurityAccessLevel values
+ bool authorized = false; // Use different variable name or move declaration
switch (tabPanel.Security)
{
- case null:
- authorized = true;
- break;
case SecurityAccessLevel.Anonymous:
authorized = true;
break;
@@ -131,13 +155,13 @@
break;
}
- // Step 4: Check RoleName if provided (additional requirement)
+ // Step 4: Additional RoleName requirement
if (authorized && !string.IsNullOrEmpty(tabPanel.RoleName))
{
authorized = UserSecurity.IsAuthorized(PageState.User, tabPanel.RoleName);
}
- // Step 5: Check PermissionName if provided (additional requirement)
+ // Step 5: Additional PermissionName requirement
if (authorized && !string.IsNullOrEmpty(tabPanel.PermissionName))
{
authorized = UserSecurity.IsAuthorized(PageState.User, tabPanel.PermissionName, ModuleState.PermissionList);