Add admin function to remove roles, rename addroles to editroles

This commit is contained in:
Christoph Kluge 2022-08-26 15:15:36 +02:00
parent 0186e886e4
commit c9954787c1
4 changed files with 85 additions and 12 deletions

View File

@ -580,14 +580,26 @@ func (api *RestApi) updateUser(rw http.ResponseWriter, r *http.Request) {
return return
} }
// TODO: Handle anything but roles... // Get Values
newrole := r.FormValue("add-role") newrole := r.FormValue("add-role")
delrole := r.FormValue("remove-role")
// TODO: Handle anything but roles...
if (newrole != "") {
if err := api.Authentication.AddRole(r.Context(), mux.Vars(r)["id"], newrole); err != nil { if err := api.Authentication.AddRole(r.Context(), mux.Vars(r)["id"], newrole); err != nil {
http.Error(rw, err.Error(), http.StatusUnprocessableEntity) http.Error(rw, err.Error(), http.StatusUnprocessableEntity)
return return
} }
rw.Write([]byte("Add Role Success"))
rw.Write([]byte("success")) } else if (delrole != "") {
if err := api.Authentication.RemoveRole(r.Context(), mux.Vars(r)["id"], delrole); err != nil {
http.Error(rw, err.Error(), http.StatusUnprocessableEntity)
return
}
rw.Write([]byte("Remove Role Success"))
} else {
http.Error(rw, "Not Add or Del?", http.StatusInternalServerError)
}
} }
func (api *RestApi) updateConfiguration(rw http.ResponseWriter, r *http.Request) { func (api *RestApi) updateConfiguration(rw http.ResponseWriter, r *http.Request) {

View File

@ -129,6 +129,37 @@ func (auth *Authentication) AddRole(ctx context.Context, username string, role s
return nil return nil
} }
func (auth *Authentication) RemoveRole(ctx context.Context, username string, role string) error {
user, err := auth.GetUser(username)
if err != nil {
return err
}
if role != RoleAdmin && role != RoleApi && role != RoleUser {
return fmt.Errorf("invalid user role: %#v", role)
}
var exists bool
var newroles []string
for _, r := range user.Roles {
if r != role {
newroles = append(newroles, r) // Append all roles not matching requested delete role
} else {
exists = true
}
}
if (exists == true) {
var mroles, _ = json.Marshal(newroles)
if _, err := sq.Update("user").Set("roles", mroles).Where("user.username = ?", username).RunWith(auth.db).Exec(); err != nil {
return err
}
return nil
} else {
return fmt.Errorf("user %#v already does not have role %#v", username, role)
}
}
func FetchUser(ctx context.Context, db *sqlx.DB, username string) (*model.User, error) { func FetchUser(ctx context.Context, db *sqlx.DB, username string) (*model.User, error) {
me := GetUser(ctx) me := GetUser(ctx)
if me != nil && !me.HasRole(RoleAdmin) && me.Username != username { if me != nil && !me.HasRole(RoleAdmin) && me.Username != username {

View File

@ -1,7 +1,7 @@
<script> <script>
import { Row, Col } from 'sveltestrap' import { Row, Col } from 'sveltestrap'
import { onMount } from 'svelte' import { onMount } from 'svelte'
import AddRole from './admin/AddRole.svelte' import EditRole from './admin/EditRole.svelte'
import AddUser from './admin/AddUser.svelte' import AddUser from './admin/AddUser.svelte'
import ShowUsers from './admin/ShowUsers.svelte' import ShowUsers from './admin/ShowUsers.svelte'
import Options from './admin/Options.svelte' import Options from './admin/Options.svelte'
@ -28,7 +28,7 @@
<ShowUsers on:reload={getUserList} bind:users={users}/> <ShowUsers on:reload={getUserList} bind:users={users}/>
</Col> </Col>
<Col> <Col>
<AddRole on:reload={getUserList}/> <EditRole on:reload={getUserList}/>
</Col> </Col>
<Col> <Col>
<Options/> <Options/>

View File

@ -9,8 +9,8 @@
let displayMessage = false let displayMessage = false
async function handleAddRole() { async function handleAddRole() {
const username = document.querySelector('#add-role-username').value const username = document.querySelector('#role-username').value
const role = document.querySelector('#add-role-select').value const role = document.querySelector('#role-select').value
if (username == "" || role == "") { if (username == "" || role == "") {
alert('Please fill in a username and select a role.') alert('Please fill in a username and select a role.')
@ -37,6 +37,35 @@
} }
} }
async function handleRemoveRole() {
const username = document.querySelector('#role-username').value
const role = document.querySelector('#role-select').value
if (username == "" || role == "") {
alert('Please fill in a username and select a role.')
return
}
let formData = new FormData()
formData.append('username', username)
formData.append('remove-role', role)
try {
const res = await fetch(`/api/user/${username}`, { method: 'POST', body: formData })
if (res.ok) {
let text = await res.text()
popMessage(text, '#048109')
reloadUserList()
} else {
let text = await res.text()
// console.log(res.statusText)
throw new Error('Response Code ' + res.status + '-> ' + text)
}
} catch (err) {
popMessage(err, '#d63384')
}
}
function popMessage(response, rescolor) { function popMessage(response, rescolor) {
message = {msg: response, color: rescolor} message = {msg: response, color: rescolor}
displayMessage = true displayMessage = true
@ -54,8 +83,8 @@
<CardBody> <CardBody>
<CardTitle class="mb-3">Add Role to User</CardTitle> <CardTitle class="mb-3">Add Role to User</CardTitle>
<div class="input-group mb-3"> <div class="input-group mb-3">
<input type="text" class="form-control" placeholder="username" id="add-role-username"/> <input type="text" class="form-control" placeholder="username" id="role-username"/>
<select class="form-select" id="add-role-select"> <select class="form-select" id="role-select">
<option selected value="">Role...</option> <option selected value="">Role...</option>
<option value="user">User</option> <option value="user">User</option>
<option value="admin">Admin</option> <option value="admin">Admin</option>
@ -64,6 +93,7 @@
<!-- PreventDefault on Sveltestrap-Button more complex to achieve than just use good ol' html button --> <!-- 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 --> <!-- see: https://stackoverflow.com/questions/69630422/svelte-how-to-use-event-modifiers-in-my-own-components -->
<button class="btn btn-primary" type="button" id="add-role-button" on:click|preventDefault={handleAddRole}>Add</button> <button class="btn btn-primary" type="button" id="add-role-button" on:click|preventDefault={handleAddRole}>Add</button>
<button class="btn btn-danger" type="button" id="remove-role-button" on:click|preventDefault={handleRemoveRole}>Remove</button>
</div> </div>
<p> <p>
{#if displayMessage}<b><code style="color: {message.color};" out:fade>Update: {message.msg}</code></b>{/if} {#if displayMessage}<b><code style="color: {message.color};" out:fade>Update: {message.msg}</code></b>{/if}