Commit 2e6cde96 authored by ale's avatar ale

Expose the ResetPassword action, and fix the ResetResourcePassword endpoint

parent ae0b11a8
Pipeline #3423 passed with stages
in 5 minutes and 16 seconds
...@@ -339,6 +339,21 @@ Request parameters: ...@@ -339,6 +339,21 @@ Request parameters:
* `cur_password` - current valid password for the user * `cur_password` - current valid password for the user
* `password` - new password (unencrypted) * `password` - new password (unencrypted)
### `/api/user/reset_password`
Admin operation to forcefully reset the password for an account. This
operation will disable all 2FA credentials and it will re-generate the
storage encryption keys. The user will lose access to existing data.
Request parameters:
* `username` - name of the user
* `sso` - SSO ticket
Response parameters:
* `password` - the new random password
### `/api/user/set_password_recovery_hint` ### `/api/user/set_password_recovery_hint`
Sets the secondary authentication password (a hint / response pair, Sets the secondary authentication password (a hint / response pair,
...@@ -447,9 +462,9 @@ Request parameters: ...@@ -447,9 +462,9 @@ Request parameters:
* `sso` - SSO ticket * `sso` - SSO ticket
* `user` - user to create, with resources * `user` - user to create, with resources
### `/api/recover_password` ### `/api/recover_account`
Special endpoint for password recovery, used by the login FE service Special endpoint for account recovery, used by the login FE service
(sso-server) to retrieve the password recovery hint, and to trigger (sso-server) to retrieve the password recovery hint, and to trigger
password recovery with the user-provided recovery password. password recovery with the user-provided recovery password.
......
...@@ -183,41 +183,42 @@ func (r *AccountRecoveryRequest) Serve(rctx *RequestContext) (interface{}, error ...@@ -183,41 +183,42 @@ func (r *AccountRecoveryRequest) Serve(rctx *RequestContext) (interface{}, error
return nil, nil return nil, nil
} }
// ResetPasswordRequest is an admin operation to forcefully reset the password // ResetPasswordRequest is an admin operation to forcefully reset the
// for an account. The user will lose access to all stored email (because the // password for an account. A new password will be randomly generated
// encryption keys will be reset) and to 2FA. // by the accountserver. The user will lose access to all stored email
// (because the encryption keys will be reset) and to 2FA.
type ResetPasswordRequest struct { type ResetPasswordRequest struct {
AdminUserRequestBase AdminUserRequestBase
}
// ResetPasswordResponse is the response type for ResetPasswordRequest.
type ResetPasswordResponse struct {
Password string `json:"password"` Password string `json:"password"`
} }
// Sanitize the request. // Sanitize the response.
func (r *ResetPasswordRequest) Sanitize() { func (r *ResetPasswordResponse) Sanitize() {
r.AdminUserRequestBase.Sanitize()
if r.Password != "" { if r.Password != "" {
r.Password = sanitizedValue r.Password = sanitizedValue
} }
} }
// Validate the request.
func (r *ResetPasswordRequest) Validate(rctx *RequestContext) error {
if err := rctx.fieldValidators.password(rctx.Context, r.Password); err != nil {
return newValidationError(nil, "password", err.Error())
}
return nil
}
// Serve the request. // Serve the request.
func (r *ResetPasswordRequest) Serve(rctx *RequestContext) (interface{}, error) { func (r *ResetPasswordRequest) Serve(rctx *RequestContext) (interface{}, error) {
if err := rctx.User.resetPassword(rctx.Context, rctx.TX, r.Password); err != nil { password := randomPassword()
if err := rctx.User.resetPassword(rctx.Context, rctx.TX, password); err != nil {
return nil, err return nil, err
} }
if err := rctx.User.disable2FA(rctx.Context, rctx.TX); err != nil { if err := rctx.User.disable2FA(rctx.Context, rctx.TX); err != nil {
return nil, err return nil, err
} }
rctx.audit.Log(rctx, nil, "password changed (admin)")
rctx.logUserAction(&rctx.User.User, umdb.LogTypePasswordReset, "password changed (admin)") rctx.audit.Log(rctx, nil, "password reset (admin)")
return nil, nil rctx.logUserAction(&rctx.User.User, umdb.LogTypePasswordReset, "password reset (admin)")
return &ResetPasswordResponse{
Password: password,
}, nil
} }
// SetAccountRecoveryHintRequest lets users set the password recovery hint // SetAccountRecoveryHintRequest lets users set the password recovery hint
......
...@@ -53,6 +53,7 @@ func New(service *as.AccountService, backend as.Backend) *APIServer { ...@@ -53,6 +53,7 @@ func New(service *as.AccountService, backend as.Backend) *APIServer {
s.Register("/api/user/update", &as.UpdateUserRequest{}) s.Register("/api/user/update", &as.UpdateUserRequest{})
s.Register("/api/user/admin_update", &as.AdminUpdateUserRequest{}) s.Register("/api/user/admin_update", &as.AdminUpdateUserRequest{})
s.Register("/api/user/change_password", &as.ChangeUserPasswordRequest{}) s.Register("/api/user/change_password", &as.ChangeUserPasswordRequest{})
s.Register("/api/user/reset_password", &as.ResetPasswordRequest{})
s.Register("/api/user/set_account_recovery_hint", &as.SetAccountRecoveryHintRequest{}) s.Register("/api/user/set_account_recovery_hint", &as.SetAccountRecoveryHintRequest{})
s.Register("/api/user/enable_otp", &as.EnableOTPRequest{}) s.Register("/api/user/enable_otp", &as.EnableOTPRequest{})
s.Register("/api/user/disable_otp", &as.DisableOTPRequest{}) s.Register("/api/user/disable_otp", &as.DisableOTPRequest{})
...@@ -63,7 +64,7 @@ func New(service *as.AccountService, backend as.Backend) *APIServer { ...@@ -63,7 +64,7 @@ func New(service *as.AccountService, backend as.Backend) *APIServer {
s.Register("/api/resource/set_status", &as.SetResourceStatusRequest{}) s.Register("/api/resource/set_status", &as.SetResourceStatusRequest{})
s.Register("/api/resource/create", &as.CreateResourcesRequest{}) s.Register("/api/resource/create", &as.CreateResourcesRequest{})
s.Register("/api/resource/move", &as.MoveResourceRequest{}) s.Register("/api/resource/move", &as.MoveResourceRequest{})
s.Register("/api/resource/reset_password", &as.ResetPasswordRequest{}) s.Register("/api/resource/reset_password", &as.ResetResourcePasswordRequest{})
s.Register("/api/resource/email/add_alias", &as.AddEmailAliasRequest{}) s.Register("/api/resource/email/add_alias", &as.AddEmailAliasRequest{})
s.Register("/api/resource/email/delete_alias", &as.DeleteEmailAliasRequest{}) s.Register("/api/resource/email/delete_alias", &as.DeleteEmailAliasRequest{})
s.Register("/api/recover_account", &as.AccountRecoveryRequest{}) s.Register("/api/recover_account", &as.AccountRecoveryRequest{})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment