Fix required mismatch in update & create user

This shouldn't break the api.
This commit is contained in:
Jannis Mattheis 2022-09-10 16:08:24 +02:00
parent ba0cee1da2
commit fcd9b88bb7
3 changed files with 128 additions and 59 deletions

View File

@ -147,7 +147,7 @@ func (a *UserAPI) GetCurrentUser(ctx *gin.Context) {
// description: the user to add // description: the user to add
// required: true // required: true
// schema: // schema:
// $ref: "#/definitions/UserWithPass" // $ref: "#/definitions/CreateUserExternal"
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -166,9 +166,13 @@ func (a *UserAPI) GetCurrentUser(ctx *gin.Context) {
// schema: // schema:
// $ref: "#/definitions/Error" // $ref: "#/definitions/Error"
func (a *UserAPI) CreateUser(ctx *gin.Context) { func (a *UserAPI) CreateUser(ctx *gin.Context) {
user := model.UserExternalWithPass{} user := model.CreateUserExternal{}
if err := ctx.Bind(&user); err == nil { if err := ctx.Bind(&user); err == nil {
internal := a.toInternalUser(&user, []byte{}) internal := &model.User{
Name: user.Name,
Admin: user.Admin,
Pass: password.CreatePassword(user.Pass, a.PasswordStrength),
}
existingUser, err := a.DB.GetUserByName(internal.Name) existingUser, err := a.DB.GetUserByName(internal.Name)
if success := successOrAbort(ctx, 500, err); !success { if success := successOrAbort(ctx, 500, err); !success {
return return
@ -389,7 +393,7 @@ func (a *UserAPI) ChangePassword(ctx *gin.Context) {
// description: the updated user // description: the updated user
// required: true // required: true
// schema: // schema:
// $ref: "#/definitions/UserWithPass" // $ref: "#/definitions/UpdateUserExternal"
// responses: // responses:
// 200: // 200:
// description: Ok // description: Ok
@ -413,7 +417,7 @@ func (a *UserAPI) ChangePassword(ctx *gin.Context) {
// $ref: "#/definitions/Error" // $ref: "#/definitions/Error"
func (a *UserAPI) UpdateUserByID(ctx *gin.Context) { func (a *UserAPI) UpdateUserByID(ctx *gin.Context) {
withID(ctx, "id", func(id uint) { withID(ctx, "id", func(id uint) {
var user *model.UserExternalWithPass var user *model.UpdateUserExternal
if err := ctx.Bind(&user); err == nil { if err := ctx.Bind(&user); err == nil {
oldUser, err := a.DB.GetUserByID(id) oldUser, err := a.DB.GetUserByID(id)
if success := successOrAbort(ctx, 500, err); !success { if success := successOrAbort(ctx, 500, err); !success {
@ -428,8 +432,15 @@ func (a *UserAPI) UpdateUserByID(ctx *gin.Context) {
ctx.AbortWithError(400, errors.New("cannot delete last admin")) ctx.AbortWithError(400, errors.New("cannot delete last admin"))
return return
} }
internal := a.toInternalUser(user, oldUser.Pass) internal := &model.User{
internal.ID = id ID: oldUser.ID,
Name: user.Name,
Admin: user.Admin,
Pass: oldUser.Pass,
}
if user.Pass != "" {
internal.Pass = password.CreatePassword(user.Pass, a.PasswordStrength)
}
if success := successOrAbort(ctx, 500, a.DB.UpdateUser(internal)); !success { if success := successOrAbort(ctx, 500, a.DB.UpdateUser(internal)); !success {
return return
} }
@ -441,13 +452,13 @@ func (a *UserAPI) UpdateUserByID(ctx *gin.Context) {
}) })
} }
func (a *UserAPI) toInternalUser(response *model.UserExternalWithPass, pw []byte) *model.User { func (a *UserAPI) toInternalUser(response *model.UserExternal, newPass string, pw []byte) *model.User {
user := &model.User{ user := &model.User{
Name: response.Name, Name: response.Name,
Admin: response.Admin, Admin: response.Admin,
} }
if response.Pass != "" { if newPass != "" {
user.Pass = password.CreatePassword(response.Pass, a.PasswordStrength) user.Pass = password.CreatePassword(newPass, a.PasswordStrength)
} else { } else {
user.Pass = pw user.Pass = pw
} }

View File

@ -1634,7 +1634,7 @@
"in": "body", "in": "body",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/UserWithPass" "$ref": "#/definitions/CreateUserExternal"
} }
} }
], ],
@ -1771,7 +1771,7 @@
"in": "body", "in": "body",
"required": true, "required": true,
"schema": { "schema": {
"$ref": "#/definitions/UserWithPass" "$ref": "#/definitions/UpdateUserExternal"
} }
} }
], ],
@ -2005,6 +2005,37 @@
}, },
"x-go-package": "github.com/gotify/server/v2/model" "x-go-package": "github.com/gotify/server/v2/model"
}, },
"CreateUserExternal": {
"description": "Used for user creation.",
"type": "object",
"title": "CreateUserExternal Model",
"required": [
"name",
"admin",
"pass"
],
"properties": {
"admin": {
"description": "If the user is an administrator.",
"type": "boolean",
"x-go-name": "Admin",
"example": true
},
"name": {
"description": "The user name. For login.",
"type": "string",
"x-go-name": "Name",
"example": "unicorn"
},
"pass": {
"description": "The user password. For login.",
"type": "string",
"x-go-name": "Pass",
"example": "nrocinu"
}
},
"x-go-package": "github.com/gotify/server/v2/model"
},
"Error": { "Error": {
"description": "The Error contains error relevant information.", "description": "The Error contains error relevant information.",
"type": "object", "type": "object",
@ -2290,13 +2321,44 @@
"x-go-name": "PluginConfExternal", "x-go-name": "PluginConfExternal",
"x-go-package": "github.com/gotify/server/v2/model" "x-go-package": "github.com/gotify/server/v2/model"
}, },
"UpdateUserExternal": {
"description": "Used for updating a user.",
"type": "object",
"title": "UpdateUserExternal Model",
"required": [
"name",
"admin"
],
"properties": {
"admin": {
"description": "If the user is an administrator.",
"type": "boolean",
"x-go-name": "Admin",
"example": true
},
"name": {
"description": "The user name. For login.",
"type": "string",
"x-go-name": "Name",
"example": "unicorn"
},
"pass": {
"description": "The user password. For login. Empty for using old password",
"type": "string",
"x-go-name": "Pass",
"example": "nrocinu"
}
},
"x-go-package": "github.com/gotify/server/v2/model"
},
"User": { "User": {
"description": "The User holds information about permission and other stuff.", "description": "The User holds information about permission and other stuff.",
"type": "object", "type": "object",
"title": "UserExternal Model", "title": "UserExternal Model",
"required": [ "required": [
"id", "id",
"name" "name",
"admin"
], ],
"properties": { "properties": {
"admin": { "admin": {
@ -2341,46 +2403,6 @@
"x-go-name": "UserExternalPass", "x-go-name": "UserExternalPass",
"x-go-package": "github.com/gotify/server/v2/model" "x-go-package": "github.com/gotify/server/v2/model"
}, },
"UserWithPass": {
"description": "The UserWithPass holds information about the credentials and other stuff.",
"type": "object",
"title": "UserExternalWithPass Model",
"required": [
"id",
"name",
"pass"
],
"properties": {
"admin": {
"description": "If the user is an administrator.",
"type": "boolean",
"x-go-name": "Admin",
"example": true
},
"id": {
"description": "The user id.",
"type": "integer",
"format": "int64",
"x-go-name": "ID",
"readOnly": true,
"example": 25
},
"name": {
"description": "The user name. For login.",
"type": "string",
"x-go-name": "Name",
"example": "unicorn"
},
"pass": {
"description": "The user password. For login.",
"type": "string",
"x-go-name": "Pass",
"example": "nrocinu"
}
},
"x-go-name": "UserExternalWithPass",
"x-go-package": "github.com/gotify/server/v2/model"
},
"VersionInfo": { "VersionInfo": {
"description": "VersionInfo Model", "description": "VersionInfo Model",
"type": "object", "type": "object",

View File

@ -30,18 +30,54 @@ type UserExternal struct {
Name string `binding:"required" json:"name" query:"name" form:"name"` Name string `binding:"required" json:"name" query:"name" form:"name"`
// If the user is an administrator. // If the user is an administrator.
// //
// required: true
// example: true // example: true
Admin bool `json:"admin" form:"admin" query:"admin"` Admin bool `json:"admin" form:"admin" query:"admin"`
} }
// UserExternalWithPass Model // CreateUserExternal Model
// //
// The UserWithPass holds information about the credentials and other stuff. // Used for user creation.
// //
// swagger:model UserWithPass // swagger:model CreateUserExternal
type UserExternalWithPass struct { type CreateUserExternal struct {
UserExternal // The user name. For login.
UserExternalPass //
// required: true
// example: unicorn
Name string `binding:"required" json:"name" query:"name" form:"name"`
// If the user is an administrator.
//
// required: true
// example: true
Admin bool `json:"admin" form:"admin" query:"admin"`
// The user password. For login.
//
// required: true
// example: nrocinu
Pass string `json:"pass,omitempty" form:"pass" query:"pass" binding:"required"`
}
// UpdateUserExternal Model
//
// Used for updating a user.
//
// swagger:model UpdateUserExternal
type UpdateUserExternal struct {
// The user name. For login.
//
// required: true
// example: unicorn
Name string `binding:"required" json:"name" query:"name" form:"name"`
// If the user is an administrator.
//
// required: true
// example: true
Admin bool `json:"admin" form:"admin" query:"admin"`
// The user password. For login. Empty for using old password
//
// example: nrocinu
Pass string `json:"pass,omitempty" form:"pass" query:"pass"`
} }
// UserExternalPass Model // UserExternalPass Model