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/auth/oidc/repository_auth_method_crea...

134 lines
4.2 KiB

package oidc
import (
"context"
"strings"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/kms"
"github.com/hashicorp/boundary/internal/oplog"
)
// CreateAuthMethod creates am (*AuthMethod) in the repo along with its
// associated embedded optional value objects of SigningAlgs, AudClaims,
// and Certificates and returns the newly created AuthMethod
// (with its PublicId set)
//
// The AuthMethod's public id and version must be empty (zero values).
//
// All options are ignored.
func (r *Repository) CreateAuthMethod(ctx context.Context, am *AuthMethod, opt ...Option) (*AuthMethod, error) {
const op = "oidc.(Repository).CreateAuthMethod"
if am == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method")
}
if am.PublicId != "" {
return nil, errors.New(errors.InvalidParameter, op, "public id must be empty")
}
if am.Version != 0 {
return nil, errors.New(errors.InvalidParameter, op, "version must be empty")
}
if err := am.validate(op); err != nil {
return nil, err // validate properly sets the op to the caller, the code and the msg, so just return it.
}
opts := getOpts(opt...)
am.PublicId = opts.withPublicId
if am.PublicId == "" {
id, err := newAuthMethodId()
if err != nil {
return nil, errors.Wrap(err, op)
}
am.PublicId = id
} else {
if !strings.HasPrefix(am.PublicId, AuthMethodPrefix+"_") {
return nil, errors.New(errors.InvalidParameter, op, "wrong auth method id prefix")
}
}
vo, err := am.convertValueObjects()
if err != nil {
return nil, errors.Wrap(err, op)
}
oplogWrapper, err := r.kms.GetWrapper(ctx, am.ScopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
}
databaseWrapper, err := r.kms.GetWrapper(context.Background(), am.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
}
if err := am.encrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op)
}
var returnedAuthMethod *AuthMethod
_, err = r.writer.DoTx(
ctx,
db.StdRetryCnt,
db.ExpBackoff{},
func(_ db.Reader, w db.Writer) error {
msgs := make([]*oplog.Message, 0, 5)
ticket, err := w.GetTicket(am)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
}
returnedAuthMethod = am.Clone()
var amOplogMsg oplog.Message
if err := w.Create(ctx, returnedAuthMethod, db.NewOplogMsg(&amOplogMsg)); err != nil {
return err
}
msgs = append(msgs, &amOplogMsg)
if len(vo.Algs) > 0 {
algOplogMsgs := make([]*oplog.Message, 0, len(vo.Algs))
if err := w.CreateItems(ctx, vo.Algs, db.NewOplogMsgs(&algOplogMsgs)); err != nil {
return err
}
msgs = append(msgs, algOplogMsgs...)
}
if len(vo.Auds) > 0 {
audOplogMsgs := make([]*oplog.Message, 0, len(vo.Auds))
if err := w.CreateItems(ctx, vo.Auds, db.NewOplogMsgs(&audOplogMsgs)); err != nil {
return err
}
msgs = append(msgs, audOplogMsgs...)
}
if len(vo.Certs) > 0 {
certOplogMsgs := make([]*oplog.Message, 0, len(vo.Certs))
if err := w.CreateItems(ctx, vo.Certs, db.NewOplogMsgs(&certOplogMsgs)); err != nil {
return err
}
msgs = append(msgs, certOplogMsgs...)
}
if len(vo.ClaimsScopes) > 0 {
scopesOplogMsgs := make([]*oplog.Message, 0, len(vo.ClaimsScopes))
if err := w.CreateItems(ctx, vo.ClaimsScopes, db.NewOplogMsgs(&scopesOplogMsgs)); err != nil {
return err
}
msgs = append(msgs, scopesOplogMsgs...)
}
if len(vo.AccountClaimMaps) > 0 {
accountClaimMapsOplogMsgs := make([]*oplog.Message, 0, len(vo.AccountClaimMaps))
if err := w.CreateItems(ctx, vo.AccountClaimMaps, db.NewOplogMsgs(&accountClaimMapsOplogMsgs)); err != nil {
return err
}
msgs = append(msgs, accountClaimMapsOplogMsgs...)
}
metadata := am.oplog(oplog.OpType_OP_TYPE_CREATE)
if err := w.WriteOplogEntryWith(ctx, oplogWrapper, ticket, metadata, msgs); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog"))
}
return nil
},
)
if err != nil {
return nil, errors.Wrap(err, op)
}
return returnedAuthMethod, nil
}