feat: move Areas to Design role, fix logout, add Sign Out button

Areas management is a design concern, not admin. Moved Areas page
authorization from RequireAdmin to RequireDesign, moved nav link from
Admin to Design section, updated ManagementActor role check. Added
GET /logout endpoint (was 404, now redirects to login). Improved Sign
Out button visibility in sidebar next to username.
This commit is contained in:
Joseph Doherty
2026-03-18 00:28:35 -04:00
parent 75a6636a2c
commit 68115e7e38
5 changed files with 22 additions and 13 deletions

View File

@@ -177,7 +177,7 @@ At any level, an override is only permitted if the attribute has **not been lock
- Areas support **parent-child relationships** (e.g., Plant → Building → Production Line → Cell). - Areas support **parent-child relationships** (e.g., Plant → Building → Production Line → Cell).
- Each instance is assigned to an area within its site. - Each instance is assigned to an area within its site.
- Areas are used for **filtering and finding instances** in the central UI. - Areas are used for **filtering and finding instances** in the central UI.
- Area definitions are managed by users with the **Admin** role. - Area definitions are managed by users with the **Design** role.
### 3.11 Pre-Deployment Validation ### 3.11 Pre-Deployment Validation
@@ -394,7 +394,7 @@ The central cluster hosts a **configuration and management UI** (no live machine
### 9.3 Roles ### 9.3 Roles
- **Admin**: System-wide permission to manage sites, data connections, LDAP group-to-role mappings, API keys, and system-level configuration. - **Admin**: System-wide permission to manage sites, data connections, LDAP group-to-role mappings, API keys, and system-level configuration.
- **Design**: System-wide permission to author and edit templates, scripts, shared scripts, external system definitions, notification lists, and inbound API method definitions. - **Design**: System-wide permission to author and edit templates, scripts, shared scripts, external system definitions, notification lists, inbound API method definitions, and area definitions.
- **Deployment**: Permission to manage instances (create, set overrides, bind connections, disable, delete) and deploy configurations to sites. Also triggers system-wide artifact deployment. Can be scoped **per site**. - **Deployment**: Permission to manage instances (create, set overrides, bind connections, disable, delete) and deploy configurations to sites. Also triggers system-wide artifact deployment. Can be scoped **per site**.
### 9.4 Role Scoping ### 9.4 Role Scoping

View File

@@ -86,6 +86,13 @@ public static class AuthEndpoints
context.Response.Redirect("/login"); context.Response.Redirect("/login");
}).DisableAntiforgery(); }).DisableAntiforgery();
// GET /logout — allows direct navigation to logout (redirects to login after sign-out)
endpoints.MapGet("/logout", async (HttpContext context) =>
{
await context.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Results.Redirect("/login");
});
return endpoints; return endpoints;
} }
} }

View File

@@ -23,9 +23,6 @@
<li class="nav-item"> <li class="nav-item">
<NavLink class="nav-link" href="/admin/data-connections">Data Connections</NavLink> <NavLink class="nav-link" href="/admin/data-connections">Data Connections</NavLink>
</li> </li>
<li class="nav-item">
<NavLink class="nav-link" href="/admin/areas">Areas</NavLink>
</li>
<li class="nav-item"> <li class="nav-item">
<NavLink class="nav-link" href="/admin/api-keys">API Keys</NavLink> <NavLink class="nav-link" href="/admin/api-keys">API Keys</NavLink>
</li> </li>
@@ -45,6 +42,9 @@
<li class="nav-item"> <li class="nav-item">
<NavLink class="nav-link" href="/design/external-systems">External Systems</NavLink> <NavLink class="nav-link" href="/design/external-systems">External Systems</NavLink>
</li> </li>
<li class="nav-item">
<NavLink class="nav-link" href="/admin/areas">Areas</NavLink>
</li>
</Authorized> </Authorized>
</AuthorizeView> </AuthorizeView>
@@ -90,12 +90,14 @@
<AuthorizeView> <AuthorizeView>
<Authorized> <Authorized>
<div class="border-top border-secondary p-2"> <div class="border-top border-secondary px-3 py-2">
<span class="d-block text-light small px-2">@context.User.FindFirst("DisplayName")?.Value</span> <div class="d-flex justify-content-between align-items-center">
<span class="text-light small">@context.User.FindFirst("DisplayName")?.Value</span>
<form method="post" action="/auth/logout" data-enhance="false"> <form method="post" action="/auth/logout" data-enhance="false">
<button type="submit" class="btn btn-link btn-sm text-muted text-decoration-none px-2">Sign Out</button> <button type="submit" class="btn btn-outline-light btn-sm py-0 px-2">Sign Out</button>
</form> </form>
</div> </div>
</div>
</Authorized> </Authorized>
</AuthorizeView> </AuthorizeView>
</nav> </nav>

View File

@@ -3,7 +3,7 @@
@using ScadaLink.Commons.Entities.Instances @using ScadaLink.Commons.Entities.Instances
@using ScadaLink.Commons.Entities.Sites @using ScadaLink.Commons.Entities.Sites
@using ScadaLink.Commons.Interfaces.Repositories @using ScadaLink.Commons.Interfaces.Repositories
@attribute [Authorize(Policy = AuthorizationPolicies.RequireAdmin)] @attribute [Authorize(Policy = AuthorizationPolicies.RequireDesign)]
@inject ISiteRepository SiteRepository @inject ISiteRepository SiteRepository
@inject ITemplateEngineRepository TemplateEngineRepository @inject ITemplateEngineRepository TemplateEngineRepository

View File

@@ -74,13 +74,13 @@ public class ManagementActor : ReceiveActor
{ {
// Admin operations // Admin operations
CreateSiteCommand or UpdateSiteCommand or DeleteSiteCommand CreateSiteCommand or UpdateSiteCommand or DeleteSiteCommand
or CreateAreaCommand or DeleteAreaCommand
or ListRoleMappingsCommand or CreateRoleMappingCommand or ListRoleMappingsCommand or CreateRoleMappingCommand
or UpdateRoleMappingCommand or DeleteRoleMappingCommand or UpdateRoleMappingCommand or DeleteRoleMappingCommand
or ListApiKeysCommand or CreateApiKeyCommand or DeleteApiKeyCommand => "Admin", or ListApiKeysCommand or CreateApiKeyCommand or DeleteApiKeyCommand => "Admin",
// Design operations // Design operations
CreateTemplateCommand or UpdateTemplateCommand or DeleteTemplateCommand CreateAreaCommand or DeleteAreaCommand
or CreateTemplateCommand or UpdateTemplateCommand or DeleteTemplateCommand
or ValidateTemplateCommand or ValidateTemplateCommand
or CreateExternalSystemCommand or UpdateExternalSystemCommand or CreateExternalSystemCommand or UpdateExternalSystemCommand
or DeleteExternalSystemCommand or DeleteExternalSystemCommand