Files
threshold/internal/storage/storagebucketcredential/storage_bucket_credential.go
T

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
}