122 lines
3.1 KiB
Go
122 lines
3.1 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"warpbox/lib/metastore"
|
|
)
|
|
|
|
type adminUserRow struct {
|
|
ID string
|
|
Username string
|
|
Email string
|
|
Tags string
|
|
CreatedAt string
|
|
Disabled bool
|
|
IsCurrent bool
|
|
}
|
|
|
|
func (app *App) handleAdminUsers(ctx *gin.Context) {
|
|
if !app.requireAdminFlag(ctx, func(perms metastore.EffectivePermissions) bool { return perms.AdminUsersManage }) {
|
|
return
|
|
}
|
|
app.renderAdminUsers(ctx, "")
|
|
}
|
|
|
|
func (app *App) handleAdminUsersPost(ctx *gin.Context) {
|
|
if !app.requireAdminFlag(ctx, func(perms metastore.EffectivePermissions) bool { return perms.AdminUsersManage }) {
|
|
return
|
|
}
|
|
|
|
if ctx.PostForm("action") == "toggle_disabled" {
|
|
userID := strings.TrimSpace(ctx.PostForm("user_id"))
|
|
user, ok, err := app.store.GetUser(userID)
|
|
if err != nil || !ok {
|
|
app.renderAdminUsers(ctx, "User not found.")
|
|
return
|
|
}
|
|
if current, ok := ctx.Get("adminUser"); ok {
|
|
if currentUser, ok := current.(metastore.User); ok && currentUser.ID == user.ID {
|
|
app.renderAdminUsers(ctx, "You cannot disable the user for the active session.")
|
|
return
|
|
}
|
|
}
|
|
user.Disabled = !user.Disabled
|
|
if err := app.store.UpdateUser(user); err != nil {
|
|
app.renderAdminUsers(ctx, err.Error())
|
|
return
|
|
}
|
|
ctx.Redirect(http.StatusSeeOther, "/admin/users")
|
|
return
|
|
}
|
|
|
|
username := ctx.PostForm("username")
|
|
email := ctx.PostForm("email")
|
|
password := ctx.PostForm("password")
|
|
tagIDs := ctx.PostFormArray("tag_ids")
|
|
if _, err := app.store.CreateUserWithPassword(username, email, password, tagIDs); err != nil {
|
|
app.renderAdminUsers(ctx, err.Error())
|
|
return
|
|
}
|
|
ctx.Redirect(http.StatusSeeOther, "/admin/users")
|
|
}
|
|
|
|
func (app *App) renderAdminUsers(ctx *gin.Context, errorMessage string) {
|
|
users, err := app.store.ListUsers()
|
|
if err != nil {
|
|
ctx.String(http.StatusInternalServerError, "Could not list users")
|
|
return
|
|
}
|
|
tags, err := app.store.ListTags()
|
|
if err != nil {
|
|
ctx.String(http.StatusInternalServerError, "Could not list tags")
|
|
return
|
|
}
|
|
tagNames := make(map[string]string, len(tags))
|
|
for _, tag := range tags {
|
|
tagNames[tag.ID] = tag.Name
|
|
}
|
|
sort.Slice(users, func(i int, j int) bool {
|
|
return strings.ToLower(users[i].Username) < strings.ToLower(users[j].Username)
|
|
})
|
|
|
|
currentID := ""
|
|
if current, ok := ctx.Get("adminUser"); ok {
|
|
if currentUser, ok := current.(metastore.User); ok {
|
|
currentID = currentUser.ID
|
|
}
|
|
}
|
|
|
|
rows := make([]adminUserRow, 0, len(users))
|
|
for _, user := range users {
|
|
names := make([]string, 0, len(user.TagIDs))
|
|
for _, tagID := range user.TagIDs {
|
|
if name := tagNames[tagID]; name != "" {
|
|
names = append(names, name)
|
|
}
|
|
}
|
|
rows = append(rows, adminUserRow{
|
|
ID: user.ID,
|
|
Username: user.Username,
|
|
Email: user.Email,
|
|
Tags: strings.Join(names, ", "),
|
|
CreatedAt: formatAdminTime(user.CreatedAt),
|
|
Disabled: user.Disabled,
|
|
IsCurrent: user.ID == currentID,
|
|
})
|
|
}
|
|
|
|
ctx.HTML(http.StatusOK, "admin_users.html", gin.H{
|
|
"AdminSection": "users",
|
|
"CurrentUser": app.currentAdminUsername(ctx),
|
|
"CSRFToken": app.currentCSRFToken(ctx),
|
|
"Users": rows,
|
|
"Tags": tags,
|
|
"Error": errorMessage,
|
|
})
|
|
}
|