129 lines
4.0 KiB
Go
129 lines
4.0 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package storagebucketcredential
|
|
|
|
import (
|
|
"context"
|
|
goerrs "errors"
|
|
"fmt"
|
|
|
|
"github.com/hashicorp/boundary/internal/errors"
|
|
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/storagebuckets"
|
|
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/types/known/structpb"
|
|
)
|
|
|
|
// StorageBucketCredential is a commmon interface for all storage bucket credential subtypes
|
|
type StorageBucketCredential interface {
|
|
HmacSecrets(context.Context, wrapping.Wrapper) ([]byte, error)
|
|
Encrypt(context.Context, wrapping.Wrapper) error
|
|
Decrypt(context.Context, wrapping.Wrapper) error
|
|
ToPersisted(context.Context) (*storagebuckets.StorageBucketPersisted, error)
|
|
Clone() StorageBucketCredential
|
|
CreateDBQuery() string
|
|
GetPrivateId() string
|
|
GetStorageBucketId() string
|
|
GetType() Subtype
|
|
GetSecrets() []byte
|
|
GetCtSecrets() []byte
|
|
GetKeyId() string
|
|
SetPrivateId(string)
|
|
SetStorageBucketId(string)
|
|
SetSecrets([]byte)
|
|
SetCtSecrets([]byte)
|
|
SetKeyId(string)
|
|
}
|
|
|
|
const (
|
|
sbcDefaultTable = "storage_bucket_credential_all_subtypes"
|
|
)
|
|
|
|
type Subtype string
|
|
|
|
const (
|
|
UnknownSubtype Subtype = "unknown"
|
|
ManagedSecretSubtype Subtype = "managed_secret"
|
|
EnvironmentalSubtype Subtype = "environmental"
|
|
)
|
|
|
|
var errSBCSubtypeNotFound = goerrs.New("storage bucket credential subtype not found")
|
|
|
|
// storageBucketCredential provides a common way to return storage bucket credentials
|
|
// regardless of their underlying type.
|
|
type storageBucketCredential struct {
|
|
// tableName is the name of the table in the database
|
|
tableName string `gorm:"-"`
|
|
// PrivateId is a surrogate key suitable for use via API.
|
|
PrivateId string `gorm:"primary_key"`
|
|
// StorageBucketId is the public id of the storage bucket.
|
|
StorageBucketId string `gorm:"not_null"`
|
|
// Secrets is the plain-text of the secret data. We are not storing this plain-text
|
|
// value in the database.
|
|
Secrets []byte `gorm:"-" wrapping:"pt,secrets_data"`
|
|
// CtSecrets is the ciphertext of the secret data stored in the db.
|
|
CtSecrets []byte `gorm:"column:secrets_encrypted;not_null" wrapping:"ct,secrets_data"`
|
|
// The KeyId of the kms database key used for encrypting this entry.
|
|
// It must be set.
|
|
KeyId string `gorm:"not_null"`
|
|
// Type represents the type of the Storage Bucket Credential
|
|
Type string `gorm:"default:null"`
|
|
}
|
|
|
|
// AllocStorageBucketCredential will allocate a storage bucket credential
|
|
func AllocStorageBucketCredential() *storageBucketCredential {
|
|
return &storageBucketCredential{}
|
|
}
|
|
|
|
// TableName provides an overridden gorm table name for storage bucket credentials.
|
|
func (sbc *storageBucketCredential) TableName() string {
|
|
if sbc.tableName != "" {
|
|
return sbc.tableName
|
|
}
|
|
return sbcDefaultTable
|
|
}
|
|
|
|
// SetTableName sets the table name for the resource. If the caller attempts to
|
|
// set the name to "" the name will be reset to the default name.
|
|
func (sbc *storageBucketCredential) SetTableName(n string) {
|
|
switch n {
|
|
case "":
|
|
sbc.tableName = sbcDefaultTable
|
|
default:
|
|
sbc.tableName = n
|
|
}
|
|
}
|
|
|
|
func (sbc *storageBucketCredential) Subtype() Subtype {
|
|
return Subtype(sbc.Type)
|
|
}
|
|
|
|
// SBCSubtype converts the storage bucket credential to the concrete subtype
|
|
func (sbc *storageBucketCredential) SBCSubtype(ctx context.Context) (StorageBucketCredential, error) {
|
|
const op = "storagebucketcredential.storageBucketCredential.sbcSubtype"
|
|
|
|
alloc, ok := SubtypeRegistry.AllocFunc(sbc.Subtype())
|
|
if !ok {
|
|
return nil, errors.Wrap(ctx,
|
|
errSBCSubtypeNotFound,
|
|
op,
|
|
errors.WithCode(errors.InvalidParameter),
|
|
errors.WithMsg(fmt.Sprintf("%s is an unknown sbc subtype of %s", sbc.PrivateId, sbc.Type)),
|
|
)
|
|
}
|
|
|
|
aSBC := alloc()
|
|
aSBC.SetPrivateId(sbc.PrivateId)
|
|
aSBC.SetStorageBucketId(sbc.StorageBucketId)
|
|
if sbc.Subtype() == ManagedSecretSubtype {
|
|
secrets := &structpb.Struct{}
|
|
if err := proto.Unmarshal(sbc.Secrets, secrets); err != nil {
|
|
return nil, err
|
|
}
|
|
aSBC.SetSecrets(sbc.Secrets)
|
|
aSBC.SetCtSecrets(sbc.CtSecrets)
|
|
}
|
|
return aSBC, nil
|
|
}
|