You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
boundary/internal/session/repository_credential.go

96 lines
3.2 KiB

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package session
import (
"context"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/kms"
)
// AddSessionCredentials encrypts the credData and adds the credentials to the repository. The credentials are linked
// to the sessionID provided, and encrypted using the sessProjectId. Session credentials are only valid for pending and
// active sessions, once a session ends, all session credentials are deleted.
// All options are ignored.
func (r *Repository) AddSessionCredentials(ctx context.Context, sessProjectId, sessionId string, credData []Credential, _ ...Option) error {
const op = "session.(Repository).AddSessionCredentials"
if sessionId == "" {
return errors.New(ctx, errors.InvalidParameter, op, "missing session id")
}
if sessProjectId == "" {
return errors.New(ctx, errors.InvalidParameter, op, "missing session project id")
}
if len(credData) == 0 {
return errors.New(ctx, errors.InvalidParameter, op, "missing credentials")
}
databaseWrapper, err := r.kms.GetWrapper(ctx, sessProjectId, kms.KeyPurposeDatabase)
if err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
addCreds := make([]credential, 0, len(credData))
for _, cred := range credData {
if len(cred) == 0 {
return errors.New(ctx, errors.InvalidParameter, op, "missing credential")
}
sessCred := credential{
SessionId: sessionId,
Credential: cred,
}
if err := sessCred.encrypt(ctx, databaseWrapper); err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to encrypt credential"))
}
addCreds = append(addCreds, sessCred)
}
_, err = r.writer.DoTx(ctx, db.StdRetryCnt, db.ExpBackoff{},
func(_ db.Reader, w db.Writer) error {
if err := w.CreateItems(ctx, addCreds); err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add session credentials"))
}
return nil
},
)
return err
}
// ListSessionCredentials returns all Credential attached to the sessionId.
// All options are ignored.
func (r *Repository) ListSessionCredentials(ctx context.Context, sessProjectId, sessionId string, _ ...Option) ([]Credential, error) {
const op = "session.(Repository).ListSessionCredentials"
if sessionId == "" {
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing session id")
}
if sessProjectId == "" {
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing session project id")
}
databaseWrapper, err := r.kms.GetWrapper(ctx, sessProjectId, kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
var creds []*credential
if err := r.reader.SearchWhere(ctx, &creds, "session_id = ?", []any{sessionId}); err != nil {
return nil, errors.Wrap(ctx, err, op)
}
if len(creds) == 0 {
return nil, nil
}
ret := make([]Credential, 0, len(creds))
for _, c := range creds {
if err := c.decrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to decrypt credential"))
}
ret = append(ret, c.Credential)
}
return ret, nil
}