feat(credentiallibraries): support vault ssh certificates
This commit is contained in:
1 parent
3a78a74571
commit
43f0ba89cf
14 files changed
+2087
-239
No files matched your search
+418
-71
@@ -2,6 +2,7 @@ package credentiallibraries
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -33,6 +34,11 @@ const (
|
||||
httpMethodField = "attributes.http_method"
|
||||
httpRequestBodyField = "attributes.http_request_body"
|
||||
credentialMappingPathField = "credential_mapping_overrides"
|
||||
sshCertUsernameField = "attributes.username"
|
||||
keyTypeField = "attributes.key_type"
|
||||
keyBitsField = "attributes.key_bits"
|
||||
criticalOptionsField = "attributes.critical_options"
|
||||
extensionsField = "attributes.extensions"
|
||||
domain = "credential"
|
||||
)
|
||||
|
||||
@@ -45,7 +51,8 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
maskManager handlers.MaskManager
|
||||
maskManager handlers.MaskManager
|
||||
sshCertMaskManager handlers.MaskManager
|
||||
|
||||
// IdActions contains the set of actions that can be performed on
|
||||
// individual resources
|
||||
@@ -62,6 +69,18 @@ var (
|
||||
action.Create,
|
||||
action.List,
|
||||
}
|
||||
|
||||
validCredentialTypesVaultGeneric = []credential.Type{
|
||||
credential.UsernamePasswordType,
|
||||
credential.SshPrivateKeyType,
|
||||
credential.UnspecifiedType,
|
||||
}
|
||||
|
||||
validKeyTypes = []string{
|
||||
vault.KeyTypeEcdsa,
|
||||
vault.KeyTypeEd25519,
|
||||
vault.KeyTypeRsa,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -70,6 +89,10 @@ func init() {
|
||||
handlers.MaskSource{&pb.CredentialLibrary{}, &pb.VaultCredentialLibraryAttributes{}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if sshCertMaskManager, err = handlers.NewMaskManager(handlers.MaskDestination{&store.SSHCertificateCredentialLibrary{}},
|
||||
handlers.MaskSource{&pb.CredentialLibrary{}, &pb.VaultSSHCertificateCredentialLibraryAttributes{}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Service handles request as described by the pbs.CredentialLibraryServiceServer interface.
|
||||
@@ -242,11 +265,23 @@ func (s Service) UpdateCredentialLibrary(ctx context.Context, req *pbs.UpdateCre
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cur, err := repo.LookupCredentialLibrary(ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
var currentCredentialType credential.Type
|
||||
var mo vault.MappingOverride
|
||||
switch subtypes.SubtypeFromId(domain, req.GetId()) {
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
cur, err := repo.LookupSSHCertificateCredentialLibrary(ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentCredentialType = credential.Type(cur.GetCredentialType())
|
||||
default:
|
||||
cur, err := repo.LookupCredentialLibrary(ctx, req.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
currentCredentialType = credential.Type(cur.GetCredentialType())
|
||||
mo = cur.MappingOverride
|
||||
}
|
||||
currentCredentialType := credential.Type(cur.GetCredentialType())
|
||||
|
||||
if err := validateUpdateRequest(req, currentCredentialType); err != nil {
|
||||
return nil, err
|
||||
@@ -255,7 +290,7 @@ func (s Service) UpdateCredentialLibrary(ctx context.Context, req *pbs.UpdateCre
|
||||
if authResults.Error != nil {
|
||||
return nil, authResults.Error
|
||||
}
|
||||
cl, err := s.updateInRepo(ctx, authResults.Scope.GetId(), req.GetId(), req.GetUpdateMask().GetPaths(), req.GetItem(), currentCredentialType, cur.MappingOverride)
|
||||
cl, err := s.updateInRepo(ctx, authResults.Scope.GetId(), req.GetId(), req.GetUpdateMask().GetPaths(), req.GetItem(), currentCredentialType, mo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -298,16 +333,28 @@ func (s Service) DeleteCredentialLibrary(ctx context.Context, req *pbs.DeleteCre
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s Service) listFromRepo(ctx context.Context, storeId string) ([]*vault.CredentialLibrary, error) {
|
||||
func (s Service) listFromRepo(ctx context.Context, storeId string) ([]credential.Library, error) {
|
||||
const op = "credentiallibraries.(Service).listFromRepo"
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
csl, err := repo.ListCredentialLibraries(ctx, storeId)
|
||||
genCsl, err := repo.ListCredentialLibraries(ctx, storeId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
certCsl, err := repo.ListSSHCertificateCredentialLibraries(ctx, storeId)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
|
||||
csl := make([]credential.Library, 0, len(genCsl)+len(certCsl))
|
||||
for _, s := range genCsl {
|
||||
csl = append(csl, s)
|
||||
}
|
||||
for _, s := range certCsl {
|
||||
csl = append(csl, s)
|
||||
}
|
||||
return csl, nil
|
||||
}
|
||||
|
||||
@@ -317,32 +364,67 @@ func (s Service) getFromRepo(ctx context.Context, id string) (credential.Library
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
cs, err := repo.LookupCredentialLibrary(ctx, id)
|
||||
if err != nil && !errors.IsNotFoundError(err) {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
switch subtypes.SubtypeFromId(domain, id) {
|
||||
case vault.GenericLibrarySubtype:
|
||||
cs, err := repo.LookupCredentialLibrary(ctx, id)
|
||||
if err != nil && !errors.IsNotFoundError(err) {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
if cs == nil {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("credential library %q not found", id))
|
||||
}
|
||||
return cs, err
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
cs, err := repo.LookupSSHCertificateCredentialLibrary(ctx, id)
|
||||
if err != nil && !errors.IsNotFoundError(err) {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
if cs == nil {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("ssh certificate credential library %q not found", id))
|
||||
}
|
||||
return cs, err
|
||||
}
|
||||
if cs == nil {
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("credential library %q not found", id))
|
||||
}
|
||||
return cs, err
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "unrecognized credential library subtype")
|
||||
}
|
||||
|
||||
func (s Service) createInRepo(ctx context.Context, scopeId string, item *pb.CredentialLibrary) (credential.Library, error) {
|
||||
const op = "credentiallibraries.(Service).createInRepo"
|
||||
cl, err := toStorageVaultLibrary(item.GetCredentialStoreId(), item)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
out, err := repo.CreateCredentialLibrary(ctx, scopeId, cl)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create credential library"))
|
||||
}
|
||||
if out == nil {
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create credential library but no error returned from repository.")
|
||||
var out credential.Library
|
||||
switch subtypes.SubtypeFromType(domain, item.GetType()) {
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
cl, err := toStorageVaultSSHCertificateLibrary(item.GetCredentialStoreId(), item)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
rl, err := repo.CreateSSHCertificateCredentialLibrary(ctx, scopeId, cl)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create ssh certificate credential library"))
|
||||
}
|
||||
if rl == nil {
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create ssh certificate credential library but no error returned from repository.")
|
||||
}
|
||||
out = rl
|
||||
default:
|
||||
cl, err := toStorageVaultLibrary(item.GetCredentialStoreId(), item)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
rl, err := repo.CreateCredentialLibrary(ctx, scopeId, cl)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create credential library"))
|
||||
}
|
||||
if rl == nil {
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create credential library but no error returned from repository.")
|
||||
}
|
||||
out = rl
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
@@ -372,26 +454,53 @@ func (s Service) updateInRepo(
|
||||
item.CredentialMappingOverrides = mappingStruct
|
||||
}
|
||||
|
||||
cl, err := toStorageVaultLibrary(item.GetCredentialStoreId(), item)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
cl.PublicId = id
|
||||
|
||||
dbMasks = append(dbMasks, maskManager.Translate(masks)...)
|
||||
if len(dbMasks) == 0 {
|
||||
return nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."})
|
||||
}
|
||||
var out credential.Library
|
||||
rowsUpdated := 0
|
||||
repo, err := s.repoFn()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
out, rowsUpdated, err := repo.UpdateCredentialLibrary(ctx, projId, cl, item.GetVersion(), dbMasks)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to update credential library"))
|
||||
}
|
||||
if rowsUpdated == 0 {
|
||||
return nil, handlers.NotFoundErrorf("Credential Library %q doesn't exist or incorrect version provided.", id)
|
||||
switch subtypes.SubtypeFromId(domain, id) {
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
dbMasks = append(dbMasks, sshCertMaskManager.Translate(masks)...)
|
||||
if getMapUpdate(criticalOptionsField, masks) {
|
||||
dbMasks = append(dbMasks, vault.CriticalOptionsField)
|
||||
}
|
||||
if getMapUpdate(extensionsField, masks) {
|
||||
dbMasks = append(dbMasks, vault.ExtensionsField)
|
||||
}
|
||||
if len(dbMasks) == 0 {
|
||||
return nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."})
|
||||
}
|
||||
cl, err := toStorageVaultSSHCertificateLibrary(item.GetCredentialStoreId(), item)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
cl.PublicId = id
|
||||
out, rowsUpdated, err = repo.UpdateSSHCertificateCredentialLibrary(ctx, projId, cl, item.GetVersion(), dbMasks)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to update credential library"))
|
||||
}
|
||||
if rowsUpdated == 0 {
|
||||
return nil, handlers.NotFoundErrorf("Credential Library %q doesn't exist or incorrect version provided.", id)
|
||||
}
|
||||
default:
|
||||
dbMasks = append(dbMasks, maskManager.Translate(masks)...)
|
||||
if len(dbMasks) == 0 {
|
||||
return nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."})
|
||||
}
|
||||
cl, err := toStorageVaultLibrary(item.GetCredentialStoreId(), item)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op)
|
||||
}
|
||||
cl.PublicId = id
|
||||
out, rowsUpdated, err = repo.UpdateCredentialLibrary(ctx, projId, cl, item.GetVersion(), dbMasks)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to update credential library"))
|
||||
}
|
||||
if rowsUpdated == 0 {
|
||||
return nil, handlers.NotFoundErrorf("Credential Library %q doesn't exist or incorrect version provided.", id)
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
@@ -402,7 +511,13 @@ func (s Service) deleteFromRepo(ctx context.Context, scopeId, id string) (bool,
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
rows, err := repo.DeleteCredentialLibrary(ctx, scopeId, id)
|
||||
rows := 0
|
||||
switch subtypes.SubtypeFromId(domain, id) {
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
rows, err = repo.DeleteSSHCertificateCredentialLibrary(ctx, scopeId, id)
|
||||
default:
|
||||
rows, err = repo.DeleteCredentialLibrary(ctx, scopeId, id)
|
||||
}
|
||||
if err != nil {
|
||||
if errors.IsNotFoundError(err) {
|
||||
return false, nil
|
||||
@@ -428,9 +543,9 @@ func (s Service) authResult(ctx context.Context, id string, a action.Type) auth.
|
||||
parentId = id
|
||||
default:
|
||||
opts = append(opts, auth.WithId(id))
|
||||
|
||||
parentId = id
|
||||
switch subtypes.SubtypeFromId(domain, id) {
|
||||
case vault.Subtype:
|
||||
case vault.GenericLibrarySubtype:
|
||||
cl, err := repo.LookupCredentialLibrary(ctx, id)
|
||||
if err != nil {
|
||||
res.Error = err
|
||||
@@ -441,6 +556,17 @@ func (s Service) authResult(ctx context.Context, id string, a action.Type) auth.
|
||||
return res
|
||||
}
|
||||
parentId = cl.GetStoreId()
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
cl, err := repo.LookupSSHCertificateCredentialLibrary(ctx, id)
|
||||
if err != nil {
|
||||
res.Error = err
|
||||
return res
|
||||
}
|
||||
if cl == nil {
|
||||
res.Error = handlers.NotFoundError()
|
||||
return res
|
||||
}
|
||||
parentId = cl.GetStoreId()
|
||||
default:
|
||||
res.Error = errors.New(ctx, errors.InvalidParameter, op, "unrecognized credential library subtype from id")
|
||||
return res
|
||||
@@ -515,7 +641,7 @@ func toProto(in credential.Library, opt ...handlers.Option) (*pb.CredentialLibra
|
||||
out.AuthorizedActions = opts.WithAuthorizedActions
|
||||
}
|
||||
switch subtypes.SubtypeFromId(domain, in.GetPublicId()) {
|
||||
case vault.Subtype:
|
||||
case vault.GenericLibrarySubtype:
|
||||
vaultIn, ok := in.(*vault.CredentialLibrary)
|
||||
if !ok {
|
||||
return nil, errors.NewDeprecated(errors.Internal, op, "unable to cast to vault credential library")
|
||||
@@ -568,6 +694,47 @@ func toProto(in credential.Library, opt ...handlers.Option) (*pb.CredentialLibra
|
||||
VaultCredentialLibraryAttributes: attrs,
|
||||
}
|
||||
}
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
vaultIn, ok := in.(*vault.SSHCertificateCredentialLibrary)
|
||||
if !ok {
|
||||
return nil, errors.NewDeprecated(errors.Internal, op, "unable to cast to vault ssh certificate credential library")
|
||||
}
|
||||
// We don't check for mapping overrides here -- this subtype does not currently support them.
|
||||
out.CredentialType = vaultIn.GetCredentialType()
|
||||
if outputFields.Has(globals.AttributesField) {
|
||||
attrs := &pb.VaultSSHCertificateCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(vaultIn.GetVaultPath()),
|
||||
}
|
||||
if vaultIn.GetUsername() != "" {
|
||||
attrs.Username = wrapperspb.String(vaultIn.GetUsername())
|
||||
}
|
||||
if vaultIn.GetKeyType() != "" {
|
||||
attrs.KeyType = wrapperspb.String(vaultIn.GetKeyType())
|
||||
}
|
||||
if vaultIn.GetKeyBits() != 0 {
|
||||
attrs.KeyBits = &wrapperspb.UInt32Value{Value: vaultIn.GetKeyBits()}
|
||||
}
|
||||
if vaultIn.GetTtl() != "" {
|
||||
attrs.Ttl = wrapperspb.String(vaultIn.GetTtl())
|
||||
}
|
||||
if vaultIn.GetKeyId() != "" {
|
||||
attrs.KeyId = wrapperspb.String(vaultIn.GetKeyId())
|
||||
}
|
||||
if vaultIn.GetCriticalOptions() != "" {
|
||||
co := make(map[string]string)
|
||||
json.Unmarshal([]byte(vaultIn.GetCriticalOptions()), &co)
|
||||
attrs.CriticalOptions = co
|
||||
}
|
||||
if vaultIn.GetExtensions() != "" {
|
||||
e := make(map[string]string)
|
||||
json.Unmarshal([]byte(vaultIn.GetExtensions()), &e)
|
||||
attrs.Extensions = e
|
||||
}
|
||||
out.Attrs = &pb.CredentialLibrary_VaultSshCertificateCredentialLibraryAttributes{
|
||||
VaultSshCertificateCredentialLibraryAttributes: attrs,
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
@@ -582,7 +749,11 @@ func toStorageVaultLibrary(storeId string, in *pb.CredentialLibrary) (out *vault
|
||||
opts = append(opts, vault.WithDescription(in.GetDescription().GetValue()))
|
||||
}
|
||||
|
||||
attrs := in.GetVaultCredentialLibraryAttributes()
|
||||
attrs := in.GetVaultGenericCredentialLibraryAttributes()
|
||||
if attrs == nil {
|
||||
// fallback to attributes for older subtype
|
||||
attrs = in.GetVaultCredentialLibraryAttributes()
|
||||
}
|
||||
if attrs.GetHttpMethod() != nil {
|
||||
opts = append(opts, vault.WithMethod(vault.Method(strings.ToUpper(attrs.GetHttpMethod().GetValue()))))
|
||||
}
|
||||
@@ -631,13 +802,66 @@ func toStorageVaultLibrary(storeId string, in *pb.CredentialLibrary) (out *vault
|
||||
return cs, err
|
||||
}
|
||||
|
||||
func toStorageVaultSSHCertificateLibrary(storeId string, in *pb.CredentialLibrary) (out *vault.SSHCertificateCredentialLibrary, err error) {
|
||||
const op = "credentiallibraries.toStorageVaultSSHCertificateLibrary"
|
||||
var opts []vault.Option
|
||||
if in.GetName() != nil {
|
||||
opts = append(opts, vault.WithName(in.GetName().GetValue()))
|
||||
}
|
||||
if in.GetDescription() != nil {
|
||||
opts = append(opts, vault.WithDescription(in.GetDescription().GetValue()))
|
||||
}
|
||||
opts = append(opts, vault.WithCredentialType(credential.Type(in.GetCredentialType())))
|
||||
|
||||
attrs := in.GetVaultSshCertificateCredentialLibraryAttributes()
|
||||
if attrs.GetKeyType() != nil {
|
||||
opts = append(opts, vault.WithKeyType(attrs.GetKeyType().GetValue()))
|
||||
}
|
||||
if attrs.GetKeyBits() != nil {
|
||||
opts = append(opts, vault.WithKeyBits(attrs.GetKeyBits().GetValue()))
|
||||
}
|
||||
if attrs.GetTtl() != nil {
|
||||
opts = append(opts, vault.WithTtl(attrs.GetTtl().GetValue()))
|
||||
}
|
||||
if attrs.GetKeyId() != nil {
|
||||
opts = append(opts, vault.WithKeyId(attrs.GetKeyId().GetValue()))
|
||||
}
|
||||
if attrs.GetCriticalOptions() != nil {
|
||||
co, err := json.Marshal(attrs.GetCriticalOptions())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
opts = append(opts, vault.WithCriticalOptions(string(co)))
|
||||
}
|
||||
if attrs.GetExtensions() != nil {
|
||||
e, err := json.Marshal(attrs.GetExtensions())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
opts = append(opts, vault.WithExtensions(string(e)))
|
||||
}
|
||||
|
||||
cs, err := vault.NewSSHCertificateCredentialLibrary(storeId, attrs.GetPath().GetValue(), attrs.GetUsername().GetValue(), opts...)
|
||||
if err != nil {
|
||||
return nil, errors.WrapDeprecated(err, op, errors.WithMsg("unable to build credential library"))
|
||||
}
|
||||
return cs, err
|
||||
}
|
||||
|
||||
// A validateX method should exist for each method above. These methods do not make calls to any backing service but enforce
|
||||
// requirements on the structure of the request. They verify that:
|
||||
// - The path passed in is correctly formatted
|
||||
// - All required parameters are set
|
||||
// - There are no conflicting parameters provided
|
||||
func validateGetRequest(req *pbs.GetCredentialLibraryRequest) error {
|
||||
return handlers.ValidateGetRequest(handlers.NoopValidatorFn, req, vault.CredentialLibraryPrefix)
|
||||
prefix := ""
|
||||
switch subtypes.SubtypeFromId(domain, req.GetId()) {
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
prefix = vault.SSHCertificateCredentialLibraryPrefix
|
||||
default:
|
||||
prefix = vault.CredentialLibraryPrefix
|
||||
}
|
||||
return handlers.ValidateGetRequest(handlers.NoopValidatorFn, req, prefix)
|
||||
}
|
||||
|
||||
func validateCreateRequest(req *pbs.CreateCredentialLibraryRequest) error {
|
||||
@@ -645,23 +869,82 @@ func validateCreateRequest(req *pbs.CreateCredentialLibraryRequest) error {
|
||||
badFields := map[string]string{}
|
||||
switch subtypes.SubtypeFromId(domain, req.GetItem().GetCredentialStoreId()) {
|
||||
case vault.Subtype:
|
||||
if t := req.GetItem().GetType(); t != "" && subtypes.SubtypeFromType(domain, t) != vault.Subtype {
|
||||
t := req.GetItem().GetType()
|
||||
if t == "" {
|
||||
badFields[globals.TypeField] = "This is a required field."
|
||||
}
|
||||
|
||||
// support older vault generic libraries with 'vault.Subtype'.
|
||||
if subtypes.SubtypeFromType(domain, t) == vault.Subtype {
|
||||
req.GetItem().Type = vault.GenericLibrarySubtype.String()
|
||||
t = vault.GenericLibrarySubtype.String()
|
||||
}
|
||||
|
||||
if subtypes.SubtypeFromType(domain, t) != vault.GenericLibrarySubtype &&
|
||||
subtypes.SubtypeFromType(domain, t) != vault.SSHCertificateLibrarySubtype {
|
||||
badFields[globals.CredentialStoreIdField] = "If included, type must match that of the credential store."
|
||||
}
|
||||
attrs := req.GetItem().GetVaultCredentialLibraryAttributes()
|
||||
if attrs == nil {
|
||||
badFields[attributesPathField] = "This is a required field."
|
||||
|
||||
switch subtypes.SubtypeFromType(domain, req.GetItem().GetType()) {
|
||||
case vault.GenericLibrarySubtype:
|
||||
isValidCred := false
|
||||
ct := req.GetItem().GetCredentialType()
|
||||
for _, t := range validCredentialTypesVaultGeneric {
|
||||
if ct == "" || ct == string(t) {
|
||||
isValidCred = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isValidCred {
|
||||
badFields[globals.CredentialTypeField] = fmt.Sprintf("Unknown credential type %q", ct)
|
||||
}
|
||||
|
||||
attrs := req.GetItem().GetVaultGenericCredentialLibraryAttributes()
|
||||
if attrs == nil {
|
||||
// fallback to attributes for older subtype
|
||||
attrs = req.GetItem().GetVaultCredentialLibraryAttributes()
|
||||
if attrs == nil {
|
||||
badFields[attributesPathField] = "This is a required field."
|
||||
}
|
||||
}
|
||||
if attrs.GetPath().GetValue() == "" {
|
||||
badFields[vaultPathField] = "This is a required field."
|
||||
}
|
||||
if m := attrs.GetHttpMethod(); m != nil && !strutil.StrListContains([]string{"GET", "POST"}, strings.ToUpper(m.GetValue())) {
|
||||
badFields[httpMethodField] = "If set, value must be 'GET' or 'POST'."
|
||||
}
|
||||
if b := attrs.GetHttpRequestBody(); b != nil && strings.ToUpper(attrs.GetHttpMethod().GetValue()) != "POST" {
|
||||
badFields[httpRequestBodyField] = fmt.Sprintf("Field can only be set if %q is set to the value 'POST'.", httpMethodField)
|
||||
}
|
||||
validateMapping(badFields, credential.Type(req.GetItem().GetCredentialType()), req.GetItem().CredentialMappingOverrides.AsMap())
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
if req.GetItem().GetCredentialType() != "" {
|
||||
badFields[globals.CredentialTypeField] = fmt.Sprintf("This field is read only and cannot be set.")
|
||||
}
|
||||
|
||||
attrs := req.GetItem().GetVaultSshCertificateCredentialLibraryAttributes()
|
||||
if attrs == nil {
|
||||
badFields[attributesPathField] = "This is a required field."
|
||||
}
|
||||
if attrs.GetPath().GetValue() == "" {
|
||||
badFields[vaultPathField] = "This is a required field."
|
||||
}
|
||||
if attrs.GetUsername().GetValue() == "" {
|
||||
badFields[sshCertUsernameField] = "This is a required field."
|
||||
}
|
||||
if (attrs.GetKeyType() == nil) != (attrs.GetKeyBits() == nil) {
|
||||
if attrs.GetKeyType() != nil && attrs.GetKeyType().GetValue() != vault.KeyTypeEd25519 {
|
||||
badFields[keyTypeField] = fmt.Sprintf("If set, %q must also be set.", keyBitsField)
|
||||
}
|
||||
if attrs.GetKeyBits() != nil {
|
||||
badFields[keyBitsField] = fmt.Sprintf("If set, %q must also be set.", keyTypeField)
|
||||
}
|
||||
}
|
||||
if t := attrs.GetKeyType(); t != nil && !strutil.StrListContains(validKeyTypes, strings.ToLower(t.GetValue())) {
|
||||
badFields[keyTypeField] = "If set, value must be 'ed25519', 'ecdsa', or 'rsa'."
|
||||
}
|
||||
validateKeyBits(badFields, attrs.GetKeyBits().GetValue(), attrs.GetKeyType().GetValue())
|
||||
}
|
||||
if attrs.GetPath().GetValue() == "" {
|
||||
badFields[vaultPathField] = "This is a required field."
|
||||
}
|
||||
if m := attrs.GetHttpMethod(); m != nil && !strutil.StrListContains([]string{"GET", "POST"}, strings.ToUpper(m.GetValue())) {
|
||||
badFields[httpMethodField] = "If set, value must be 'GET' or 'POST'."
|
||||
}
|
||||
if b := attrs.GetHttpRequestBody(); b != nil && strings.ToUpper(attrs.GetHttpMethod().GetValue()) != "POST" {
|
||||
badFields[httpRequestBodyField] = fmt.Sprintf("Field can only be set if %q is set to the value 'POST'.", httpMethodField)
|
||||
}
|
||||
validateMapping(badFields, credential.Type(req.GetItem().GetCredentialType()), req.GetItem().CredentialMappingOverrides.AsMap())
|
||||
default:
|
||||
badFields[globals.CredentialStoreIdField] = "This field must be a valid credential store id."
|
||||
}
|
||||
@@ -670,17 +953,29 @@ func validateCreateRequest(req *pbs.CreateCredentialLibraryRequest) error {
|
||||
}
|
||||
|
||||
func validateUpdateRequest(req *pbs.UpdateCredentialLibraryRequest, currentCredentialType credential.Type) error {
|
||||
prefix := ""
|
||||
st := subtypes.SubtypeFromId(domain, req.GetId())
|
||||
switch st {
|
||||
case vault.GenericLibrarySubtype:
|
||||
prefix = vault.CredentialLibraryPrefix
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
prefix = vault.SSHCertificateCredentialLibraryPrefix
|
||||
}
|
||||
return handlers.ValidateUpdateRequest(req, req.GetItem(), func() map[string]string {
|
||||
badFields := map[string]string{}
|
||||
switch subtypes.SubtypeFromId(domain, req.GetId()) {
|
||||
case vault.Subtype:
|
||||
if req.GetItem().GetType() != "" && subtypes.SubtypeFromType(domain, req.GetItem().GetType()) != vault.Subtype {
|
||||
switch st {
|
||||
case vault.GenericLibrarySubtype:
|
||||
if req.GetItem().GetType() != "" && subtypes.SubtypeFromType(domain, req.GetItem().GetType()) != vault.GenericLibrarySubtype {
|
||||
badFields[globals.TypeField] = "Cannot modify resource type."
|
||||
}
|
||||
if req.GetItem().GetCredentialType() != "" && req.GetItem().GetCredentialType() != string(currentCredentialType) {
|
||||
badFields[globals.CredentialTypeField] = "Cannot modify credential type."
|
||||
}
|
||||
attrs := req.GetItem().GetVaultCredentialLibraryAttributes()
|
||||
attrs := req.GetItem().GetVaultGenericCredentialLibraryAttributes()
|
||||
if attrs == nil {
|
||||
// fallback to attributes for older subtype
|
||||
attrs = req.GetItem().GetVaultCredentialLibraryAttributes()
|
||||
}
|
||||
if attrs != nil {
|
||||
if handlers.MaskContains(req.GetUpdateMask().GetPaths(), vaultPathField) && attrs.GetPath().GetValue() == "" {
|
||||
badFields[vaultPathField] = "This is a required field and cannot be set to empty."
|
||||
@@ -693,13 +988,33 @@ func validateUpdateRequest(req *pbs.UpdateCredentialLibraryRequest, currentCrede
|
||||
}
|
||||
validateMapping(badFields, currentCredentialType, req.GetItem().CredentialMappingOverrides.AsMap())
|
||||
}
|
||||
case vault.SSHCertificateLibrarySubtype:
|
||||
if req.GetItem().GetType() != "" && subtypes.SubtypeFromType(domain, req.GetItem().GetType()) != vault.SSHCertificateLibrarySubtype {
|
||||
badFields[globals.TypeField] = "Cannot modify resource type."
|
||||
}
|
||||
if req.GetItem().GetCredentialType() != "" && req.GetItem().GetCredentialType() != string(currentCredentialType) {
|
||||
badFields[globals.CredentialTypeField] = "Cannot modify credential type."
|
||||
}
|
||||
attrs := req.GetItem().GetVaultSshCertificateCredentialLibraryAttributes()
|
||||
if attrs != nil {
|
||||
if handlers.MaskContains(req.GetUpdateMask().GetPaths(), vaultPathField) && attrs.GetPath().GetValue() == "" {
|
||||
badFields[vaultPathField] = "This is a required field and cannot be set to empty."
|
||||
}
|
||||
if u := attrs.GetUsername().GetValue(); handlers.MaskContains(req.GetUpdateMask().GetPaths(), sshCertUsernameField) && u == "" {
|
||||
badFields[sshCertUsernameField] = "This is a required field and cannot be set to empty."
|
||||
}
|
||||
if t := attrs.GetKeyType(); t != nil && !strutil.StrListContains(validKeyTypes, strings.ToLower(t.GetValue())) {
|
||||
badFields[keyTypeField] = "If set, value must be 'ed25519', 'ecdsa', or 'rsa'."
|
||||
}
|
||||
validateKeyBits(badFields, attrs.GetKeyBits().GetValue(), attrs.GetKeyType().GetValue())
|
||||
}
|
||||
}
|
||||
return badFields
|
||||
}, vault.CredentialLibraryPrefix)
|
||||
}, prefix)
|
||||
}
|
||||
|
||||
func validateDeleteRequest(req *pbs.DeleteCredentialLibraryRequest) error {
|
||||
return handlers.ValidateDeleteRequest(handlers.NoopValidatorFn, req, vault.CredentialLibraryPrefix)
|
||||
return handlers.ValidateDeleteRequest(handlers.NoopValidatorFn, req, vault.CredentialLibraryPrefix, vault.SSHCertificateCredentialLibraryPrefix)
|
||||
}
|
||||
|
||||
func validateListRequest(req *pbs.ListCredentialLibrariesRequest) error {
|
||||
@@ -747,6 +1062,38 @@ func validateMapping(badFields map[string]string, credentialType credential.Type
|
||||
}
|
||||
}
|
||||
|
||||
// validateKeyBits appends to badFields if keyBits and keyType aren't accepted combinations for an SSHCertificateCredentialLibrary.
|
||||
// If keyType is an empty string, validateKeyBits only validates keyBits.
|
||||
func validateKeyBits(badFields map[string]string, keyBits uint32, keyType string) {
|
||||
switch keyBits {
|
||||
case vault.KeyBitsDefault:
|
||||
case vault.KeyBitsEcdsa256, vault.KeyBitsEcdsa384, vault.KeyBitsEcdsa521:
|
||||
if keyType != "" && keyType != vault.KeyTypeEcdsa {
|
||||
badFields[keyBitsField] = fmt.Sprintf("Invalid bit size %d for key type %s", keyBits, keyType)
|
||||
}
|
||||
case vault.KeyBitsRsa2048, vault.KeyBitsRsa3072, vault.KeyBitsRsa4096:
|
||||
if keyType != "" && keyType != vault.KeyTypeRsa {
|
||||
badFields[keyBitsField] = fmt.Sprintf("Invalid bit size %d for key type %s", keyBits, keyType)
|
||||
}
|
||||
default:
|
||||
badFields[keyBitsField] = fmt.Sprintf("Invalid bit size %d", keyBits)
|
||||
}
|
||||
}
|
||||
|
||||
func getMapUpdate(field string, apiMasks []string) bool {
|
||||
for _, m := range apiMasks {
|
||||
if m == field {
|
||||
return true
|
||||
}
|
||||
|
||||
fieldPrefix := fmt.Sprintf("%v.", field)
|
||||
if s := strings.SplitN(m, fieldPrefix, 2); len(s) == 2 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func getMappingUpdates(credentialType credential.Type, current vault.MappingOverride, new map[string]any, apiMasks []string) (map[string]any, bool) {
|
||||
ret := make(map[string]any)
|
||||
masks := make(map[string]bool)
|
||||
|
||||
+893
-19
File diff suppressed because it is too large.
Load diff
@@ -2516,6 +2516,7 @@ func TestAuthorizeSession(t *testing.T) {
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Name: wrapperspb.String("Library Name"),
|
||||
Description: wrapperspb.String("Library Description"),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: &wrapperspb.StringValue{
|
||||
@@ -2629,7 +2630,7 @@ func TestAuthorizeSession(t *testing.T) {
|
||||
Name: clsResp.GetItem().GetName().GetValue(),
|
||||
Description: clsResp.GetItem().GetDescription().GetValue(),
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Type: vault.Subtype.String(),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
},
|
||||
}},
|
||||
// TODO: validate the contents of the authorization token is what is expected
|
||||
@@ -2758,6 +2759,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Name: wrapperspb.String("Usernamepassword Library"),
|
||||
Description: wrapperspb.String("Usernamepassword Library Description"),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(path.Join("secret", "data", "default-userpass")),
|
||||
@@ -2772,6 +2774,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Name: wrapperspb.String("Unspecified Library"),
|
||||
Description: wrapperspb.String("Unspecified Library Description"),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(path.Join("secret", "data", "default-userpass")),
|
||||
@@ -2789,6 +2792,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Name: wrapperspb.String("Usernamepassword Mapping Library"),
|
||||
Description: wrapperspb.String("Usernamepassword Mapping Library Description"),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(path.Join("secret", "data", "non-default-userpass")),
|
||||
@@ -2860,6 +2864,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Name: wrapperspb.String("SSH Private Key Library"),
|
||||
Description: wrapperspb.String("SSH Private Key Library Description"),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(path.Join("secret", "data", "default-sshpk")),
|
||||
@@ -2878,6 +2883,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Name: wrapperspb.String("SSH Private Key Mapping Library"),
|
||||
Description: wrapperspb.String("SSH Private Key Mapping Library Description"),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(path.Join("secret", "data", "non-default-sshpk")),
|
||||
@@ -2900,6 +2906,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Name: wrapperspb.String("SSH Private Key With Passphrase Library"),
|
||||
Description: wrapperspb.String("SSH Private Key Library Description"),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(path.Join("secret", "data", "default-sshpk-with-pass")),
|
||||
@@ -2919,6 +2926,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Name: wrapperspb.String("SSH Private Key With Passphrase Mapping Library"),
|
||||
Description: wrapperspb.String("SSH Private Key Mapping Library Description"),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(path.Join("secret", "data", "non-default-sshpk-with-pass")),
|
||||
@@ -2955,7 +2963,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
Name: clsRespUnspecified.GetItem().GetName().GetValue(),
|
||||
Description: clsRespUnspecified.GetItem().GetDescription().GetValue(),
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Type: vault.Subtype.String(),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2971,7 +2979,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
Name: clsRespUsernamePassword.GetItem().GetName().GetValue(),
|
||||
Description: clsRespUsernamePassword.GetItem().GetDescription().GetValue(),
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Type: vault.Subtype.String(),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
CredentialType: string(credential.UsernamePasswordType),
|
||||
},
|
||||
Credential: func() *structpb.Struct {
|
||||
@@ -2997,7 +3005,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
Name: clsRespUsernamePasswordWithMapping.GetItem().GetName().GetValue(),
|
||||
Description: clsRespUsernamePasswordWithMapping.GetItem().GetDescription().GetValue(),
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Type: vault.Subtype.String(),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
CredentialType: string(credential.UsernamePasswordType),
|
||||
},
|
||||
Credential: func() *structpb.Struct {
|
||||
@@ -3075,7 +3083,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
Name: clsRespSshPrivateKey.GetItem().GetName().GetValue(),
|
||||
Description: clsRespSshPrivateKey.GetItem().GetDescription().GetValue(),
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Type: vault.Subtype.String(),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
CredentialType: string(credential.SshPrivateKeyType),
|
||||
},
|
||||
Credential: func() *structpb.Struct {
|
||||
@@ -3101,7 +3109,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
Name: clsRespSshPrivateKeyWithMapping.GetItem().GetName().GetValue(),
|
||||
Description: clsRespSshPrivateKeyWithMapping.GetItem().GetDescription().GetValue(),
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Type: vault.Subtype.String(),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
CredentialType: string(credential.SshPrivateKeyType),
|
||||
},
|
||||
Credential: func() *structpb.Struct {
|
||||
@@ -3154,7 +3162,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
Name: clsRespSshPrivateKeyWithPass.GetItem().GetName().GetValue(),
|
||||
Description: clsRespSshPrivateKeyWithPass.GetItem().GetDescription().GetValue(),
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Type: vault.Subtype.String(),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
CredentialType: string(credential.SshPrivateKeyType),
|
||||
},
|
||||
Credential: func() *structpb.Struct {
|
||||
@@ -3181,7 +3189,7 @@ func TestAuthorizeSessionTypedCredentials(t *testing.T) {
|
||||
Name: clsRespSshPrivateKeyWithPassWithMapping.GetItem().GetName().GetValue(),
|
||||
Description: clsRespSshPrivateKeyWithPassWithMapping.GetItem().GetDescription().GetValue(),
|
||||
CredentialStoreId: vaultStore.GetPublicId(),
|
||||
Type: vault.Subtype.String(),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
CredentialType: string(credential.SshPrivateKeyType),
|
||||
},
|
||||
Credential: func() *structpb.Struct {
|
||||
@@ -3392,6 +3400,7 @@ func TestAuthorizeSession_Errors(t *testing.T) {
|
||||
clsResp, err := credService.CreateCredentialLibrary(ctx, &pbs.CreateCredentialLibraryRequest{Item: &credlibpb.CredentialLibrary{
|
||||
CredentialStoreId: store.GetPublicId(),
|
||||
Description: wrapperspb.String(fmt.Sprintf("Library Description for target %q", tar.GetName())),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(path.Join("database", "creds", "opened")),
|
||||
@@ -3416,6 +3425,7 @@ func TestAuthorizeSession_Errors(t *testing.T) {
|
||||
clsResp, err := credService.CreateCredentialLibrary(ctx, &pbs.CreateCredentialLibraryRequest{Item: &credlibpb.CredentialLibrary{
|
||||
CredentialStoreId: store.GetPublicId(),
|
||||
Description: wrapperspb.String(fmt.Sprintf("Library Description for target %q", tar.GetName())),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String("bad path"),
|
||||
@@ -3440,6 +3450,7 @@ func TestAuthorizeSession_Errors(t *testing.T) {
|
||||
clsResp, err := credService.CreateCredentialLibrary(ctx, &pbs.CreateCredentialLibraryRequest{Item: &credlibpb.CredentialLibrary{
|
||||
CredentialStoreId: expiredStore.GetPublicId(),
|
||||
Description: wrapperspb.String(fmt.Sprintf("Library Description for target %q", tar.GetName())),
|
||||
Type: vault.GenericLibrarySubtype.String(),
|
||||
Attrs: &credlibpb.CredentialLibrary_VaultCredentialLibraryAttributes{
|
||||
VaultCredentialLibraryAttributes: &credlibpb.VaultCredentialLibraryAttributes{
|
||||
Path: wrapperspb.String(path.Join("database", "creds", "opened")),
|
||||
|
||||
Reference in new issue
Block a user