mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-11-10 08:57:25 +01:00
Add API call for frontend to fetch list of valid roles from backend
- only relevant for admin config (addUser, editRole) - admin only (double-checked)
This commit is contained in:
parent
7d4f4ab2c8
commit
7fb94c33cf
@ -76,6 +76,7 @@ func (api *RestApi) MountRoutes(r *mux.Router) {
|
||||
|
||||
if api.Authentication != nil {
|
||||
r.HandleFunc("/jwt/", api.getJWT).Methods(http.MethodGet)
|
||||
r.HandleFunc("/roles/", api.getRoles).Methods(http.MethodGet)
|
||||
r.HandleFunc("/users/", api.createUser).Methods(http.MethodPost, http.MethodPut)
|
||||
r.HandleFunc("/users/", api.getUsers).Methods(http.MethodGet)
|
||||
r.HandleFunc("/users/", api.deleteUser).Methods(http.MethodDelete)
|
||||
@ -880,6 +881,22 @@ func (api *RestApi) getUsers(rw http.ResponseWriter, r *http.Request) {
|
||||
json.NewEncoder(rw).Encode(users)
|
||||
}
|
||||
|
||||
func (api *RestApi) getRoles(rw http.ResponseWriter, r *http.Request) {
|
||||
user := auth.GetUser(r.Context())
|
||||
if (!user.HasRole(auth.RoleAdmin)) {
|
||||
http.Error(rw, "only admins are allowed to fetch a list of roles", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
roles, err := auth.GetValidRoles(user)
|
||||
if err != nil {
|
||||
http.Error(rw, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
json.NewEncoder(rw).Encode(roles)
|
||||
}
|
||||
|
||||
func (api *RestApi) updateUser(rw http.ResponseWriter, r *http.Request) {
|
||||
if user := auth.GetUser(r.Context()); !user.HasRole(auth.RoleAdmin) {
|
||||
http.Error(rw, "only admins are allowed to update a user", http.StatusForbidden)
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
"fmt"
|
||||
|
||||
"github.com/ClusterCockpit/cc-backend/pkg/log"
|
||||
"github.com/gorilla/sessions"
|
||||
@ -139,6 +140,15 @@ func IsValidRole(role string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func GetValidRoles(user *User) ([5]string, error) {
|
||||
var vals [5]string
|
||||
if (!user.HasRole(RoleAdmin)) {
|
||||
return vals, fmt.Errorf("%#v: only admins are allowed to fetch a list of roles", user.Username)
|
||||
} else {
|
||||
return validRoles, nil
|
||||
}
|
||||
}
|
||||
|
||||
func GetUser(ctx context.Context) *User {
|
||||
x := ctx.Value(ContextUserKey)
|
||||
if x == nil {
|
||||
|
@ -8,6 +8,7 @@
|
||||
import Options from './admin/Options.svelte'
|
||||
|
||||
let users = []
|
||||
let roles = []
|
||||
|
||||
function getUserList() {
|
||||
fetch('/api/users/?via-ldap=false¬-just-user=true')
|
||||
@ -17,19 +18,32 @@
|
||||
})
|
||||
}
|
||||
|
||||
onMount(() => getUserList())
|
||||
function getValidRoles() {
|
||||
fetch('/api/roles/')
|
||||
.then(res => res.json())
|
||||
.then(rolesRaw => {
|
||||
roles = rolesRaw
|
||||
})
|
||||
}
|
||||
|
||||
function initAdmin() {
|
||||
getUserList()
|
||||
getValidRoles()
|
||||
}
|
||||
|
||||
onMount(() => initAdmin())
|
||||
|
||||
</script>
|
||||
|
||||
<Row cols={2} class="p-2 g-2" >
|
||||
<Col class="mb-1">
|
||||
<AddUser on:reload={getUserList}/>
|
||||
<AddUser roles={roles} on:reload={getUserList}/>
|
||||
</Col>
|
||||
<Col class="mb-1">
|
||||
<ShowUsers on:reload={getUserList} bind:users={users}/>
|
||||
</Col>
|
||||
<Col>
|
||||
<EditRole on:reload={getUserList}/>
|
||||
<EditRole roles={roles} on:reload={getUserList}/>
|
||||
</Col>
|
||||
<Col>
|
||||
<EditProject on:reload={getUserList}/>
|
||||
|
@ -7,6 +7,15 @@
|
||||
|
||||
let message = {msg: '', color: '#d63384'}
|
||||
let displayMessage = false
|
||||
let roleLabel = {
|
||||
api: 'API',
|
||||
user: 'User (regular user, same as if created via LDAP sync.)',
|
||||
manager: 'Manager',
|
||||
support: 'Support',
|
||||
admin: 'Admin'
|
||||
}
|
||||
|
||||
export let roles = []
|
||||
|
||||
async function handleUserSubmit() {
|
||||
let form = document.querySelector('#create-user-form')
|
||||
@ -73,26 +82,19 @@
|
||||
|
||||
<div class="mb-3">
|
||||
<p>Role:</p>
|
||||
{#each roles as role, i}
|
||||
{#if i == 0}
|
||||
<div>
|
||||
<input type="radio" id="user" name="role" value="user" checked/>
|
||||
<label for="user">User (regular user, same as if created via LDAP sync.)</label>
|
||||
<input type="radio" id={role} name="role" value={role} checked/>
|
||||
<label for={role}>{roleLabel[role]}</label>
|
||||
</div>
|
||||
{:else}
|
||||
<div>
|
||||
<input type="radio" id="api" name="role" value="api"/>
|
||||
<label for="api">API</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" id="manager" name="role" value="manager"/>
|
||||
<label for="manager">Manager</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" id="support" name="role" value="support"/>
|
||||
<label for="support">Support</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" id="admin" name="role" value="admin"/>
|
||||
<label for="admin">Admin</label>
|
||||
<input type="radio" id={role} name="role" value={role}/>
|
||||
<label for={role}>{roleLabel[role]}</label>
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
</div>
|
||||
<p style="display: flex; align-items: center;">
|
||||
<Button type="submit" color="primary">Submit</Button>
|
||||
|
@ -8,6 +8,15 @@
|
||||
let message = {msg: '', color: '#d63384'}
|
||||
let displayMessage = false
|
||||
|
||||
export let roles = []
|
||||
let roleLabel = {
|
||||
api: 'API',
|
||||
user: 'User',
|
||||
manager: 'Manager',
|
||||
support: 'Support',
|
||||
admin: 'Admin'
|
||||
}
|
||||
|
||||
async function handleAddRole() {
|
||||
const username = document.querySelector('#role-username').value
|
||||
const role = document.querySelector('#role-select').value
|
||||
@ -86,11 +95,9 @@
|
||||
<input type="text" class="form-control" placeholder="username" id="role-username"/>
|
||||
<select class="form-select" id="role-select">
|
||||
<option selected value="">Role...</option>
|
||||
<option value="user">User</option>
|
||||
<option value="manager">Manager</option>
|
||||
<option value="support">Support</option>
|
||||
<option value="admin">Admin</option>
|
||||
<option value="api">API</option>
|
||||
{#each roles as role}
|
||||
<option value={role}>{roleLabel[role]}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<!-- PreventDefault on Sveltestrap-Button more complex to achieve than just use good ol' html button -->
|
||||
<!-- see: https://stackoverflow.com/questions/69630422/svelte-how-to-use-event-modifiers-in-my-own-components -->
|
||||
|
Loading…
Reference in New Issue
Block a user