diff --git a/api/user.go b/api/user.go index e1d393a..6ce764d 100644 --- a/api/user.go +++ b/api/user.go @@ -445,35 +445,32 @@ func (a *UserAPI) ChangePassword(ctx *gin.Context) { // $ref: "#/definitions/Error" func (a *UserAPI) UpdateUserByID(ctx *gin.Context) { withID(ctx, "id", func(id uint) { - var user *model.UpdateUserExternal - if err := ctx.Bind(&user); err == nil { - oldUser, err := a.DB.GetUserByID(id) + var updatedUser *model.UpdateUserExternal + if err := ctx.Bind(&updatedUser); err == nil { + dbUser, err := a.DB.GetUserByID(id) if success := successOrAbort(ctx, 500, err); !success { return } - if oldUser != nil { + if dbUser != nil { adminCount, err := a.DB.CountUser(&model.User{Admin: true}) if success := successOrAbort(ctx, 500, err); !success { return } - if !user.Admin && oldUser.Admin && adminCount == 1 { + if !updatedUser.Admin && dbUser.Admin && adminCount == 1 { ctx.AbortWithError(400, errors.New("cannot delete last admin")) return } - internal := &model.User{ - ID: oldUser.ID, - Name: user.Name, - Admin: user.Admin, - Pass: oldUser.Pass, - CreatedAt: oldUser.CreatedAt, + + dbUser.Name = updatedUser.Name + dbUser.Admin = updatedUser.Admin + + if updatedUser.Pass != "" { + dbUser.Pass = password.CreatePassword(updatedUser.Pass, a.PasswordStrength) } - 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(dbUser)); !success { return } - ctx.JSON(200, toExternalUser(internal)) + ctx.JSON(200, toExternalUser(dbUser)) } else { ctx.AbortWithError(404, errors.New("user does not exist")) } diff --git a/api/user_test.go b/api/user_test.go index fe44c8c..6380525 100644 --- a/api/user_test.go +++ b/api/user_test.go @@ -392,6 +392,26 @@ func (s *UserSuite) Test_UpdateUserByID_UpdatePassword() { assert.True(s.T(), password.ComparePassword(user.Pass, []byte("new"))) } +func (s *UserSuite) Test_UpdateUserByID_PreservesOIDCID() { + oidcID := "https://issuer.example.com#subject" + s.db.CreateUser(&model.User{ID: 2, Name: "nico", OIDCID: &oidcID}) + + s.ctx.Params = gin.Params{{Key: "id", Value: "2"}} + + s.ctx.Request = httptest.NewRequest("POST", "/user/2", strings.NewReader(`{"name": "tom", "pass": "", "admin": true}`)) + s.ctx.Request.Header.Set("Content-Type", "application/json") + + s.a.UpdateUserByID(s.ctx) + + assert.Equal(s.T(), 200, s.recorder.Code) + user, err := s.db.GetUserByID(2) + assert.NoError(s.T(), err) + assert.NotNil(s.T(), user) + if assert.NotNil(s.T(), user.OIDCID) { + assert.Equal(s.T(), oidcID, *user.OIDCID) + } +} + func (s *UserSuite) Test_UpdatePassword() { s.db.CreateUser(&model.User{ID: 1, Name: "jmattheis", Pass: password.CreatePassword("old", 5)})