feat: implement multi-user credits redeem and storage isolation
This commit is contained in:
+137
@@ -0,0 +1,137 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user