mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 18:35:51 +02:00
refactor: user curd
This commit is contained in:
parent
80f01e61d3
commit
465eae9858
19 changed files with 1601 additions and 1881 deletions
|
@ -17,15 +17,6 @@ func InitAuthRouter(r *gin.RouterGroup) {
|
|||
r.GET("/passkeys/config", GetPasskeyConfigStatus)
|
||||
}
|
||||
|
||||
func InitManageUserRouter(r *gin.RouterGroup) {
|
||||
r.GET("users", GetUsers)
|
||||
r.GET("users/:id", GetUser)
|
||||
r.POST("users", AddUser)
|
||||
r.POST("users/:id", EditUser)
|
||||
r.DELETE("users/:id", DeleteUser)
|
||||
r.PATCH("users/:id", RecoverUser)
|
||||
}
|
||||
|
||||
func InitUserRouter(r *gin.RouterGroup) {
|
||||
r.GET("/2fa_status", Get2FAStatus)
|
||||
r.GET("/2fa_secure_session/status", SecureSessionStatus)
|
||||
|
|
153
api/user/user.go
153
api/user/user.go
|
@ -1,140 +1,53 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"github.com/0xJacky/Nginx-UI/api"
|
||||
"github.com/0xJacky/Nginx-UI/internal/user"
|
||||
"github.com/0xJacky/Nginx-UI/model"
|
||||
"github.com/0xJacky/Nginx-UI/query"
|
||||
"github.com/0xJacky/Nginx-UI/settings"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/uozi-tech/cosy"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func GetUsers(c *gin.Context) {
|
||||
cosy.Core[model.User](c).SetFussy("name").PagingList()
|
||||
}
|
||||
|
||||
func GetUser(c *gin.Context) {
|
||||
id := cast.ToUint64(c.Param("id"))
|
||||
|
||||
u := query.User
|
||||
|
||||
user, err := u.FirstByID(id)
|
||||
|
||||
if err != nil {
|
||||
api.ErrHandler(c, err)
|
||||
func encryptPassword(ctx *cosy.Ctx[model.User]) {
|
||||
if ctx.Payload["password"] == nil {
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, user)
|
||||
}
|
||||
|
||||
type UserJson struct {
|
||||
Name string `json:"name" binding:"required,max=255"`
|
||||
Password string `json:"password" binding:"max=255"`
|
||||
}
|
||||
|
||||
func AddUser(c *gin.Context) {
|
||||
var json UserJson
|
||||
ok := cosy.BindAndValid(c, &json)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
u := query.User
|
||||
|
||||
pwd, err := bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
api.ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
json.Password = string(pwd)
|
||||
|
||||
user := model.User{
|
||||
Name: json.Name,
|
||||
Password: json.Password,
|
||||
}
|
||||
|
||||
// duplicate name
|
||||
_, err = u.Where(u.Name.Eq(json.Name)).First()
|
||||
if !(err != nil && err.Error() == "record not found") {
|
||||
c.JSON(http.StatusConflict, gin.H{
|
||||
"message": "name already exists",
|
||||
})
|
||||
}
|
||||
|
||||
err = u.Create(&user)
|
||||
|
||||
if err != nil {
|
||||
api.ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, user)
|
||||
|
||||
}
|
||||
|
||||
func EditUser(c *gin.Context) {
|
||||
userId := cast.ToUint64(c.Param("id"))
|
||||
|
||||
if settings.NodeSettings.Demo && userId == 1 {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "Changing user password is forbidden in demo mode",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
var json UserJson
|
||||
ok := cosy.BindAndValid(c, &json)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
u := query.User
|
||||
user, err := u.FirstByID(userId)
|
||||
|
||||
if err != nil {
|
||||
api.ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
edit := &model.User{
|
||||
Name: json.Name,
|
||||
}
|
||||
|
||||
// encrypt password
|
||||
if json.Password != "" {
|
||||
var pwd []byte
|
||||
pwd, err = bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost)
|
||||
pwd := ctx.Payload["password"].(string)
|
||||
if pwd != "" {
|
||||
pwdBytes, err := bcrypt.GenerateFromPassword([]byte(pwd), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
api.ErrHandler(c, err)
|
||||
ctx.AbortWithError(err)
|
||||
return
|
||||
}
|
||||
edit.Password = string(pwd)
|
||||
ctx.Model.Password = string(pwdBytes)
|
||||
} else {
|
||||
delete(ctx.Payload, "password")
|
||||
}
|
||||
|
||||
_, err = u.Where(u.ID.Eq(userId)).Updates(&edit)
|
||||
|
||||
if err != nil {
|
||||
api.ErrHandler(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, user)
|
||||
}
|
||||
|
||||
func DeleteUser(c *gin.Context) {
|
||||
id := cast.ToInt(c.Param("id"))
|
||||
if cast.ToInt(id) == 1 {
|
||||
c.JSON(http.StatusNotAcceptable, gin.H{
|
||||
"message": "Prohibit deleting the default user",
|
||||
func InitManageUserRouter(g *gin.RouterGroup) {
|
||||
c := cosy.Api[model.User]("users")
|
||||
|
||||
c.CreateHook(func(c *cosy.Ctx[model.User]) {
|
||||
c.BeforeDecodeHook(encryptPassword)
|
||||
})
|
||||
|
||||
c.ModifyHook(func(c *cosy.Ctx[model.User]) {
|
||||
c.BeforeDecodeHook(func(ctx *cosy.Ctx[model.User]) {
|
||||
if ctx.ID == 1 {
|
||||
ctx.AbortWithError(user.ErrChangeInitUserPwdInDemo)
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
cosy.Core[model.User](c).Destroy()
|
||||
}
|
||||
c.BeforeDecodeHook(encryptPassword)
|
||||
})
|
||||
|
||||
func RecoverUser(c *gin.Context) {
|
||||
cosy.Core[model.User](c).Recover()
|
||||
c.DestroyHook(func(c *cosy.Ctx[model.User]) {
|
||||
c.BeforeExecuteHook(func(ctx *cosy.Ctx[model.User]) {
|
||||
if ctx.ID == 1 {
|
||||
ctx.AbortWithError(user.ErrCannotRemoveInitUser)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
c.InitRouter(g)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue