mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2025-07-23 12:51:40 +02:00
Rework roles as enum, change AuthSource to enum
This commit is contained in:
@@ -10,11 +10,11 @@
|
||||
|
||||
const ccconfig = getContext('cc-config')
|
||||
|
||||
export let user
|
||||
export let isAdmin
|
||||
|
||||
</script>
|
||||
|
||||
{#if user.AuthLevel == 5}
|
||||
{#if isAdmin == true}
|
||||
<Card style="margin-bottom: 1.5em;">
|
||||
<CardHeader>
|
||||
<CardTitle class="mb-1">Admin Options</CardTitle>
|
||||
|
@@ -4,8 +4,9 @@
|
||||
Dropdown, DropdownToggle, DropdownMenu, DropdownItem, InputGroupText } from 'sveltestrap'
|
||||
|
||||
export let username // empty string if auth. is disabled, otherwise the username as string
|
||||
export let authlevel // integer
|
||||
export let authlevel // Integer
|
||||
export let clusters // array of names
|
||||
export let roles // Role Enum-Like
|
||||
|
||||
let isOpen = false
|
||||
|
||||
@@ -39,9 +40,9 @@
|
||||
]
|
||||
|
||||
const viewsPerCluster = [
|
||||
{ title: 'Analysis', authLevel: 4, href: '/monitoring/analysis/', icon: 'graph-up' },
|
||||
{ title: 'Systems', authLevel: 5, href: '/monitoring/systems/', icon: 'cpu' },
|
||||
{ title: 'Status', authLevel: 5, href: '/monitoring/status/', icon: 'cpu' },
|
||||
{ title: 'Analysis', requiredRole: roles.support, href: '/monitoring/analysis/', icon: 'graph-up' },
|
||||
{ title: 'Systems', requiredRole: roles.admin, href: '/monitoring/systems/', icon: 'cpu' },
|
||||
{ title: 'Status', requiredRole: roles.admin, href: '/monitoring/status/', icon: 'cpu' },
|
||||
]
|
||||
</script>
|
||||
|
||||
@@ -52,26 +53,26 @@
|
||||
<NavbarToggler on:click={() => (isOpen = !isOpen)} />
|
||||
<Collapse {isOpen} navbar expand="lg" on:update={({ detail }) => (isOpen = detail.isOpen)}>
|
||||
<Nav pills>
|
||||
{#if authlevel == 5} <!-- admin -->
|
||||
{#if authlevel == roles.admin}
|
||||
{#each adminviews as item}
|
||||
<NavLink href={item.href} active={window.location.pathname == item.href}><Icon name={item.icon}/> {item.title}</NavLink>
|
||||
{/each}
|
||||
{:else if authlevel == 4} <!-- support -->
|
||||
{:else if authlevel == roles.support}
|
||||
{#each supportviews as item}
|
||||
<NavLink href={item.href} active={window.location.pathname == item.href}><Icon name={item.icon}/> {item.title}</NavLink>
|
||||
{/each}
|
||||
{:else if authlevel == 3} <!-- manager -->
|
||||
{:else if authlevel == roles.manager}
|
||||
{#each managerviews as item}
|
||||
<NavLink href={item.href} active={window.location.pathname == item.href}><Icon name={item.icon}/> {item.title}</NavLink>
|
||||
{/each}
|
||||
{:else if authlevel == 2} <!-- user -->
|
||||
{:else if authlevel == roles.user}
|
||||
{#each userviews as item}
|
||||
<NavLink href={item.href} active={window.location.pathname == item.href}><Icon name={item.icon}/> {item.title}</NavLink>
|
||||
{/each}
|
||||
{:else}
|
||||
<p>API User or Unauthorized!</p>
|
||||
{/if}
|
||||
{#each viewsPerCluster.filter(item => item.authLevel <= authlevel) as item}
|
||||
{#each viewsPerCluster.filter(item => item.requiredRole <= authlevel) as item}
|
||||
<NavItem>
|
||||
<Dropdown nav inNavbar>
|
||||
<DropdownToggle nav caret>
|
||||
@@ -94,7 +95,7 @@
|
||||
<InputGroup>
|
||||
<Input type="text" placeholder="Search 'type:<query>' ..." name="searchId"/>
|
||||
<Button outline type="submit"><Icon name="search"/></Button>
|
||||
<InputGroupText style="cursor:help;" title={(authlevel >= 4) ? "Example: 'projectId:a100cd', Types are: jobId | jobName | projectId | username | name" : "Example: 'jobName:myjob', Types are jobId | jobName | projectId"}><Icon name="info-circle"/></InputGroupText>
|
||||
<InputGroupText style="cursor:help;" title={(authlevel >= roles.support) ? "Example: 'projectId:a100cd', Types are: jobId | jobName | projectId | username | name" : "Example: 'jobName:myjob', Types are jobId | jobName | projectId"}><Icon name="info-circle"/></InputGroupText>
|
||||
</InputGroup>
|
||||
</form>
|
||||
{#if username}
|
||||
|
@@ -14,7 +14,8 @@
|
||||
const ccconfig = getContext('cc-config')
|
||||
|
||||
export let filterPresets = {}
|
||||
export let authLevel
|
||||
export let authlevel
|
||||
export let roles
|
||||
|
||||
let filters, jobList, matchedJobs = null
|
||||
let sorting = { field: 'startTime', order: 'DESC' }, isSortingOpen = false, isMetricsSelectionOpen = false
|
||||
@@ -61,7 +62,7 @@
|
||||
</Col>
|
||||
|
||||
<Col xs="3" style="margin-left: auto;">
|
||||
<UserOrProject bind:authLevel={authLevel} on:update={({ detail }) => filters.update(detail)}/>
|
||||
<UserOrProject bind:authlevel={authlevel} bind:roles={roles} on:update={({ detail }) => filters.update(detail)}/>
|
||||
</Col>
|
||||
<Col xs="2">
|
||||
<Refresher on:reload={() => jobList.update()} />
|
||||
|
@@ -4,7 +4,7 @@ import Config from './Config.root.svelte'
|
||||
new Config({
|
||||
target: document.getElementById('svelte-app'),
|
||||
props: {
|
||||
user: user
|
||||
isAdmin: isAdmin
|
||||
},
|
||||
context: new Map([
|
||||
['cc-config', clusterCockpitConfig]
|
||||
|
@@ -6,7 +6,8 @@
|
||||
|
||||
export let user = ''
|
||||
export let project = ''
|
||||
export let authLevel
|
||||
export let authlevel
|
||||
export let roles
|
||||
let mode = 'user', term = ''
|
||||
const throttle = 500
|
||||
|
||||
@@ -23,7 +24,7 @@
|
||||
|
||||
let timeoutId = null
|
||||
function termChanged(sleep = throttle) {
|
||||
if (authLevel == 2) {
|
||||
if (authlevel == roles.user) {
|
||||
project = term
|
||||
|
||||
if (timeoutId != null)
|
||||
@@ -34,7 +35,7 @@
|
||||
project
|
||||
})
|
||||
}, sleep)
|
||||
} else if (authLevel >= 3) {
|
||||
} else if (authlevel >= roles.manager) {
|
||||
if (mode == 'user')
|
||||
user = term
|
||||
else
|
||||
@@ -53,13 +54,13 @@
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if authLevel == 2}
|
||||
{#if authlevel == roles.user}
|
||||
<InputGroup>
|
||||
<Input
|
||||
type="text" bind:value={term} on:change={() => termChanged()} on:keyup={(event) => termChanged(event.key == 'Enter' ? 0 : throttle)} placeholder='filter project...'
|
||||
/>
|
||||
</InputGroup>
|
||||
{:else if authLevel >= 3}
|
||||
{:else if authlevel >= roles.manager}
|
||||
<InputGroup>
|
||||
<select style="max-width: 175px;" class="form-select"
|
||||
bind:value={mode} on:change={modeChanged}>
|
||||
|
@@ -5,7 +5,8 @@ new Jobs({
|
||||
target: document.getElementById('svelte-app'),
|
||||
props: {
|
||||
filterPresets: filterPresets,
|
||||
authLevel: authLevel
|
||||
authlevel: authlevel,
|
||||
roles: roles
|
||||
},
|
||||
context: new Map([
|
||||
['cc-config', clusterCockpitConfig]
|
||||
|
@@ -15,9 +15,10 @@
|
||||
{{end}}
|
||||
<script>
|
||||
const header = {
|
||||
"username": "{{ .User.Username }}",
|
||||
"authlevel": {{ .User.AuthLevel }},
|
||||
"clusters": {{ .Clusters }},
|
||||
"username": "{{ .User.Username }}",
|
||||
"authlevel": {{ .User.GetAuthLevel }},
|
||||
"clusters": {{ .Clusters }},
|
||||
"roles": {{ .Roles }}
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
{{end}}
|
||||
{{define "javascript"}}
|
||||
<script>
|
||||
const user = {{ .User }};
|
||||
const isAdmin = {{ .User.HasRole .Roles.admin }};
|
||||
const filterPresets = {{ .FilterPresets }};
|
||||
const clusterCockpitConfig = {{ .Config }};
|
||||
</script>
|
||||
|
@@ -9,14 +9,14 @@
|
||||
<th>Running Jobs (short ones not listed)</th>
|
||||
<th>Total Jobs</th>
|
||||
<th>Short Jobs in past 24h</th>
|
||||
{{if ge .User.AuthLevel 4}}
|
||||
{{if .User.HasRole .Roles.admin}}
|
||||
<th>System View</th>
|
||||
<th>Analysis View</th>
|
||||
{{end}}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{if ge .User.AuthLevel 4}}
|
||||
{{if .User.HasRole .Roles.admin}}
|
||||
{{range .Infos.clusters}}
|
||||
<tr>
|
||||
<td>{{.Name}}</td>
|
||||
|
@@ -10,7 +10,8 @@
|
||||
<script>
|
||||
const filterPresets = {{ .FilterPresets }};
|
||||
const clusterCockpitConfig = {{ .Config }};
|
||||
const authLevel = {{ .User.AuthLevel }};
|
||||
const authlevel = {{ .User.GetAuthLevel }};
|
||||
const roles = {{ .Roles }};
|
||||
</script>
|
||||
<script src='/build/jobs.js'></script>
|
||||
{{end}}
|
||||
|
@@ -11,6 +11,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/ClusterCockpit/cc-backend/internal/auth"
|
||||
"github.com/ClusterCockpit/cc-backend/internal/config"
|
||||
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
||||
"github.com/ClusterCockpit/cc-backend/pkg/schema"
|
||||
@@ -55,11 +56,6 @@ func init() {
|
||||
_ = base
|
||||
}
|
||||
|
||||
type User struct {
|
||||
Username string // Username of the currently logged in user
|
||||
AuthLevel int // Level of authorization
|
||||
}
|
||||
|
||||
type Build struct {
|
||||
Version string
|
||||
Hash string
|
||||
@@ -70,7 +66,8 @@ type Page struct {
|
||||
Title string // Page title
|
||||
Error string // For generic use (e.g. the exact error message on /login)
|
||||
Info string // For generic use (e.g. "Logout successfull" on /login)
|
||||
User User // Information about the currently logged in user
|
||||
User auth.User // Information about the currently logged in user (Full User Info)
|
||||
Roles map[string]auth.Role // Available roles for frontend render checks
|
||||
Build Build // Latest information about the application
|
||||
Clusters []schema.ClusterConfig // List of all clusters for use in the Header
|
||||
FilterPresets map[string]interface{} // For pages with the Filter component, this can be used to set initial filters.
|
||||
|
Reference in New Issue
Block a user