// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package userpass import ( "context" "fmt" "golang.org/x/crypto/bcrypt" "github.com/hashicorp/vault/sdk/framework" "github.com/hashicorp/vault/sdk/logical" ) func pathUserPassword(b *backend) *framework.Path { return &framework.Path{ Pattern: "users/" + framework.GenericNameRegex("username") + "/password$", Fields: map[string]*framework.FieldSchema{ "username": { Type: framework.TypeString, Description: "Username for this user.", }, "password": { Type: framework.TypeString, Description: "Password for this user.", }, }, Callbacks: map[logical.Operation]framework.OperationFunc{ logical.UpdateOperation: b.pathUserPasswordUpdate, }, HelpSynopsis: pathUserPasswordHelpSyn, HelpDescription: pathUserPasswordHelpDesc, } } func (b *backend) pathUserPasswordUpdate(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) { username := d.Get("username").(string) userEntry, err := b.user(ctx, req.Storage, username) if err != nil { return nil, err } if userEntry == nil { return nil, fmt.Errorf("username does not exist") } userErr, intErr := b.updateUserPassword(req, d, userEntry) if intErr != nil { return nil, err } if userErr != nil { return logical.ErrorResponse(userErr.Error()), logical.ErrInvalidRequest } return nil, b.setUser(ctx, req.Storage, username, userEntry) } func (b *backend) updateUserPassword(req *logical.Request, d *framework.FieldData, userEntry *UserEntry) (error, error) { password := d.Get("password").(string) if password == "" { return fmt.Errorf("missing password"), nil } // Generate a hash of the password hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { return nil, err } userEntry.PasswordHash = hash return nil, nil } const pathUserPasswordHelpSyn = ` Reset user's password. ` const pathUserPasswordHelpDesc = ` This endpoint allows resetting the user's password. `