Repository: hashicorp/vault
File: builtin/credential/ldap/path_config_rotate_root.go (Go)

Code before:
			OperationVerb:   "rotate",
			OperationSuffix: "root-credentials",
		},

		Operations: map[logical.Operation]framework.OperationHandler{
			logical.UpdateOperation: &framework.PathOperation{
				Callback:                    b.pathConfigRotateRootUpdate,
				ForwardPerformanceSecondary: true,
				ForwardPerformanceStandby:   true,
			},
		},

		HelpSynopsis:    pathConfigRotateRootHelpSyn,
		HelpDescription: pathConfigRotateRootHelpDesc,
	}
}

func (b *backend) pathConfigRotateRootUpdate(ctx context.Context, req *logical.Request, _ *framework.FieldData) (*logical.Response, error) {
	err := b.rotateRootCredential(ctx, req)
	if err != nil {
		// log here instead of inside the actual rotate call because the rotation manager also logs, so this is
		// the "equivalent" place for manual rotations.
		b.Logger().Error("failed to rotate root credential", "rotationID", req.Path, "err", err.Error())
	} else {
		// err is nil in this case
		b.Logger().Info("succesfully rotated root credential on user request", "rotatioNID", req.Path)
	}
	var responseError responseError
	if errors.As(err, &responseError) {
		return logical.ErrorResponse(responseError.Error()), nil
	}

	// naturally this is `nil, nil` if the err is nil
	return nil, err
}

// responseError exists to capture the cases in the old rotate call that returned specific error responses
type responseError struct {
	error
}

func (b *backend) rotateRootCredential(ctx context.Context, req *logical.Request) error {
	// lock the backend's state - really just the config state - for mutating
	b.mu.Lock()
	defer b.mu.Unlock()

	cfg, err := b.Config(ctx, req)
	if err != nil {
		return err
	}
	if cfg == nil {

Review comment (security):
```suggestion
		b.Logger().Info("succesfully rotated root credential on user request", "rotationID", req.Path)
```

Code after:
			OperationVerb:   "rotate",
			OperationSuffix: "root-credentials",
		},

		Operations: map[logical.Operation]framework.OperationHandler{
			logical.UpdateOperation: &framework.PathOperation{
				Callback:                    b.pathConfigRotateRootUpdate,
				ForwardPerformanceSecondary: true,
				ForwardPerformanceStandby:   true,
			},
		},

		HelpSynopsis:    pathConfigRotateRootHelpSyn,
		HelpDescription: pathConfigRotateRootHelpDesc,
	}
}

func (b *backend) pathConfigRotateRootUpdate(ctx context.Context, req *logical.Request, _ *framework.FieldData) (*logical.Response, error) {
	err := b.rotateRootCredential(ctx, req)
	if err != nil {
		// log here instead of inside the actual rotate call because the rotation manager also logs, so this is
		// the "equivalent" place for manual rotations.
		b.Logger().Error("failed to rotate root credential on user request", "path", req.Path, "error", err.Error())
	} else {
		// err is nil in this case
		b.Logger().Info("succesfully rotated root credential on user request", "path", req.Path)
	}
	var responseError responseError
	if errors.As(err, &responseError) {
		return logical.ErrorResponse(responseError.Error()), nil
	}

	// naturally this is `nil, nil` if the err is nil
	return nil, err
}

// responseError exists to capture the cases in the old rotate call that returned specific error responses
type responseError struct {
	error
}

func (b *backend) rotateRootCredential(ctx context.Context, req *logical.Request) error {
	// lock the backend's state - really just the config state - for mutating
	b.mu.Lock()
	defer b.mu.Unlock()

	cfg, err := b.Config(ctx, req)
	if err != nil {
		return err
	}
	if cfg == nil {