Skip to content

Commit

Permalink
fix: update the password reset feature for the administrator
Browse files Browse the repository at this point in the history
  • Loading branch information
saltbo committed Jul 8, 2021
1 parent 49f00a8 commit 9d01dce
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 90 deletions.
201 changes: 112 additions & 89 deletions internal/app/api/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/saltbo/gopkg/ginutil"
_ "github.com/saltbo/gopkg/httputil"
"github.com/saltbo/gopkg/strutil"

"github.com/saltbo/zpan/internal/app/dao"
"github.com/saltbo/zpan/internal/app/model"
Expand All @@ -30,18 +31,96 @@ func (rs *UserResource) Register(router *gin.RouterGroup) {
router.POST("/users", rs.create) // 账户注册
router.PATCH("/users/:email", rs.patch) // 账户激活、密码重置

router.GET("/users", rs.findAll) // 查询用户列表,需管理员权限
router.GET("/users/:username", rs.find) // 查询某一个用户的公开信息
router.DELETE("/users/:username", rs.remove) // 删除某一个用户
router.PUT("/users/:username/storage", rs.updateStorage) // 修改某一个用户的存储空间
router.PUT("/users/:username/password", rs.updatePassword) // 修改某一个用户的用户密码
router.PUT("/users/:username/status", rs.updateStatus) // 修改某一个用户的状态
router.GET("/users", rs.findAll) // 查询用户列表,需管理员权限
router.GET("/users/:username", rs.find) // 查询某一个用户的公开信息
router.DELETE("/users/:username", rs.remove) // 删除某一个用户
router.PUT("/users/:username/storage", rs.updateStorage) // 修改某一个用户的存储空间
router.PUT("/users/:username/password", rs.resetPassword) // 修改某一个用户的用户密码
router.PUT("/users/:username/status", rs.updateStatus) // 修改某一个用户的状态

router.GET("/user", rs.userMe) // 获取已登录用户的所有信息
router.PUT("/user/profile", rs.updateProfile) // 更新已登录用户个人信息
router.PUT("/user/password", rs.updatePassword) // 修改已登录用户密码
}

// create godoc
// @Tags v1/Users
// @Summary 用户注册
// @Description 注册一个用户
// @Accept json
// @Produce json
// @Param body body bind.BodyUser true "参数"
// @Success 200 {object} httputil.JSONResponse{data=model.User}
// @Failure 400 {object} httputil.JSONResponse
// @Failure 500 {object} httputil.JSONResponse
// @Router /v1/users [post]
func (rs *UserResource) create(c *gin.Context) {
p := new(bind.BodyUserCreation)
if err := c.ShouldBindJSON(p); err != nil {
ginutil.JSONBadRequest(c, err)
return
}

if !authed.IsAdmin(c) && rs.sUser.InviteRequired() && p.Ticket == "" {
ginutil.JSONBadRequest(c, fmt.Errorf("ticket required"))
return
}

opt := model.NewUserCreateOption()
opt.Roles = model.RoleMember
opt.Ticket = p.Ticket
if authed.IsAdmin(c) {
opt.Roles = p.Roles
opt.StorageMax = p.StorageMax
}

opt.Origin = ginutil.GetOrigin(c)
if _, err := rs.sUser.Signup(p.Email, p.Password, opt); err != nil {
ginutil.JSONBadRequest(c, err)
return
}

ginutil.JSON(c)
}

// patch godoc
// @Tags v1/Users
// @Summary 更新一项用户信息
// @Description 用于账户激活和密码重置
// @Accept json
// @Produce json
// @Param email path string true "邮箱"
// @Param body body bind.BodyUserPatch true "参数"
// @Success 200 {object} httputil.JSONResponse
// @Failure 400 {object} httputil.JSONResponse
// @Failure 500 {object} httputil.JSONResponse
// @Router /v1/users/{email} [patch]
func (rs *UserResource) patch(c *gin.Context) {
p := new(bind.BodyUserPatch)
if err := c.ShouldBindJSON(p); err != nil {
ginutil.JSONBadRequest(c, err)
return
}

// account activate
if p.Activated {
if err := rs.sUser.Active(p.Token); err != nil {
ginutil.JSONServerError(c, err)
return
}
}

// password reset
if p.Password != "" {
if err := rs.sUser.PasswordReset(p.Token, p.Password); err != nil {
ginutil.JSONServerError(c, err)
return
}
}

ginutil.JSON(c)
}

// findAll godoc
// @Tags v1/Users
// @Summary 用户列表
Expand Down Expand Up @@ -96,33 +175,6 @@ func (rs *UserResource) find(c *gin.Context) {
ginutil.JSONData(c, user.Profile)
}

// remove godoc
// @Tags v1/Users
// @Summary 删除某一个用户
// @Description 删除某一个用户
// @Accept json
// @Produce json
// @Param username path string true "用户名"
// @Success 200 {object} httputil.JSONResponse
// @Failure 400 {object} httputil.JSONResponse
// @Failure 500 {object} httputil.JSONResponse
// @Router /v1/users/{username} [delete]
func (rs *UserResource) remove(c *gin.Context) {
user, err := rs.dUser.FindByUsername(c.Param("username"))
if err != nil {
ginutil.JSONBadRequest(c, err)
return
}

if err := rs.dUser.Delete(user); err != nil {
ginutil.JSONServerError(c, err)
return
}

ginutil.JSON(c)
}


// updateStorage godoc
// @Tags v1/Users
// @Summary 修改某一个用户的存储空间
Expand Down Expand Up @@ -189,79 +241,61 @@ func (rs *UserResource) updateStatus(c *gin.Context) {
ginutil.JSON(c)
}

// create godoc
// resetPassword godoc
// @Tags v1/Users
// @Summary 用户注册
// @Description 注册一个用户
// @Summary 重置某一个用户的密码
// @Description 重置某一个用户的密码
// @Accept json
// @Produce json
// @Param body body bind.BodyUser true "参数"
// @Success 200 {object} httputil.JSONResponse{data=model.User}
// @Param username path string true "用户名"
// @Param body body bind.BodyUserStatus true "参数"
// @Success 200 {object} httputil.JSONResponse
// @Failure 400 {object} httputil.JSONResponse
// @Failure 500 {object} httputil.JSONResponse
// @Router /v1/users [post]
func (rs *UserResource) create(c *gin.Context) {
p := new(bind.BodyUserCreation)
// @Router /v1/users/{username}/password [put]
func (rs *UserResource) resetPassword(c *gin.Context) {
p := new(bind.BodyUserPasswordReset)
if err := c.ShouldBindJSON(p); err != nil {
ginutil.JSONBadRequest(c, err)
return
}

if !authed.IsAdmin(c) && rs.sUser.InviteRequired() && p.Ticket == "" {
ginutil.JSONBadRequest(c, fmt.Errorf("ticket required"))
user, err := rs.dUser.FindByUsername(c.Param("username"))
if err != nil {
ginutil.JSONBadRequest(c, err)
return
}

opt := model.NewUserCreateOption()
opt.Roles = model.RoleMember
opt.Ticket = p.Ticket
if authed.IsAdmin(c) {
opt.Roles = p.Roles
opt.StorageMax = p.StorageMax
}

opt.Origin = ginutil.GetOrigin(c)
if _, err := rs.sUser.Signup(p.Email, p.Password, opt); err != nil {
ginutil.JSONBadRequest(c, err)
user.Password = strutil.Md5Hex(p.Password)
if err := rs.dUser.Update(user); err != nil {
ginutil.JSONServerError(c, err)
return
}

ginutil.JSON(c)
}

// patch godoc
// remove godoc
// @Tags v1/Users
// @Summary 更新一项用户信息
// @Description 用于账户激活和密码重置
// @Summary 删除某一个用户
// @Description 删除某一个用户
// @Accept json
// @Produce json
// @Param email path string true "邮箱"
// @Param body body bind.BodyUserPatch true "参数"
// @Param username path string true "用户名"
// @Success 200 {object} httputil.JSONResponse
// @Failure 400 {object} httputil.JSONResponse
// @Failure 500 {object} httputil.JSONResponse
// @Router /v1/users/{email} [patch]
func (rs *UserResource) patch(c *gin.Context) {
p := new(bind.BodyUserPatch)
if err := c.ShouldBindJSON(p); err != nil {
// @Router /v1/users/{username} [delete]
func (rs *UserResource) remove(c *gin.Context) {
user, err := rs.dUser.FindByUsername(c.Param("username"))
if err != nil {
ginutil.JSONBadRequest(c, err)
return
}

// account activate
if p.Activated {
if err := rs.sUser.Active(p.Token); err != nil {
ginutil.JSONServerError(c, err)
return
}
}

// password reset
if p.Password != "" {
if err := rs.sUser.PasswordReset(p.Token, p.Password); err != nil {
ginutil.JSONServerError(c, err)
return
}
if err := rs.dUser.Delete(user); err != nil {
ginutil.JSONServerError(c, err)
return
}

ginutil.JSON(c)
Expand Down Expand Up @@ -297,7 +331,6 @@ func (rs *UserResource) userMe(c *gin.Context) {
// @Success 200 {object} httputil.JSONResponse
// @Failure 400 {object} httputil.JSONResponse
// @Failure 500 {object} httputil.JSONResponse
// @Router /v1/users/{username}/password [put]
// @Router /v1/user/password [put]
func (rs *UserResource) updatePassword(c *gin.Context) {
p := new(bind.BodyUserPassword)
Expand All @@ -307,16 +340,6 @@ func (rs *UserResource) updatePassword(c *gin.Context) {
}

uid := authed.UidGet(c)
if username := c.Param("username"); username != "" {
user, err := rs.dUser.FindByUsername(username)
if err != nil {
ginutil.JSONBadRequest(c, err)
return
}

uid = user.Id
}

if err := rs.sUser.PasswordUpdate(uid, p.OldPassword, p.NewPassword); err != nil {
ginutil.JSONServerError(c, err)
return
Expand Down Expand Up @@ -363,4 +386,4 @@ func (rs *UserResource) updateProfile(c *gin.Context) {
}

ginutil.JSON(c)
}
}
6 changes: 5 additions & 1 deletion internal/pkg/bind/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,9 @@ type BodyUserStorage struct {
}

type BodyUserStatus struct {
Status uint8 `json:"status"`
Status uint8 `json:"status" binding:"required"`
}

type BodyUserPasswordReset struct {
Password string `json:"password" binding:"required"`
}

0 comments on commit 9d01dce

Please sign in to comment.