diff --git a/routes/user/user_endpoints.go b/routes/user/user_endpoints.go index 5998c08..9d869d4 100644 --- a/routes/user/user_endpoints.go +++ b/routes/user/user_endpoints.go @@ -181,11 +181,11 @@ func updateUser(c *gin.Context) { // Create the updatedUser from oldUser considering callerRole (in // case that the request updates the role of the old user) - updatedUser, err := req.updatedUser(callerRole, oldUser) + updatedUser, err := req.updatedUser(callerID, callerRole, oldUser) if err != nil { if strings.Contains(err.Error(), "Admin") || strings.Contains(err.Error(), "pw not changed") { helper.ForbiddenError(c, err.Error()) - } else if strings.Contains(err.Error(), "Username") || strings.Contains(err.Error(), "old password") { + } else if strings.Contains(err.Error(), "Username") || strings.Contains(err.Error(), "old or admin password") { helper.BadRequestError(c, err.Error()) } else { // password encryption failed helper.InternalServerError(c, err.Error()) diff --git a/routes/user/user_test.go b/routes/user/user_test.go index 6c4689d..63e8dcd 100644 --- a/routes/user/user_test.go +++ b/routes/user/user_test.go @@ -631,7 +631,7 @@ func TestModifyAddedUserAsAdmin(t *testing.T) { err = helper.CompareResponse(resp, helper.KeyModels{"user": newUser}) assert.NoError(t, err) - // modify newUser's password, should work without old password + // modify newUser's password, should not work without admin password modRequest = UserRequest{ Password: "4_g00d_pw!", } @@ -639,6 +639,17 @@ func TestModifyAddedUserAsAdmin(t *testing.T) { fmt.Sprintf("/api/users/%v", newUserID), "PUT", helper.KeyModels{"user": modRequest}) assert.NoError(t, err) + assert.Equalf(t, 400, code, "Response body: \n%v\n", resp) + + // modify newUser's password, requires admin password + modRequest = UserRequest{ + Password: "4_g00d_pw!", + OldPassword: database.StrPassword0, + } + code, resp, err = helper.TestEndpoint(router, token, + fmt.Sprintf("/api/users/%v", newUserID), "PUT", + helper.KeyModels{"user": modRequest}) + assert.NoError(t, err) assert.Equalf(t, 200, code, "Response body: \n%v\n", resp) // try to login as newUser with the modified username and password diff --git a/routes/user/user_validators.go b/routes/user/user_validators.go index 5b81f95..94aa99f 100644 --- a/routes/user/user_validators.go +++ b/routes/user/user_validators.go @@ -52,8 +52,7 @@ func (r *updateUserRequest) validate() error { return nil } -func (r *updateUserRequest) updatedUser(role interface{}, - oldUser User) (User, error) { +func (r *updateUserRequest) updatedUser(callerID interface{}, role interface{}, oldUser User) (User, error) { // Use the old User as a basis for the updated User `u` u := oldUser @@ -88,12 +87,25 @@ func (r *updateUserRequest) updatedUser(role interface{}, // If there is a new password then hash it and update it if r.Password != "" { - if role != "Admin" { // if requesting user is NOT admin, old password needs to be validated - if r.OldPassword == "" { - return u, fmt.Errorf("old password is missing in request") + if r.OldPassword == "" { // admin or old password has to be present for pw change + return u, fmt.Errorf("old or admin password is missing in request") + } + + if role == "Admin" { // admin has to enter admin password + var adminUser User + err := adminUser.ByID(callerID.(uint)) + if err != nil { + return u, err } + err = adminUser.validatePassword(r.OldPassword) + if err != nil { + return u, fmt.Errorf("admin password not correct, pw not changed") + } + + } else { //normal or guest user has to enter old password + err := oldUser.validatePassword(r.OldPassword) if err != nil { return u, fmt.Errorf("previous password not correct, pw not changed")