Files
am-downloader/admin_users.go
T

138 lines
3.3 KiB
Go

package main
import (
"strconv"
"strings"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
func defaultPermissions(role string) []string {
if role == RolePrivileged {
return []string{PermDownload, PermRedeem, PermWebDAV, PermWebDAVConfig}
}
if role == RoleUser {
return []string{PermDownload, PermRedeem}
}
return nil
}
func (a *App) adminListUsers(c *gin.Context) {
var users []User
if err := a.db.Order("id asc").Find(&users).Error; err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
for i := range users {
users[i].PasswordHash = ""
}
c.JSON(200, gin.H{"data": users})
}
func (a *App) adminCreateUser(c *gin.Context) {
var in struct {
Username string `json:"username"`
Password string `json:"password"`
Role string `json:"role"`
Credits int64 `json:"credits"`
}
if c.BindJSON(&in) != nil || strings.TrimSpace(in.Username) == "" || len(in.Password) < 8 {
c.JSON(400, gin.H{"error": "username and password(8+) required"})
return
}
if in.Role == "" {
in.Role = RoleUser
}
if in.Role != RoleUser && in.Role != RolePrivileged && in.Role != RoleAdmin {
c.JSON(400, gin.H{"error": "invalid role"})
return
}
hash, err := hashPassword(in.Password)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
var u User
err = a.db.Transaction(func(tx *gorm.DB) error {
u = User{Username: strings.TrimSpace(in.Username), PasswordHash: hash, Role: in.Role, Status: UserActive}
if err := tx.Create(&u).Error; err != nil {
return err
}
if err := tx.Create(&CreditAccount{UserID: u.ID, Balance: in.Credits}).Error; err != nil {
return err
}
for _, p := range defaultPermissions(in.Role) {
if err := tx.Create(&UserPermission{UserID: u.ID, Permission: p, Enabled: true}).Error; err != nil {
return err
}
}
if in.Credits > 0 {
if err := tx.Create(&CreditTransaction{UserID: u.ID, Type: "grant", Amount: in.Credits, BalanceAfter: in.Credits, ReferenceType: "admin", ReferenceID: strconv.FormatUint(uint64(c.MustGet("user").(*User).ID), 10), Reason: "initial credits"}).Error; err != nil {
return err
}
}
return nil
})
if err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
u.PasswordHash = ""
c.JSON(201, u)
}
func (a *App) adminUpdateUser(c *gin.Context) {
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
if err != nil {
c.Status(400)
return
}
var in struct {
Password *string `json:"password"`
Role *string `json:"role"`
Status *string `json:"status"`
}
if c.BindJSON(&in) != nil {
c.Status(400)
return
}
var u User
if a.db.First(&u, id).Error != nil {
c.Status(404)
return
}
if in.Password != nil {
if len(*in.Password) < 8 {
c.JSON(400, gin.H{"error": "password must be 8+"})
return
}
h, e := hashPassword(*in.Password)
if e != nil {
c.JSON(500, gin.H{"error": e.Error()})
return
}
u.PasswordHash = h
}
if in.Role != nil {
if *in.Role != RoleUser && *in.Role != RolePrivileged && *in.Role != RoleAdmin {
c.JSON(400, gin.H{"error": "invalid role"})
return
}
u.Role = *in.Role
}
if in.Status != nil {
if *in.Status != UserActive && *in.Status != UserDisabled {
c.JSON(400, gin.H{"error": "invalid status"})
return
}
u.Status = *in.Status
}
if err := a.db.Save(&u).Error; err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
u.PasswordHash = ""
c.JSON(200, u)
}