Add functionality to update password with password hash (#15343)
* Add functionality to update password with password hash This can be used to update a user's password with a direct password hash instead of providing the password in plaintext. * Use test helper for local mode
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e83462637e
Коммит
90ef61f74c
33
api4/user.go
33
api4/user.go
@@ -1492,18 +1492,31 @@ func updatePassword(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
var err *model.AppError
|
||||
if c.Params.UserId == c.App.Session().UserId {
|
||||
currentPassword := props["current_password"]
|
||||
if len(currentPassword) <= 0 {
|
||||
c.SetInvalidParam("current_password")
|
||||
return
|
||||
}
|
||||
|
||||
err = c.App.UpdatePasswordAsUser(c.Params.UserId, currentPassword, newPassword)
|
||||
} else if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
|
||||
err = c.App.UpdatePasswordByUserIdSendEmail(c.Params.UserId, newPassword, c.App.T("api.user.reset_password.method"))
|
||||
// There are two main update flows depending on whether the provided password
|
||||
// is already hashed or not.
|
||||
if props["already_hashed"] == "true" {
|
||||
if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
|
||||
err = c.App.UpdateHashedPasswordByUserId(c.Params.UserId, newPassword)
|
||||
} else if c.Params.UserId == c.App.Session().UserId {
|
||||
err = model.NewAppError("updatePassword", "api.user.update_password.user_and_hashed.app_error", nil, "", http.StatusUnauthorized)
|
||||
} else {
|
||||
err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden)
|
||||
}
|
||||
} else {
|
||||
err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden)
|
||||
if c.Params.UserId == c.App.Session().UserId {
|
||||
currentPassword := props["current_password"]
|
||||
if len(currentPassword) <= 0 {
|
||||
c.SetInvalidParam("current_password")
|
||||
return
|
||||
}
|
||||
|
||||
err = c.App.UpdatePasswordAsUser(c.Params.UserId, currentPassword, newPassword)
|
||||
} else if c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
|
||||
err = c.App.UpdatePasswordByUserIdSendEmail(c.Params.UserId, newPassword, c.App.T("api.user.reset_password.method"))
|
||||
} else {
|
||||
err = model.NewAppError("updatePassword", "api.user.update_password.context.app_error", nil, "", http.StatusForbidden)
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -25,6 +25,7 @@ func (api *API) InitUserLocal() {
|
||||
api.BaseRoutes.User.Handle("/roles", api.ApiLocal(updateUserRoles)).Methods("PUT")
|
||||
api.BaseRoutes.User.Handle("/mfa", api.ApiLocal(updateUserMfa)).Methods("PUT")
|
||||
api.BaseRoutes.User.Handle("/active", api.ApiLocal(updateUserActive)).Methods("PUT")
|
||||
api.BaseRoutes.User.Handle("/password", api.ApiLocal(updatePassword)).Methods("PUT")
|
||||
api.BaseRoutes.User.Handle("/convert_to_bot", api.ApiLocal(convertUserToBot)).Methods("POST")
|
||||
api.BaseRoutes.User.Handle("/email/verify/member", api.ApiLocal(verifyUserEmailWithoutToken)).Methods("POST")
|
||||
|
||||
|
||||
@@ -2806,6 +2806,29 @@ func TestUpdateUserPassword(t *testing.T) {
|
||||
CheckNoError(t, resp)
|
||||
}
|
||||
|
||||
func TestUpdateUserHashedPassword(t *testing.T) {
|
||||
th := Setup(t).InitBasic()
|
||||
defer th.TearDown()
|
||||
client := th.Client
|
||||
|
||||
password := "SuperSecurePass23!"
|
||||
passwordHash := "$2a$10$CiS1iWVPUj7rQNdY6XW53.DmaPLsETIvmW2p0asp4Dqpofs10UL5W"
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||
pass, resp := client.UpdateUserHashedPassword(th.BasicUser.Id, passwordHash)
|
||||
CheckNoError(t, resp)
|
||||
require.True(t, pass)
|
||||
})
|
||||
|
||||
_, resp := client.Login(th.BasicUser.Email, password)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
// Standard users should never be updating their passwords with already-
|
||||
// hashed passwords.
|
||||
pass, resp := client.UpdateUserHashedPassword(th.BasicUser.Id, passwordHash)
|
||||
CheckUnauthorizedStatus(t, resp)
|
||||
require.False(t, pass)
|
||||
}
|
||||
|
||||
func TestResetPassword(t *testing.T) {
|
||||
t.Skip("test disabled during old build server changes, should be investigated")
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user