diff --git a/internal/db/user.go b/internal/db/user.go index b19876190a1..313c3b0c313 100644 --- a/internal/db/user.go +++ b/internal/db/user.go @@ -86,6 +86,9 @@ func DeleteUserById(id uint) error { if err != nil { return err } + if old.IsAdmin() || old.IsGuest() { + return errors.WithStack(errs.DeleteAdminOrGuest) + } userCache.Del(old.Username) return errors.WithStack(db.Delete(&model.User{}, id).Error) } diff --git a/internal/errs/user.go b/internal/errs/user.go index 5c577a76053..9e2d5b26cd4 100644 --- a/internal/errs/user.go +++ b/internal/errs/user.go @@ -3,7 +3,8 @@ package errs import "errors" var ( - EmptyUsername = errors.New("username is empty") - EmptyPassword = errors.New("password is empty") - WrongPassword = errors.New("password is incorrect") + EmptyUsername = errors.New("username is empty") + EmptyPassword = errors.New("password is empty") + WrongPassword = errors.New("password is incorrect") + DeleteAdminOrGuest = errors.New("cannot delete admin or guest") ) diff --git a/internal/model/user.go b/internal/model/user.go index 94df51619a8..4086b57b283 100644 --- a/internal/model/user.go +++ b/internal/model/user.go @@ -12,13 +12,13 @@ const ( ) type User struct { - ID uint `json:"id" gorm:"primaryKey"` // unique key - Username string `json:"username" gorm:"unique"` // username - Password string `json:"password"` // password - BasePath string `json:"base_path"` // base path - ReadOnly bool `json:"read_only"` // read only - Webdav bool `json:"webdav"` // allow webdav - Role int `json:"role"` // user's role + ID uint `json:"id" gorm:"primaryKey"` // unique key + Username string `json:"username" gorm:"unique" binding:"required"` // username + Password string `json:"password"` // password + BasePath string `json:"base_path"` // base path + ReadOnly bool `json:"read_only"` // read only + Webdav bool `json:"webdav"` // allow webdav + Role int `json:"role"` // user's role } func (u User) IsGuest() bool { diff --git a/server/controllers/user.go b/server/controllers/user.go new file mode 100644 index 00000000000..18150d07e14 --- /dev/null +++ b/server/controllers/user.go @@ -0,0 +1,81 @@ +package controllers + +import ( + "github.com/alist-org/alist/v3/internal/db" + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/server/common" + "github.com/gin-gonic/gin" + log "github.com/sirupsen/logrus" + "strconv" +) + +func ListUsers(c *gin.Context) { + var req common.PageReq + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400, true) + return + } + log.Debugf("%+v", req) + users, total, err := db.GetUsers(req.PageIndex, req.PageSize) + if err != nil { + common.ErrorResp(c, err, 500) + return + } + common.SuccessResp(c, common.PageResp{ + Content: users, + Total: total, + }) +} + +func CreateUser(c *gin.Context) { + var req model.User + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400, true) + return + } + if req.IsAdmin() || req.IsGuest() { + common.ErrorStrResp(c, "admin or guest user can not be created", 400, true) + return + } + if err := db.CreateUser(&req); err != nil { + common.ErrorResp(c, err, 500) + } else { + common.SuccessResp(c) + } +} + +func UpdateUser(c *gin.Context) { + var req model.User + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400, true) + return + } + user, err := db.GetUserById(req.ID) + if err != nil { + common.ErrorResp(c, err, 500) + return + } + if user.Role != req.Role { + common.ErrorStrResp(c, "role can not be changed", 400, true) + return + } + if err := db.UpdateUser(&req); err != nil { + common.ErrorResp(c, err, 500) + } else { + common.SuccessResp(c) + } +} + +func DeleteUser(c *gin.Context) { + idStr := c.Query("id") + id, err := strconv.Atoi(idStr) + if err != nil { + common.ErrorResp(c, err, 400, true) + return + } + if err := db.DeleteUserById(uint(id)); err != nil { + common.ErrorResp(c, err, 500) + return + } + common.SuccessResp(c) +} diff --git a/server/router.go b/server/router.go index 17841be9326..db1694633a2 100644 --- a/server/router.go +++ b/server/router.go @@ -24,6 +24,12 @@ func Init(r *gin.Engine) { meta.POST("/create", controllers.CreateMeta) meta.POST("/update", controllers.UpdateMeta) meta.POST("/delete", controllers.DeleteMeta) + + user := admin.Group("/user") + user.GET("/list", controllers.ListUsers) + user.POST("/create", controllers.CreateUser) + user.POST("/update", controllers.UpdateUser) + user.POST("/delete", controllers.DeleteUser) } func Cors(r *gin.Engine) {