Update primary error functions to take a context, deprecate old functions (#1358)

* add new error funcs which take a ctx and deprecate existing funcs

* use context where available when writing error events

* remove circular internal/errors pkg dep

* suppress some chatty errors using errors.WithoutEvent()

* convert auth oidc funcs to take context where needed to write events

Co-authored-by: Jim <jlambert@hashicorp.com>
This commit is contained in:
s-christoffandJim authored and GitHub committed 2021-07-29 20:52:56 -04:00
1 parent 02ff2db66e
commit 6b78108ecf
227 files changed
+3945 -3736

No files matched your search

+9 -8
View File
@@ -1,6 +1,7 @@
package oidc
import (
"context"
"net/url"
"github.com/hashicorp/boundary/internal/auth/oidc/store"
@@ -40,7 +41,7 @@ type Account struct {
// value being unique
//
// See: https://openid.net/specs/openid-connect-core-1_0.html
func NewAccount(authMethodId string, subject string, opt ...Option) (*Account, error) {
func NewAccount(ctx context.Context, authMethodId string, subject string, opt ...Option) (*Account, error) {
const op = "oidc.NewAccount"
opts := getOpts(opt...)
a := &Account{
@@ -56,7 +57,7 @@ func NewAccount(authMethodId string, subject string, opt ...Option) (*Account, e
if opts.withIssuer != nil {
a.Issuer = opts.withIssuer.String()
}
if err := a.validate(op); err != nil {
if err := a.validate(ctx, op); err != nil {
return nil, err // intentionally not wrapped.
}
@@ -64,21 +65,21 @@ func NewAccount(authMethodId string, subject string, opt ...Option) (*Account, e
}
// validate the Account. On success, it will return nil.
func (a *Account) validate(caller errors.Op) error {
func (a *Account) validate(ctx context.Context, caller errors.Op) error {
if a.AuthMethodId == "" {
return errors.New(errors.InvalidParameter, caller, "missing auth method id")
return errors.New(ctx, errors.InvalidParameter, caller, "missing auth method id")
}
if a.Subject == "" {
return errors.New(errors.InvalidParameter, caller, "missing subject")
return errors.New(ctx, errors.InvalidParameter, caller, "missing subject")
}
if _, err := url.Parse(a.Issuer); a.Issuer != "" && err != nil {
return errors.New(errors.InvalidParameter, caller, "not a valid issuer", errors.WithWrap(err))
return errors.New(ctx, errors.InvalidParameter, caller, "not a valid issuer", errors.WithWrap(err))
}
if a.Email != "" && len(a.Email) > 320 {
return errors.New(errors.InvalidParameter, caller, "email address is too long")
return errors.New(ctx, errors.InvalidParameter, caller, "email address is too long")
}
if a.FullName != "" && len(a.FullName) > 512 {
return errors.New(errors.InvalidParameter, caller, "full name is too long")
return errors.New(ctx, errors.InvalidParameter, caller, "full name is too long")
}
return nil
}
+10 -9
View File
@@ -1,6 +1,7 @@
package oidc
import (
"context"
"fmt"
"github.com/hashicorp/boundary/internal/auth/oidc/store"
@@ -21,7 +22,7 @@ const (
ToNameClaim AccountToClaim = "name"
)
func ConvertToAccountToClaim(s string) (AccountToClaim, error) {
func ConvertToAccountToClaim(ctx context.Context, s string) (AccountToClaim, error) {
const op = "oidc.(AccountToClaim).convertToAccountToClaim"
switch s {
case string(ToSubClaim):
@@ -31,7 +32,7 @@ func ConvertToAccountToClaim(s string) (AccountToClaim, error) {
case string(ToNameClaim):
return ToNameClaim, nil
default:
return "", errors.New(errors.InvalidParameter, op, fmt.Sprintf("%s is not a valid ToAccountClaim value", s))
return "", errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("%s is not a valid ToAccountClaim value", s))
}
}
@@ -42,7 +43,7 @@ type AccountClaimMap struct {
tableName string
}
func NewAccountClaimMap(authMethodId, fromClaim string, toClaim AccountToClaim) (*AccountClaimMap, error) {
func NewAccountClaimMap(ctx context.Context, authMethodId, fromClaim string, toClaim AccountToClaim) (*AccountClaimMap, error) {
const op = "oidc.NewAccountClaimMap"
cs := &AccountClaimMap{
AccountClaimMap: &store.AccountClaimMap{
@@ -51,22 +52,22 @@ func NewAccountClaimMap(authMethodId, fromClaim string, toClaim AccountToClaim)
ToClaim: string(toClaim),
},
}
if err := cs.validate(op); err != nil {
if err := cs.validate(ctx, op); err != nil {
return nil, err
}
return cs, nil
}
// validate the AccountClaimMap. On success, it will return nil.
func (cs *AccountClaimMap) validate(caller errors.Op) error {
func (cs *AccountClaimMap) validate(ctx context.Context, caller errors.Op) error {
if cs.OidcMethodId == "" {
return errors.New(errors.InvalidParameter, caller, "missing oidc auth method id")
return errors.New(ctx, errors.InvalidParameter, caller, "missing oidc auth method id")
}
if cs.FromClaim == "" {
return errors.New(errors.InvalidParameter, caller, "missing from claim")
return errors.New(ctx, errors.InvalidParameter, caller, "missing from claim")
}
if _, err := ConvertToAccountToClaim(cs.ToClaim); err != nil {
return errors.Wrap(err, caller)
if _, err := ConvertToAccountToClaim(ctx, cs.ToClaim); err != nil {
return errors.Wrap(ctx, err, caller)
}
return nil
}
+5 -5
View File
@@ -108,7 +108,7 @@ func TestAccountClaimMap_Create(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
got, err := NewAccountClaimMap(tt.args.authMethodId, tt.args.from, tt.args.to)
got, err := NewAccountClaimMap(context.TODO(), tt.args.authMethodId, tt.args.from, tt.args.to)
if tt.wantErr {
require.Error(err)
assert.True(errors.Match(errors.T(tt.wantIsErr), err))
@@ -150,7 +150,7 @@ func TestAccountClaimMap_Delete(t *testing.T) {
WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]), WithAudClaims("alice.com")) // seed an extra callback url to just make sure the delete only gets the right num of rows
testResource := func(authMethodId string, fromClaim string, toClaim AccountToClaim) *AccountClaimMap {
c, err := NewAccountClaimMap(authMethodId, fromClaim, toClaim)
c, err := NewAccountClaimMap(context.TODO(), authMethodId, fromClaim, toClaim)
require.NoError(t, err)
return c
}
@@ -228,7 +228,7 @@ func TestAccountClaimMap_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewAccountClaimMap(m.PublicId, "oid", ToSubClaim)
orig, err := NewAccountClaimMap(context.TODO(), m.PublicId, "oid", ToSubClaim)
require.NoError(err)
cp := orig.Clone()
assert.True(proto.Equal(cp.AccountClaimMap, orig.AccountClaimMap))
@@ -240,9 +240,9 @@ func TestAccountClaimMap_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewAccountClaimMap(m.PublicId, "oid", ToSubClaim)
orig, err := NewAccountClaimMap(context.TODO(), m.PublicId, "oid", ToSubClaim)
require.NoError(err)
orig2, err := NewAccountClaimMap(m.PublicId, "uid", ToSubClaim)
orig2, err := NewAccountClaimMap(context.TODO(), m.PublicId, "uid", ToSubClaim)
require.NoError(err)
cp := orig.Clone()
+17 -14
View File
@@ -17,6 +17,7 @@ import (
func TestAccount_Create(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -53,7 +54,7 @@ func TestAccount_Create(t *testing.T) {
},
create: true,
want: func() *Account {
want, err := NewAccount(testAuthMethod.PublicId, "alice", WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithEmail("alice@alice.com"), WithFullName("Alice Eve Smith"), WithName("alice's restuarant"), WithDescription("A good place to eat"))
want, err := NewAccount(ctx, testAuthMethod.PublicId, "alice", WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithEmail("alice@alice.com"), WithFullName("Alice Eve Smith"), WithName("alice's restuarant"), WithDescription("A good place to eat"))
require.NoError(t, err)
return want
}(),
@@ -67,7 +68,7 @@ func TestAccount_Create(t *testing.T) {
},
create: true,
want: func() *Account {
want, err := NewAccount(testAuthMethod.PublicId, "alice", WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithEmail("alice@alice.com"), WithFullName("Alice Eve Smith"), WithName("alice's restuarant"), WithDescription("A good place to eat"))
want, err := NewAccount(ctx, testAuthMethod.PublicId, "alice", WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithEmail("alice@alice.com"), WithFullName("Alice Eve Smith"), WithName("alice's restuarant"), WithDescription("A good place to eat"))
require.NoError(t, err)
return want
}(),
@@ -83,7 +84,7 @@ func TestAccount_Create(t *testing.T) {
},
create: true,
want: func() *Account {
want, err := NewAccount(testAuthMethod.PublicId, "newsubject", WithIssuer(TestConvertToUrls(t, "https://somethingelse.com")[0]))
want, err := NewAccount(ctx, testAuthMethod.PublicId, "newsubject", WithIssuer(TestConvertToUrls(t, "https://somethingelse.com")[0]))
require.NoError(t, err)
return want
}(),
@@ -135,7 +136,7 @@ func TestAccount_Create(t *testing.T) {
},
create: true,
want: func() *Account {
want, err := NewAccount(testAuthMethod.PublicId, "alice", WithIssuer(&url.URL{}))
want, err := NewAccount(ctx, testAuthMethod.PublicId, "alice", WithIssuer(&url.URL{}))
require.NoError(t, err)
return want
}(),
@@ -150,7 +151,7 @@ func TestAccount_Create(t *testing.T) {
},
create: true,
want: func() *Account {
want, err := NewAccount(testAuthMethod.PublicId, "alice")
want, err := NewAccount(ctx, testAuthMethod.PublicId, "alice")
require.NoError(t, err)
return want
}(),
@@ -161,7 +162,7 @@ func TestAccount_Create(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
got, err := NewAccount(tt.args.authMethodId, tt.args.subject, tt.args.opts...)
got, err := NewAccount(ctx, tt.args.authMethodId, tt.args.subject, tt.args.opts...)
if tt.wantErr {
require.Error(err)
assert.True(errors.Match(errors.T(tt.wantIsErr), err))
@@ -171,7 +172,7 @@ func TestAccount_Create(t *testing.T) {
assert.Equal(tt.want, got)
if tt.create {
ctx := context.Background()
id, err := newAccountId(testAuthMethod.GetPublicId(), testAuthMethod.GetIssuer(), tt.args.subject)
id, err := newAccountId(ctx, testAuthMethod.GetPublicId(), testAuthMethod.GetIssuer(), tt.args.subject)
require.NoError(err)
got.PublicId = id
err = rw.Create(ctx, got)
@@ -194,9 +195,9 @@ func TestAccount_Create(t *testing.T) {
t.Run("account issuer stays when auth method discovery url changes", func(t *testing.T) {
am := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "client", "secret",
WithIssuer(TestConvertToUrls(t, "https://discovery.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
a, err := NewAccount(am.GetPublicId(), "subject", WithIssuer(TestConvertToUrls(t, am.GetIssuer())[0]))
a, err := NewAccount(ctx, am.GetPublicId(), "subject", WithIssuer(TestConvertToUrls(t, am.GetIssuer())[0]))
require.NoError(t, err)
id, err := newAccountId(am.GetPublicId(), am.GetIssuer(), a.GetSubject())
id, err := newAccountId(ctx, am.GetPublicId(), am.GetIssuer(), a.GetSubject())
require.NoError(t, err)
a.PublicId = id
ctx := context.Background()
@@ -218,6 +219,7 @@ func TestAccount_Create(t *testing.T) {
func TestAccount_Delete(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -242,9 +244,9 @@ func TestAccount_Delete(t *testing.T) {
testResource := func(authMethodId string, subject string) *Account {
u, err := url.Parse(testAuthMethod.GetIssuer())
require.NoError(t, err)
a, err := NewAccount(authMethodId, subject, WithIssuer(u))
a, err := NewAccount(ctx, authMethodId, subject, WithIssuer(u))
require.NoError(t, err)
id, err := newAccountId(testAuthMethod.GetPublicId(), testAuthMethod.GetIssuer(), subject)
id, err := newAccountId(ctx, testAuthMethod.GetPublicId(), testAuthMethod.GetIssuer(), subject)
require.NoError(t, err)
a.PublicId = id
return a
@@ -307,6 +309,7 @@ func TestAccount_Delete(t *testing.T) {
func TestAccount_Clone(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -318,7 +321,7 @@ func TestAccount_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewAccount(m.PublicId, "alice", WithFullName("Alice Eve Smith"), WithEmail("alice@alice.com"))
orig, err := NewAccount(ctx, m.PublicId, "alice", WithFullName("Alice Eve Smith"), WithEmail("alice@alice.com"))
require.NoError(err)
cp := orig.Clone()
assert.True(proto.Equal(cp.Account, orig.Account))
@@ -330,9 +333,9 @@ func TestAccount_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewAccount(m.PublicId, "alice", WithFullName("Alice Eve Smith"), WithEmail("alice@alice.com"))
orig, err := NewAccount(ctx, m.PublicId, "alice", WithFullName("Alice Eve Smith"), WithEmail("alice@alice.com"))
require.NoError(err)
orig2, err := NewAccount(m.PublicId, "bob", WithFullName("Bob Eve Smith"), WithEmail("bob@alice.com"))
orig2, err := NewAccount(ctx, m.PublicId, "bob", WithFullName("Bob Eve Smith"), WithEmail("bob@alice.com"))
require.NoError(err)
cp := orig.Clone()
+7 -5
View File
@@ -1,6 +1,8 @@
package oidc
import (
"context"
"github.com/hashicorp/boundary/internal/auth/oidc/store"
"github.com/hashicorp/boundary/internal/errors"
"google.golang.org/protobuf/proto"
@@ -29,7 +31,7 @@ type AudClaim struct {
//
// For more info on oidc aud claims, see the oidc spec:
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
func NewAudClaim(authMethodId string, audClaim string) (*AudClaim, error) {
func NewAudClaim(ctx context.Context, authMethodId string, audClaim string) (*AudClaim, error) {
const op = "oidc.NewAudClaim"
c := &AudClaim{
@@ -38,19 +40,19 @@ func NewAudClaim(authMethodId string, audClaim string) (*AudClaim, error) {
Aud: audClaim,
},
}
if err := c.validate(op); err != nil {
if err := c.validate(ctx, op); err != nil {
return nil, err // intentionally not wrapped
}
return c, nil
}
// validate the AudClaim. On success, it will return nil.
func (a *AudClaim) validate(caller errors.Op) error {
func (a *AudClaim) validate(ctx context.Context, caller errors.Op) error {
if a.OidcMethodId == "" {
return errors.New(errors.InvalidParameter, caller, "missing oidc auth method id")
return errors.New(ctx, errors.InvalidParameter, caller, "missing oidc auth method id")
}
if a.Aud == "" {
return errors.New(errors.InvalidParameter, caller, "missing aud claim")
return errors.New(ctx, errors.InvalidParameter, caller, "missing aud claim")
}
return nil
}
+8 -5
View File
@@ -15,6 +15,7 @@ import (
func TestAudClaim_Create(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -93,7 +94,7 @@ func TestAudClaim_Create(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
got, err := NewAudClaim(tt.args.authMethodId, tt.args.aud)
got, err := NewAudClaim(ctx, tt.args.authMethodId, tt.args.aud)
if tt.wantErr {
require.Error(err)
assert.True(errors.Match(errors.T(tt.wantIsErr), err))
@@ -121,6 +122,7 @@ func TestAudClaim_Create(t *testing.T) {
func TestAudClaim_Delete(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -135,7 +137,7 @@ func TestAudClaim_Delete(t *testing.T) {
WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]), WithAudClaims("alice.com")) // seed an extra callback url to just make sure the delete only gets the right num of rows
testResource := func(authMethodId string, AudClaim string) *AudClaim {
c, err := NewAudClaim(authMethodId, AudClaim)
c, err := NewAudClaim(ctx, authMethodId, AudClaim)
require.NoError(t, err)
return c
}
@@ -198,6 +200,7 @@ func TestAudClaim_Delete(t *testing.T) {
func TestAudClaim_Clone(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -209,7 +212,7 @@ func TestAudClaim_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewAudClaim(m.PublicId, "eve.com")
orig, err := NewAudClaim(ctx, m.PublicId, "eve.com")
require.NoError(err)
cp := orig.Clone()
assert.True(proto.Equal(cp.AudClaim, orig.AudClaim))
@@ -221,9 +224,9 @@ func TestAudClaim_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewAudClaim(m.PublicId, "eve.com")
orig, err := NewAudClaim(ctx, m.PublicId, "eve.com")
require.NoError(err)
orig2, err := NewAudClaim(m.PublicId, "alice.com")
orig2, err := NewAudClaim(ctx, m.PublicId, "alice.com")
require.NoError(err)
cp := orig.Clone()
+68 -69
View File
@@ -63,9 +63,8 @@ type AuthMethod struct {
//
// Supports the options of WithMaxAge, WithSigningAlgs, WithAudClaims,
// WithApiUrl and WithCertificates and all other options are ignored.
func NewAuthMethod(scopeId string, clientId string, clientSecret ClientSecret, opt ...Option) (*AuthMethod, error) {
func NewAuthMethod(ctx context.Context, scopeId string, clientId string, clientSecret ClientSecret, opt ...Option) (*AuthMethod, error) {
const op = "oidc.NewAuthMethod"
opts := getOpts(opt...)
var u string
switch {
@@ -96,9 +95,9 @@ func NewAuthMethod(scopeId string, clientId string, clientSecret ClientSecret, o
}
if len(opts.withCertificates) > 0 {
a.Certificates = make([]string, 0, len(opts.withCertificates))
pem, err := EncodeCertificates(opts.withCertificates...)
pem, err := EncodeCertificates(ctx, opts.withCertificates...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
a.Certificates = append(a.Certificates, pem...)
@@ -116,16 +115,16 @@ func NewAuthMethod(scopeId string, clientId string, clientSecret ClientSecret, o
}
}
if a.OperationalState != string(InactiveState) {
if err := a.isComplete(); err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("new auth method being created with incomplete data but non-inactive state"))
if err := a.isComplete(ctx); err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("new auth method being created with incomplete data but non-inactive state"))
}
}
if err := a.validate(op); err != nil {
if err := a.validate(ctx, op); err != nil {
return nil, err // intentionally not wrapped.
}
if a.ClientSecretHmac != "" {
return nil, errors.New(errors.InvalidParameter, op, "client secret hmac should be empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "client secret hmac should be empty")
}
return a, nil
}
@@ -141,25 +140,25 @@ func NewAuthMethod(scopeId string, clientId string, clientSecret ClientSecret, o
// Also, you can't enforce that MaxAge can't equal zero, since the zero value ==
// NULL in the database and that's what you want if it's unset. A db constraint
// will enforce that MaxAge is either -1, NULL or greater than zero.
func (a *AuthMethod) validate(caller errors.Op) error {
func (a *AuthMethod) validate(ctx context.Context, caller errors.Op) error {
if a.ScopeId == "" {
return errors.New(errors.InvalidParameter, caller, "missing scope id")
return errors.New(ctx, errors.InvalidParameter, caller, "missing scope id")
}
if !validState(a.OperationalState) {
return errors.New(errors.InvalidParameter, caller, fmt.Sprintf("invalid state: %s", a.OperationalState))
return errors.New(ctx, errors.InvalidParameter, caller, fmt.Sprintf("invalid state: %s", a.OperationalState))
}
if a.Issuer != "" {
if _, err := url.Parse(a.Issuer); err != nil {
return errors.New(errors.InvalidParameter, caller, "not a valid issuer", errors.WithWrap(err))
return errors.New(ctx, errors.InvalidParameter, caller, "not a valid issuer", errors.WithWrap(err))
}
}
if a.ApiUrl != "" {
if _, err := url.Parse(a.ApiUrl); err != nil {
return errors.New(errors.InvalidParameter, caller, "not a valid api url", errors.WithWrap(err))
return errors.New(ctx, errors.InvalidParameter, caller, "not a valid api url", errors.WithWrap(err))
}
}
if a.MaxAge < -1 {
return errors.New(errors.InvalidParameter, caller, "max age cannot be less than -1")
return errors.New(ctx, errors.InvalidParameter, caller, "max age cannot be less than -1")
}
return nil
}
@@ -207,14 +206,14 @@ func (a *AuthMethod) oplog(op oplog.OpType) oplog.Metadata {
func (a *AuthMethod) encrypt(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "oidc.(AuthMethod).encrypt"
if cipher == nil {
return errors.New(errors.InvalidParameter, op, "missing cipher")
return errors.New(ctx, errors.InvalidParameter, op, "missing cipher")
}
if err := structwrapping.WrapStruct(ctx, cipher, a.AuthMethod, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Encrypt))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt))
}
a.KeyId = cipher.KeyID()
if err := a.hmacClientSecret(ctx, cipher); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -223,10 +222,10 @@ func (a *AuthMethod) encrypt(ctx context.Context, cipher wrapping.Wrapper) error
func (a *AuthMethod) decrypt(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "oidc.(AuthMethod).decrypt"
if cipher == nil {
return errors.New(errors.InvalidParameter, op, "missing cipher")
return errors.New(ctx, errors.InvalidParameter, op, "missing cipher")
}
if err := structwrapping.UnwrapStruct(ctx, cipher, a.AuthMethod, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt))
}
return nil
}
@@ -235,15 +234,15 @@ func (a *AuthMethod) decrypt(ctx context.Context, cipher wrapping.Wrapper) error
func (a *AuthMethod) hmacClientSecret(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "oidc.(AuthMethod).hmacClientSecret"
if cipher == nil {
return errors.New(errors.InvalidParameter, op, "missing cipher")
return errors.New(ctx, errors.InvalidParameter, op, "missing cipher")
}
reader, err := kms.NewDerivedReader(cipher, 32, []byte(a.PublicId), nil)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
key, _, err := ed25519.GenerateKey(reader)
if err != nil {
return errors.New(errors.Encrypt, op, "unable to generate derived key")
return errors.New(ctx, errors.Encrypt, op, "unable to generate derived key")
}
mac := hmac.New(sha256.New, key)
_, _ = mac.Write([]byte(a.ClientSecret))
@@ -253,26 +252,26 @@ func (a *AuthMethod) hmacClientSecret(ctx context.Context, cipher wrapping.Wrapp
// isComplete() checks the auth method to see if it has all the required
// components of a complete/valid oidc auth method.
func (am *AuthMethod) isComplete() error {
func (am *AuthMethod) isComplete(ctx context.Context) error {
const op = "oidc.(AuthMethod).isComplete"
var result *multierror.Error
if err := am.validate(op); err != nil {
result = multierror.Append(result, errors.Wrap(err, op))
if err := am.validate(ctx, op); err != nil {
result = multierror.Append(result, errors.Wrap(ctx, err, op))
}
if am.Issuer == "" {
result = multierror.Append(result, errors.New(errors.InvalidParameter, op, "missing issuer"))
result = multierror.Append(result, errors.New(ctx, errors.InvalidParameter, op, "missing issuer"))
}
if am.ApiUrl == "" {
result = multierror.Append(result, errors.New(errors.InvalidParameter, op, "missing api url"))
result = multierror.Append(result, errors.New(ctx, errors.InvalidParameter, op, "missing api url"))
}
if am.ClientId == "" {
result = multierror.Append(result, errors.New(errors.InvalidParameter, op, "missing client id"))
result = multierror.Append(result, errors.New(ctx, errors.InvalidParameter, op, "missing client id"))
}
if am.ClientSecret == "" {
result = multierror.Append(result, errors.New(errors.InvalidParameter, op, "missing client secret"))
result = multierror.Append(result, errors.New(ctx, errors.InvalidParameter, op, "missing client secret"))
}
if len(am.SigningAlgs) == 0 {
result = multierror.Append(result, errors.New(errors.InvalidParameter, op, "missing signing algorithms"))
result = multierror.Append(result, errors.New(ctx, errors.InvalidParameter, op, "missing signing algorithms"))
}
return result.ErrorOrNil()
}
@@ -287,27 +286,27 @@ type convertedValues struct {
// convertValueObjects converts the embedded value objects. It will return an
// error if the AuthMethod's public id is not set.
func (am *AuthMethod) convertValueObjects() (*convertedValues, error) {
func (am *AuthMethod) convertValueObjects(ctx context.Context) (*convertedValues, error) {
const op = "oidc.(AuthMethod).valueObjects"
if am.PublicId == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
var err error
var addAlgs, addAuds, addCerts, addScopes, addAccountClaimMaps []interface{}
if addAlgs, err = am.convertSigningAlgs(); err != nil {
return nil, errors.Wrap(err, op)
if addAlgs, err = am.convertSigningAlgs(ctx); err != nil {
return nil, errors.Wrap(ctx, err, op)
}
if addAuds, err = am.convertAudClaims(); err != nil {
return nil, errors.Wrap(err, op)
if addAuds, err = am.convertAudClaims(ctx); err != nil {
return nil, errors.Wrap(ctx, err, op)
}
if addCerts, err = am.convertCertificates(); err != nil {
return nil, errors.Wrap(err, op)
if addCerts, err = am.convertCertificates(ctx); err != nil {
return nil, errors.Wrap(ctx, err, op)
}
if addScopes, err = am.convertClaimsScopes(); err != nil {
return nil, errors.Wrap(err, op)
if addScopes, err = am.convertClaimsScopes(ctx); err != nil {
return nil, errors.Wrap(ctx, err, op)
}
if addAccountClaimMaps, err = am.convertAccountClaimMaps(); err != nil {
return nil, errors.Wrap(err, op)
if addAccountClaimMaps, err = am.convertAccountClaimMaps(ctx); err != nil {
return nil, errors.Wrap(ctx, err, op)
}
return &convertedValues{
Algs: addAlgs,
@@ -321,16 +320,16 @@ func (am *AuthMethod) convertValueObjects() (*convertedValues, error) {
// convertSigningAlgs converts the embedded signing algorithms from []string
// to []interface{} where each slice element is a *SigningAlg. It will return an
// error if the AuthMethod's public id is not set.
func (am *AuthMethod) convertSigningAlgs() ([]interface{}, error) {
func (am *AuthMethod) convertSigningAlgs(ctx context.Context) ([]interface{}, error) {
const op = "oidc.(AuthMethod).convertSigningAlgs"
if am.PublicId == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
newInterfaces := make([]interface{}, 0, len(am.SigningAlgs))
for _, a := range am.SigningAlgs {
obj, err := NewSigningAlg(am.PublicId, Alg(a))
obj, err := NewSigningAlg(ctx, am.PublicId, Alg(a))
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
newInterfaces = append(newInterfaces, obj)
}
@@ -340,16 +339,16 @@ func (am *AuthMethod) convertSigningAlgs() ([]interface{}, error) {
// convertAudClaims converts the embedded audience claims from []string
// to []interface{} where each slice element is a *AudClaim. It will return an
// error if the AuthMethod's public id is not set.
func (am *AuthMethod) convertAudClaims() ([]interface{}, error) {
func (am *AuthMethod) convertAudClaims(ctx context.Context) ([]interface{}, error) {
const op = "oidc.(AuthMethod).convertAudClaims"
if am.PublicId == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
newInterfaces := make([]interface{}, 0, len(am.AudClaims))
for _, a := range am.AudClaims {
obj, err := NewAudClaim(am.PublicId, a)
obj, err := NewAudClaim(ctx, am.PublicId, a)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
newInterfaces = append(newInterfaces, obj)
}
@@ -359,16 +358,16 @@ func (am *AuthMethod) convertAudClaims() ([]interface{}, error) {
// convertCertificates converts the embedded certificates from []string
// to []interface{} where each slice element is a *Certificate. It will return an
// error if the AuthMethod's public id is not set.
func (am *AuthMethod) convertCertificates() ([]interface{}, error) {
func (am *AuthMethod) convertCertificates(ctx context.Context) ([]interface{}, error) {
const op = "oidc.(AuthMethod).convertCertificates"
if am.PublicId == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
newInterfaces := make([]interface{}, 0, len(am.Certificates))
for _, cert := range am.Certificates {
obj, err := NewCertificate(am.PublicId, cert)
obj, err := NewCertificate(ctx, am.PublicId, cert)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
newInterfaces = append(newInterfaces, obj)
}
@@ -378,16 +377,16 @@ func (am *AuthMethod) convertCertificates() ([]interface{}, error) {
// convertClaimsScopes converts the embedded claims scopes from []string
// to []interface{} where each slice element is a *ClaimsScope. It will return an
// error if the AuthMethod's public id is not set.
func (am *AuthMethod) convertClaimsScopes() ([]interface{}, error) {
func (am *AuthMethod) convertClaimsScopes(ctx context.Context) ([]interface{}, error) {
const op = "oidc.(AuthMethod).convertClaimsScopes"
if am.PublicId == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
newInterfaces := make([]interface{}, 0, len(am.ClaimsScopes))
for _, cs := range am.ClaimsScopes {
obj, err := NewClaimsScope(am.PublicId, cs)
obj, err := NewClaimsScope(ctx, am.PublicId, cs)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
newInterfaces = append(newInterfaces, obj)
}
@@ -398,28 +397,28 @@ func (am *AuthMethod) convertClaimsScopes() ([]interface{}, error) {
// []string to []interface{} where each slice element is a *AccountClaimMap. It
// will return an error if the AuthMethod's public id is not set or it can
// convert the account claim maps.
func (am *AuthMethod) convertAccountClaimMaps() ([]interface{}, error) {
func (am *AuthMethod) convertAccountClaimMaps(ctx context.Context) ([]interface{}, error) {
const op = "oidc.(AuthMethod).convertAccountClaimMaps"
if am.PublicId == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
newInterfaces := make([]interface{}, 0, len(am.AccountClaimMaps))
const (
from = 0
to = 1
)
acms, err := ParseAccountClaimMaps(am.AccountClaimMaps...)
acms, err := ParseAccountClaimMaps(ctx, am.AccountClaimMaps...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
for _, m := range acms {
toClaim, err := ConvertToAccountToClaim(m.To)
toClaim, err := ConvertToAccountToClaim(ctx, m.To)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
obj, err := NewAccountClaimMap(am.PublicId, m.From, toClaim)
obj, err := NewAccountClaimMap(ctx, am.PublicId, m.From, toClaim)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
newInterfaces = append(newInterfaces, obj)
}
@@ -433,11 +432,11 @@ type ClaimMap struct {
}
// ParseAccountClaimMaps will parse the inbound claim maps
func ParseAccountClaimMaps(m ...string) ([]ClaimMap, error) {
func ParseAccountClaimMaps(ctx context.Context, m ...string) ([]ClaimMap, error) {
const op = "oidc.parseAccountClaimMaps"
var b kvbuilder.Builder
if err := b.Add(m...); err != nil {
return nil, errors.New(errors.InvalidParameter, op, "error parsing map", errors.WithWrap(err))
return nil, errors.New(ctx, errors.InvalidParameter, op, "error parsing map", errors.WithWrap(err))
}
fromKeys := make([]string, 0, len(m))
for k := range b.Map() {
@@ -450,7 +449,7 @@ func ParseAccountClaimMaps(m ...string) ([]ClaimMap, error) {
var ok bool
to, ok := b.Map()[from].(string)
if !ok {
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("account claim map %s value %q is not a string", from, b.Map()[from]))
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("account claim map %s value %q is not a string", from, b.Map()[from]))
}
claimMap = append(claimMap, ClaimMap{
To: to,
+20 -18
View File
@@ -20,6 +20,7 @@ import (
func TestAuthMethod_Create(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -243,7 +244,7 @@ func TestAuthMethod_Create(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
got, err := NewAuthMethod(tt.args.scopeId, tt.args.clientId, tt.args.clientSecret, tt.args.opt...)
got, err := NewAuthMethod(ctx, tt.args.scopeId, tt.args.clientId, tt.args.clientSecret, tt.args.opt...)
if tt.wantErr {
require.Error(err)
assert.True(errors.Match(errors.T(tt.wantIsErr), err))
@@ -258,7 +259,7 @@ func TestAuthMethod_Create(t *testing.T) {
assert.Equal(tt.want, got)
if tt.create {
ctx := context.Background()
id, err := newAuthMethodId()
id, err := newAuthMethodId(ctx)
require.NoError(err)
got.PublicId = id
err = got.encrypt(ctx, databaseWrapper)
@@ -284,21 +285,21 @@ func TestAuthMethod_Create(t *testing.T) {
func TestAuthMethod_Delete(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
org, _ := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
rw := db.New(conn)
ctx := context.Background()
databaseWrapper, err := kmsCache.GetWrapper(context.Background(), org.PublicId, kms.KeyPurposeDatabase)
require.NoError(t, err)
testResource := func(issuer string, clientId, clientSecret string) *AuthMethod {
got, err := NewAuthMethod(org.PublicId, clientId, ClientSecret(clientSecret),
got, err := NewAuthMethod(ctx, org.PublicId, clientId, ClientSecret(clientSecret),
WithIssuer(TestConvertToUrls(t, issuer)[0]), WithApiUrl(TestConvertToUrls(t, "http://api.com")[0]))
require.NoError(t, err)
id, err := newAuthMethodId()
id, err := newAuthMethodId(ctx)
require.NoError(t, err)
got.PublicId = id
err = got.encrypt(ctx, databaseWrapper)
@@ -542,12 +543,13 @@ func Test_encrypt_decrypt_hmac(t *testing.T) {
}
func Test_convertValueObjects(t *testing.T) {
ctx := context.TODO()
testPublicId := "test-id"
testAlgs := []string{string(RS256), string(RS384)}
var testSigningAlgs []interface{}
for _, a := range []Alg{RS256, RS384} {
obj, err := NewSigningAlg(testPublicId, Alg(a))
obj, err := NewSigningAlg(ctx, testPublicId, Alg(a))
require.NoError(t, err)
testSigningAlgs = append(testSigningAlgs, obj)
}
@@ -555,33 +557,33 @@ func Test_convertValueObjects(t *testing.T) {
testAuds := []string{"alice", "eve"}
var testAudiences []interface{}
for _, a := range testAuds {
obj, err := NewAudClaim(testPublicId, a)
obj, err := NewAudClaim(ctx, testPublicId, a)
require.NoError(t, err)
testAudiences = append(testAudiences, obj)
}
_, pem := testGenerateCA(t, "localhost")
testCerts := []string{pem}
c, err := NewCertificate(testPublicId, pem)
c, err := NewCertificate(ctx, testPublicId, pem)
require.NoError(t, err)
testCertificates := []interface{}{c}
testScopes := []string{"profile", "email"}
testClaimsScopes := make([]interface{}, 0, len(testScopes))
for _, s := range testScopes {
obj, err := NewClaimsScope(testPublicId, s)
obj, err := NewClaimsScope(ctx, testPublicId, s)
require.NoError(t, err)
testClaimsScopes = append(testClaimsScopes, obj)
}
testClaimMaps := []string{"oid=sub", "display_name=name"}
testAccountClaimMaps := make([]interface{}, 0, len(testClaimMaps))
acms, err := ParseAccountClaimMaps(testClaimMaps...)
acms, err := ParseAccountClaimMaps(ctx, testClaimMaps...)
require.NoError(t, err)
for _, m := range acms {
toClaim, err := ConvertToAccountToClaim(m.To)
toClaim, err := ConvertToAccountToClaim(ctx, m.To)
require.NoError(t, err)
obj, err := NewAccountClaimMap(testPublicId, m.From, toClaim)
obj, err := NewAccountClaimMap(ctx, testPublicId, m.From, toClaim)
require.NoError(t, err)
testAccountClaimMaps = append(testAccountClaimMaps, obj)
}
@@ -634,7 +636,7 @@ func Test_convertValueObjects(t *testing.T) {
},
}
convertedAlgs, err := am.convertSigningAlgs()
convertedAlgs, err := am.convertSigningAlgs(ctx)
if tt.wantErrMatch != nil {
require.Error(err)
assert.Truef(errors.Match(tt.wantErrMatch, err), "wanted err %q and got: %+v", tt.wantErrMatch.Code, err)
@@ -642,7 +644,7 @@ func Test_convertValueObjects(t *testing.T) {
assert.Equal(tt.wantValues.Algs, convertedAlgs)
}
convertedAuds, err := am.convertAudClaims()
convertedAuds, err := am.convertAudClaims(ctx)
if tt.wantErrMatch != nil {
require.Error(err)
assert.Truef(errors.Match(tt.wantErrMatch, err), "wanted err %q and got: %+v", tt.wantErrMatch.Code, err)
@@ -650,7 +652,7 @@ func Test_convertValueObjects(t *testing.T) {
assert.Equal(tt.wantValues.Auds, convertedAuds)
}
convertedCerts, err := am.convertCertificates()
convertedCerts, err := am.convertCertificates(ctx)
if tt.wantErrMatch != nil {
require.Error(err)
assert.Truef(errors.Match(tt.wantErrMatch, err), "wanted err %q and got: %+v", tt.wantErrMatch.Code, err)
@@ -658,7 +660,7 @@ func Test_convertValueObjects(t *testing.T) {
assert.Equal(tt.wantValues.Certs, convertedCerts)
}
convertedScopes, err := am.convertClaimsScopes()
convertedScopes, err := am.convertClaimsScopes(ctx)
if tt.wantErrMatch != nil {
require.Error(err)
assert.Truef(errors.Match(tt.wantErrMatch, err), "wanted err %q and got: %+v", tt.wantErrMatch.Code, err)
@@ -666,7 +668,7 @@ func Test_convertValueObjects(t *testing.T) {
assert.Equal(tt.wantValues.ClaimsScopes, convertedScopes)
}
convertedMaps, err := am.convertAccountClaimMaps()
convertedMaps, err := am.convertAccountClaimMaps(ctx)
if tt.wantErrMatch != nil {
require.Error(err)
assert.Truef(errors.Match(tt.wantErrMatch, err), "wanted err %q and got: %+v", tt.wantErrMatch.Code, err)
@@ -688,7 +690,7 @@ func Test_convertValueObjects(t *testing.T) {
assert.Equal(want, got)
}
values, err := am.convertValueObjects()
values, err := am.convertValueObjects(ctx)
if tt.wantErrMatch != nil {
require.Error(err)
assert.Truef(errors.Match(tt.wantErrMatch, err), "wanted err %q and got: %+v", tt.wantErrMatch.Code, err)
+8 -7
View File
@@ -1,6 +1,7 @@
package oidc
import (
"context"
"crypto/x509"
"encoding/pem"
"fmt"
@@ -26,7 +27,7 @@ type Certificate struct {
// NewCertificate creates a new in memory certificate assigned to and OIDC auth
// method.
func NewCertificate(authMethodId string, certificatePem string) (*Certificate, error) {
func NewCertificate(ctx context.Context, authMethodId string, certificatePem string) (*Certificate, error) {
const op = "oidc.NewCertificate"
c := &Certificate{
@@ -35,27 +36,27 @@ func NewCertificate(authMethodId string, certificatePem string) (*Certificate, e
Cert: certificatePem,
},
}
if err := c.validate(op); err != nil {
if err := c.validate(ctx, op); err != nil {
return nil, err // intentionally not wrapped
}
return c, nil
}
// validate the Certifcate and on success return nil
func (c *Certificate) validate(caller errors.Op) error {
func (c *Certificate) validate(ctx context.Context, caller errors.Op) error {
if c.OidcMethodId == "" {
return errors.New(errors.InvalidParameter, caller, "missing oidc auth method id")
return errors.New(ctx, errors.InvalidParameter, caller, "missing oidc auth method id")
}
if c.Cert == "" {
return errors.New(errors.InvalidParameter, caller, "empty cert")
return errors.New(ctx, errors.InvalidParameter, caller, "empty cert")
}
block, _ := pem.Decode([]byte(c.Cert))
if block == nil {
return errors.New(errors.InvalidParameter, caller, "failed to parse certificate PEM")
return errors.New(ctx, errors.InvalidParameter, caller, "failed to parse certificate PEM")
}
_, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return errors.New(errors.InvalidParameter, caller, fmt.Sprintf("failed to parse certificate: %s"+err.Error()), errors.WithWrap(err))
return errors.New(ctx, errors.InvalidParameter, caller, fmt.Sprintf("failed to parse certificate: %s"+err.Error()), errors.WithWrap(err))
}
return nil
}
+10 -7
View File
@@ -15,6 +15,7 @@ import (
func TestCertificate_Create(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -50,7 +51,7 @@ func TestCertificate_Create(t *testing.T) {
},
create: true,
want: func() *Certificate {
want, err := NewCertificate(testAuthMethod.PublicId, pem)
want, err := NewCertificate(ctx, testAuthMethod.PublicId, pem)
require.NoError(t, err)
return want
}(),
@@ -63,7 +64,7 @@ func TestCertificate_Create(t *testing.T) {
},
create: true,
want: func() *Certificate {
want, err := NewCertificate(testAuthMethod.PublicId, pem)
want, err := NewCertificate(ctx, testAuthMethod.PublicId, pem)
require.NoError(t, err)
return want
}(),
@@ -92,7 +93,7 @@ func TestCertificate_Create(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
got, err := NewCertificate(tt.args.authMethodId, tt.args.certificate)
got, err := NewCertificate(ctx, tt.args.authMethodId, tt.args.certificate)
if tt.wantErr {
require.Error(err)
assert.True(errors.Match(errors.T(tt.wantIsErr), err))
@@ -120,6 +121,7 @@ func TestCertificate_Create(t *testing.T) {
func TestCertificate_Delete(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -140,7 +142,7 @@ func TestCertificate_Delete(t *testing.T) {
_, pem4 := testGenerateCA(t, "localhost")
testResource := func(authMethodId string, cert string) *Certificate {
c, err := NewCertificate(authMethodId, cert)
c, err := NewCertificate(ctx, authMethodId, cert)
require.NoError(t, err)
return c
}
@@ -203,6 +205,7 @@ func TestCertificate_Delete(t *testing.T) {
func TestCertificate_Clone(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -216,7 +219,7 @@ func TestCertificate_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewCertificate(m.PublicId, pem)
orig, err := NewCertificate(ctx, m.PublicId, pem)
require.NoError(err)
cp := orig.Clone()
assert.True(proto.Equal(cp.Certificate, orig.Certificate))
@@ -228,9 +231,9 @@ func TestCertificate_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewCertificate(m.PublicId, pem)
orig, err := NewCertificate(ctx, m.PublicId, pem)
require.NoError(err)
orig2, err := NewCertificate(m.PublicId, pem2)
orig2, err := NewCertificate(ctx, m.PublicId, pem2)
require.NoError(err)
cp := orig.Clone()
+10 -9
View File
@@ -2,6 +2,7 @@ package oidc
import (
"bytes"
"context"
"crypto/x509"
"encoding/pem"
@@ -9,15 +10,15 @@ import (
)
// EncodeCertificates will encode a number of x509 certificates to PEMs.
func EncodeCertificates(certs ...*x509.Certificate) ([]string, error) {
func EncodeCertificates(ctx context.Context, certs ...*x509.Certificate) ([]string, error) {
const op = "oidc.EncodeCertificates"
if len(certs) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "no certs provided")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no certs provided")
}
var pems []string
for _, cert := range certs {
if cert == nil {
return nil, errors.New(errors.InvalidParameter, op, "nil cert")
return nil, errors.New(ctx, errors.InvalidParameter, op, "nil cert")
}
var buffer bytes.Buffer
err := pem.Encode(&buffer, &pem.Block{
@@ -25,7 +26,7 @@ func EncodeCertificates(certs ...*x509.Certificate) ([]string, error) {
Bytes: cert.Raw,
})
if err != nil {
return nil, errors.New(errors.InvalidParameter, op, "failed to encode cert: "+err.Error(), errors.WithWrap(err))
return nil, errors.New(ctx, errors.InvalidParameter, op, "failed to encode cert: "+err.Error(), errors.WithWrap(err))
}
pems = append(pems, buffer.String())
}
@@ -33,23 +34,23 @@ func EncodeCertificates(certs ...*x509.Certificate) ([]string, error) {
}
// ParseCertificates will parse a number of certificates PEMs to x509s.
func ParseCertificates(pems ...string) ([]*x509.Certificate, error) {
func ParseCertificates(ctx context.Context, pems ...string) ([]*x509.Certificate, error) {
const op = "oidc.ParseCertificates"
if len(pems) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "no PEMs provided")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no PEMs provided")
}
var certs []*x509.Certificate
for _, p := range pems {
if p == "" {
return nil, errors.New(errors.InvalidParameter, op, "empty certificate PEM")
return nil, errors.New(ctx, errors.InvalidParameter, op, "empty certificate PEM")
}
block, _ := pem.Decode([]byte(p))
if block == nil {
return nil, errors.New(errors.InvalidParameter, op, "failed to parse certificate PEM")
return nil, errors.New(ctx, errors.InvalidParameter, op, "failed to parse certificate PEM")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, errors.New(errors.InvalidParameter, op, "failed to parse certificate: "+err.Error(), errors.WithWrap(err))
return nil, errors.New(ctx, errors.InvalidParameter, op, "failed to parse certificate: "+err.Error(), errors.WithWrap(err))
}
certs = append(certs, cert)
}
+5 -2
View File
@@ -1,6 +1,7 @@
package oidc
import (
"context"
"crypto/x509"
"testing"
@@ -10,6 +11,7 @@ import (
)
func TestEncodeCertificates(t *testing.T) {
ctx := context.TODO()
tests := []struct {
name string
setup func() ([]*x509.Certificate, []string)
@@ -53,7 +55,7 @@ func TestEncodeCertificates(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
certs, pems := tt.setup()
got, err := EncodeCertificates(certs...)
got, err := EncodeCertificates(ctx, certs...)
if tt.wantErr {
require.Error(err)
assert.True(errors.Match(errors.T(tt.wantIsErr), err))
@@ -66,6 +68,7 @@ func TestEncodeCertificates(t *testing.T) {
}
func TestParseCertificates(t *testing.T) {
ctx := context.TODO()
tests := []struct {
name string
setup func() ([]*x509.Certificate, []string)
@@ -109,7 +112,7 @@ func TestParseCertificates(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
certs, pems := tt.setup()
got, err := ParseCertificates(pems...)
got, err := ParseCertificates(ctx, pems...)
if tt.wantErr {
require.Error(err)
assert.True(errors.Match(errors.T(tt.wantIsErr), err))
+8 -6
View File
@@ -1,6 +1,8 @@
package oidc
import (
"context"
"github.com/hashicorp/boundary/internal/auth/oidc/store"
"github.com/hashicorp/boundary/internal/errors"
"google.golang.org/protobuf/proto"
@@ -22,7 +24,7 @@ type ClaimsScope struct {
tableName string
}
func NewClaimsScope(authMethodId, claimsScope string) (*ClaimsScope, error) {
func NewClaimsScope(ctx context.Context, authMethodId, claimsScope string) (*ClaimsScope, error) {
const op = "oidc.NewClaimsScope"
cs := &ClaimsScope{
ClaimsScope: &store.ClaimsScope{
@@ -30,22 +32,22 @@ func NewClaimsScope(authMethodId, claimsScope string) (*ClaimsScope, error) {
Scope: claimsScope,
},
}
if err := cs.validate(op); err != nil {
if err := cs.validate(ctx, op); err != nil {
return nil, err
}
return cs, nil
}
// validate the ClaimsScope. On success, it will return nil.
func (cs *ClaimsScope) validate(caller errors.Op) error {
func (cs *ClaimsScope) validate(ctx context.Context, caller errors.Op) error {
if cs.OidcMethodId == "" {
return errors.New(errors.InvalidParameter, caller, "missing oidc auth method id")
return errors.New(ctx, errors.InvalidParameter, caller, "missing oidc auth method id")
}
if cs.Scope == "" {
return errors.New(errors.InvalidParameter, caller, "missing claims scope")
return errors.New(ctx, errors.InvalidParameter, caller, "missing claims scope")
}
if cs.Scope == DefaultClaimsScope {
return errors.New(errors.InvalidParameter, caller, "openid is the default scope and cannot be added as optional")
return errors.New(ctx, errors.InvalidParameter, caller, "openid is the default scope and cannot be added as optional")
}
return nil
}
+7 -5
View File
@@ -97,7 +97,7 @@ func TestClaimsScope_Create(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
got, err := NewClaimsScope(tt.args.authMethodId, tt.args.claimsScope)
got, err := NewClaimsScope(ctx, tt.args.authMethodId, tt.args.claimsScope)
if tt.wantErrMatch != nil {
require.Error(err)
assert.Nil(got)
@@ -123,6 +123,7 @@ func TestClaimsScope_Create(t *testing.T) {
func TestClaimsScope_Delete(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -137,7 +138,7 @@ func TestClaimsScope_Delete(t *testing.T) {
WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]), WithAudClaims("alice.com")) // seed an extra callback url to just make sure the delete only gets the right num of rows
testResource := func(authMethodId string, claimsScope string) *ClaimsScope {
c, err := NewClaimsScope(authMethodId, claimsScope)
c, err := NewClaimsScope(ctx, authMethodId, claimsScope)
require.NoError(t, err)
return c
}
@@ -200,6 +201,7 @@ func TestClaimsScope_Delete(t *testing.T) {
func TestClaimsScope_Clone(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -211,7 +213,7 @@ func TestClaimsScope_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewClaimsScope(m.PublicId, "profile")
orig, err := NewClaimsScope(ctx, m.PublicId, "profile")
require.NoError(err)
cp := orig.Clone()
assert.True(proto.Equal(cp.ClaimsScope, orig.ClaimsScope))
@@ -223,9 +225,9 @@ func TestClaimsScope_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewClaimsScope(m.PublicId, "email")
orig, err := NewClaimsScope(ctx, m.PublicId, "email")
require.NoError(err)
orig2, err := NewClaimsScope(m.PublicId, "profile")
orig2, err := NewClaimsScope(ctx, m.PublicId, "profile")
require.NoError(err)
cp := orig.Clone()
+11 -9
View File
@@ -1,6 +1,8 @@
package oidc
import (
"context"
"github.com/hashicorp/boundary/internal/auth"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/errors"
@@ -23,38 +25,38 @@ const (
Subtype = subtypes.Subtype("oidc")
)
func newAuthMethodId() (string, error) {
func newAuthMethodId(ctx context.Context) (string, error) {
const op = "oidc.newAuthMethodId"
id, err := db.NewPublicId(AuthMethodPrefix)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
return id, nil
}
func newAccountId(authMethodId, issuer, sub string) (string, error) {
func newAccountId(ctx context.Context, authMethodId, issuer, sub string) (string, error) {
const op = "oidc.newAccountId"
if authMethodId == "" {
return "", errors.New(errors.InvalidParameter, op, "missing auth method id")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
if issuer == "" {
return "", errors.New(errors.InvalidParameter, op, "missing issuer")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing issuer")
}
if sub == "" {
return "", errors.New(errors.InvalidParameter, op, "missing subject")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing subject")
}
id, err := db.NewPublicId(AccountPrefix, db.WithPrngValues([]string{authMethodId, issuer, sub}))
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
return id, nil
}
func newManagedGroupId() (string, error) {
func newManagedGroupId(ctx context.Context) (string, error) {
const op = "oidc.newManagedGroupId"
id, err := db.NewPublicId(intglobals.OidcManagedGroupPrefix)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
return id, nil
}
+4 -2
View File
@@ -1,6 +1,7 @@
package oidc
import (
"context"
"strings"
"testing"
@@ -10,13 +11,14 @@ import (
func Test_Ids(t *testing.T) {
t.Parallel()
ctx := context.TODO()
t.Run(AuthMethodPrefix, func(t *testing.T) {
id, err := newAuthMethodId()
id, err := newAuthMethodId(ctx)
require.NoError(t, err)
assert.True(t, strings.HasPrefix(id, AuthMethodPrefix+"_"))
})
t.Run(AccountPrefix, func(t *testing.T) {
id, err := newAccountId("public-id", "test-issuer", "test-subject")
id, err := newAccountId(ctx, "public-id", "test-issuer", "test-subject")
require.NoError(t, err)
assert.True(t, strings.HasPrefix(id, AccountPrefix+"_"))
})
+8 -6
View File
@@ -1,6 +1,8 @@
package oidc
import (
"context"
"github.com/hashicorp/boundary/internal/auth/oidc/store"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/oplog"
@@ -20,7 +22,7 @@ type ManagedGroup struct {
// NewManagedGroup creates a new in memory ManagedGroup assigned to OIDC
// AuthMethod. Supported options are withName and withDescription.
func NewManagedGroup(authMethodId string, filter string, opt ...Option) (*ManagedGroup, error) {
func NewManagedGroup(ctx context.Context, authMethodId string, filter string, opt ...Option) (*ManagedGroup, error) {
const op = "oidc.NewManagedGroup"
opts := getOpts(opt...)
mg := &ManagedGroup{
@@ -31,7 +33,7 @@ func NewManagedGroup(authMethodId string, filter string, opt ...Option) (*Manage
Filter: filter,
},
}
if err := mg.validate(op); err != nil {
if err := mg.validate(ctx, op); err != nil {
return nil, err // intentionally not wrapped.
}
@@ -39,15 +41,15 @@ func NewManagedGroup(authMethodId string, filter string, opt ...Option) (*Manage
}
// validate the Managed Group. On success, it will return nil.
func (mg *ManagedGroup) validate(caller errors.Op) error {
func (mg *ManagedGroup) validate(ctx context.Context, caller errors.Op) error {
if mg.AuthMethodId == "" {
return errors.New(errors.InvalidParameter, caller, "missing auth method id")
return errors.New(ctx, errors.InvalidParameter, caller, "missing auth method id")
}
if mg.Filter == "" {
return errors.New(errors.InvalidParameter, caller, "missing filter")
return errors.New(ctx, errors.InvalidParameter, caller, "missing filter")
}
if _, err := bexpr.CreateEvaluator(mg.Filter); err != nil {
return errors.New(errors.InvalidParameter, caller, "error evaluating filter expression", errors.WithWrap(err))
return errors.New(ctx, errors.InvalidParameter, caller, "error evaluating filter expression", errors.WithWrap(err))
}
return nil
@@ -1,6 +1,8 @@
package oidc
import (
"context"
"github.com/hashicorp/boundary/internal/auth/oidc/store"
"github.com/hashicorp/boundary/internal/errors"
"google.golang.org/protobuf/proto"
@@ -19,7 +21,7 @@ type ManagedGroupMemberAccount struct {
// NewManagedGroupMemberAccount creates a new in memory
// ManagedGroupMemberAccount assigned to a managed group within an OIDC
// AuthMethod. Supported options are withName and withDescription.
func NewManagedGroupMemberAccount(managedGroupId string, memberId string, opt ...Option) (*ManagedGroupMemberAccount, error) {
func NewManagedGroupMemberAccount(ctx context.Context, managedGroupId string, memberId string, opt ...Option) (*ManagedGroupMemberAccount, error) {
const op = "oidc.NewManagedGroupMemberAccount"
mg := &ManagedGroupMemberAccount{
ManagedGroupMemberAccount: &store.ManagedGroupMemberAccount{
@@ -27,7 +29,7 @@ func NewManagedGroupMemberAccount(managedGroupId string, memberId string, opt ..
MemberId: memberId,
},
}
if err := mg.validate(op); err != nil {
if err := mg.validate(ctx, op); err != nil {
return nil, err // intentionally not wrapped.
}
@@ -35,12 +37,12 @@ func NewManagedGroupMemberAccount(managedGroupId string, memberId string, opt ..
}
// validate the ManagedGroupMemberAccount. On success, it will return nil.
func (mg *ManagedGroupMemberAccount) validate(caller errors.Op) error {
func (mg *ManagedGroupMemberAccount) validate(ctx context.Context, caller errors.Op) error {
if mg.ManagedGroupId == "" {
return errors.New(errors.InvalidParameter, caller, "missing managed group id")
return errors.New(ctx, errors.InvalidParameter, caller, "missing managed group id")
}
if mg.MemberId == "" {
return errors.New(errors.InvalidParameter, caller, "missing member id")
return errors.New(ctx, errors.InvalidParameter, caller, "missing member id")
}
return nil
+6 -4
View File
@@ -1,6 +1,7 @@
package oidc
import (
"context"
"testing"
"github.com/hashicorp/boundary/internal/errors"
@@ -9,24 +10,25 @@ import (
func Test_ManagedGroups_RepoValidate(t *testing.T) {
t.Parallel()
ctx := context.TODO()
assert := assert.New(t)
const op = "test"
mg := AllocManagedGroup()
t.Run("empty auth method", func(t *testing.T) {
assert.Contains(mg.validate(op).Error(), errors.New(errors.InvalidParameter, op, "missing auth method id").Error())
assert.Contains(mg.validate(ctx, op).Error(), errors.New(ctx, errors.InvalidParameter, op, "missing auth method id").Error(), errors.WithoutEvent())
})
t.Run("empty filter", func(t *testing.T) {
mg.AuthMethodId = "amoidc_1234567890"
assert.Contains(mg.validate(op).Error(), errors.New(errors.InvalidParameter, op, "missing filter").Error())
assert.Contains(mg.validate(ctx, op).Error(), errors.New(ctx, errors.InvalidParameter, op, "missing filter").Error(), errors.WithoutEvent())
})
t.Run("bad filter", func(t *testing.T) {
mg.AuthMethodId = "amoidc_1234567890"
mg.Filter = "foobar"
assert.Contains(mg.validate(op).Error(), errors.New(errors.InvalidParameter, op, "error evaluating filter expression").Error())
assert.Contains(mg.validate(ctx, op).Error(), errors.New(ctx, errors.InvalidParameter, op, "error evaluating filter expression").Error(), errors.WithoutEvent())
})
t.Run("valid", func(t *testing.T) {
mg.AuthMethodId = "amoidc_1234567890"
mg.Filter = TestFakeManagedGroupFilter
assert.NoError(mg.validate(op))
assert.NoError(mg.validate(ctx, op))
})
}
+8 -8
View File
@@ -58,7 +58,7 @@ func (c *providers) get(ctx context.Context, currentFromDb *AuthMethod) (*oidc.P
const op = "oidc.(providers).getProvider"
storedProvider, err := convertToProvider(ctx, currentFromDb)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
c.mu.RLock()
p, ok := c.cache[currentFromDb.PublicId]
@@ -66,11 +66,11 @@ func (c *providers) get(ctx context.Context, currentFromDb *AuthMethod) (*oidc.P
if ok {
cachedHash, err := p.ConfigHash()
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to hash provider from cache"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to hash provider from cache"))
}
storedHash, err := storedProvider.ConfigHash()
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to hash provider from database"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to hash provider from database"))
}
switch cachedHash == storedHash {
case true:
@@ -100,10 +100,10 @@ func (c *providers) delete(ctx context.Context, authMethodId string) {
func convertToProvider(ctx context.Context, am *AuthMethod) (*oidc.Provider, error) {
const op = "oidc.convertToProvider"
if am == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method")
}
if err := am.isComplete(); err != nil {
return nil, errors.Wrap(err, op)
if err := am.isComplete(ctx); err != nil {
return nil, errors.Wrap(ctx, err, op)
}
algs := make([]oidc.Alg, 0, len(am.SigningAlgs))
for _, a := range am.SigningAlgs {
@@ -119,11 +119,11 @@ func convertToProvider(ctx context.Context, am *AuthMethod) (*oidc.Provider, err
oidc.WithProviderCA(strings.Join(am.Certificates, "\n")),
)
if err != nil {
return nil, errors.New(errors.InvalidParameter, op, "AuthMethod cannot be converted to a valid OIDC Provider Configuration", errors.WithWrap(err))
return nil, errors.New(ctx, errors.InvalidParameter, op, "AuthMethod cannot be converted to a valid OIDC Provider Configuration", errors.WithWrap(err))
}
p, err := oidc.NewProvider(c)
if err != nil {
return nil, errors.New(errors.InvalidParameter, op, "AuthMethod cannot be converted to a valid OIDC Provider", errors.WithWrap(err))
return nil, errors.New(ctx, errors.InvalidParameter, op, "AuthMethod cannot be converted to a valid OIDC Provider", errors.WithWrap(err))
}
return p, nil
}
+4 -4
View File
@@ -21,13 +21,13 @@ func Test_ProviderCaching(t *testing.T) {
_, _, signingAlg, _ := tp.SigningKeys()
allowedRedirect := "https://alice.com/callback"
authMethodId, err := newAuthMethodId()
authMethodId, err := newAuthMethodId(ctx)
require.NoError(t, err)
id := authMethodId
secret := authMethodId
p1 := testProvider(t, id, secret, fmt.Sprintf(CallbackEndpoint, allowedRedirect), tp) // provider needs the complete callback URL
testAm, err := NewAuthMethod("fake-org", id, ClientSecret(secret),
testAm, err := NewAuthMethod(ctx, "fake-org", id, ClientSecret(secret),
WithIssuer(issuer), WithApiUrl(TestConvertToUrls(t, allowedRedirect)[0]))
require.NoError(t, err)
@@ -90,12 +90,12 @@ func Test_convertToProvider(t *testing.T) {
_, _, signingAlg, _ := tp.SigningKeys()
allowedRedirect := "https://alice.com/callback"
authMethodId, err := newAuthMethodId()
authMethodId, err := newAuthMethodId(ctx)
require.NoError(t, err)
id := authMethodId
secret := authMethodId
p := testProvider(t, id, secret, fmt.Sprintf(CallbackEndpoint, allowedRedirect), tp) // provider callback needs the complete URL
testAm, err := NewAuthMethod("fake-org", id, ClientSecret(secret),
testAm, err := NewAuthMethod(ctx, "fake-org", id, ClientSecret(secret),
WithIssuer(issuer), WithApiUrl(TestConvertToUrls(t, allowedRedirect)[0]))
require.NoError(t, err)
+6 -4
View File
@@ -1,6 +1,8 @@
package oidc
import (
"context"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/kms"
@@ -18,16 +20,16 @@ type Repository struct {
// NewRepository creates a new oidc Repository. Supports the options: WithLimit
// which sets a default limit on results returned by repo operations.
func NewRepository(r db.Reader, w db.Writer, kms *kms.Kms, opt ...Option) (*Repository, error) {
func NewRepository(ctx context.Context, r db.Reader, w db.Writer, kms *kms.Kms, opt ...Option) (*Repository, error) {
const op = "oidc.NewRepository"
if r == nil {
return nil, errors.New(errors.InvalidParameter, op, "reader is nil")
return nil, errors.New(ctx, errors.InvalidParameter, op, "reader is nil")
}
if w == nil {
return nil, errors.New(errors.InvalidParameter, op, "writer is nil")
return nil, errors.New(ctx, errors.InvalidParameter, op, "writer is nil")
}
if kms == nil {
return nil, errors.New(errors.InvalidParameter, op, "kms is nil")
return nil, errors.New(ctx, errors.InvalidParameter, op, "kms is nil")
}
opts := getOpts(opt...)
if opts.withLimit == 0 {
+38 -38
View File
@@ -29,22 +29,22 @@ import (
func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Account, opt ...Option) (*Account, error) {
const op = "oidc.(Repository).CreateAccount"
if a == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing Account")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing Account")
}
if a.Account == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing embedded Account")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing embedded Account")
}
if a.AuthMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
if a.Subject == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing subject")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing subject")
}
if a.PublicId != "" {
return nil, errors.New(errors.InvalidParameter, op, "public id must be empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "public id must be empty")
}
if scopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
a = a.Clone()
@@ -59,34 +59,34 @@ func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Accou
if a.Issuer == "" {
am, err := r.LookupAuthMethod(ctx, a.AuthMethodId)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get auth method"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get auth method"))
}
if am.GetIssuer() == "" {
return nil, errors.New(errors.InvalidParameter, op, "no issuer on auth method")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no issuer on auth method")
}
a.Issuer = am.GetIssuer()
}
if a.Issuer == "" {
return nil, errors.New(errors.InvalidParameter, op, "no issuer provided or defined in auth method")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no issuer provided or defined in auth method")
}
opts := getOpts(opt...)
if opts.withPublicId != "" {
if !strings.HasPrefix(opts.withPublicId, AccountPrefix+"_") {
return nil, errors.New(errors.InvalidParameter, op, "chosen account id does not have a valid prefix")
return nil, errors.New(ctx, errors.InvalidParameter, op, "chosen account id does not have a valid prefix")
}
a.PublicId = opts.withPublicId
} else {
id, err := newAccountId(a.AuthMethodId, a.Issuer, a.Subject)
id, err := newAccountId(ctx, a.AuthMethodId, a.Issuer, a.Subject)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
a.PublicId = id
}
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"), errors.WithCode(errors.Encrypt))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"), errors.WithCode(errors.Encrypt))
}
var newAccount *Account
@@ -94,7 +94,7 @@ func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Accou
func(_ db.Reader, w db.Writer) error {
newAccount = a.Clone()
if err := w.Create(ctx, newAccount, db.WithOplog(oplogWrapper, a.oplog(oplog.OpType_OP_TYPE_CREATE, scopeId))); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
},
@@ -102,11 +102,11 @@ func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Accou
if err != nil {
if errors.IsUniqueError(err) {
return nil, errors.New(errors.NotUnique, op, fmt.Sprintf(
return nil, errors.New(ctx, errors.NotUnique, op, fmt.Sprintf(
"in auth method %s: name %q already exists or subject %q already exists for issuer %q in scope %s",
a.AuthMethodId, a.Name, a.Subject, a.Issuer, scopeId))
}
return nil, errors.Wrap(err, op, errors.WithMsg(a.AuthMethodId))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(a.AuthMethodId))
}
return newAccount, nil
}
@@ -116,7 +116,7 @@ func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Accou
func (r *Repository) LookupAccount(ctx context.Context, withPublicId string, opt ...Option) (*Account, error) {
const op = "oidc.(Repository).LookupAccount"
if withPublicId == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
a := AllocAccount()
a.PublicId = withPublicId
@@ -124,7 +124,7 @@ func (r *Repository) LookupAccount(ctx context.Context, withPublicId string, opt
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("failed for %s", withPublicId)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("failed for %s", withPublicId)))
}
return a, nil
}
@@ -133,7 +133,7 @@ func (r *Repository) LookupAccount(ctx context.Context, withPublicId string, opt
func (r *Repository) ListAccounts(ctx context.Context, withAuthMethodId string, opt ...Option) ([]*Account, error) {
const op = "oidc.(Repository).ListAccounts"
if withAuthMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
opts := getOpts(opt...)
limit := r.defaultLimit
@@ -144,7 +144,7 @@ func (r *Repository) ListAccounts(ctx context.Context, withAuthMethodId string,
var accts []*Account
err := r.reader.SearchWhere(ctx, &accts, "auth_method_id = ?", []interface{}{withAuthMethodId}, db.WithLimit(limit))
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return accts, nil
}
@@ -154,17 +154,17 @@ func (r *Repository) ListAccounts(ctx context.Context, withAuthMethodId string,
func (r *Repository) DeleteAccount(ctx context.Context, scopeId, withPublicId string, opt ...Option) (int, error) {
const op = "oidc.(Repository).DeleteAccount"
if withPublicId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
if scopeId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing scope id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
ac := AllocAccount()
ac.PublicId = withPublicId
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
}
var rowsDeleted int
@@ -177,17 +177,17 @@ func (r *Repository) DeleteAccount(ctx context.Context, scopeId, withPublicId st
dAc := ac.Clone()
rowsDeleted, err = w.Delete(ctx, dAc, db.WithOplog(oplogWrapper, metadata))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsDeleted > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been deleted")
}
return nil
},
)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(withPublicId))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(withPublicId))
}
return rowsDeleted, nil
@@ -207,19 +207,19 @@ func (r *Repository) DeleteAccount(ctx context.Context, scopeId, withPublicId st
func (r *Repository) UpdateAccount(ctx context.Context, scopeId string, a *Account, version uint32, fieldMaskPaths []string, opt ...Option) (*Account, int, error) {
const op = "oidc.(Repository).UpdateAccount"
if a == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing Account")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing Account")
}
if a.Account == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing embedded Account")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing embedded Account")
}
if a.PublicId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
if version == 0 {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing version")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing version")
}
if scopeId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
for _, f := range fieldMaskPaths {
@@ -227,7 +227,7 @@ func (r *Repository) UpdateAccount(ctx context.Context, scopeId string, a *Accou
case strings.EqualFold(NameField, f):
case strings.EqualFold(DescriptionField, f):
default:
return nil, db.NoRowsAffected, errors.New(errors.InvalidFieldMask, op, f)
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, f)
}
}
var dbMask, nullFields []string
@@ -240,12 +240,12 @@ func (r *Repository) UpdateAccount(ctx context.Context, scopeId string, a *Accou
nil,
)
if len(dbMask) == 0 && len(nullFields) == 0 {
return nil, db.NoRowsAffected, errors.New(errors.EmptyFieldMask, op, "missing field mask")
return nil, db.NoRowsAffected, errors.New(ctx, errors.EmptyFieldMask, op, "missing field mask")
}
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithCode(errors.Encrypt),
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt),
errors.WithMsg(("unable to get oplog wrapper")))
}
@@ -261,10 +261,10 @@ func (r *Repository) UpdateAccount(ctx context.Context, scopeId string, a *Accou
var err error
rowsUpdated, err = w.Update(ctx, returnedAccount, dbMask, nullFields, db.WithOplog(oplogWrapper, metadata), db.WithVersion(&version))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsUpdated > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been updated")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been updated")
}
return nil
},
@@ -272,10 +272,10 @@ func (r *Repository) UpdateAccount(ctx context.Context, scopeId string, a *Accou
if err != nil {
if errors.IsUniqueError(err) {
return nil, db.NoRowsAffected, errors.New(errors.NotUnique, op,
return nil, db.NoRowsAffected, errors.New(ctx, errors.NotUnique, op,
fmt.Sprintf("name %s already exists: %s", a.Name, a.PublicId))
}
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(a.PublicId))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(a.PublicId))
}
return returnedAccount, rowsUpdated, nil
+16 -16
View File
@@ -199,7 +199,7 @@ func TestRepository_CreateAccount(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.CreateAccount(context.Background(), org.GetPublicId(), tt.in, tt.opts...)
@@ -235,7 +235,7 @@ func TestRepository_CreateAccount_DuplicateFields(t *testing.T) {
t.Run("invalid-duplicate-names", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
@@ -275,7 +275,7 @@ func TestRepository_CreateAccount_DuplicateFields(t *testing.T) {
t.Run("valid-duplicate-names-diff-parents", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
@@ -328,7 +328,7 @@ func TestRepository_CreateAccount_DuplicateFields(t *testing.T) {
t.Run("invalid-duplicate-subjects", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
@@ -367,7 +367,7 @@ func TestRepository_CreateAccount_DuplicateFields(t *testing.T) {
t.Run("valid-duplicate-subject-diff-authmethod", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
@@ -423,7 +423,7 @@ func TestRepository_CreateAccount_DuplicateFields(t *testing.T) {
t.Run("valid-duplicate-subject-diff-issuer", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
@@ -496,7 +496,7 @@ func TestRepository_LookupAccount(t *testing.T) {
)
account := TestAccount(t, conn, authMethod, "test-subject")
newAcctId, err := newAccountId(authMethod.GetPublicId(), authMethod.Issuer, "random-id")
newAcctId, err := newAccountId(ctx, authMethod.GetPublicId(), authMethod.Issuer, "random-id")
require.NoError(t, err)
tests := []struct {
name string
@@ -525,7 +525,7 @@ func TestRepository_LookupAccount(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.LookupAccount(context.Background(), tt.in)
@@ -560,7 +560,7 @@ func TestRepository_DeleteAccount(t *testing.T) {
WithApiUrl(TestConvertToUrls(t, "https://www.alice.com/callback")[0]),
)
account := TestAccount(t, conn, authMethod, "create-success")
newAcctId, err := newAccountId(authMethod.GetPublicId(), authMethod.Issuer, "random-subject")
newAcctId, err := newAccountId(ctx, authMethod.GetPublicId(), authMethod.Issuer, "random-subject")
require.NoError(t, err)
tests := []struct {
name string
@@ -601,7 +601,7 @@ func TestRepository_DeleteAccount(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.DeleteAccount(context.Background(), tt.scopeId, tt.in)
@@ -690,7 +690,7 @@ func TestRepository_ListAccounts(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.ListAccounts(context.Background(), tt.in, tt.opts...)
@@ -783,7 +783,7 @@ func TestRepository_ListAccounts_Limits(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache, tt.repoOpts...)
repo, err := NewRepository(ctx, rw, rw, kmsCache, tt.repoOpts...)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.ListAccounts(context.Background(), am.GetPublicId(), tt.listOpts...)
@@ -1130,7 +1130,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
@@ -1188,7 +1188,7 @@ func TestRepository_UpdateAccount_DupeNames(t *testing.T) {
t.Run("invalid-duplicate-names", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
@@ -1227,7 +1227,7 @@ func TestRepository_UpdateAccount_DupeNames(t *testing.T) {
t.Run("valid-duplicate-names-diff-AuthMethods", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
@@ -1265,7 +1265,7 @@ func TestRepository_UpdateAccount_DupeNames(t *testing.T) {
t.Run("change-authmethod-id", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
+35 -35
View File
@@ -25,25 +25,25 @@ var _ proto.Message = (*Account)(nil)
func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenClaims, AccessTokenClaims map[string]interface{}) (*Account, error) {
const op = "oidc.(Repository).upsertAccount"
if am == nil || am.AuthMethod == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method")
}
if IdTokenClaims == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing ID Token claims")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing ID Token claims")
}
if AccessTokenClaims == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing Access Token claims")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing Access Token claims")
}
fromSub, fromName, fromEmail := string(ToSubClaim), string(ToNameClaim), string(ToEmailClaim)
if len(am.AccountClaimMaps) > 0 {
acms, err := ParseAccountClaimMaps(am.AccountClaimMaps...)
acms, err := ParseAccountClaimMaps(ctx, am.AccountClaimMaps...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
for _, m := range acms {
toClaim, err := ConvertToAccountToClaim(m.To)
toClaim, err := ConvertToAccountToClaim(ctx, m.To)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
switch toClaim {
case ToSubClaim:
@@ -54,7 +54,7 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
fromName = m.From
default:
// should never happen, but including it just in case.
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("%s=%s is not a valid account claim map", m.From, m.To))
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("%s=%s is not a valid account claim map", m.From, m.To))
}
}
}
@@ -62,14 +62,14 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
var iss, sub string
var ok bool
if iss, ok = IdTokenClaims["iss"].(string); !ok {
return nil, errors.New(errors.Unknown, op, "issuer is not present in ID Token, which should not be possible")
return nil, errors.New(ctx, errors.Unknown, op, "issuer is not present in ID Token, which should not be possible")
}
if sub, ok = IdTokenClaims[fromSub].(string); !ok {
return nil, errors.New(errors.Unknown, op, fmt.Sprintf("mapping 'claim' %s to account subject and it is not present in ID Token", fromSub))
return nil, errors.New(ctx, errors.Unknown, op, fmt.Sprintf("mapping 'claim' %s to account subject and it is not present in ID Token", fromSub))
}
pubId, err := newAccountId(am.GetPublicId(), iss, sub)
pubId, err := newAccountId(ctx, am.GetPublicId(), iss, sub)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
columns := []string{"public_id", "auth_method_id", "issuer", "subject"}
@@ -79,7 +79,7 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
{
marshaledTokenClaims, err := json.Marshal(IdTokenClaims)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
columns, values = append(columns, "token_claims"), append(values, string(marshaledTokenClaims))
conflictClauses = append(conflictClauses, fmt.Sprintf("token_claims = $%d", len(values)))
@@ -88,7 +88,7 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
{
marshaledAccessTokenClaims, err := json.Marshal(AccessTokenClaims)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
columns, values = append(columns, "userinfo_claims"), append(values, string(marshaledAccessTokenClaims))
conflictClauses = append(conflictClauses, fmt.Sprintf("userinfo_claims = $%d", len(values)))
@@ -97,11 +97,11 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
issAsUrl, err := url.Parse(iss)
if err != nil {
return nil, errors.New(errors.Unknown, op, "unable to parse issuer", errors.WithWrap(err))
return nil, errors.New(ctx, errors.Unknown, op, "unable to parse issuer", errors.WithWrap(err))
}
acctForOplog, err := NewAccount(am.PublicId, sub, WithIssuer(issAsUrl))
acctForOplog, err := NewAccount(ctx, am.PublicId, sub, WithIssuer(issAsUrl))
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to create new acct for oplog"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create new acct for oplog"))
}
var foundName interface{}
@@ -148,7 +148,7 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
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"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
}
updatedAcct := AllocAccount()
@@ -160,7 +160,7 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
var err error
rows, err := w.Query(ctx, query, values)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to insert/update auth oidc account"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to insert/update auth oidc account"))
}
defer rows.Close()
result := struct {
@@ -172,19 +172,19 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
rowCnt += 1
err = r.reader.ScanRows(rows, &result)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to scan rows for account"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to scan rows for account"))
}
}
if rowCnt > 1 {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("expected 1 row but got: %d", rowCnt))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("expected 1 row but got: %d", rowCnt))
}
if err := reader.LookupWhere(ctx, &updatedAcct, "auth_method_id = ? and issuer = ? and subject = ?", am.PublicId, iss, sub); err != nil {
return errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("unable to look up auth oidc account for: %s / %s / %s", am.PublicId, iss, sub)))
return errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("unable to look up auth oidc account for: %s / %s / %s", am.PublicId, iss, sub)))
}
// include the version incase of predictable account public ids based on a calculation using authmethod id and subject
if result.Version == 1 && updatedAcct.PublicId == pubId {
if err := upsertOplog(ctx, w, oplogWrapper, oplog.OpType_OP_TYPE_CREATE, am.ScopeId, updatedAcct, nil, nil); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to write create oplog for account"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write create oplog for account"))
}
} else {
if len(fieldMasks) > 0 || len(nullMasks) > 0 {
@@ -197,7 +197,7 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
acctForOplog.FullName = foundName.(string)
}
if err := upsertOplog(ctx, w, oplogWrapper, oplog.OpType_OP_TYPE_UPDATE, am.ScopeId, acctForOplog, fieldMasks, nullMasks); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to write update oplog for account"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write update oplog for account"))
}
}
}
@@ -205,7 +205,7 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
},
)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return updatedAcct, nil
}
@@ -215,35 +215,35 @@ func (r *Repository) upsertAccount(ctx context.Context, am *AuthMethod, IdTokenC
func upsertOplog(ctx context.Context, w db.Writer, oplogWrapper wrapping.Wrapper, operation oplog.OpType, scopeId string, acct *Account, fieldMasks, nullMasks []string) error {
const op = "oidc.upsertOplog"
if w == nil {
return errors.New(errors.InvalidParameter, op, "missing db writer")
return errors.New(ctx, errors.InvalidParameter, op, "missing db writer")
}
if oplogWrapper == nil {
return errors.New(errors.InvalidParameter, op, "missing oplog wrapper")
return errors.New(ctx, errors.InvalidParameter, op, "missing oplog wrapper")
}
if operation != oplog.OpType_OP_TYPE_CREATE && operation != oplog.OpType_OP_TYPE_UPDATE {
return errors.New(errors.Internal, op, fmt.Sprintf("not a supported operation: %s", operation))
return errors.New(ctx, errors.Internal, op, fmt.Sprintf("not a supported operation: %s", operation))
}
if scopeId == "" {
return errors.New(errors.InvalidParameter, op, "missing scope id")
return errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
if acct == nil || acct.Account == nil {
return errors.New(errors.InvalidParameter, op, "missing account")
return errors.New(ctx, errors.InvalidParameter, op, "missing account")
}
if operation == oplog.OpType_OP_TYPE_UPDATE && len(fieldMasks) == 0 && len(nullMasks) == 0 {
return errors.New(errors.InvalidParameter, op, "update operations must specify field masks and/or null masks")
return errors.New(ctx, errors.InvalidParameter, op, "update operations must specify field masks and/or null masks")
}
ticket, err := w.GetTicket(acct)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
metadata := acct.oplog(operation, scopeId)
acctAsReplayable, ok := interface{}(acct).(oplog.ReplayableMessage)
if !ok {
return errors.New(errors.Internal, op, "account is not replayable")
return errors.New(ctx, errors.Internal, op, "account is not replayable")
}
acctAsProto, ok := interface{}(acct).(proto.Message)
if !ok {
return errors.New(errors.Internal, op, "account is not a proto message")
return errors.New(ctx, errors.Internal, op, "account is not a proto message")
}
msg := oplog.Message{
Message: acctAsProto,
@@ -253,7 +253,7 @@ func upsertOplog(ctx context.Context, w db.Writer, oplogWrapper wrapping.Wrapper
SetToNullPaths: nullMasks,
}
if err := w.WriteOplogEntryWith(ctx, oplogWrapper, ticket, metadata, []*oplog.Message{&msg}); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -21,48 +21,48 @@ import (
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")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method")
}
if am.PublicId != "" {
return nil, errors.New(errors.InvalidParameter, op, "public id must be empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "public id must be empty")
}
if am.Version != 0 {
return nil, errors.New(errors.InvalidParameter, op, "version must be empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "version must be empty")
}
if err := am.validate(op); err != nil {
if err := am.validate(ctx, 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()
id, err := newAuthMethodId(ctx)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
am.PublicId = id
} else {
if !strings.HasPrefix(am.PublicId, AuthMethodPrefix+"_") {
return nil, errors.New(errors.InvalidParameter, op, "wrong auth method id prefix")
return nil, errors.New(ctx, errors.InvalidParameter, op, "wrong auth method id prefix")
}
}
vo, err := am.convertValueObjects()
vo, err := am.convertValueObjects(ctx)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, 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"))
return nil, errors.Wrap(ctx, 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"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err := am.encrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
var returnedAuthMethod *AuthMethod
@@ -74,7 +74,7 @@ func (r *Repository) CreateAuthMethod(ctx context.Context, am *AuthMethod, opt .
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"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
returnedAuthMethod = am.Clone()
@@ -121,13 +121,13 @@ func (r *Repository) CreateAuthMethod(ctx context.Context, am *AuthMethod, opt .
}
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 errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog"))
}
return nil
},
)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return returnedAuthMethod, nil
}
@@ -50,6 +50,7 @@ func TestRepository_CreateAuthMethod(t *testing.T) {
certs := []*x509.Certificate{cert1, cert2}
pems := []string{pem1, pem2}
am, err := NewAuthMethod(
ctx,
org.PublicId,
"alice-rp",
"alice-secret", WithAudClaims("alice-rp"),
@@ -84,6 +85,7 @@ func TestRepository_CreateAuthMethod(t *testing.T) {
certs := []*x509.Certificate{cert1, cert2}
pems := []string{pem1, pem2}
am, err := NewAuthMethod(
ctx,
org.PublicId,
"alice-rp-custom",
"alice-secret-custom", WithAudClaims("alice-rp-custom"),
@@ -119,6 +121,7 @@ func TestRepository_CreateAuthMethod(t *testing.T) {
certs := []*x509.Certificate{cert1, cert2}
pems := []string{pem1, pem2}
am, err := NewAuthMethod(
ctx,
org.PublicId,
"alice-rp-bad",
"alice-secret-bad", WithAudClaims("alice-rp-bad"),
@@ -147,7 +150,7 @@ func TestRepository_CreateAuthMethod(t *testing.T) {
{
name: "bad-state",
am: func(t *testing.T) *AuthMethod {
am, err := NewAuthMethod(org.PublicId, "bad-state-rp", "alice-secret",
am, err := NewAuthMethod(ctx, org.PublicId, "bad-state-rp", "alice-secret",
WithAudClaims("alice-rp"), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
require.NoError(t, err)
am.OperationalState = "not-a-valid-state"
@@ -165,7 +168,7 @@ func TestRepository_CreateAuthMethod(t *testing.T) {
{
name: "bad-public-id",
am: func(t *testing.T) *AuthMethod {
id, err := newAuthMethodId()
id, err := newAuthMethodId(ctx)
require.NoError(t, err)
am := AllocAuthMethod()
am.PublicId = id
@@ -186,7 +189,7 @@ func TestRepository_CreateAuthMethod(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
am := tt.am(t)
@@ -16,11 +16,11 @@ import (
func (r *Repository) DeleteAuthMethod(ctx context.Context, publicId string, _ ...Option) (int, error) {
const op = "oidc.(Repository).DeleteAuthMethod"
if publicId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
am, err := r.LookupAuthMethod(ctx, publicId)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op)
return db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
if am == nil {
// already deleted and this is not an error.
@@ -29,7 +29,7 @@ func (r *Repository) DeleteAuthMethod(ctx context.Context, publicId string, _ ..
oplogWrapper, err := r.kms.GetWrapper(ctx, am.ScopeId, kms.KeyPurposeOplog)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
}
metadata := am.oplog(oplog.OpType_OP_TYPE_DELETE)
var rowsDeleted int
@@ -44,13 +44,13 @@ func (r *Repository) DeleteAuthMethod(ctx context.Context, publicId string, _ ..
return err
}
if rowsDeleted > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 auth method would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 auth method would have been deleted")
}
return nil
},
)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("unable to delete %s", publicId)))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("unable to delete %s", publicId)))
}
return rowsDeleted, nil
}
@@ -48,7 +48,7 @@ func TestRepository_DeleteAuthMethod(t *testing.T) {
authMethod: func() *AuthMethod {
am := AllocAuthMethod()
var err error
am.PublicId, err = newAuthMethodId()
am.PublicId, err = newAuthMethodId(ctx)
require.NoError(t, err)
return &am
}(),
@@ -57,7 +57,7 @@ func TestRepository_DeleteAuthMethod(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
require.NoError(err)
deletedRows, err := repo.DeleteAuthMethod(ctx, tt.authMethod.PublicId)
if tt.wantErrMatch != nil {
@@ -17,7 +17,7 @@ func (r *Repository) MakeInactive(ctx context.Context, authMethodId string, vers
const op = "oidc.(Repository).MakeInactive"
updated, err := r.transitionAuthMethodTo(ctx, authMethodId, InactiveState, version)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return updated, nil
}
@@ -32,7 +32,7 @@ func (r *Repository) MakePrivate(ctx context.Context, authMethodId string, versi
const op = "oidc.(Repository).MakePrivate"
updated, err := r.transitionAuthMethodTo(ctx, authMethodId, ActivePrivateState, version, opt...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return updated, nil
}
@@ -47,7 +47,7 @@ func (r *Repository) MakePublic(ctx context.Context, authMethodId string, versio
const op = "oidc.(Repository).MakePublic"
updated, err := r.transitionAuthMethodTo(ctx, authMethodId, ActivePublicState, version, opt...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return updated, nil
}
@@ -55,17 +55,17 @@ func (r *Repository) MakePublic(ctx context.Context, authMethodId string, versio
func (r *Repository) transitionAuthMethodTo(ctx context.Context, authMethodId string, desiredState AuthMethodState, version uint32, opt ...Option) (*AuthMethod, error) {
const op = "oidc.(Repository).transitionAuthMethodTo"
if authMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
if !validState(string(desiredState)) {
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("%s is not a valid auth method state", desiredState))
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("%s is not a valid auth method state", desiredState))
}
am, err := r.lookupAuthMethod(ctx, authMethodId)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if am == nil {
return nil, errors.New(errors.RecordNotFound, op, fmt.Sprintf("%s auth method not found", authMethodId))
return nil, errors.New(ctx, errors.RecordNotFound, op, fmt.Sprintf("%s auth method not found", authMethodId))
}
opts := getOpts(opt...)
if am.OperationalState == string(desiredState) && am.DisableDiscoveredConfigValidation == opts.withForce {
@@ -76,17 +76,17 @@ func (r *Repository) transitionAuthMethodTo(ctx context.Context, authMethodId st
updatedAm := am.Clone()
updatedAm.OperationalState = string(desiredState)
if err := r.ValidateDiscoveryInfo(ctx, WithAuthMethod(updatedAm)); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
}
if err := am.isComplete(); err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("unable to transition from %s to %s", InactiveState, desiredState)))
if err := am.isComplete(ctx); err != nil {
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("unable to transition from %s to %s", InactiveState, desiredState)))
}
}
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"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
}
var updatedAm *AuthMethod
@@ -102,14 +102,14 @@ func (r *Repository) transitionAuthMethodTo(ctx context.Context, authMethodId st
rowsUpdated, err := w.Update(ctx, updatedAm, dbMask, nil, db.WithOplog(oplogWrapper, updatedAm.oplog(oplog.OpType_OP_TYPE_UPDATE)), db.WithVersion(&version))
switch {
case err != nil:
return errors.Wrap(err, op, errors.WithMsg("unable to update auth method"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update auth method"))
case err == nil && rowsUpdated > 1:
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("updated auth method and %d rows updated", rowsUpdated))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated auth method and %d rows updated", rowsUpdated))
case err == nil && rowsUpdated == 0:
// this is different than how "no rows updated" is handled in
// the typical update pattern since we are not returning the
// number of rows updated, we need to raise an error here.
return errors.New(errors.RecordNotFound, op, fmt.Sprintf("updated auth method and %d rows updated", rowsUpdated))
return errors.New(ctx, errors.RecordNotFound, op, fmt.Sprintf("updated auth method and %d rows updated", rowsUpdated))
default:
}
// we need a new repo, that's using the same reader/writer as this TxHandler
@@ -122,16 +122,16 @@ func (r *Repository) transitionAuthMethodTo(ctx context.Context, authMethodId st
}
updatedAm, err = txRepo.lookupAuthMethod(ctx, updatedAm.PublicId)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to lookup auth method after update"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to lookup auth method after update"))
}
if updatedAm == nil {
return errors.New(errors.RecordNotFound, op, "unable to lookup auth method after update")
return errors.New(ctx, errors.RecordNotFound, op, "unable to lookup auth method after update")
}
return err
},
)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return updatedAm, nil
}
@@ -27,12 +27,12 @@ func Test_MakeInactive_MakePrivate_MakePublic(t *testing.T) {
tpClientSecret := "her-dog's-name"
tp.SetClientCreds(tpClientId, tpClientSecret)
_, _, tpAlg, _ := tp.SigningKeys()
tpCert, err := ParseCertificates(tp.CACert())
tpCert, err := ParseCertificates(ctx, tp.CACert())
require.NoError(t, err)
require.Equal(t, 1, len(tpCert))
rw := db.New(conn)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
require.NoError(t, err)
tests := []struct {
@@ -20,7 +20,7 @@ import (
func (r *Repository) LookupAuthMethod(ctx context.Context, publicId string, opt ...Option) (*AuthMethod, error) {
const op = "oidc.(Repository).LookupAuthMethod"
if publicId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing public id")
}
opts := getOpts(opt...)
return r.lookupAuthMethod(ctx, publicId, WithUnauthenticatedUser(opts.withUnauthenticatedUser))
@@ -32,11 +32,11 @@ func (r *Repository) LookupAuthMethod(ctx context.Context, publicId string, opt
func (r *Repository) ListAuthMethods(ctx context.Context, scopeIds []string, opt ...Option) ([]*AuthMethod, error) {
const op = "oidc.(Repository).ListAuthMethods"
if len(scopeIds) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "missing scope IDs")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope IDs")
}
authMethods, err := r.getAuthMethods(ctx, "", scopeIds, opt...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return authMethods, nil
}
@@ -47,13 +47,13 @@ func (r *Repository) lookupAuthMethod(ctx context.Context, authMethodId string,
var err error
ams, err := r.getAuthMethods(ctx, authMethodId, nil, opt...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
switch {
case len(ams) == 0:
return nil, nil // not an error to return no rows for a "lookup"
case len(ams) > 1:
return nil, errors.New(errors.NotSpecificIntegrity, op, fmt.Sprintf("%s matched more than 1 ", authMethodId))
return nil, errors.New(ctx, errors.NotSpecificIntegrity, op, fmt.Sprintf("%s matched more than 1 ", authMethodId))
default:
return ams[0], nil
}
@@ -73,10 +73,10 @@ func (r *Repository) lookupAuthMethod(ctx context.Context, authMethodId string,
func (r *Repository) getAuthMethods(ctx context.Context, authMethodId string, scopeIds []string, opt ...Option) ([]*AuthMethod, error) {
const op = "oidc.(Repository).getAuthMethods"
if authMethodId == "" && len(scopeIds) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "missing search criteria: both auth method id and Scope IDs are empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing search criteria: both auth method id and Scope IDs are empty")
}
if authMethodId != "" && len(scopeIds) > 0 {
return nil, errors.New(errors.InvalidParameter, op, "searching for both an auth method id and Scope IDs is not supported")
return nil, errors.New(ctx, errors.InvalidParameter, op, "searching for both an auth method id and Scope IDs is not supported")
}
const aggregateDelimiter = "|"
@@ -114,7 +114,7 @@ func (r *Repository) getAuthMethods(ctx context.Context, authMethodId string, sc
var aggAuthMethods []*authMethodAgg
err := r.reader.SearchWhere(ctx, &aggAuthMethods, strings.Join(where, " and "), args, dbArgs...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if len(aggAuthMethods) == 0 { // we're done if nothing is found.
@@ -125,10 +125,10 @@ func (r *Repository) getAuthMethods(ctx context.Context, authMethodId string, sc
for _, agg := range aggAuthMethods {
databaseWrapper, err := r.kms.GetWrapper(ctx, agg.ScopeId, kms.KeyPurposeDatabase, kms.WithKeyId(agg.KeyId))
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err := structwrapping.UnwrapStruct(ctx, databaseWrapper, agg, nil); err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Decrypt))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt))
}
am := AllocAuthMethod()
am.PublicId = agg.PublicId
@@ -43,7 +43,7 @@ func TestRepository_LookupAuthMethod(t *testing.T) {
amActivePub.IsPrimaryAuthMethod = true
iam.TestSetPrimaryAuthMethod(t, iam.TestRepo(t, conn, wrapper), org, amActivePub.PublicId)
amId, err := newAuthMethodId()
amId, err := newAuthMethodId(ctx)
require.NoError(t, err)
tests := []struct {
name string
@@ -91,7 +91,7 @@ func TestRepository_LookupAuthMethod(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.LookupAuthMethod(ctx, tt.in, tt.opt...)
@@ -162,7 +162,7 @@ func TestRepository_ListAuthMethods(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
scopeIds, want, wantPrimaryAuthMethodId := tt.setupFn()
@@ -344,7 +344,7 @@ func TestRepository_getAuthMethods(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
r, err := NewRepository(rw, rw, kmsCache)
r, err := NewRepository(ctx, rw, rw, kmsCache)
require.NoError(err)
authMethodId, scopeIds, want := tt.setupFn()
@@ -25,7 +25,7 @@ func Test_upsertAccount(t *testing.T) {
kmsCache := kms.TestKms(t, conn, rootWrapper)
rw := db.New(conn)
r, err := NewRepository(rw, rw, kmsCache)
r, err := NewRepository(ctx, rw, rw, kmsCache)
require.NoError(t, err)
org, _ := iam.TestScopes(t, iam.TestRepo(t, conn, rootWrapper))
@@ -78,17 +78,17 @@ const (
func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, version uint32, fieldMaskPaths []string, opt ...Option) (*AuthMethod, int, error) {
const op = "oidc.(Repository).UpdateAuthMethod"
if am == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing auth method")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing auth method")
}
if am.AuthMethod == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing auth method store")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing auth method store")
}
if am.PublicId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing public id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing public id")
}
if err := validateFieldMask(fieldMaskPaths); err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
if err := validateFieldMask(ctx, fieldMaskPaths); err != nil {
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
dbMask, nullFields := dbcommon.BuildUpdatePaths(
@@ -110,25 +110,25 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
nil,
)
if len(dbMask) == 0 && len(nullFields) == 0 {
return nil, db.NoRowsAffected, errors.New(errors.EmptyFieldMask, op, "empty field mask")
return nil, db.NoRowsAffected, errors.New(ctx, errors.EmptyFieldMask, op, "empty field mask")
}
origAm, err := r.lookupAuthMethod(ctx, am.PublicId)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
if origAm == nil {
return nil, db.NoRowsAffected, errors.New(errors.RecordNotFound, op, fmt.Sprintf("auth method %s", am.PublicId))
return nil, db.NoRowsAffected, errors.New(ctx, errors.RecordNotFound, op, fmt.Sprintf("auth method %s", am.PublicId))
}
// there's no reason to continue if another controller has already updated this auth method.
if origAm.Version != version {
return nil, db.NoRowsAffected, errors.New(errors.VersionMismatch, op, fmt.Sprintf("update version %d doesn't match db version %d", version, origAm.Version))
return nil, db.NoRowsAffected, errors.New(ctx, errors.VersionMismatch, op, fmt.Sprintf("update version %d doesn't match db version %d", version, origAm.Version))
}
opts := getOpts(opt...)
if opts.withDryRun {
updated := applyUpdate(am, origAm, fieldMaskPaths)
if err := updated.isComplete(); err != nil {
if err := updated.isComplete(ctx); err != nil {
return updated, db.NoRowsAffected, err
}
err := r.ValidateDiscoveryInfo(ctx, WithAuthMethod(updated))
@@ -138,40 +138,40 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
// prevent an "active" auth method from being updated in a manner that would create
// an incomplete and unusable auth method.
if origAm.OperationalState != string(InactiveState) {
if err := applyUpdate(am, origAm, fieldMaskPaths).isComplete(); err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("update would result in an incomplete auth method"))
if err := applyUpdate(am, origAm, fieldMaskPaths).isComplete(ctx); err != nil {
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("update would result in an incomplete auth method"))
}
}
if !opts.withForce {
if err := r.ValidateDiscoveryInfo(ctx, WithAuthMethod(applyUpdate(am, origAm, fieldMaskPaths))); err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
}
addAlgs, deleteAlgs, err := valueObjectChanges(origAm.PublicId, SigningAlgVO, am.SigningAlgs, origAm.SigningAlgs, dbMask, nullFields)
addAlgs, deleteAlgs, err := valueObjectChanges(ctx, origAm.PublicId, SigningAlgVO, am.SigningAlgs, origAm.SigningAlgs, dbMask, nullFields)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
addCerts, deleteCerts, err := valueObjectChanges(origAm.PublicId, CertificateVO, am.Certificates, origAm.Certificates, dbMask, nullFields)
addCerts, deleteCerts, err := valueObjectChanges(ctx, origAm.PublicId, CertificateVO, am.Certificates, origAm.Certificates, dbMask, nullFields)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
addAuds, deleteAuds, err := valueObjectChanges(origAm.PublicId, AudClaimVO, am.AudClaims, origAm.AudClaims, dbMask, nullFields)
addAuds, deleteAuds, err := valueObjectChanges(ctx, origAm.PublicId, AudClaimVO, am.AudClaims, origAm.AudClaims, dbMask, nullFields)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
addScopes, deleteScopes, err := valueObjectChanges(origAm.PublicId, ClaimsScopesVO, am.ClaimsScopes, origAm.ClaimsScopes, dbMask, nullFields)
addScopes, deleteScopes, err := valueObjectChanges(ctx, origAm.PublicId, ClaimsScopesVO, am.ClaimsScopes, origAm.ClaimsScopes, dbMask, nullFields)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
addMaps, deleteMaps, err := valueObjectChanges(origAm.PublicId, AccountClaimMapsVO, am.AccountClaimMaps, origAm.AccountClaimMaps, dbMask, nullFields)
addMaps, deleteMaps, err := valueObjectChanges(ctx, origAm.PublicId, AccountClaimMapsVO, am.AccountClaimMaps, origAm.AccountClaimMaps, dbMask, nullFields)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
// we don't allow updates for "sub" claim maps, because we have no way to
// determine if the updated "from" claim in the map might create collisions
@@ -179,13 +179,13 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
for _, rawCm := range addMaps {
cm := rawCm.(*AccountClaimMap)
if cm.ToClaim == string(ToSubClaim) {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, fmt.Sprintf("you cannot update account claim map %s=%s for the \"sub\" claim", cm.FromClaim, cm.ToClaim))
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("you cannot update account claim map %s=%s for the \"sub\" claim", cm.FromClaim, cm.ToClaim))
}
}
for _, rawCm := range deleteMaps {
cm := rawCm.(*AccountClaimMap)
if cm.ToClaim == string(ToSubClaim) {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, fmt.Sprintf("you cannot update account claim map %s=%s for the \"sub\" claim", cm.FromClaim, cm.ToClaim))
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("you cannot update account claim map %s=%s for the \"sub\" claim", cm.FromClaim, cm.ToClaim))
}
}
@@ -234,15 +234,15 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
databaseWrapper, err := r.kms.GetWrapper(ctx, origAm.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err := am.encrypt(ctx, databaseWrapper); err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
oplogWrapper, err := r.kms.GetWrapper(ctx, origAm.ScopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
}
// we always set this to the current value of opts.withForce
@@ -258,7 +258,7 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
msgs := make([]*oplog.Message, 0, 7) // AuthMethod, Algs*2, Certs*2, Audiences*2
ticket, err := w.GetTicket(am)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
var authMethodOplogMsg oplog.Message
switch {
@@ -269,20 +269,20 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
updatedAm.Version = uint32(version) + 1
rowsUpdated, err = w.Update(ctx, updatedAm, []string{VersionField, DisableDiscoveredConfigValidationField}, nil, db.NewOplogMsg(&authMethodOplogMsg), db.WithVersion(&version))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to update auth method version"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update auth method version"))
}
if rowsUpdated != 1 {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("updated auth method version and %d rows updated", rowsUpdated))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated auth method version and %d rows updated", rowsUpdated))
}
default:
filteredDbMask = append(filteredDbMask, DisableDiscoveredConfigValidationField)
updatedAm = am.Clone()
rowsUpdated, err = w.Update(ctx, updatedAm, filteredDbMask, filteredNullFields, db.NewOplogMsg(&authMethodOplogMsg), db.WithVersion(&version))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to update auth method"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update auth method"))
}
if rowsUpdated != 1 {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("updated auth method and %d rows updated", rowsUpdated))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated auth method and %d rows updated", rowsUpdated))
}
}
msgs = append(msgs, &authMethodOplogMsg)
@@ -291,17 +291,17 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
deleteAlgOplogMsgs := make([]*oplog.Message, 0, len(deleteAlgs))
rowsDeleted, err := w.DeleteItems(ctx, deleteAlgs, db.NewOplogMsgs(&deleteAlgOplogMsgs))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to delete signing algorithms"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to delete signing algorithms"))
}
if rowsDeleted != len(deleteAlgs) {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("signing algorithms deleted %d did not match request for %d", rowsDeleted, len(deleteAlgs)))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("signing algorithms deleted %d did not match request for %d", rowsDeleted, len(deleteAlgs)))
}
msgs = append(msgs, deleteAlgOplogMsgs...)
}
if len(addAlgs) > 0 {
addAlgsOplogMsgs := make([]*oplog.Message, 0, len(addAlgs))
if err := w.CreateItems(ctx, addAlgs, db.NewOplogMsgs(&addAlgsOplogMsgs)); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to add signing algorithms"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add signing algorithms"))
}
msgs = append(msgs, addAlgsOplogMsgs...)
}
@@ -310,17 +310,17 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
deleteCertOplogMsgs := make([]*oplog.Message, 0, len(deleteCerts))
rowsDeleted, err := w.DeleteItems(ctx, deleteCerts, db.NewOplogMsgs(&deleteCertOplogMsgs))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to delete certificates"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to delete certificates"))
}
if rowsDeleted != len(deleteCerts) {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("certificates deleted %d did not match request for %d", rowsDeleted, len(deleteCerts)))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("certificates deleted %d did not match request for %d", rowsDeleted, len(deleteCerts)))
}
msgs = append(msgs, deleteCertOplogMsgs...)
}
if len(addCerts) > 0 {
addCertsOplogMsgs := make([]*oplog.Message, 0, len(addCerts))
if err := w.CreateItems(ctx, addCerts, db.NewOplogMsgs(&addCertsOplogMsgs)); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to add certificates"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add certificates"))
}
msgs = append(msgs, addCertsOplogMsgs...)
}
@@ -329,17 +329,17 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
deleteAudsOplogMsgs := make([]*oplog.Message, 0, len(deleteAuds))
rowsDeleted, err := w.DeleteItems(ctx, deleteAuds, db.NewOplogMsgs(&deleteAudsOplogMsgs))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to delete audiences URLs"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to delete audiences URLs"))
}
if rowsDeleted != len(deleteAuds) {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("audiences deleted %d did not match request for %d", rowsDeleted, len(deleteAuds)))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("audiences deleted %d did not match request for %d", rowsDeleted, len(deleteAuds)))
}
msgs = append(msgs, deleteAudsOplogMsgs...)
}
if len(addAuds) > 0 {
addAudsOplogMsgs := make([]*oplog.Message, 0, len(addAuds))
if err := w.CreateItems(ctx, addAuds, db.NewOplogMsgs(&addAudsOplogMsgs)); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to add audiences URLs"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add audiences URLs"))
}
msgs = append(msgs, addAudsOplogMsgs...)
}
@@ -348,17 +348,17 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
deleteScopesOplogMsgs := make([]*oplog.Message, 0, len(deleteScopes))
rowsDeleted, err := w.DeleteItems(ctx, deleteScopes, db.NewOplogMsgs(&deleteScopesOplogMsgs))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to delete claims scopes"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to delete claims scopes"))
}
if rowsDeleted != len(deleteScopes) {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("claims scopes deleted %d did not match request for %d", rowsDeleted, len(deleteScopes)))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("claims scopes deleted %d did not match request for %d", rowsDeleted, len(deleteScopes)))
}
msgs = append(msgs, deleteScopesOplogMsgs...)
}
if len(addScopes) > 0 {
addScopesOplogMsgs := make([]*oplog.Message, 0, len(addScopes))
if err := w.CreateItems(ctx, addScopes, db.NewOplogMsgs(&addScopesOplogMsgs)); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to add claims scopes"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add claims scopes"))
}
msgs = append(msgs, addScopesOplogMsgs...)
}
@@ -367,24 +367,24 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
deleteMapsOplogMsgs := make([]*oplog.Message, 0, len(deleteMaps))
rowsDeleted, err := w.DeleteItems(ctx, deleteMaps, db.NewOplogMsgs(&deleteMapsOplogMsgs))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to delete account claim maps"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to delete account claim maps"))
}
if rowsDeleted != len(deleteMaps) {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("account claim maps deleted %d did not match request for %d", rowsDeleted, len(deleteMaps)))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("account claim maps deleted %d did not match request for %d", rowsDeleted, len(deleteMaps)))
}
msgs = append(msgs, deleteMapsOplogMsgs...)
}
if len(addMaps) > 0 {
addMapsOplogMsgs := make([]*oplog.Message, 0, len(addMaps))
if err := w.CreateItems(ctx, addMaps, db.NewOplogMsgs(&addMapsOplogMsgs)); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to add account claim maps"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add account claim maps"))
}
msgs = append(msgs, addMapsOplogMsgs...)
}
metadata := updatedAm.oplog(oplog.OpType_OP_TYPE_UPDATE)
if err := w.WriteOplogEntryWith(ctx, oplogWrapper, ticket, metadata, msgs); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog"))
}
// we need a new repo, that's using the same reader/writer as this TxHandler
txRepo := &Repository{
@@ -396,16 +396,16 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, am *AuthMethod, versi
}
updatedAm, err = txRepo.lookupAuthMethod(ctx, updatedAm.PublicId)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to lookup auth method after update"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to lookup auth method after update"))
}
if updatedAm == nil {
return errors.New(errors.RecordNotFound, op, "unable to lookup auth method after update")
return errors.New(ctx, errors.RecordNotFound, op, "unable to lookup auth method after update")
}
return nil
},
)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
providerCache().delete(ctx, updatedAm.PublicId)
@@ -435,44 +435,44 @@ func validVoName(name voName) bool {
}
// factoryFunc defines a func type for value object factories
type factoryFunc func(publicId string, i interface{}) (interface{}, error)
type factoryFunc func(ctx context.Context, publicId string, i interface{}) (interface{}, error)
// supportedFactories are the currently supported factoryFunc for value objects
var supportedFactories = map[voName]factoryFunc{
SigningAlgVO: func(publicId string, i interface{}) (interface{}, error) {
SigningAlgVO: func(ctx context.Context, publicId string, i interface{}) (interface{}, error) {
str := fmt.Sprintf("%s", i)
return NewSigningAlg(publicId, Alg(str))
return NewSigningAlg(ctx, publicId, Alg(str))
},
CertificateVO: func(publicId string, i interface{}) (interface{}, error) {
CertificateVO: func(ctx context.Context, publicId string, i interface{}) (interface{}, error) {
str := fmt.Sprintf("%s", i)
return NewCertificate(publicId, str)
return NewCertificate(ctx, publicId, str)
},
AudClaimVO: func(publicId string, i interface{}) (interface{}, error) {
AudClaimVO: func(ctx context.Context, publicId string, i interface{}) (interface{}, error) {
str := fmt.Sprintf("%s", i)
return NewAudClaim(publicId, str)
return NewAudClaim(ctx, publicId, str)
},
ClaimsScopesVO: func(publicId string, i interface{}) (interface{}, error) {
ClaimsScopesVO: func(ctx context.Context, publicId string, i interface{}) (interface{}, error) {
str := fmt.Sprintf("%s", i)
return NewClaimsScope(publicId, str)
return NewClaimsScope(ctx, publicId, str)
},
AccountClaimMapsVO: func(publicId string, i interface{}) (interface{}, error) {
AccountClaimMapsVO: func(ctx context.Context, publicId string, i interface{}) (interface{}, error) {
const op = "oidc.AccountClaimMapsFactory"
str := fmt.Sprintf("%s", i)
acm, err := ParseAccountClaimMaps(str)
acm, err := ParseAccountClaimMaps(ctx, str)
if err != nil {
return nil, err
}
if len(acm) > 1 {
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("unable to parse account claim map %s", str))
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("unable to parse account claim map %s", str))
}
var m ClaimMap
for _, m = range acm {
}
to, err := ConvertToAccountToClaim(m.To)
to, err := ConvertToAccountToClaim(ctx, m.To)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return NewAccountClaimMap(publicId, m.From, to)
return NewAccountClaimMap(ctx, publicId, m.From, to)
},
}
@@ -480,6 +480,7 @@ var supportedFactories = map[voName]factoryFunc{
// using the dbMasks/nullFields it will return lists of VOs where need to be
// added and deleted in order to reconcile auth method's value objects.
func valueObjectChanges(
ctx context.Context,
publicId string,
valueObjectName voName,
newVOs,
@@ -489,24 +490,24 @@ func valueObjectChanges(
) (add []interface{}, del []interface{}, e error) {
const op = "valueObjectChanges"
if publicId == "" {
return nil, nil, errors.New(errors.InvalidParameter, op, "missing public id")
return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "missing public id")
}
if !validVoName(valueObjectName) {
return nil, nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("invalid value object name: %s", valueObjectName))
return nil, nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("invalid value object name: %s", valueObjectName))
}
if !strutil.StrListContains(dbMask, string(valueObjectName)) && !strutil.StrListContains(nullFields, string(valueObjectName)) {
return nil, nil, nil
}
if len(strutil.RemoveDuplicates(newVOs, false)) != len(newVOs) {
return nil, nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("duplicate new %s", valueObjectName))
return nil, nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("duplicate new %s", valueObjectName))
}
if len(strutil.RemoveDuplicates(oldVOs, false)) != len(oldVOs) {
return nil, nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("duplicate old %s", valueObjectName))
return nil, nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("duplicate old %s", valueObjectName))
}
factory, ok := supportedFactories[valueObjectName]
if !ok {
return nil, nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("unsupported factory for value object: %s", valueObjectName))
return nil, nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("unsupported factory for value object: %s", valueObjectName))
}
if len(dbMask) == 0 && len(nullFields) == 0 {
@@ -522,9 +523,9 @@ func valueObjectChanges(
if strutil.StrListContains(nullFields, string(valueObjectName)) {
deletes = make([]interface{}, 0, len(oldVOs))
for _, v := range oldVOs {
deleteObj, err := factory(publicId, v)
deleteObj, err := factory(ctx, publicId, v)
if err != nil {
return nil, nil, errors.Wrap(err, op)
return nil, nil, errors.Wrap(ctx, err, op)
}
deletes = append(deletes, deleteObj)
delete(foundVOs, v)
@@ -537,9 +538,9 @@ func valueObjectChanges(
delete(foundVOs, v)
continue
}
obj, err := factory(publicId, v)
obj, err := factory(ctx, publicId, v)
if err != nil {
return nil, nil, errors.Wrap(err, op)
return nil, nil, errors.Wrap(ctx, err, op)
}
adds = append(adds, obj)
delete(foundVOs, v)
@@ -547,9 +548,9 @@ func valueObjectChanges(
}
if len(foundVOs) > 0 {
for v := range foundVOs {
obj, err := factory(publicId, v)
obj, err := factory(ctx, publicId, v)
if err != nil {
return nil, nil, errors.Wrap(err, op)
return nil, nil, errors.Wrap(ctx, err, op)
}
deletes = append(deletes, obj)
delete(foundVOs, v)
@@ -559,7 +560,7 @@ func valueObjectChanges(
}
// validateFieldMask check the field mask to ensure all the fields are updatable
func validateFieldMask(fieldMaskPaths []string) error {
func validateFieldMask(ctx context.Context, fieldMaskPaths []string) error {
const op = "validateFieldMask"
for _, f := range fieldMaskPaths {
switch {
@@ -576,7 +577,7 @@ func validateFieldMask(fieldMaskPaths []string) error {
case strings.EqualFold(ClaimsScopesField, f):
case strings.EqualFold(AccountClaimMapsField, f):
default:
return errors.New(errors.InvalidParameter, op, fmt.Sprintf("invalid field mask: %s", f))
return errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("invalid field mask: %s", f))
}
}
return nil
@@ -669,15 +670,15 @@ func (r *Repository) ValidateDiscoveryInfo(ctx context.Context, opt ...Option) e
var err error
am, err = r.lookupAuthMethod(ctx, opts.withPublicId)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if am == nil {
return errors.New(errors.RecordNotFound, op, fmt.Sprintf("unable to lookup auth method %s", opts.withPublicId))
return errors.New(ctx, errors.RecordNotFound, op, fmt.Sprintf("unable to lookup auth method %s", opts.withPublicId))
}
case opts.withAuthMethod != nil:
am = opts.withAuthMethod
default:
return errors.New(errors.InvalidParameter, op, "neither WithPublicId(...) nor WithAuthMethod(...) options were provided")
return errors.New(ctx, errors.InvalidParameter, op, "neither WithPublicId(...) nor WithAuthMethod(...) options were provided")
}
// FYI: once converted to an oidc.Provider, any certs configured will be used as trust anchors for all HTTP requests
@@ -686,28 +687,28 @@ func (r *Repository) ValidateDiscoveryInfo(ctx context.Context, opt ...Option) e
return nil
}
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
info, err := provider.DiscoveryInfo(ctx)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
var result *multierror.Error
if info.Issuer != am.Issuer {
result = multierror.Append(result, errors.New(errors.InvalidParameter, op,
result = multierror.Append(result, errors.New(ctx, errors.InvalidParameter, op,
fmt.Sprintf("auth method issuer doesn't match discovery issuer: expected %s and got %s", am.Issuer, info.Issuer)))
}
for _, a := range am.SigningAlgs {
if !strutil.StrListContains(info.IdTokenSigningAlgsSupported, a) {
result = multierror.Append(result, errors.New(errors.InvalidParameter, op,
result = multierror.Append(result, errors.New(ctx, errors.InvalidParameter, op,
fmt.Sprintf("auth method signing alg is not in discovered supported algs: expected %s and got %s", a, info.IdTokenSigningAlgsSupported)))
}
}
providerClient, err := provider.HTTPClient()
if err != nil {
result = multierror.Append(result, errors.New(errors.Unknown, op, "unable to get oidc http client", errors.WithWrap(err)))
result = multierror.Append(result, errors.New(ctx, errors.Unknown, op, "unable to get oidc http client", errors.WithWrap(err)))
return result.ErrorOrNil()
}
@@ -720,20 +721,20 @@ func (r *Repository) ValidateDiscoveryInfo(ctx context.Context, opt ...Option) e
// test JWKs URL
statusCode, err := pingEndpoint(ctx, providerClient, "JWKs", "GET", info.JWKSURL)
if err != nil {
result = multierror.Append(result, errors.New(errors.Unknown, op, fmt.Sprintf("unable to verify JWKs endpoint: %s", info.JWKSURL), errors.WithWrap(err)))
result = multierror.Append(result, errors.New(ctx, errors.Unknown, op, fmt.Sprintf("unable to verify JWKs endpoint: %s", info.JWKSURL), errors.WithWrap(err)))
}
if statusCode != 200 {
result = multierror.Append(result, errors.New(errors.Unknown, op, fmt.Sprintf("non-200 status (%d) from JWKs endpoint: %s", statusCode, info.JWKSURL), errors.WithWrap(err)))
result = multierror.Append(result, errors.New(ctx, errors.Unknown, op, fmt.Sprintf("non-200 status (%d) from JWKs endpoint: %s", statusCode, info.JWKSURL), errors.WithWrap(err)))
}
// test Auth URL
if _, err := pingEndpoint(ctx, providerClient, "AuthURL", "GET", info.AuthURL); err != nil {
result = multierror.Append(result, errors.New(errors.Unknown, op, fmt.Sprintf("unable to verify authorize endpoint: %s", info.AuthURL), errors.WithWrap(err)))
result = multierror.Append(result, errors.New(ctx, errors.Unknown, op, fmt.Sprintf("unable to verify authorize endpoint: %s", info.AuthURL), errors.WithWrap(err)))
}
// test Token URL
if _, err := pingEndpoint(ctx, providerClient, "TokenURL", "POST", info.TokenURL); err != nil {
result = multierror.Append(result, errors.New(errors.Unknown, op, fmt.Sprintf("unable to verify token endpoint: %s", info.TokenURL), errors.WithWrap(err)))
result = multierror.Append(result, errors.New(ctx, errors.Unknown, op, fmt.Sprintf("unable to verify token endpoint: %s", info.TokenURL), errors.WithWrap(err)))
}
// we're not verifying the UserInfo URL, since it's not a required dependency.
@@ -750,11 +751,11 @@ func pingEndpoint(ctx context.Context, client HTTPClient, endpointType, method,
const op = "oidc.pingEndpoint"
req, err := http.NewRequestWithContext(ctx, method, url, nil)
if err != nil {
return 0, errors.New(errors.Unknown, op, fmt.Sprintf("unable to create %s http request", endpointType), errors.WithWrap(err))
return 0, errors.New(ctx, errors.Unknown, op, fmt.Sprintf("unable to create %s http request", endpointType), errors.WithWrap(err))
}
resp, err := client.Do(req)
if err != nil {
return 0, errors.New(errors.Unknown, op, fmt.Sprintf("request to %s endpoint failed", endpointType), errors.WithWrap(err))
return 0, errors.New(ctx, errors.Unknown, op, fmt.Sprintf("request to %s endpoint failed", endpointType), errors.WithWrap(err))
}
return resp.StatusCode, nil
}
@@ -35,12 +35,12 @@ func Test_UpdateAuthMethod(t *testing.T) {
tpClientSecret := "her-dog's-name"
tp.SetClientCreds(tpClientId, tpClientSecret)
_, _, tpAlg, _ := tp.SigningKeys()
tpCert, err := ParseCertificates(tp.CACert())
tpCert, err := ParseCertificates(ctx, tp.CACert())
require.NoError(t, err)
require.Equal(t, 1, len(tpCert))
rw := db.New(conn)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
require.NoError(t, err)
tests := []struct {
@@ -428,7 +428,7 @@ func Test_UpdateAuthMethod(t *testing.T) {
setup: func() *AuthMethod { return nil },
updateWith: func(orig *AuthMethod) *AuthMethod {
a := AllocAuthMethod()
id, _ := newAuthMethodId()
id, _ := newAuthMethodId(ctx)
a.PublicId = id
return &a
},
@@ -441,7 +441,7 @@ func Test_UpdateAuthMethod(t *testing.T) {
setup: func() *AuthMethod { return nil },
updateWith: func(orig *AuthMethod) *AuthMethod {
a := AllocAuthMethod()
id, _ := newAuthMethodId()
id, _ := newAuthMethodId(ctx)
a.PublicId = id
return &a
},
@@ -453,7 +453,7 @@ func Test_UpdateAuthMethod(t *testing.T) {
setup: func() *AuthMethod { return nil },
updateWith: func(orig *AuthMethod) *AuthMethod {
a := AllocAuthMethod()
id, _ := newAuthMethodId()
id, _ := newAuthMethodId(ctx)
a.PublicId = id
return &a
},
@@ -601,12 +601,12 @@ func Test_DisableDiscoveredConfigValidation(t *testing.T) {
tpClientSecret := "her-dog's-name"
tp.SetClientCreds(tpClientId, tpClientSecret)
_, _, tpAlg, _ := tp.SigningKeys()
tpCert, err := ParseCertificates(tp.CACert())
tpCert, err := ParseCertificates(ctx, tp.CACert())
require.NoError(err)
require.Equal(1, len(tpCert))
rw := db.New(conn)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
require.NoError(err)
org, _ := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
databaseWrapper, err := kmsCache.GetWrapper(context.Background(), org.PublicId, kms.KeyPurposeDatabase)
@@ -661,7 +661,7 @@ func Test_ValidateDiscoveryInfo(t *testing.T) {
tpClientSecret := "her-dog's-name"
tp.SetClientCreds(tpClientId, tpClientSecret)
_, _, tpAlg, _ := tp.SigningKeys()
tpCert, err := ParseCertificates(tp.CACert())
tpCert, err := ParseCertificates(ctx, tp.CACert())
require.NoError(t, err)
require.Equal(t, 1, len(tpCert))
@@ -670,7 +670,7 @@ func Test_ValidateDiscoveryInfo(t *testing.T) {
kmsCache := kms.TestKms(t, conn, wrapper)
org, _ := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
rw := db.New(conn)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
require.NoError(t, err)
databaseWrapper, err := kmsCache.GetWrapper(context.Background(), org.PublicId, kms.KeyPurposeDatabase)
@@ -772,6 +772,7 @@ func Test_ValidateDiscoveryInfo(t *testing.T) {
func Test_valueObjectChanges(t *testing.T) {
t.Parallel()
ctx := context.TODO()
_, pem1 := testGenerateCA(t, "localhost")
_, pem2 := testGenerateCA(t, "127.0.0.1")
_, pem3 := testGenerateCA(t, "www.example.com")
@@ -795,18 +796,18 @@ func Test_valueObjectChanges(t *testing.T) {
old: []string{"RS256", "RS384", "RS512"},
dbMask: []string{string(SigningAlgVO)},
wantAdd: func() []interface{} {
a, err := NewSigningAlg("am-public-id", ES256)
a, err := NewSigningAlg(ctx, "am-public-id", ES256)
require.NoError(t, err)
a2, err := NewSigningAlg("am-public-id", ES384)
a2, err := NewSigningAlg(ctx, "am-public-id", ES384)
require.NoError(t, err)
return []interface{}{a, a2}
}(),
wantDel: func() []interface{} {
a, err := NewSigningAlg("am-public-id", RS256)
a, err := NewSigningAlg(ctx, "am-public-id", RS256)
require.NoError(t, err)
a2, err := NewSigningAlg("am-public-id", RS384)
a2, err := NewSigningAlg(ctx, "am-public-id", RS384)
require.NoError(t, err)
a3, err := NewSigningAlg("am-public-id", RS512)
a3, err := NewSigningAlg(ctx, "am-public-id", RS512)
require.NoError(t, err)
return []interface{}{a, a2, a3}
}(),
@@ -819,14 +820,14 @@ func Test_valueObjectChanges(t *testing.T) {
old: []string{pem3},
dbMask: []string{string(CertificateVO)},
wantAdd: func() []interface{} {
c, err := NewCertificate("am-public-id", pem1)
c, err := NewCertificate(ctx, "am-public-id", pem1)
require.NoError(t, err)
c2, err := NewCertificate("am-public-id", pem2)
c2, err := NewCertificate(ctx, "am-public-id", pem2)
require.NoError(t, err)
return []interface{}{c, c2}
}(),
wantDel: func() []interface{} {
c, err := NewCertificate("am-public-id", pem3)
c, err := NewCertificate(ctx, "am-public-id", pem3)
require.NoError(t, err)
return []interface{}{c}
}(),
@@ -839,18 +840,18 @@ func Test_valueObjectChanges(t *testing.T) {
old: []string{"old-aud1", "old-aud2", "old-aud3"},
dbMask: []string{string(AudClaimVO)},
wantAdd: func() []interface{} {
a, err := NewAudClaim("am-public-id", "new-aud1")
a, err := NewAudClaim(ctx, "am-public-id", "new-aud1")
require.NoError(t, err)
a2, err := NewAudClaim("am-public-id", "new-aud2")
a2, err := NewAudClaim(ctx, "am-public-id", "new-aud2")
require.NoError(t, err)
return []interface{}{a, a2}
}(),
wantDel: func() []interface{} {
a, err := NewAudClaim("am-public-id", "old-aud1")
a, err := NewAudClaim(ctx, "am-public-id", "old-aud1")
require.NoError(t, err)
a2, err := NewAudClaim("am-public-id", "old-aud2")
a2, err := NewAudClaim(ctx, "am-public-id", "old-aud2")
require.NoError(t, err)
a3, err := NewAudClaim("am-public-id", "old-aud3")
a3, err := NewAudClaim(ctx, "am-public-id", "old-aud3")
require.NoError(t, err)
return []interface{}{a, a2, a3}
}(),
@@ -864,11 +865,11 @@ func Test_valueObjectChanges(t *testing.T) {
old: []string{"old-aud1", "old-aud2", "old-aud3"},
nullFields: []string{string(AudClaimVO)},
wantDel: func() []interface{} {
a, err := NewAudClaim("am-public-id", "old-aud1")
a, err := NewAudClaim(ctx, "am-public-id", "old-aud1")
require.NoError(t, err)
a2, err := NewAudClaim("am-public-id", "old-aud2")
a2, err := NewAudClaim(ctx, "am-public-id", "old-aud2")
require.NoError(t, err)
a3, err := NewAudClaim("am-public-id", "old-aud3")
a3, err := NewAudClaim(ctx, "am-public-id", "old-aud3")
require.NoError(t, err)
return []interface{}{a, a2, a3}
}(),
@@ -881,18 +882,18 @@ func Test_valueObjectChanges(t *testing.T) {
old: []string{"old-scope1", "old-scope2", "old-scope3"},
dbMask: []string{string(ClaimsScopesVO)},
wantAdd: func() []interface{} {
cs, err := NewClaimsScope("am-public-id", "new-scope1")
cs, err := NewClaimsScope(ctx, "am-public-id", "new-scope1")
require.NoError(t, err)
cs2, err := NewClaimsScope("am-public-id", "new-scope2")
cs2, err := NewClaimsScope(ctx, "am-public-id", "new-scope2")
require.NoError(t, err)
return []interface{}{cs, cs2}
}(),
wantDel: func() []interface{} {
cs, err := NewClaimsScope("am-public-id", "old-scope1")
cs, err := NewClaimsScope(ctx, "am-public-id", "old-scope1")
require.NoError(t, err)
cs2, err := NewClaimsScope("am-public-id", "old-scope2")
cs2, err := NewClaimsScope(ctx, "am-public-id", "old-scope2")
require.NoError(t, err)
cs3, err := NewClaimsScope("am-public-id", "old-scope3")
cs3, err := NewClaimsScope(ctx, "am-public-id", "old-scope3")
require.NoError(t, err)
return []interface{}{cs, cs2, cs3}
}(),
@@ -905,11 +906,11 @@ func Test_valueObjectChanges(t *testing.T) {
old: []string{"old-scope1", "old-scope2", "old-scope3"},
nullFields: []string{string(ClaimsScopesVO)},
wantDel: func() []interface{} {
cs, err := NewClaimsScope("am-public-id", "old-scope1")
cs, err := NewClaimsScope(ctx, "am-public-id", "old-scope1")
require.NoError(t, err)
cs2, err := NewClaimsScope("am-public-id", "old-scope2")
cs2, err := NewClaimsScope(ctx, "am-public-id", "old-scope2")
require.NoError(t, err)
cs3, err := NewClaimsScope("am-public-id", "old-scope3")
cs3, err := NewClaimsScope(ctx, "am-public-id", "old-scope3")
require.NoError(t, err)
return []interface{}{cs, cs2, cs3}
}(),
@@ -921,11 +922,11 @@ func Test_valueObjectChanges(t *testing.T) {
old: []string{"old-aud1", "old-aud2", "old-aud3"},
nullFields: []string{string(AudClaimVO)},
wantDel: func() []interface{} {
a, err := NewAudClaim("am-public-id", "old-aud1")
a, err := NewAudClaim(ctx, "am-public-id", "old-aud1")
require.NoError(t, err)
a2, err := NewAudClaim("am-public-id", "old-aud2")
a2, err := NewAudClaim(ctx, "am-public-id", "old-aud2")
require.NoError(t, err)
a3, err := NewAudClaim("am-public-id", "old-aud3")
a3, err := NewAudClaim(ctx, "am-public-id", "old-aud3")
require.NoError(t, err)
return []interface{}{a, a2, a3}
}(),
@@ -939,11 +940,11 @@ func Test_valueObjectChanges(t *testing.T) {
old: []string{"old-aud1", "old-aud2", "old-aud3"},
nullFields: []string{string(AudClaimVO)},
wantDel: func() []interface{} {
a, err := NewAudClaim("am-public-id", "old-aud1")
a, err := NewAudClaim(ctx, "am-public-id", "old-aud1")
require.NoError(t, err)
a2, err := NewAudClaim("am-public-id", "old-aud2")
a2, err := NewAudClaim(ctx, "am-public-id", "old-aud2")
require.NoError(t, err)
a3, err := NewAudClaim("am-public-id", "old-aud3")
a3, err := NewAudClaim(ctx, "am-public-id", "old-aud3")
require.NoError(t, err)
return []interface{}{a, a2, a3}
}(),
@@ -957,18 +958,18 @@ func Test_valueObjectChanges(t *testing.T) {
old: []string{"RS256", "RS384", "RS512"},
dbMask: []string{string(SigningAlgVO)},
wantAdd: func() []interface{} {
a, err := NewSigningAlg("am-public-id", ES256)
a, err := NewSigningAlg(ctx, "am-public-id", ES256)
require.NoError(t, err)
a2, err := NewSigningAlg("am-public-id", ES384)
a2, err := NewSigningAlg(ctx, "am-public-id", ES384)
require.NoError(t, err)
return []interface{}{a, a2}
}(),
wantDel: func() []interface{} {
a, err := NewSigningAlg("am-public-id", RS256)
a, err := NewSigningAlg(ctx, "am-public-id", RS256)
require.NoError(t, err)
a2, err := NewSigningAlg("am-public-id", RS384)
a2, err := NewSigningAlg(ctx, "am-public-id", RS384)
require.NoError(t, err)
a3, err := NewSigningAlg("am-public-id", RS512)
a3, err := NewSigningAlg(ctx, "am-public-id", RS512)
require.NoError(t, err)
return []interface{}{a, a2, a3}
}(),
@@ -982,18 +983,18 @@ func Test_valueObjectChanges(t *testing.T) {
old: []string{"RS256", "RS256", "RS512"},
dbMask: []string{string(SigningAlgVO)},
wantAdd: func() []interface{} {
a, err := NewSigningAlg("am-public-id", ES256)
a, err := NewSigningAlg(ctx, "am-public-id", ES256)
require.NoError(t, err)
a2, err := NewSigningAlg("am-public-id", ES384)
a2, err := NewSigningAlg(ctx, "am-public-id", ES384)
require.NoError(t, err)
return []interface{}{a, a2}
}(),
wantDel: func() []interface{} {
a, err := NewSigningAlg("am-public-id", RS256)
a, err := NewSigningAlg(ctx, "am-public-id", RS256)
require.NoError(t, err)
a2, err := NewSigningAlg("am-public-id", RS384)
a2, err := NewSigningAlg(ctx, "am-public-id", RS384)
require.NoError(t, err)
a3, err := NewSigningAlg("am-public-id", RS512)
a3, err := NewSigningAlg(ctx, "am-public-id", RS512)
require.NoError(t, err)
return []interface{}{a, a2, a3}
}(),
@@ -1003,7 +1004,7 @@ func Test_valueObjectChanges(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
gotAdd, gotDel, err := valueObjectChanges(tt.id, tt.voName, tt.new, tt.old, tt.dbMask, tt.nullFields)
gotAdd, gotDel, err := valueObjectChanges(context.TODO(), tt.id, tt.voName, tt.new, tt.old, tt.dbMask, tt.nullFields)
if tt.wantErrMatch != nil {
require.Error(err)
assert.Truef(errors.Match(tt.wantErrMatch, err), "want err code: %q got: %q", tt.wantErrMatch.Code, err)
@@ -1075,7 +1076,7 @@ func Test_validateFieldMask(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
require := require.New(t)
err := validateFieldMask(tt.fieldMask)
err := validateFieldMask(context.TODO(), tt.fieldMask)
if tt.wantErr {
require.Error(err)
return
+34 -34
View File
@@ -22,35 +22,35 @@ import (
func (r *Repository) CreateManagedGroup(ctx context.Context, scopeId string, mg *ManagedGroup, opt ...Option) (*ManagedGroup, error) {
const op = "oidc.(Repository).CreateManagedGroup"
if mg == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing ManagedGroup")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing ManagedGroup")
}
if mg.ManagedGroup == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing embedded ManagedGroup")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing embedded ManagedGroup")
}
if mg.AuthMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
if mg.Filter == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing filter")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing filter")
}
if mg.PublicId != "" {
return nil, errors.New(errors.InvalidParameter, op, "public id must be empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "public id must be empty")
}
if scopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
mg = mg.Clone()
id, err := newManagedGroupId()
id, err := newManagedGroupId(ctx)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
mg.PublicId = id
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"), errors.WithCode(errors.Encrypt))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"), errors.WithCode(errors.Encrypt))
}
var newManagedGroup *ManagedGroup
@@ -58,7 +58,7 @@ func (r *Repository) CreateManagedGroup(ctx context.Context, scopeId string, mg
func(_ db.Reader, w db.Writer) error {
newManagedGroup = mg.Clone()
if err := w.Create(ctx, newManagedGroup, db.WithOplog(oplogWrapper, mg.oplog(oplog.OpType_OP_TYPE_CREATE, scopeId))); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
},
@@ -66,11 +66,11 @@ func (r *Repository) CreateManagedGroup(ctx context.Context, scopeId string, mg
if err != nil {
if errors.IsUniqueError(err) {
return nil, errors.New(errors.NotUnique, op, fmt.Sprintf(
return nil, errors.New(ctx, errors.NotUnique, op, fmt.Sprintf(
"in auth method %s: name %q already exists",
mg.AuthMethodId, mg.Name))
}
return nil, errors.Wrap(err, op, errors.WithMsg(mg.AuthMethodId))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(mg.AuthMethodId))
}
return newManagedGroup, nil
}
@@ -80,7 +80,7 @@ func (r *Repository) CreateManagedGroup(ctx context.Context, scopeId string, mg
func (r *Repository) LookupManagedGroup(ctx context.Context, withPublicId string, opt ...Option) (*ManagedGroup, error) {
const op = "oidc.(Repository).LookupManagedGroup"
if withPublicId == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
a := AllocManagedGroup()
a.PublicId = withPublicId
@@ -88,7 +88,7 @@ func (r *Repository) LookupManagedGroup(ctx context.Context, withPublicId string
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("failed for %s", withPublicId)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("failed for %s", withPublicId)))
}
return a, nil
}
@@ -97,7 +97,7 @@ func (r *Repository) LookupManagedGroup(ctx context.Context, withPublicId string
func (r *Repository) ListManagedGroups(ctx context.Context, withAuthMethodId string, opt ...Option) ([]*ManagedGroup, error) {
const op = "oidc.(Repository).ListManagedGroups"
if withAuthMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
opts := getOpts(opt...)
limit := r.defaultLimit
@@ -108,7 +108,7 @@ func (r *Repository) ListManagedGroups(ctx context.Context, withAuthMethodId str
var mgs []*ManagedGroup
err := r.reader.SearchWhere(ctx, &mgs, "auth_method_id = ?", []interface{}{withAuthMethodId}, db.WithLimit(limit))
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return mgs, nil
}
@@ -119,17 +119,17 @@ func (r *Repository) ListManagedGroups(ctx context.Context, withAuthMethodId str
func (r *Repository) DeleteManagedGroup(ctx context.Context, scopeId, withPublicId string, opt ...Option) (int, error) {
const op = "oidc.(Repository).DeleteManagedGroup"
if withPublicId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
if scopeId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing scope id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
mg := AllocManagedGroup()
mg.PublicId = withPublicId
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
}
var rowsDeleted int
@@ -142,17 +142,17 @@ func (r *Repository) DeleteManagedGroup(ctx context.Context, scopeId, withPublic
dMg := mg.Clone()
rowsDeleted, err = w.Delete(ctx, dMg, db.WithOplog(oplogWrapper, metadata))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsDeleted > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been deleted")
}
return nil
},
)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(withPublicId))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(withPublicId))
}
return rowsDeleted, nil
@@ -172,19 +172,19 @@ func (r *Repository) DeleteManagedGroup(ctx context.Context, scopeId, withPublic
func (r *Repository) UpdateManagedGroup(ctx context.Context, scopeId string, mg *ManagedGroup, version uint32, fieldMaskPaths []string, opt ...Option) (*ManagedGroup, int, error) {
const op = "oidc.(Repository).UpdateManagedGroup"
if mg == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing ManagedGroup")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing ManagedGroup")
}
if mg.ManagedGroup == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing embedded ManagedGroup")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing embedded ManagedGroup")
}
if mg.PublicId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
if version == 0 {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing version")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing version")
}
if scopeId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
for _, f := range fieldMaskPaths {
@@ -193,7 +193,7 @@ func (r *Repository) UpdateManagedGroup(ctx context.Context, scopeId string, mg
case strings.EqualFold(DescriptionField, f):
case strings.EqualFold(FilterField, f):
default:
return nil, db.NoRowsAffected, errors.New(errors.InvalidFieldMask, op, f)
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, f)
}
}
var dbMask, nullFields []string
@@ -207,12 +207,12 @@ func (r *Repository) UpdateManagedGroup(ctx context.Context, scopeId string, mg
nil,
)
if len(dbMask) == 0 && len(nullFields) == 0 {
return nil, db.NoRowsAffected, errors.New(errors.EmptyFieldMask, op, "missing field mask")
return nil, db.NoRowsAffected, errors.New(ctx, errors.EmptyFieldMask, op, "missing field mask")
}
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithCode(errors.Encrypt),
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt),
errors.WithMsg(("unable to get oplog wrapper")))
}
@@ -230,10 +230,10 @@ func (r *Repository) UpdateManagedGroup(ctx context.Context, scopeId string, mg
var err error
rowsUpdated, err = w.Update(ctx, returnedManagedGroup, dbMask, nullFields, db.WithOplog(oplogWrapper, metadata), db.WithVersion(&version))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsUpdated > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been updated")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been updated")
}
return nil
},
@@ -241,10 +241,10 @@ func (r *Repository) UpdateManagedGroup(ctx context.Context, scopeId string, mg
if err != nil {
if errors.IsUniqueError(err) {
return nil, db.NoRowsAffected, errors.New(errors.NotUnique, op,
return nil, db.NoRowsAffected, errors.New(ctx, errors.NotUnique, op,
fmt.Sprintf("name %s already exists: %s", mg.Name, mg.PublicId))
}
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(mg.PublicId))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(mg.PublicId))
}
return returnedManagedGroup, rowsUpdated, nil
@@ -21,37 +21,37 @@ import (
func (r *Repository) SetManagedGroupMemberships(ctx context.Context, am *AuthMethod, acct *Account, mgs []*ManagedGroup, _ ...Option) ([]*ManagedGroupMemberAccount, int, error) {
const op = "oidc.(Repository).SetManagedGroupMemberships"
if am == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing auth method")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing auth method")
}
if am.AuthMethod == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing auth method store")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing auth method store")
}
if am.PublicId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
if am.ScopeId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing auth method scope id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing auth method scope id")
}
if acct == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing account")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing account")
}
if acct.Account == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing account store")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing account store")
}
if acct.PublicId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing account id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing account id")
}
oplogWrapper, err := r.kms.GetWrapper(ctx, am.ScopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
}
newMgPublicIds := make(map[string]bool, len(mgs))
mgsToUpdate := make([]*ManagedGroup, 0, len(mgs))
for _, mg := range mgs {
if mg.Version == 0 {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, fmt.Sprintf("missing version for managed group %s", mg.PublicId))
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("missing version for managed group %s", mg.PublicId))
}
if newMgPublicIds[mg.PublicId] {
// We've already seen this -- could be a duplicate in the incoming
@@ -80,7 +80,7 @@ func (r *Repository) SetManagedGroupMemberships(ctx context.Context, am *AuthMet
// we need to write oplog entries for deletes and adds.
mgTicket, err := w.GetTicket(ticketMg)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket for oidc managed groups"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket for oidc managed groups"))
}
msgs := make([]*oplog.Message, 0, len(mgs)+5)
@@ -100,17 +100,17 @@ func (r *Repository) SetManagedGroupMemberships(ctx context.Context, am *AuthMet
prevVersion := mgToUpdate.Version - 1
rowsUpdated, err := w.Update(ctx, mgToUpdate, []string{"Version"}, nil, db.NewOplogMsg(&mgOplogMsg), db.WithVersion(&prevVersion))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsUpdated != 1 {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("updated oidc managed group and %d rows updated", rowsUpdated))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated oidc managed group and %d rows updated", rowsUpdated))
}
msgs = append(msgs, &mgOplogMsg)
}
currentMemberships, err = r.ListManagedGroupMembershipsByMember(ctx, acct.PublicId, WithReader(reader))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to retrieve current managed group memberships before deletion"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to retrieve current managed group memberships before deletion"))
}
// Figure out which ones to delete and which ones we already have
@@ -136,7 +136,7 @@ func (r *Repository) SetManagedGroupMemberships(ctx context.Context, am *AuthMet
// also none to delete, we return at this point. Nothing will have
// changed and nothing will be changed either.
if len(mgs) == 0 && len(toDelete) == 0 {
return errors.New(errors.GracefullyAborted, op, "nothing to do")
return errors.New(ctx, errors.GracefullyAborted, op, "nothing to do")
}
// Start with deletion
@@ -145,10 +145,10 @@ func (r *Repository) SetManagedGroupMemberships(ctx context.Context, am *AuthMet
deleteOplogMsgs := make([]*oplog.Message, 0, len(toDelete))
rowsDeleted, err := w.DeleteItems(ctx, toDelete, db.NewOplogMsgs(&deleteOplogMsgs))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to delete managed group member accounts"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to delete managed group member accounts"))
}
if rowsDeleted != len(toDelete) {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("managed group member accounts deleted %d did not match request for %d", rowsDeleted, len(toDelete)))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("managed group member accounts deleted %d did not match request for %d", rowsDeleted, len(toDelete)))
}
totalRowsAffected += rowsDeleted
msgs = append(msgs, deleteOplogMsgs...)
@@ -166,7 +166,7 @@ func (r *Repository) SetManagedGroupMemberships(ctx context.Context, am *AuthMet
toAdd = append(toAdd, newMg)
}
if err := w.CreateItems(ctx, toAdd, db.NewOplogMsgs(&addOplogMsgs)); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to add managed group member accounts"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add managed group member accounts"))
}
totalRowsAffected += len(toAdd)
msgs = append(msgs, addOplogMsgs...)
@@ -174,18 +174,18 @@ func (r *Repository) SetManagedGroupMemberships(ctx context.Context, am *AuthMet
if len(msgs) > 0 {
if err := w.WriteOplogEntryWith(ctx, oplogWrapper, mgTicket, metadata, msgs); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog"))
}
}
currentMemberships, err = r.ListManagedGroupMembershipsByMember(ctx, acct.PublicId, WithReader(reader))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to retrieve current managed group memberships after set"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to retrieve current managed group memberships after set"))
}
return nil
})
if err != nil && !errors.Match(errors.T(errors.GracefullyAborted), err) {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
return currentMemberships, totalRowsAffected, nil
}
@@ -195,7 +195,7 @@ func (r *Repository) SetManagedGroupMemberships(ctx context.Context, am *AuthMet
func (r *Repository) ListManagedGroupMembershipsByMember(ctx context.Context, withAcctId string, opt ...Option) ([]*ManagedGroupMemberAccount, error) {
const op = "oidc.(Repository).ListManagedGroupMembershipsByMember"
if withAcctId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing account id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing account id")
}
opts := getOpts(opt...)
limit := r.defaultLimit
@@ -210,7 +210,7 @@ func (r *Repository) ListManagedGroupMembershipsByMember(ctx context.Context, wi
var mgs []*ManagedGroupMemberAccount
err := reader.SearchWhere(ctx, &mgs, "member_id = ?", []interface{}{withAcctId}, db.WithLimit(limit))
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return mgs, nil
}
@@ -220,7 +220,7 @@ func (r *Repository) ListManagedGroupMembershipsByMember(ctx context.Context, wi
func (r *Repository) ListManagedGroupMembershipsByGroup(ctx context.Context, withGroupId string, opt ...Option) ([]*ManagedGroupMemberAccount, error) {
const op = "oidc.(Repository).ListManagedGroupMembershipsByGroup"
if withGroupId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing managed group id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing managed group id")
}
opts := getOpts(opt...)
limit := r.defaultLimit
@@ -235,7 +235,7 @@ func (r *Repository) ListManagedGroupMembershipsByGroup(ctx context.Context, wit
var mgs []*ManagedGroupMemberAccount
err := reader.SearchWhere(ctx, &mgs, "managed_group_id = ?", []interface{}{withGroupId}, db.WithLimit(limit))
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return mgs, nil
}
@@ -51,7 +51,7 @@ func Test_ManagedGroupMemberships(t *testing.T) {
oidc.WithApiUrl(oidc.TestConvertToUrls(t, "https://www.alice.com/callback")[0]),
)
repo, err := oidc.NewRepository(rw, rw, kmsCache)
repo, err := oidc.NewRepository(ctx, rw, rw, kmsCache)
require.NoError(t, err)
require.NotNil(t, repo)
@@ -182,7 +182,7 @@ func TestRepository_CreateManagedGroup(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.CreateManagedGroup(context.Background(), tt.scopeId, tt.in, tt.opts...)
@@ -232,7 +232,7 @@ func TestRepository_LookupManagedGroup(t *testing.T) {
)
mg := TestManagedGroup(t, conn, authMethod, TestFakeManagedGroupFilter)
newMgId, err := newManagedGroupId()
newMgId, err := newManagedGroupId(ctx)
require.NoError(t, err)
tests := []struct {
name string
@@ -261,7 +261,7 @@ func TestRepository_LookupManagedGroup(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.LookupManagedGroup(context.Background(), tt.in)
@@ -296,7 +296,7 @@ func TestRepository_DeleteManagedGroup(t *testing.T) {
WithApiUrl(TestConvertToUrls(t, "https://www.alice.com/callback")[0]),
)
mg := TestManagedGroup(t, conn, authMethod, TestFakeManagedGroupFilter)
newMgId, err := newManagedGroupId()
newMgId, err := newManagedGroupId(ctx)
require.NoError(t, err)
tests := []struct {
name string
@@ -337,7 +337,7 @@ func TestRepository_DeleteManagedGroup(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.DeleteManagedGroup(context.Background(), tt.scopeId, tt.in)
@@ -437,7 +437,7 @@ func TestRepository_ListManagedGroups(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.ListManagedGroups(context.Background(), tt.in, tt.opts...)
@@ -531,7 +531,7 @@ func TestRepository_ListManagedGroups_Limits(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache, tt.repoOpts...)
repo, err := NewRepository(ctx, rw, rw, kmsCache, tt.repoOpts...)
assert.NoError(err)
require.NotNil(repo)
got, err := repo.ListManagedGroups(context.Background(), am.GetPublicId(), tt.listOpts...)
@@ -918,7 +918,7 @@ func TestRepository_UpdateManagedGroup(t *testing.T) {
tt := tt
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
assert.NoError(err)
require.NotNil(repo)
+3 -1
View File
@@ -1,6 +1,7 @@
package oidc
import (
"context"
"testing"
"github.com/hashicorp/boundary/internal/db"
@@ -11,6 +12,7 @@ import (
)
func TestNewRepository(t *testing.T) {
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -101,7 +103,7 @@ func TestNewRepository(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
got, err := NewRepository(tt.args.r, tt.args.w, tt.args.kms, tt.args.opts...)
got, err := NewRepository(ctx, tt.args.r, tt.args.w, tt.args.kms, tt.args.opts...)
if tt.wantErrMatch != nil {
require.Error(err)
assert.Truef(errors.Match(tt.wantErrMatch, err), "want err code: %q got: %q", tt.wantErrMatch, err)
+23 -19
View File
@@ -1,66 +1,70 @@
package request
import "github.com/hashicorp/boundary/internal/errors"
import (
"context"
"github.com/hashicorp/boundary/internal/errors"
)
// Validate the request.State
func (s *State) Validate() error {
func (s *State) Validate(ctx context.Context) error {
const op = "request.(State).Validate"
if s == nil {
return errors.New(errors.InvalidParameter, op, "missing state")
return errors.New(ctx, errors.InvalidParameter, op, "missing state")
}
if s.TokenRequestId == "" {
return errors.New(errors.InvalidParameter, op, "missing token request id")
return errors.New(ctx, errors.InvalidParameter, op, "missing token request id")
}
if s.CreateTime == nil {
return errors.New(errors.InvalidParameter, op, "missing create time")
return errors.New(ctx, errors.InvalidParameter, op, "missing create time")
}
if s.ExpirationTime == nil {
return errors.New(errors.InvalidParameter, op, "missing expiration time")
return errors.New(ctx, errors.InvalidParameter, op, "missing expiration time")
}
if s.FinalRedirectUrl == "" {
return errors.New(errors.InvalidParameter, op, "missing final redirect URL")
return errors.New(ctx, errors.InvalidParameter, op, "missing final redirect URL")
}
if s.Nonce == "" {
return errors.New(errors.InvalidParameter, op, "missing nonce")
return errors.New(ctx, errors.InvalidParameter, op, "missing nonce")
}
if s.ProviderConfigHash == 0 {
return errors.New(errors.InvalidParameter, op, "missing provider config hash")
return errors.New(ctx, errors.InvalidParameter, op, "missing provider config hash")
}
return nil
}
// Validate the request.Wrapper
func (w *Wrapper) Validate() error {
func (w *Wrapper) Validate(ctx context.Context) error {
const op = "request.(Wrapper).Validate"
if w == nil {
return errors.New(errors.InvalidParameter, op, "missing wrapper")
return errors.New(ctx, errors.InvalidParameter, op, "missing wrapper")
}
if w.AuthMethodId == "" {
return errors.New(errors.InvalidParameter, op, "missing auth method id")
return errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
if w.ScopeId == "" {
return errors.New(errors.InvalidParameter, op, "missing scope id")
return errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
if w.WrapperKeyId == "" {
return errors.New(errors.InvalidParameter, op, "missing wrapper key id")
return errors.New(ctx, errors.InvalidParameter, op, "missing wrapper key id")
}
if len(w.Ct) == 0 {
return errors.New(errors.InvalidParameter, op, "missing ct")
return errors.New(ctx, errors.InvalidParameter, op, "missing ct")
}
return nil
}
// Validate the request.Token
func (t *Token) Validate() error {
func (t *Token) Validate(ctx context.Context) error {
const op = "request.(Token).Validate"
if t == nil {
return errors.New(errors.InvalidParameter, op, "missing token")
return errors.New(ctx, errors.InvalidParameter, op, "missing token")
}
if t.RequestId == "" {
return errors.New(errors.InvalidParameter, op, "missing request id")
return errors.New(ctx, errors.InvalidParameter, op, "missing request id")
}
if t.ExpirationTime == nil {
return errors.New(errors.InvalidParameter, op, "missing expiration time")
return errors.New(ctx, errors.InvalidParameter, op, "missing expiration time")
}
return nil
}
+28 -28
View File
@@ -59,46 +59,46 @@ type validator interface {
func encryptMessage(ctx context.Context, wrapper wrapping.Wrapper, am *AuthMethod, m proto.Message) (encodedEncryptedState string, e error) {
const op = "oidc.encryptMessage"
if wrapper == nil {
return "", errors.New(errors.InvalidParameter, op, "missing wrapper")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing wrapper")
}
if wrapper.KeyID() == "" {
return "", errors.New(errors.InvalidParameter, op, "missing wrapper key id")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing wrapper key id")
}
if am == nil || am.AuthMethod == nil {
return "", errors.New(errors.InvalidParameter, op, "missing auth method")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing auth method")
}
if am.ScopeId == "" {
return "", errors.New(errors.InvalidParameter, op, "missing auth method scope id")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing auth method scope id")
}
if am.PublicId == "" {
return "", errors.New(errors.InvalidParameter, op, "missing auth method public id")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing auth method public id")
}
if m == nil {
return "", errors.New(errors.InvalidParameter, op, "missing message to encrypt")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing message to encrypt")
}
switch v := m.(type) {
case *request.State, *request.Token:
default:
return "", errors.New(errors.InvalidParameter, op, fmt.Sprintf("unsupported message type %v for encryption", v))
return "", errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("unsupported message type %v for encryption", v))
}
v, ok := m.(validator)
if ok {
if err := v.Validate(); err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
}
marshaled, err := proto.Marshal(m)
if err != nil {
return "", errors.Wrap(err, op, errors.WithMsg("unable to marshal message"), errors.WithCode(errors.Encode))
return "", errors.Wrap(ctx, err, op, errors.WithMsg("unable to marshal message"), errors.WithCode(errors.Encode))
}
blobInfo, err := wrapper.Encrypt(ctx, marshaled, []byte(fmt.Sprintf("%s%s", am.PublicId, am.ScopeId)))
if err != nil {
return "", errors.New(errors.Encrypt, op, "unable to encrypt message", errors.WithWrap(err))
return "", errors.New(ctx, errors.Encrypt, op, "unable to encrypt message", errors.WithWrap(err))
}
marshaledBlob, err := proto.Marshal(blobInfo)
if err != nil {
return "", errors.Wrap(err, op, errors.WithMsg("unable to marshal blob"), errors.WithCode(errors.Encode))
return "", errors.Wrap(ctx, err, op, errors.WithMsg("unable to marshal blob"), errors.WithCode(errors.Encode))
}
wrapped := &request.Wrapper{
AuthMethodId: am.PublicId,
@@ -106,12 +106,12 @@ func encryptMessage(ctx context.Context, wrapper wrapping.Wrapper, am *AuthMetho
WrapperKeyId: wrapper.KeyID(),
Ct: marshaledBlob,
}
if err := wrapped.Validate(); err != nil {
return "", errors.Wrap(err, op)
if err := wrapped.Validate(ctx); err != nil {
return "", errors.Wrap(ctx, err, op)
}
marshaledEncryptedSt, err := proto.Marshal(wrapped)
if err != nil {
return "", errors.New(errors.Unknown, op, "unable to marshal encrypted message", errors.WithWrap(err))
return "", errors.New(ctx, errors.Unknown, op, "unable to marshal encrypted message", errors.WithWrap(err))
}
return base58.FastBase58Encoding(marshaledEncryptedSt), nil
@@ -122,19 +122,19 @@ func encryptMessage(ctx context.Context, wrapper wrapping.Wrapper, am *AuthMetho
func decryptMessage(ctx context.Context, wrappingWrapper wrapping.Wrapper, wrappedRequest *request.Wrapper) (messageBytes []byte, e error) {
const op = "oidc.decryptMessage"
if wrappedRequest == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing wrapped request")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing wrapped request")
}
if wrappingWrapper == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing wrapping wrapper")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing wrapping wrapper")
}
var blobInfo wrapping.EncryptedBlobInfo
if err := proto.Unmarshal(wrappedRequest.Ct, &blobInfo); err != nil {
return nil, errors.New(errors.Unknown, op, "unable to marshal blob info", errors.WithWrap(err))
return nil, errors.New(ctx, errors.Unknown, op, "unable to marshal blob info", errors.WithWrap(err))
}
decryptedMsg, err := wrappingWrapper.Decrypt(ctx, &blobInfo, []byte(fmt.Sprintf("%s%s", wrappedRequest.AuthMethodId, wrappedRequest.ScopeId)))
if err != nil {
return nil, errors.New(errors.Decrypt, op, "unable to decrypt message", errors.WithWrap(err))
return nil, errors.New(ctx, errors.Decrypt, op, "unable to decrypt message", errors.WithWrap(err))
}
return decryptedMsg, nil
}
@@ -144,11 +144,11 @@ func UnwrapMessage(ctx context.Context, encodedWrappedMsg string) (*request.Wrap
const op = ""
decoded, err := base58.FastBase58Decoding(encodedWrappedMsg)
if err != nil {
return nil, errors.New(errors.Unknown, op, "unable to decode message", errors.WithWrap(err))
return nil, errors.New(ctx, errors.Unknown, op, "unable to decode message", errors.WithWrap(err))
}
var wrapper request.Wrapper
if err := proto.Unmarshal(decoded, &wrapper); err != nil {
return nil, errors.New(errors.Unknown, op, "unable to marshal encoded/encrypted message", errors.WithWrap(err))
return nil, errors.New(ctx, errors.Unknown, op, "unable to marshal encoded/encrypted message", errors.WithWrap(err))
}
return &wrapper, nil
}
@@ -166,19 +166,19 @@ func UnwrapMessage(ctx context.Context, encodedWrappedMsg string) (*request.Wrap
func requestWrappingWrapper(ctx context.Context, k *kms.Kms, scopeId, authMethodId string, opt ...Option) (wrapping.Wrapper, error) {
const op = "oidc.(Repository).oidcWrapper"
if k == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing kms")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing kms")
}
if scopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
if authMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
opts := getOpts(opt...)
// get a specific oidcWrapper using the WithKeyId(...) option
oidcWrapper, err := k.GetWrapper(ctx, scopeId, kms.KeyPurposeOidc, kms.WithKeyId(opts.withKeyId))
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oidc wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oidc wrapper"))
}
// What derived key are we looking for?
@@ -191,20 +191,20 @@ func requestWrappingWrapper(ctx context.Context, k *kms.Kms, scopeId, authMethod
// okay, I guess we need to derive a new key for this combo of oidcWrapper and authMethod
reader, err := kms.NewDerivedReader(oidcWrapper, 32, []byte(authMethodId), []byte(scopeId))
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
privKey, _, err := ed25519.GenerateKey(reader)
if err != nil {
return nil, errors.New(errors.Encrypt, op, "unable to generate key", errors.WithWrap(err))
return nil, errors.New(ctx, errors.Encrypt, op, "unable to generate key", errors.WithWrap(err))
}
wrapper := aead.NewWrapper(nil)
if _, err := wrapper.SetConfig(map[string]string{
"key_id": keyId,
}); err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("error setting config on aead wrapper in auth method %s", authMethodId)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("error setting config on aead wrapper in auth method %s", authMethodId)))
}
if err := wrapper.SetAESGCMKeyBytes(privKey); err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("error setting key bytes on aead wrapper in auth method %s", authMethodId)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("error setting key bytes on aead wrapper in auth method %s", authMethodId)))
}
// store the derived key in our cache
k.GetDerivedPurposeCache().Store(keyId, wrapper)
+33 -33
View File
@@ -52,22 +52,22 @@ func Callback(
state, code string) (finalRedirect string, e error) {
const op = "oidc.Callback"
if oidcRepoFn == nil {
return "", errors.New(errors.InvalidParameter, op, "missing oidc repository function")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing oidc repository function")
}
if iamRepoFn == nil {
return "", errors.New(errors.InvalidParameter, op, "missing iam repository function")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing iam repository function")
}
if atRepoFn == nil {
return "", errors.New(errors.InvalidParameter, op, "missing auth token repository function")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing auth token repository function")
}
if am == nil {
return "", errors.New(errors.InvalidParameter, op, "missing auth method")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing auth method")
}
if state == "" {
return "", errors.New(errors.InvalidParameter, op, "missing state")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing state")
}
if code == "" {
return "", errors.New(errors.InvalidParameter, op, "missing code")
return "", errors.New(ctx, errors.InvalidParameter, op, "missing code")
}
// One comment before we begin, Callback orchestrates repositories which
@@ -82,55 +82,55 @@ func Callback(
r, err := oidcRepoFn()
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
// state is a proto request.Wrapper msg, which contains a cipher text field, so
// we need the derived wrapper that was used to encrypt it.
requestWrapper, err := requestWrappingWrapper(ctx, r.kms, am.ScopeId, am.GetPublicId())
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
stateWrapper, err := UnwrapMessage(ctx, state)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
// it appears the authentication request was started with one auth method
// and the callback came to a different auth method.
if stateWrapper.AuthMethodId != am.GetPublicId() {
return "", errors.New(errors.InvalidParameter, op, fmt.Sprintf("%s auth method id does not match request wrapper auth method id: %s", am.GetPublicId(), stateWrapper))
return "", errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("%s auth method id does not match request wrapper auth method id: %s", am.GetPublicId(), stateWrapper))
}
stateBytes, err := decryptMessage(ctx, requestWrapper, stateWrapper)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
var reqState request.State
if err := proto.Unmarshal(stateBytes, &reqState); err != nil {
return "", errors.New(errors.Unknown, op, "unable to unmarshal request state", errors.WithWrap(err))
return "", errors.New(ctx, errors.Unknown, op, "unable to unmarshal request state", errors.WithWrap(err))
}
// get the provider from the cache (if possible). FYI: "get" just does the right thing
// about comparing the cache with the auth method from the db.
provider, err := providerCache().get(ctx, am)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
// if auth method is inactive, we don't allow inflight requests to finish if the
// auth method's config has changed since the request was kicked off.
hash, err := provider.ConfigHash()
if err != nil {
return "", errors.New(errors.Unknown, op, "unable to get provider config hash", errors.WithWrap(err))
return "", errors.New(ctx, errors.Unknown, op, "unable to get provider config hash", errors.WithWrap(err))
}
if reqState.ProviderConfigHash != hash && am.OperationalState == string(InactiveState) {
return "", errors.New(errors.AuthMethodInactive, op, "auth method configuration changed during in-flight authentication attempt")
return "", errors.New(ctx, errors.AuthMethodInactive, op, "auth method configuration changed during in-flight authentication attempt")
}
// before proceeding, make sure the request hasn't timed out
if time.Now().After(reqState.ExpirationTime.Timestamp.AsTime()) {
return "", errors.New(errors.AuthAttemptExpired, op, "request state has expired")
return "", errors.New(ctx, errors.AuthAttemptExpired, op, "request state has expired")
}
// now, we need to prep for the token exchange with the oidc provider, which
@@ -151,15 +151,15 @@ func Callback(
opts = append(opts, oidc.WithAudiences(am.AudClaims...))
}
if strings.TrimSpace(am.ApiUrl) == "" {
return "", errors.New(errors.InvalidParameter, op, "empty api URL")
return "", errors.New(ctx, errors.InvalidParameter, op, "empty api URL")
}
oidcRequest, err := oidc.NewRequest(AttemptExpiration, fmt.Sprintf(CallbackEndpoint, am.ApiUrl), opts...)
if err != nil {
return "", errors.New(errors.Unknown, op, "unable to create oidc request for token exchange", errors.WithWrap(err))
return "", errors.New(ctx, errors.Unknown, op, "unable to create oidc request for token exchange", errors.WithWrap(err))
}
tk, err := provider.Exchange(ctx, oidcRequest, state, code)
if err != nil {
return "", errors.New(errors.Unknown, op, "unable to complete exchange with oidc provider", errors.WithWrap(err))
return "", errors.New(ctx, errors.Unknown, op, "unable to complete exchange with oidc provider", errors.WithWrap(err))
}
// okay, now we need some claims from both the ID Token and userinfo, so we can
@@ -168,29 +168,29 @@ func Callback(
userInfoClaims := map[string]interface{}{} // intentionally, NOT nil for call to upsertAccount(...)
if err := tk.IDToken().Claims(&idTkClaims); err != nil {
return "", errors.New(errors.Unknown, op, "unable to parse ID Token claims", errors.WithWrap(err))
return "", errors.New(ctx, errors.Unknown, op, "unable to parse ID Token claims", errors.WithWrap(err))
}
userInfoTokenSource := tk.StaticTokenSource()
if userInfoTokenSource != nil {
sub, ok := idTkClaims["sub"].(string)
if !ok {
return "", errors.New(errors.Unknown, op, "subject is not present in ID Token, which should not be possible")
return "", errors.New(ctx, errors.Unknown, op, "subject is not present in ID Token, which should not be possible")
}
if err := provider.UserInfo(ctx, userInfoTokenSource, sub, &userInfoClaims); err != nil {
return "", errors.New(errors.Unknown, op, "unable to get user info from provider", errors.WithWrap(err))
return "", errors.New(ctx, errors.Unknown, op, "unable to get user info from provider", errors.WithWrap(err))
}
}
acct, err := r.upsertAccount(ctx, am, idTkClaims, userInfoClaims)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
// Get the set of all managed groups so we can filter
mgs, err := r.ListManagedGroups(ctx, am.GetPublicId())
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
if len(mgs) > 0 {
matchedMgs := make([]*ManagedGroup, 0, len(mgs))
@@ -204,11 +204,11 @@ func Callback(
if err != nil {
// We check all filters on ingress so this should never happen,
// but we validate anyways
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
match, err := eval.Evaluate(evalData)
if err != nil && !errors.Is(err, pointerstructure.ErrNotFound) {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
if match {
matchedMgs = append(matchedMgs, mg)
@@ -217,7 +217,7 @@ func Callback(
// We always pass it in, even if none match, because in that case we
// need to remove any mappings that exist
if _, _, err := r.SetManagedGroupMemberships(ctx, am, acct, matchedMgs); err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
}
@@ -226,17 +226,17 @@ func Callback(
// autovivify users for the scope.
iamRepo, err := iamRepoFn()
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
scope, err := iamRepo.LookupScope(ctx, am.ScopeId)
if err != nil {
return "", errors.Wrap(err, op, errors.WithMsg("unable to lookup account scope: "+scope.PublicId))
return "", errors.Wrap(ctx, err, op, errors.WithMsg("unable to lookup account scope: "+scope.PublicId))
}
user, err := iamRepo.LookupUserWithLogin(ctx, acct.PublicId)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
// Now we need to check filters and assign managed groups by filter.
@@ -246,13 +246,13 @@ func Callback(
// that initialed the authentication attempt.
tokenRepo, err := atRepoFn()
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
if _, err := tokenRepo.CreateAuthToken(ctx, user, acct.PublicId, authtoken.WithPublicId(reqState.TokenRequestId), authtoken.WithStatus(authtoken.PendingStatus)); err != nil {
if errors.Match(errors.T(errors.NotUnique), err) {
return "", errors.New(errors.Forbidden, op, "not a unique request", errors.WithWrap(err))
return "", errors.New(ctx, errors.Forbidden, op, "not a unique request", errors.WithWrap(err))
}
return "", errors.Wrap(err, op)
return "", errors.Wrap(ctx, err, op)
}
// tada! we can return a final redirect URL for the successful authentication.
return reqState.FinalRedirectUrl, nil
+6 -6
View File
@@ -41,7 +41,7 @@ func Test_Callback(t *testing.T) {
return iam.NewRepository(rw, rw, kmsCache)
}
repoFn := func() (*Repository, error) {
return NewRepository(rw, rw, kmsCache)
return NewRepository(ctx, rw, rw, kmsCache)
}
atRepoFn := func() (*authtoken.Repository, error) {
return authtoken.NewRepository(rw, rw, kmsCache)
@@ -65,7 +65,7 @@ func Test_Callback(t *testing.T) {
// test provider for the tests (see the oidc package docs for more info)
// it will provide discovery, JWKs, a token endpoint, etc for these tests.
tp := oidc.StartTestProvider(t)
tpCert, err := ParseCertificates(tp.CACert())
tpCert, err := ParseCertificates(ctx, tp.CACert())
require.NoError(t, err)
_, _, tpAlg, _ := tp.SigningKeys()
@@ -513,7 +513,7 @@ func Test_StartAuth_to_Callback(t *testing.T) {
return iam.NewRepository(rw, rw, kmsCache)
}
repoFn := func() (*Repository, error) {
return NewRepository(rw, rw, kmsCache)
return NewRepository(ctx, rw, rw, kmsCache)
}
atRepoFn := func() (*authtoken.Repository, error) {
return authtoken.NewRepository(rw, rw, kmsCache)
@@ -531,7 +531,7 @@ func Test_StartAuth_to_Callback(t *testing.T) {
// the testing OIDC provider (it's a functional fake, see the package docs)
tp := oidc.StartTestProvider(t)
tpCert, err := ParseCertificates(tp.CACert())
tpCert, err := ParseCertificates(ctx, tp.CACert())
require.NoError(err)
_, _, tpAlg, _ := tp.SigningKeys()
@@ -617,7 +617,7 @@ func Test_ManagedGroupFiltering(t *testing.T) {
return iam.NewRepository(rw, rw, kmsCache)
}
repoFn := func() (*Repository, error) {
return NewRepository(rw, rw, kmsCache)
return NewRepository(ctx, rw, rw, kmsCache)
}
atRepoFn := func() (*authtoken.Repository, error) {
return authtoken.NewRepository(rw, rw, kmsCache)
@@ -639,7 +639,7 @@ func Test_ManagedGroupFiltering(t *testing.T) {
// test provider for the tests (see the oidc package docs for more info)
// it will provide discovery, JWKs, a token endpoint, etc for these tests.
tp := oidc.StartTestProvider(t)
tpCert, err := ParseCertificates(tp.CACert())
tpCert, err := ParseCertificates(ctx, tp.CACert())
require.NoError(t, err)
_, _, tpAlg, _ := tp.SigningKeys()
+16 -16
View File
@@ -33,30 +33,30 @@ import (
func StartAuth(ctx context.Context, oidcRepoFn OidcRepoFactory, authMethodId string, opt ...Option) (authUrl *url.URL, tokenId string, e error) {
const op = "oidc.StartAuth"
if authMethodId == "" {
return nil, "", errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, "", errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
if oidcRepoFn == nil {
return nil, "", errors.New(errors.InvalidParameter, op, "missing oidc repo function")
return nil, "", errors.New(ctx, errors.InvalidParameter, op, "missing oidc repo function")
}
r, err := oidcRepoFn()
if err != nil {
return nil, "", errors.Wrap(err, op)
return nil, "", errors.Wrap(ctx, err, op)
}
am, err := r.lookupAuthMethod(ctx, authMethodId)
if err != nil {
return nil, "", errors.Wrap(err, op)
return nil, "", errors.Wrap(ctx, err, op)
}
if am == nil {
return nil, "", errors.New(errors.RecordNotFound, op, fmt.Sprintf("auth method %s not found", authMethodId))
return nil, "", errors.New(ctx, errors.RecordNotFound, op, fmt.Sprintf("auth method %s not found", authMethodId))
}
if am.OperationalState == string(InactiveState) {
return nil, "", errors.New(errors.AuthMethodInactive, op, "not allowed to start authentication attempt")
return nil, "", errors.New(ctx, errors.AuthMethodInactive, op, "not allowed to start authentication attempt")
}
// get the provider from the cache (if possible)
provider, err := providerCache().get(ctx, am)
if err != nil {
return nil, "", errors.Wrap(err, op)
return nil, "", errors.Wrap(ctx, err, op)
}
callbackRedirect := fmt.Sprintf(CallbackEndpoint, am.GetApiUrl())
@@ -72,15 +72,15 @@ func StartAuth(ctx context.Context, oidcRepoFn OidcRepoFactory, authMethodId str
exp := timestamppb.New(now.Add(AttemptExpiration).Truncate(time.Second))
tokenRequestId, err := authtoken.NewAuthTokenId()
if err != nil {
return nil, "", errors.Wrap(err, op)
return nil, "", errors.Wrap(ctx, err, op)
}
nonce, err := oidc.NewID()
if err != nil {
return nil, "", errors.New(errors.Unknown, op, "unable to generate nonce", errors.WithWrap(err))
return nil, "", errors.New(ctx, errors.Unknown, op, "unable to generate nonce", errors.WithWrap(err))
}
hash, err := provider.ConfigHash()
if err != nil {
return nil, "", errors.New(errors.Unknown, op, "unable to get provider config hash", errors.WithWrap(err))
return nil, "", errors.New(ctx, errors.Unknown, op, "unable to get provider config hash", errors.WithWrap(err))
}
st := &request.State{
TokenRequestId: tokenRequestId,
@@ -93,11 +93,11 @@ func StartAuth(ctx context.Context, oidcRepoFn OidcRepoFactory, authMethodId str
requestWrapper, err := requestWrappingWrapper(ctx, r.kms, am.ScopeId, authMethodId)
if err != nil {
return nil, "", errors.Wrap(err, op)
return nil, "", errors.Wrap(ctx, err, op)
}
encodedEncryptedSt, err := encryptMessage(ctx, requestWrapper, am, st)
if err != nil {
return nil, "", errors.Wrap(err, op)
return nil, "", errors.Wrap(ctx, err, op)
}
oidcOpts := []oidc.Option{
oidc.WithState(string(encodedEncryptedSt)),
@@ -123,16 +123,16 @@ func StartAuth(ctx context.Context, oidcRepoFn OidcRepoFactory, authMethodId str
callbackRedirect,
oidcOpts...)
if err != nil {
return nil, "", errors.New(errors.Unknown, op, "unable to create oidc request", errors.WithWrap(err))
return nil, "", errors.New(ctx, errors.Unknown, op, "unable to create oidc request", errors.WithWrap(err))
}
u, err := provider.AuthURL(ctx, oidcReq)
if err != nil {
return nil, "", errors.New(errors.Unknown, op, "unable to get auth url from provider", errors.WithWrap(err))
return nil, "", errors.New(ctx, errors.Unknown, op, "unable to get auth url from provider", errors.WithWrap(err))
}
authUrl, err = url.Parse(u)
if err != nil {
return nil, "", errors.New(errors.Unknown, op, "unable to parse auth url", errors.WithWrap(err))
return nil, "", errors.New(ctx, errors.Unknown, op, "unable to parse auth url", errors.WithWrap(err))
}
t := &request.Token{
@@ -141,7 +141,7 @@ func StartAuth(ctx context.Context, oidcRepoFn OidcRepoFactory, authMethodId str
}
encodedEncryptedTk, err := encryptMessage(ctx, requestWrapper, am, t)
if err != nil {
return nil, "", errors.Wrap(err, op)
return nil, "", errors.Wrap(ctx, err, op)
}
return authUrl, encodedEncryptedTk, nil
}
@@ -28,7 +28,7 @@ func Test_StartAuth(t *testing.T) {
ctx := context.Background()
tp := oidc.StartTestProvider(t)
_, _, tpAlg, _ := tp.SigningKeys()
tpCert, err := ParseCertificates(tp.CACert())
tpCert, err := ParseCertificates(ctx, tp.CACert())
require.NoError(t, err)
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
@@ -40,7 +40,7 @@ func Test_StartAuth(t *testing.T) {
defer testController.Close()
repoFn := func() (*Repository, error) {
return NewRepository(rw, rw, kmsCache)
return NewRepository(ctx, rw, rw, kmsCache)
}
org, _ := iam.TestScopes(t, iam.TestRepo(t, conn, rootWrapper))
databaseWrapper, err := kmsCache.GetWrapper(ctx, org.PublicId, kms.KeyPurposeDatabase)
+1 -1
View File
@@ -180,7 +180,7 @@ func Test_requestWrappingWrapper(t *testing.T) {
kmsCache := kms.TestKms(t, conn, rootWrapper)
rw := db.New(conn)
repo, err := NewRepository(rw, rw, kmsCache)
repo, err := NewRepository(ctx, rw, rw, kmsCache)
require.NoError(t, err)
org, _ := iam.TestScopes(t, iam.TestRepo(t, conn, rootWrapper))
databaseWrapper, err := kmsCache.GetWrapper(ctx, org.PublicId, kms.KeyPurposeDatabase)
+16 -16
View File
@@ -25,59 +25,59 @@ import (
func TokenRequest(ctx context.Context, kms *kms.Kms, atRepoFn AuthTokenRepoFactory, authMethodId, tokenRequestId string) (*authtoken.AuthToken, error) {
const op = "oidc.TokenRequest"
if kms == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing kms")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing kms")
}
if atRepoFn == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing auth token repo function")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth token repo function")
}
if authMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
if tokenRequestId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing token request id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing token request id")
}
reqTkWrapper, err := UnwrapMessage(ctx, tokenRequestId)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if reqTkWrapper.ScopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "request token id wrapper missing scope id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "request token id wrapper missing scope id")
}
if reqTkWrapper.AuthMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "request token id wrapper missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "request token id wrapper missing auth method id")
}
if reqTkWrapper.AuthMethodId != authMethodId {
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("%s auth method id does not match request wrapper auth method id: %s", authMethodId, reqTkWrapper.AuthMethodId))
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("%s auth method id does not match request wrapper auth method id: %s", authMethodId, reqTkWrapper.AuthMethodId))
}
// tokenRequestId is a proto request.Wrapper, which contains a cipher text field,
// so we need the derived wrapper that was used to encrypt it.
requestWrapper, err := requestWrappingWrapper(ctx, kms, reqTkWrapper.ScopeId, reqTkWrapper.AuthMethodId)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
reqTkBytes, err := decryptMessage(ctx, requestWrapper, reqTkWrapper)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
var reqTk request.Token
if err := proto.Unmarshal(reqTkBytes, &reqTk); err != nil {
return nil, errors.New(errors.Unknown, op, "unable to unmarshal request token", errors.WithWrap(err))
return nil, errors.New(ctx, errors.Unknown, op, "unable to unmarshal request token", errors.WithWrap(err))
}
if reqTk.ExpirationTime == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing request token id expiration time")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing request token id expiration time")
}
// before proceeding, make sure the request hasn't timed out
if time.Now().After(reqTk.ExpirationTime.Timestamp.AsTime()) {
return nil, errors.New(errors.AuthAttemptExpired, op, "request token id has expired")
return nil, errors.New(ctx, errors.AuthAttemptExpired, op, "request token id has expired")
}
tokenRepo, err := atRepoFn()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
authTk, err := tokenRepo.IssueAuthToken(ctx, reqTk.RequestId)
if err != nil {
@@ -86,10 +86,10 @@ func TokenRequest(ctx context.Context, kms *kms.Kms, atRepoFn AuthTokenRepoFacto
// error, but nothing is returned.
return nil, nil
}
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if authTk.Token == "" {
return nil, errors.New(errors.Internal, op, "issued token is missing")
return nil, errors.New(ctx, errors.Internal, op, "issued token is missing")
}
return authTk, nil
}
@@ -163,7 +163,7 @@ func Test_TokenRequest(t *testing.T) {
name: "atRepoFn-error",
kms: kmsCache,
atRepoFn: func() (*authtoken.Repository, error) {
return nil, errors.New(errors.Unknown, "test op", "atRepoFn-error")
return nil, errors.New(ctx, errors.Unknown, "test op", "atRepoFn-error", errors.WithoutEvent())
},
authMethodId: testAuthMethod.PublicId,
tokenRequest: func() string {
+6 -5
View File
@@ -1,6 +1,7 @@
package oidc
import (
"context"
"fmt"
"github.com/hashicorp/boundary/internal/auth/oidc/store"
@@ -55,7 +56,7 @@ type SigningAlg struct {
// NewSigningAlg creates a new in memory signing alg assigned to an OIDC
// AuthMethod. It supports no options.
func NewSigningAlg(authMethodId string, alg Alg) (*SigningAlg, error) {
func NewSigningAlg(ctx context.Context, authMethodId string, alg Alg) (*SigningAlg, error) {
const op = "oidc.NewSigningAlg"
s := &SigningAlg{
SigningAlg: &store.SigningAlg{
@@ -63,7 +64,7 @@ func NewSigningAlg(authMethodId string, alg Alg) (*SigningAlg, error) {
Alg: string(alg),
},
}
if err := s.validate(op); err != nil {
if err := s.validate(ctx, op); err != nil {
return nil, err // intentionally not wrapped
}
return s, nil
@@ -76,12 +77,12 @@ func SupportedAlgorithm(a Alg) bool {
}
// validate the SigningAlg. On success, it will return nil.
func (s *SigningAlg) validate(caller errors.Op) error {
func (s *SigningAlg) validate(ctx context.Context, caller errors.Op) error {
if s.OidcMethodId == "" {
return errors.New(errors.InvalidParameter, caller, "missing oidc auth method id")
return errors.New(ctx, errors.InvalidParameter, caller, "missing oidc auth method id")
}
if _, ok := supportedAlgorithms[Alg(s.Alg)]; !ok {
return errors.New(errors.InvalidParameter, caller, fmt.Sprintf("unsupported signing algorithm: %s", s.Alg))
return errors.New(ctx, errors.InvalidParameter, caller, fmt.Sprintf("unsupported signing algorithm: %s", s.Alg))
}
return nil
}
+8 -5
View File
@@ -15,6 +15,7 @@ import (
func TestSigningAlg_Create(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -102,7 +103,7 @@ func TestSigningAlg_Create(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
got, err := NewSigningAlg(tt.args.authMethodId, tt.args.alg)
got, err := NewSigningAlg(ctx, tt.args.authMethodId, tt.args.alg)
if tt.wantErr {
require.Error(err)
assert.True(errors.Match(errors.T(tt.wantIsErr), err))
@@ -130,6 +131,7 @@ func TestSigningAlg_Create(t *testing.T) {
func TestSigningAlg_Delete(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -153,7 +155,7 @@ func TestSigningAlg_Delete(t *testing.T) {
WithSigningAlgs(RS256)) // seed an extra callback url to just make sure the delete only gets the right num of rows
testResource := func(authMethodId string, signingAlg Alg) *SigningAlg {
c, err := NewSigningAlg(authMethodId, signingAlg)
c, err := NewSigningAlg(ctx, authMethodId, signingAlg)
require.NoError(t, err)
return c
}
@@ -216,6 +218,7 @@ func TestSigningAlg_Delete(t *testing.T) {
func TestSigningAlg_Clone(t *testing.T) {
t.Parallel()
ctx := context.TODO()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, wrapper)
@@ -227,7 +230,7 @@ func TestSigningAlg_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewSigningAlg(m.PublicId, RS256)
orig, err := NewSigningAlg(ctx, m.PublicId, RS256)
require.NoError(err)
cp := orig.Clone()
assert.True(proto.Equal(cp.SigningAlg, orig.SigningAlg))
@@ -239,9 +242,9 @@ func TestSigningAlg_Clone(t *testing.T) {
require.NoError(err)
m := TestAuthMethod(t, conn, databaseWrapper, org.PublicId, InactiveState, "alice_rp", "my-dogs-name",
WithIssuer(TestConvertToUrls(t, "https://alice.com")[0]), WithApiUrl(TestConvertToUrls(t, "https://api.com")[0]))
orig, err := NewSigningAlg(m.PublicId, ES256)
orig, err := NewSigningAlg(ctx, m.PublicId, ES256)
require.NoError(err)
orig2, err := NewSigningAlg(m.PublicId, ES384)
orig2, err := NewSigningAlg(ctx, m.PublicId, ES384)
require.NoError(err)
cp := orig.Clone()
+14 -14
View File
@@ -49,14 +49,14 @@ func TestAuthMethod(
clientSecret ClientSecret,
opt ...Option) *AuthMethod {
t.Helper()
ctx := context.TODO()
opts := getOpts(opt...)
require := require.New(t)
rw := db.New(conn)
ctx := context.Background()
authMethod, err := NewAuthMethod(scopeId, clientId, clientSecret, opt...)
authMethod, err := NewAuthMethod(ctx, scopeId, clientId, clientSecret, opt...)
require.NoError(err)
id, err := newAuthMethodId()
id, err := newAuthMethodId(ctx)
require.NoError(err)
authMethod.PublicId = id
err = authMethod.encrypt(ctx, databaseWrapper)
@@ -67,7 +67,7 @@ func TestAuthMethod(
if len(opts.withAudClaims) > 0 {
newAudClaims := make([]interface{}, 0, len(opts.withAudClaims))
for _, a := range opts.withAudClaims {
aud, err := NewAudClaim(authMethod.PublicId, a)
aud, err := NewAudClaim(ctx, authMethod.PublicId, a)
require.NoError(err)
newAudClaims = append(newAudClaims, aud)
}
@@ -78,9 +78,9 @@ func TestAuthMethod(
if len(opts.withCertificates) > 0 {
newCerts := make([]interface{}, 0, len(opts.withCertificates))
for _, c := range opts.withCertificates {
pem, err := EncodeCertificates(c)
pem, err := EncodeCertificates(ctx, c)
require.NoError(err)
cert, err := NewCertificate(authMethod.PublicId, pem[0])
cert, err := NewCertificate(ctx, authMethod.PublicId, pem[0])
require.NoError(err)
newCerts = append(newCerts, cert)
}
@@ -91,7 +91,7 @@ func TestAuthMethod(
if len(opts.withSigningAlgs) > 0 {
newAlgs := make([]interface{}, 0, len(opts.withSigningAlgs))
for _, a := range opts.withSigningAlgs {
alg, err := NewSigningAlg(authMethod.PublicId, a)
alg, err := NewSigningAlg(ctx, authMethod.PublicId, a)
require.NoError(err)
newAlgs = append(newAlgs, alg)
}
@@ -102,7 +102,7 @@ func TestAuthMethod(
if len(opts.withClaimsScopes) > 0 {
newClaimsScopes := make([]interface{}, 0, len(opts.withClaimsScopes))
for _, cs := range opts.withClaimsScopes {
s, err := NewClaimsScope(authMethod.PublicId, cs)
s, err := NewClaimsScope(ctx, authMethod.PublicId, cs)
require.NoError(err)
newClaimsScopes = append(newClaimsScopes, s)
}
@@ -113,7 +113,7 @@ func TestAuthMethod(
if len(opts.withAccountClaimMap) > 0 {
newAccountClaimMaps := make([]interface{}, 0, len(opts.withAccountClaimMap))
for k, v := range opts.withAccountClaimMap {
acm, err := NewAccountClaimMap(authMethod.PublicId, k, v)
acm, err := NewAccountClaimMap(ctx, authMethod.PublicId, k, v)
require.NoError(err)
newAccountClaimMaps = append(newAccountClaimMaps, acm)
}
@@ -167,10 +167,10 @@ func TestAccount(t *testing.T, conn *gorm.DB, am *AuthMethod, subject string, op
u, err := url.Parse(am.GetIssuer())
require.NoError(err)
opt = append(opt, WithIssuer(u))
a, err := NewAccount(am.PublicId, subject, opt...)
a, err := NewAccount(ctx, am.PublicId, subject, opt...)
require.NoError(err)
id, err := newAccountId(am.GetPublicId(), am.Issuer, subject)
id, err := newAccountId(ctx, am.GetPublicId(), am.Issuer, subject)
require.NoError(err)
a.PublicId = id
@@ -185,10 +185,10 @@ func TestManagedGroup(t *testing.T, conn *gorm.DB, am *AuthMethod, filter string
rw := db.New(conn)
ctx := context.Background()
mg, err := NewManagedGroup(am.PublicId, filter, opt...)
mg, err := NewManagedGroup(ctx, am.PublicId, filter, opt...)
require.NoError(err)
id, err := newManagedGroupId()
id, err := newManagedGroupId(ctx)
require.NoError(err)
mg.PublicId = id
@@ -203,7 +203,7 @@ func TestManagedGroupMember(t *testing.T, conn *gorm.DB, managedGroupId, memberI
rw := db.New(conn)
ctx := context.Background()
mg, err := NewManagedGroupMemberAccount(managedGroupId, memberId, opt...)
mg, err := NewManagedGroupMemberAccount(ctx, managedGroupId, memberId, opt...)
require.NoError(err)
require.NoError(rw.Create(ctx, mg))
+1 -1
View File
@@ -30,7 +30,7 @@ func NewAccount(authMethodId string, opt ...Option) (*Account, error) {
// NOTE(mgaffney): The scopeId in the embedded *store.Account is
// populated by a trigger in the database.
if authMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing auth method id")
}
opts := getOpts(opt...)
+14 -14
View File
@@ -45,25 +45,25 @@ func NewArgon2Configuration() *Argon2Configuration {
func (c *Argon2Configuration) validate() error {
const op = "password.(Argon2Configuration).validate"
if c == nil {
return errors.New(errors.PasswordInvalidConfiguration, op, "missing config")
return errors.NewDeprecated(errors.PasswordInvalidConfiguration, op, "missing config")
}
if c.Argon2Configuration == nil {
return errors.New(errors.PasswordInvalidConfiguration, op, "missing embedded config")
return errors.NewDeprecated(errors.PasswordInvalidConfiguration, op, "missing embedded config")
}
if c.Iterations == 0 {
return errors.New(errors.PasswordInvalidConfiguration, op, "missing iterations")
return errors.NewDeprecated(errors.PasswordInvalidConfiguration, op, "missing iterations")
}
if c.Memory == 0 {
return errors.New(errors.PasswordInvalidConfiguration, op, "missing memory")
return errors.NewDeprecated(errors.PasswordInvalidConfiguration, op, "missing memory")
}
if c.Threads == 0 {
return errors.New(errors.PasswordInvalidConfiguration, op, "missing threads")
return errors.NewDeprecated(errors.PasswordInvalidConfiguration, op, "missing threads")
}
if c.SaltLength == 0 {
return errors.New(errors.PasswordInvalidConfiguration, op, "missing salt length")
return errors.NewDeprecated(errors.PasswordInvalidConfiguration, op, "missing salt length")
}
if c.KeyLength == 0 {
return errors.New(errors.PasswordInvalidConfiguration, op, "missing key length")
return errors.NewDeprecated(errors.PasswordInvalidConfiguration, op, "missing key length")
}
return nil
}
@@ -132,18 +132,18 @@ type Argon2Credential struct {
func newArgon2Credential(accountId string, password string, conf *Argon2Configuration) (*Argon2Credential, error) {
const op = "password.newArgon2Credential"
if accountId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing accountId")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing accountId")
}
if password == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing password")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing password")
}
if conf == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing argon2 configuration")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing argon2 configuration")
}
id, err := newArgon2CredentialId()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.WrapDeprecated(err, op)
}
c := &Argon2Credential{
@@ -157,7 +157,7 @@ func newArgon2Credential(accountId string, password string, conf *Argon2Configur
salt := make([]byte, conf.SaltLength)
if _, err := rand.Read(salt); err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Io))
return nil, errors.WrapDeprecated(err, op, errors.WithCode(errors.Io))
}
c.Salt = salt
c.DerivedKey = argon2.IDKey([]byte(password), c.Salt, conf.Iterations, conf.Memory, uint8(conf.Threads), conf.KeyLength)
@@ -187,7 +187,7 @@ func (c *Argon2Credential) SetTableName(n string) {
func (c *Argon2Credential) encrypt(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "password.(Argon2Credential).encrypt"
if err := structwrapping.WrapStruct(ctx, cipher, c.Argon2Credential, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Encrypt))
return errors.WrapDeprecated(err, op, errors.WithCode(errors.Encrypt))
}
c.KeyId = cipher.KeyID()
return nil
@@ -196,7 +196,7 @@ func (c *Argon2Credential) encrypt(ctx context.Context, cipher wrapping.Wrapper)
func (c *Argon2Credential) decrypt(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "password.(Argon2Credential).decrypt"
if err := structwrapping.UnwrapStruct(ctx, cipher, c.Argon2Credential, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt))
return errors.WrapDeprecated(err, op, errors.WithCode(errors.Decrypt))
}
return nil
}
+1 -1
View File
@@ -27,7 +27,7 @@ func allocAuthMethod() AuthMethod {
func NewAuthMethod(scopeId string, opt ...Option) (*AuthMethod, error) {
const op = "password.NewAuthMethod"
if scopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing scope id")
}
opts := getOpts(opt...)
+2 -2
View File
@@ -15,7 +15,7 @@ func newArgon2ConfigurationId() (string, error) {
const op = "password.newArgon2ConfigurationId"
id, err := db.NewPrivateId(argon2ConfigurationPrefix)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.WrapDeprecated(err, op)
}
return id, nil
}
@@ -24,7 +24,7 @@ func newArgon2CredentialId() (string, error) {
const op = "password.newArgon2CredentialId"
id, err := db.NewPrivateId(argon2CredentialPrefix)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.WrapDeprecated(err, op)
}
return id, nil
}
+2 -2
View File
@@ -26,7 +26,7 @@ func newAuthMethodId() (string, error) {
const op = "password.newAuthMethodId"
id, err := db.NewPublicId(AuthMethodPrefix)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.WrapDeprecated(err, op)
}
return id, nil
}
@@ -35,7 +35,7 @@ func newAccountId() (string, error) {
const op = "password.newAccountId"
id, err := db.NewPublicId(intglobals.NewPasswordAccountPrefix)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.WrapDeprecated(err, op)
}
return id, nil
}
+3 -3
View File
@@ -26,11 +26,11 @@ func NewRepository(r db.Reader, w db.Writer, kms *kms.Kms, opt ...Option) (*Repo
const op = "password.NewRepository"
switch {
case r == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Reader")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Reader")
case w == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Writer")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Writer")
case kms == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing kms")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing kms")
}
opts := getOpts(opt...)
+44 -44
View File
@@ -30,31 +30,31 @@ import (
func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Account, opt ...Option) (*Account, error) {
const op = "password.(Repository).CreateAccount"
if a == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing Account")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing Account")
}
if a.Account == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing embedded Account")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing embedded Account")
}
if a.AuthMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
if a.PublicId != "" {
return nil, errors.New(errors.InvalidParameter, op, "public id must be empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "public id must be empty")
}
if scopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
if !validLoginName(a.LoginName) {
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("login name must be all-lowercase alphanumeric, period or hyphen. got: %s", a.LoginName))
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("login name must be all-lowercase alphanumeric, period or hyphen. got: %s", a.LoginName))
}
cc, err := r.currentConfig(ctx, a.AuthMethodId)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("retrieve current configuration"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("retrieve current configuration"))
}
if cc.MinLoginNameLength > len(a.LoginName) {
return nil, errors.New(errors.TooShort, op, fmt.Sprintf("username: %s, must be longer than %d", a.LoginName, cc.MinLoginNameLength))
return nil, errors.New(ctx, errors.TooShort, op, fmt.Sprintf("username: %s, must be longer than %d", a.LoginName, cc.MinLoginNameLength))
}
opts := getOpts(opt...)
@@ -62,13 +62,13 @@ func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Accou
a = a.clone()
if opts.withPublicId != "" {
if !strings.HasPrefix(opts.withPublicId, intglobals.NewPasswordAccountPrefix+"_") {
return nil, errors.New(errors.InvalidParameter, op, "chosen account id does not have a valid prefix")
return nil, errors.New(ctx, errors.InvalidParameter, op, "chosen account id does not have a valid prefix")
}
a.PublicId = opts.withPublicId
} else {
id, err := newAccountId()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
a.PublicId = id
}
@@ -76,20 +76,20 @@ func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Accou
var cred *Argon2Credential
if opts.withPassword {
if cc.MinPasswordLength > len(opts.password) {
return nil, errors.New(errors.PasswordTooShort, op, fmt.Sprintf("must be longer than %v", cc.MinPasswordLength))
return nil, errors.New(ctx, errors.PasswordTooShort, op, fmt.Sprintf("must be longer than %v", cc.MinPasswordLength))
}
if cred, err = newArgon2Credential(a.PublicId, opts.password, cc.argon2()); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
}
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"), errors.WithCode(errors.Encrypt))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"), errors.WithCode(errors.Encrypt))
}
databaseWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"), errors.WithCode(errors.Encrypt))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"), errors.WithCode(errors.Encrypt))
}
var newCred *Argon2Credential
@@ -98,16 +98,16 @@ func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Accou
func(_ db.Reader, w db.Writer) error {
newAccount = a.clone()
if err := w.Create(ctx, newAccount, db.WithOplog(oplogWrapper, a.oplog(oplog.OpType_OP_TYPE_CREATE))); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if cred != nil {
newCred = cred.clone()
if err := newCred.encrypt(ctx, databaseWrapper); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err := w.Create(ctx, newCred, db.WithOplog(oplogWrapper, cred.oplog(oplog.OpType_OP_TYPE_CREATE))); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
}
return nil
@@ -116,10 +116,10 @@ func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Accou
if err != nil {
if errors.IsUniqueError(err) {
return nil, errors.New(errors.NotUnique, op, fmt.Sprintf("in auth method %s: name %q or loginName %q already exists",
return nil, errors.New(ctx, errors.NotUnique, op, fmt.Sprintf("in auth method %s: name %q or loginName %q already exists",
a.AuthMethodId, a.Name, a.LoginName))
}
return nil, errors.Wrap(err, op, errors.WithMsg(a.AuthMethodId))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(a.AuthMethodId))
}
return newAccount, nil
}
@@ -129,7 +129,7 @@ func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Accou
func (r *Repository) LookupAccount(ctx context.Context, withPublicId string, opt ...Option) (*Account, error) {
const op = "password.(Repository).LookupAccount"
if withPublicId == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
a := allocAccount()
a.PublicId = withPublicId
@@ -137,7 +137,7 @@ func (r *Repository) LookupAccount(ctx context.Context, withPublicId string, opt
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("failed for %s", withPublicId)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("failed for %s", withPublicId)))
}
return a, nil
}
@@ -146,7 +146,7 @@ func (r *Repository) LookupAccount(ctx context.Context, withPublicId string, opt
func (r *Repository) ListAccounts(ctx context.Context, withAuthMethodId string, opt ...Option) ([]*Account, error) {
const op = "password.(Repository).ListAccounts"
if withAuthMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
opts := getOpts(opt...)
limit := r.defaultLimit
@@ -157,7 +157,7 @@ func (r *Repository) ListAccounts(ctx context.Context, withAuthMethodId string,
var accts []*Account
err := r.reader.SearchWhere(ctx, &accts, "auth_method_id = ?", []interface{}{withAuthMethodId}, db.WithLimit(limit))
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return accts, nil
}
@@ -167,17 +167,17 @@ func (r *Repository) ListAccounts(ctx context.Context, withAuthMethodId string,
func (r *Repository) DeleteAccount(ctx context.Context, scopeId, withPublicId string, opt ...Option) (int, error) {
const op = "password.(Repository).DeleteAccount"
if withPublicId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
if scopeId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing scope id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
ac := allocAccount()
ac.PublicId = withPublicId
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
}
var rowsDeleted int
@@ -190,17 +190,17 @@ func (r *Repository) DeleteAccount(ctx context.Context, scopeId, withPublicId st
dAc := ac.clone()
rowsDeleted, err = w.Delete(ctx, dAc, db.WithOplog(oplogWrapper, metadata))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsDeleted > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been deleted")
}
return nil
},
)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(withPublicId))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(withPublicId))
}
return rowsDeleted, nil
@@ -231,19 +231,19 @@ func validLoginName(u string) bool {
func (r *Repository) UpdateAccount(ctx context.Context, scopeId string, a *Account, version uint32, fieldMaskPaths []string, opt ...Option) (*Account, int, error) {
const op = "password.(Repository).UpdateAccount"
if a == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing Account")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing Account")
}
if a.Account == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing embedded Account")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing embedded Account")
}
if a.PublicId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
if version == 0 {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing version")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing version")
}
if scopeId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
var changeLoginName bool
@@ -253,12 +253,12 @@ func (r *Repository) UpdateAccount(ctx context.Context, scopeId string, a *Accou
case strings.EqualFold("Description", f):
case strings.EqualFold("LoginName", f):
if !validLoginName(a.LoginName) {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op,
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op,
fmt.Sprintf("invalid username: must be all-lowercase alphanumeric, period or hyphen, got %s", a.LoginName))
}
changeLoginName = true
default:
return nil, db.NoRowsAffected, errors.New(errors.InvalidFieldMask, op, f)
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, f)
}
}
var dbMask, nullFields []string
@@ -272,23 +272,23 @@ func (r *Repository) UpdateAccount(ctx context.Context, scopeId string, a *Accou
nil,
)
if len(dbMask) == 0 && len(nullFields) == 0 {
return nil, db.NoRowsAffected, errors.New(errors.EmptyFieldMask, op, "missing field mask")
return nil, db.NoRowsAffected, errors.New(ctx, errors.EmptyFieldMask, op, "missing field mask")
}
if changeLoginName {
cc, err := r.currentConfigForAccount(ctx, a.PublicId)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("retrieve current configuration"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("retrieve current configuration"))
}
if cc.MinLoginNameLength > len(a.LoginName) {
return nil, db.NoRowsAffected, errors.New(errors.TooShort, op,
return nil, db.NoRowsAffected, errors.New(ctx, errors.TooShort, op,
fmt.Sprintf("username: %s, must be longer than %v", a.LoginName, cc.MinLoginNameLength))
}
}
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithCode(errors.Encrypt),
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt),
errors.WithMsg(("unable to get oplog wrapper")))
}
@@ -304,10 +304,10 @@ func (r *Repository) UpdateAccount(ctx context.Context, scopeId string, a *Accou
var err error
rowsUpdated, err = w.Update(ctx, returnedAccount, dbMask, nullFields, db.WithOplog(oplogWrapper, metadata), db.WithVersion(&version))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsUpdated > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been updated")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been updated")
}
return nil
},
@@ -315,10 +315,10 @@ func (r *Repository) UpdateAccount(ctx context.Context, scopeId string, a *Accou
if err != nil {
if errors.IsUniqueError(err) {
return nil, db.NoRowsAffected, errors.New(errors.NotUnique, op,
return nil, db.NoRowsAffected, errors.New(ctx, errors.NotUnique, op,
fmt.Sprintf("name %s already exists: %s", a.Name, a.PublicId))
}
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(a.PublicId))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(a.PublicId))
}
return returnedAccount, rowsUpdated, nil
+39 -39
View File
@@ -25,16 +25,16 @@ import (
func (r *Repository) CreateAuthMethod(ctx context.Context, m *AuthMethod, opt ...Option) (*AuthMethod, error) {
const op = "password.(Repository).CreateAuthMethod"
if m == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing AuthMethod")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing AuthMethod")
}
if m.AuthMethod == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing embedded AuthMethod")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing embedded AuthMethod")
}
if m.ScopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
if m.PublicId != "" {
return nil, errors.New(errors.InvalidParameter, op, "public id not empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "public id not empty")
}
m = m.Clone()
@@ -42,35 +42,35 @@ func (r *Repository) CreateAuthMethod(ctx context.Context, m *AuthMethod, opt ..
if opts.withPublicId != "" {
if !strings.HasPrefix(opts.withPublicId, AuthMethodPrefix+"_") {
return nil, errors.New(errors.InvalidPublicId, op, fmt.Sprintf("passed-in public ID %q has wrong prefix, should be %q", opts.withPublicId, AuthMethodPrefix))
return nil, errors.New(ctx, errors.InvalidPublicId, op, fmt.Sprintf("passed-in public ID %q has wrong prefix, should be %q", opts.withPublicId, AuthMethodPrefix))
}
m.PublicId = opts.withPublicId
} else {
id, err := newAuthMethodId()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
m.PublicId = id
}
c, ok := opts.withConfig.(*Argon2Configuration)
if !ok {
return nil, errors.New(errors.PasswordUnsupportedConfiguration, op, "unknown configuration")
return nil, errors.New(ctx, errors.PasswordUnsupportedConfiguration, op, "unknown configuration")
}
if err := c.validate(); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
var err error
c.PrivateId, err = newArgon2ConfigurationId()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
m.PasswordConfId, c.PasswordMethodId = c.PrivateId, m.PublicId
oplogWrapper, err := r.kms.GetWrapper(ctx, m.GetScopeId(), kms.KeyPurposeOplog)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
}
var newAuthMethod *AuthMethod
@@ -79,11 +79,11 @@ func (r *Repository) CreateAuthMethod(ctx context.Context, m *AuthMethod, opt ..
func(_ db.Reader, w db.Writer) error {
newArgon2Conf = c.clone()
if err := w.Create(ctx, newArgon2Conf, db.WithOplog(oplogWrapper, c.oplog(oplog.OpType_OP_TYPE_CREATE))); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to create argon conf"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to create argon conf"))
}
newAuthMethod = m.Clone()
if err := w.Create(ctx, newAuthMethod, db.WithOplog(oplogWrapper, m.oplog(oplog.OpType_OP_TYPE_CREATE))); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to create auth method"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to create auth method"))
}
return nil
},
@@ -91,9 +91,9 @@ func (r *Repository) CreateAuthMethod(ctx context.Context, m *AuthMethod, opt ..
if err != nil {
if errors.IsUniqueError(err) {
return nil, errors.New(errors.NotUnique, op, fmt.Sprintf("in scope: %s: name %s already exists", m.ScopeId, m.Name))
return nil, errors.New(ctx, errors.NotUnique, op, fmt.Sprintf("in scope: %s: name %s already exists", m.ScopeId, m.Name))
}
return nil, errors.Wrap(err, op, errors.WithMsg(m.ScopeId))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(m.ScopeId))
}
return newAuthMethod, nil
}
@@ -103,7 +103,7 @@ func (r *Repository) CreateAuthMethod(ctx context.Context, m *AuthMethod, opt ..
func (r *Repository) LookupAuthMethod(ctx context.Context, publicId string, _ ...Option) (*AuthMethod, error) {
const op = "password.(Repository).LookupAuthMethod"
if publicId == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
return r.lookupAuthMethod(ctx, publicId)
}
@@ -113,11 +113,11 @@ func (r *Repository) LookupAuthMethod(ctx context.Context, publicId string, _ ..
func (r *Repository) ListAuthMethods(ctx context.Context, scopeIds []string, opt ...Option) ([]*AuthMethod, error) {
const op = "password.(Repository).ListAuthMethods"
if len(scopeIds) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
authMethods, err := r.getAuthMethods(ctx, "", scopeIds, opt...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return authMethods, nil
}
@@ -127,14 +127,14 @@ func (r *Repository) ListAuthMethods(ctx context.Context, scopeIds []string, opt
func (r *Repository) DeleteAuthMethod(ctx context.Context, scopeId, publicId string, opt ...Option) (int, error) {
const op = "password.(Repository).DeleteAuthMethod"
if publicId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
am := allocAuthMethod()
am.PublicId = publicId
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithCode(errors.Encrypt),
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt),
errors.WithMsg("unable to get oplog wrapper"))
}
@@ -148,17 +148,17 @@ func (r *Repository) DeleteAuthMethod(ctx context.Context, scopeId, publicId str
dAc := am.Clone()
rowsDeleted, err = w.Delete(ctx, dAc, db.WithOplog(oplogWrapper, metadata))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsDeleted > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been deleted")
}
return nil
},
)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(publicId))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(publicId))
}
return rowsDeleted, nil
@@ -179,13 +179,13 @@ func (r *Repository) DeleteAuthMethod(ctx context.Context, scopeId, publicId str
func (r *Repository) UpdateAuthMethod(ctx context.Context, authMethod *AuthMethod, version uint32, fieldMaskPaths []string, opt ...Option) (*AuthMethod, int, error) {
const op = "password.(Repository).UpdateAuthMethod"
if authMethod == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing authMethod")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing authMethod")
}
if authMethod.PublicId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing authMethod public id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing authMethod public id")
}
if authMethod.ScopeId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
for _, f := range fieldMaskPaths {
switch {
@@ -194,7 +194,7 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, authMethod *AuthMetho
case strings.EqualFold("MinLoginNameLength", f):
case strings.EqualFold("MinPasswordLength", f):
default:
return nil, db.NoRowsAffected, errors.New(errors.InvalidFieldMask, op, f)
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, f)
}
}
var dbMask, nullFields []string
@@ -209,12 +209,12 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, authMethod *AuthMetho
nil,
)
if len(dbMask) == 0 && len(nullFields) == 0 {
return nil, db.NoRowsAffected, errors.New(errors.EmptyFieldMask, op, "field mask must not be empty")
return nil, db.NoRowsAffected, errors.New(ctx, errors.EmptyFieldMask, op, "field mask must not be empty")
}
oplogWrapper, err := r.kms.GetWrapper(ctx, authMethod.ScopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithCode(errors.Encrypt),
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt),
errors.WithMsg("unable to get oplog wrapper"))
}
@@ -238,10 +238,10 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, authMethod *AuthMetho
dbOpts...,
)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsUpdated > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been updated")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been updated")
}
// we need a new repo, that's using the same reader/writer as this TxHandler
txRepo := &Repository{
@@ -253,19 +253,19 @@ func (r *Repository) UpdateAuthMethod(ctx context.Context, authMethod *AuthMetho
}
upAuthMethod, err = txRepo.lookupAuthMethod(ctx, upAuthMethod.PublicId)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to lookup auth method after update"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to lookup auth method after update"))
}
if upAuthMethod == nil {
return errors.New(errors.RecordNotFound, op, "unable to lookup auth method after update")
return errors.New(ctx, errors.RecordNotFound, op, "unable to lookup auth method after update")
}
return nil
},
)
if err != nil {
if errors.IsUniqueError(err) {
return nil, db.NoRowsAffected, errors.New(errors.NotUnique, op, fmt.Sprintf("authMethod %s already exists in scope %s", authMethod.Name, authMethod.ScopeId))
return nil, db.NoRowsAffected, errors.New(ctx, errors.NotUnique, op, fmt.Sprintf("authMethod %s already exists in scope %s", authMethod.Name, authMethod.ScopeId))
}
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(authMethod.PublicId))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(authMethod.PublicId))
}
return upAuthMethod, rowsUpdated, nil
}
@@ -276,13 +276,13 @@ func (r *Repository) lookupAuthMethod(ctx context.Context, authMethodId string,
var err error
ams, err := r.getAuthMethods(ctx, authMethodId, nil, opt...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
switch {
case len(ams) == 0:
return nil, nil // not an error to return no rows for a "lookup"
case len(ams) > 1:
return nil, errors.New(errors.NotSpecificIntegrity, op, fmt.Sprintf("%s matched more than 1 ", authMethodId))
return nil, errors.New(ctx, errors.NotSpecificIntegrity, op, fmt.Sprintf("%s matched more than 1 ", authMethodId))
default:
return ams[0], nil
}
@@ -300,10 +300,10 @@ func (r *Repository) lookupAuthMethod(ctx context.Context, authMethodId string,
func (r *Repository) getAuthMethods(ctx context.Context, authMethodId string, scopeIds []string, opt ...Option) ([]*AuthMethod, error) {
const op = "password.(Repository).getAuthMethods"
if authMethodId == "" && len(scopeIds) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "missing search criteria: both auth method id and Scope IDs are empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing search criteria: both auth method id and Scope IDs are empty")
}
if authMethodId != "" && len(scopeIds) > 0 {
return nil, errors.New(errors.InvalidParameter, op, "searching for both an auth method id and Scope IDs is not supported")
return nil, errors.New(ctx, errors.InvalidParameter, op, "searching for both an auth method id and Scope IDs is not supported")
}
dbArgs := []db.Option{}
@@ -335,7 +335,7 @@ func (r *Repository) getAuthMethods(ctx context.Context, authMethodId string, sc
var views []*authMethodView
err := r.reader.SearchWhere(ctx, &views, strings.Join(where, " and "), args, dbArgs...)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if len(views) == 0 { // we're done if nothing is found.
@@ -22,11 +22,11 @@ type Configuration interface {
func (r *Repository) GetConfiguration(ctx context.Context, authMethodId string) (Configuration, error) {
const op = "password.(Repository).GetConfiguration"
if authMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
cc, err := r.currentConfig(ctx, authMethodId)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return cc.argon2(), nil
}
@@ -44,24 +44,24 @@ func (r *Repository) GetConfiguration(ctx context.Context, authMethodId string)
func (r *Repository) SetConfiguration(ctx context.Context, scopeId string, c Configuration) (Configuration, error) {
const op = "password.(Repository).SetConfiguration"
if c == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing configuration")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing configuration")
}
if c.AuthMethodId() == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth method id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
if err := c.validate(); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
switch v := c.(type) {
case *Argon2Configuration:
out, err := r.setArgon2Conf(ctx, scopeId, v)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return out, nil
default:
return nil, errors.New(errors.PasswordUnsupportedConfiguration, op, "unknown configuration")
return nil, errors.New(ctx, errors.PasswordUnsupportedConfiguration, op, "unknown configuration")
}
}
@@ -71,7 +71,7 @@ func (r *Repository) setArgon2Conf(ctx context.Context, scopeId string, c *Argon
id, err := newArgon2ConfigurationId()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
c.PrivateId = id
@@ -83,7 +83,7 @@ func (r *Repository) setArgon2Conf(ctx context.Context, scopeId string, c *Argon
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
}
newArgon2Conf := &Argon2Configuration{Argon2Configuration: &store.Argon2Configuration{}}
@@ -93,27 +93,27 @@ func (r *Repository) setArgon2Conf(ctx context.Context, scopeId string, c *Argon
where, args := c.whereDup()
if err := rr.LookupWhere(ctx, newArgon2Conf, where, args...); err != nil {
if !errors.IsNotFoundError(err) {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
newArgon2Conf = c.clone()
if err := w.Create(ctx, newArgon2Conf, db.WithOplog(oplogWrapper, c.oplog(oplog.OpType_OP_TYPE_CREATE))); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
}
a.PasswordConfId = newArgon2Conf.PrivateId
rowsUpdated, err := w.Update(ctx, a, []string{"PasswordConfId"}, nil, db.WithOplog(oplogWrapper, a.oplog(oplog.OpType_OP_TYPE_UPDATE)))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsUpdated > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been updated")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been updated")
}
return nil
},
)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return newArgon2Conf, nil
}
@@ -134,7 +134,7 @@ func (r *Repository) currentConfig(ctx context.Context, authMethodId string) (*c
const op = "password.(Repository).currentConfig"
var cc currentConfig
if err := r.reader.LookupWhere(ctx, &cc, "password_method_id = ?", authMethodId); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return &cc, nil
}
@@ -145,13 +145,13 @@ func (r *Repository) currentConfigForAccount(ctx context.Context, accountId stri
rows, err := r.reader.Query(ctx, currentConfigForAccountQuery, []interface{}{accountId})
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
defer rows.Close()
for rows.Next() {
var conf currentConfig
if err := r.reader.ScanRows(rows, &conf); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
confs = append(confs, conf)
}
@@ -162,7 +162,7 @@ func (r *Repository) currentConfigForAccount(ctx context.Context, accountId stri
return nil, nil
case len(confs) > 1:
// this should never happen
return nil, errors.New(errors.Unknown, op, "multiple current configs returned for account")
return nil, errors.New(ctx, errors.Unknown, op, "multiple current configs returned for account")
default:
cc = confs[0]
}
+55 -55
View File
@@ -34,26 +34,26 @@ type authAccount struct {
func (r *Repository) Authenticate(ctx context.Context, scopeId, authMethodId, loginName, password string) (*Account, error) {
const op = "password.(Repository).Authenticate"
if authMethodId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing authMethodId")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing authMethodId", errors.WithoutEvent())
}
if loginName == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing loginName")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing loginName", errors.WithoutEvent())
}
if password == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing password")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing password", errors.WithoutEvent())
}
if scopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing scopeId")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scopeId", errors.WithoutEvent())
}
databaseWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get database wrapper"))
}
acct, err := r.authenticate(ctx, scopeId, authMethodId, loginName, password)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if acct == nil {
return nil, nil
@@ -62,22 +62,22 @@ func (r *Repository) Authenticate(ctx context.Context, scopeId, authMethodId, lo
if !acct.IsCurrentConf {
cc, err := r.currentConfig(ctx, authMethodId)
if err != nil {
return acct.Account, errors.Wrap(err, op, errors.WithMsg("retrieve current password configuration"))
return acct.Account, errors.Wrap(ctx, err, op, errors.WithMsg("retrieve current password configuration"))
}
cred, err := newArgon2Credential(acct.PublicId, password, cc.argon2())
if err != nil {
return acct.Account, errors.Wrap(err, op, errors.WithCode(errors.PasswordInvalidConfiguration))
return acct.Account, errors.Wrap(ctx, err, op, errors.WithCode(errors.PasswordInvalidConfiguration))
}
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return acct.Account, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplong wrapper"))
return acct.Account, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplong wrapper"))
}
// do not change the Credential Id
cred.PrivateId = acct.CredentialId
if err := cred.encrypt(ctx, databaseWrapper); err != nil {
return acct.Account, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("update credential"))
return acct.Account, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("update credential"))
}
fields := []string{"CtSalt", "DerivedKey", "PasswordConfId"}
@@ -87,16 +87,16 @@ func (r *Repository) Authenticate(ctx context.Context, scopeId, authMethodId, lo
func(_ db.Reader, w db.Writer) error {
rowsUpdated, err := w.Update(ctx, cred, fields, nil, db.WithOplog(oplogWrapper, metadata))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsUpdated > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been updated")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been updated")
}
return nil
},
)
if err != nil {
return acct.Account, errors.Wrap(err, op, errors.WithMsg("update credential"))
return acct.Account, errors.Wrap(ctx, err, op, errors.WithMsg("update credential"))
}
}
return acct.Account, nil
@@ -112,44 +112,44 @@ func (r *Repository) Authenticate(ctx context.Context, scopeId, authMethodId, lo
func (r *Repository) ChangePassword(ctx context.Context, scopeId, accountId, old, new string, version uint32) (*Account, error) {
const op = "password.(Repository).ChangePassword"
if accountId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing account id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing account id")
}
if old == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing old password")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing old password")
}
if new == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing new password")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing new password")
}
if old == new {
return nil, errors.New(errors.PasswordsEqual, op, "passwords must not equal")
return nil, errors.New(ctx, errors.PasswordsEqual, op, "passwords must not equal")
}
if version == 0 {
return nil, errors.New(errors.InvalidParameter, op, "missing version")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing version")
}
if scopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing scopeId")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scopeId")
}
authAccount, err := r.LookupAccount(ctx, accountId)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if authAccount == nil {
return nil, errors.New(errors.RecordNotFound, op, "account not found")
return nil, errors.New(ctx, errors.RecordNotFound, op, "account not found")
}
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
}
databaseWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get database wrapper"))
}
acct, err := r.authenticate(ctx, scopeId, authAccount.GetAuthMethodId(), authAccount.GetLoginName(), old)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if acct == nil {
return nil, nil
@@ -157,18 +157,18 @@ func (r *Repository) ChangePassword(ctx context.Context, scopeId, accountId, old
cc, err := r.currentConfig(ctx, authAccount.GetAuthMethodId())
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("retrieve current password configuration"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("retrieve current password configuration"))
}
if cc.MinPasswordLength > len(new) {
return nil, errors.New(errors.PasswordTooShort, op, fmt.Sprintf("must be at least %d", cc.MinPasswordLength))
return nil, errors.New(ctx, errors.PasswordTooShort, op, fmt.Sprintf("must be at least %d", cc.MinPasswordLength))
}
newCred, err := newArgon2Credential(accountId, new, cc.argon2())
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if err := newCred.encrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt))
}
oldCred := acct.Argon2Credential
@@ -181,27 +181,27 @@ func (r *Repository) ChangePassword(ctx context.Context, scopeId, accountId, old
updatedAccount.Version = version + 1
rowsUpdated, err := w.Update(ctx, updatedAccount, []string{"Version"}, nil, db.WithOplog(oplogWrapper, acct.Account.oplog(oplog.OpType_OP_TYPE_UPDATE)), db.WithVersion(&version))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to update account version"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update account version"))
}
if rowsUpdated != 1 {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("updated account and %d rows updated", rowsUpdated))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated account and %d rows updated", rowsUpdated))
}
rowsDeleted, err := w.Delete(ctx, oldCred, db.WithOplog(oplogWrapper, oldCred.oplog(oplog.OpType_OP_TYPE_DELETE)))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsDeleted > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been deleted")
}
if err = w.Create(ctx, newCred, db.WithOplog(oplogWrapper, newCred.oplog(oplog.OpType_OP_TYPE_CREATE))); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to create new credential"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to create new credential"))
}
return nil
},
)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
// change the Credential Id
@@ -215,13 +215,13 @@ func (r *Repository) authenticate(ctx context.Context, scopeId, authMethodId, lo
rows, err := r.reader.Query(ctx, authenticateQuery, []interface{}{authMethodId, loginName})
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
defer rows.Close()
for rows.Next() {
var aa authAccount
if err := r.reader.ScanRows(rows, &aa); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
accts = append(accts, aa)
}
@@ -232,7 +232,7 @@ func (r *Repository) authenticate(ctx context.Context, scopeId, authMethodId, lo
return nil, nil
case len(accts) > 1:
// this should never happen
return nil, errors.New(errors.Unknown, op, "multiple accounts returned for user name")
return nil, errors.New(ctx, errors.Unknown, op, "multiple accounts returned for user name")
default:
acct = accts[0]
}
@@ -240,11 +240,11 @@ func (r *Repository) authenticate(ctx context.Context, scopeId, authMethodId, lo
// We don't pass a wrapper in here because for ecryption we want to indicate the expected key ID
databaseWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase, kms.WithKeyId(acct.GetKeyId()))
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get database wrapper"))
}
if err := acct.decrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("unable to decrypt credential"))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("unable to decrypt credential"))
}
inputKey := argon2.IDKey([]byte(password), acct.Salt, acct.Iterations, acct.Memory, uint8(acct.Threads), acct.KeyLength)
@@ -260,42 +260,42 @@ func (r *Repository) authenticate(ctx context.Context, scopeId, authMethodId, lo
func (r *Repository) SetPassword(ctx context.Context, scopeId, accountId, password string, version uint32) (*Account, error) {
const op = "password.(Repository).SetPassword"
if accountId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing accountId")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing accountId")
}
if version == 0 {
return nil, errors.New(errors.InvalidParameter, op, "missing version")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing version")
}
if scopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing scopeId")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scopeId")
}
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get oplog wrapper"))
}
databaseWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get database wrapper"))
}
var newCred *Argon2Credential
if password != "" {
cc, err := r.currentConfigForAccount(ctx, accountId)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if cc == nil {
return nil, errors.New(errors.RecordNotFound, op, "unable to retrieve current configuration")
return nil, errors.New(ctx, errors.RecordNotFound, op, "unable to retrieve current configuration")
}
if cc.MinPasswordLength > len(password) {
return nil, errors.New(errors.PasswordTooShort, op, fmt.Sprintf("password must be at least %v", cc.MinPasswordLength))
return nil, errors.New(ctx, errors.PasswordTooShort, op, fmt.Sprintf("password must be at least %v", cc.MinPasswordLength))
}
newCred, err = newArgon2Credential(accountId, password, cc.argon2())
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if err := newCred.encrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt))
}
}
@@ -307,27 +307,27 @@ func (r *Repository) SetPassword(ctx context.Context, scopeId, accountId, passwo
updatedAccount.Version = version + 1
rowsUpdated, err := w.Update(ctx, updatedAccount, []string{"Version"}, nil, db.WithOplog(oplogWrapper, updatedAccount.oplog(oplog.OpType_OP_TYPE_UPDATE)), db.WithVersion(&version))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to update account version"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update account version"))
}
if rowsUpdated != 1 {
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("updated account and %d rows updated", rowsUpdated))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated account and %d rows updated", rowsUpdated))
}
acct = updatedAccount
oldCred := allocCredential()
if err := rr.LookupWhere(ctx, &oldCred, "password_account_id = ?", accountId); err != nil {
if !errors.IsNotFoundError(err) {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
}
if oldCred.PrivateId != "" {
dCred := oldCred.clone()
rowsDeleted, err := w.Delete(ctx, dCred, db.WithOplog(oplogWrapper, oldCred.oplog(oplog.OpType_OP_TYPE_DELETE)))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsDeleted > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been deleted")
}
}
if newCred != nil {
@@ -337,7 +337,7 @@ func (r *Repository) SetPassword(ctx context.Context, scopeId, accountId, passwo
},
)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return acct, nil
}
+8 -8
View File
@@ -74,7 +74,7 @@ func (at *AuthToken) encrypt(ctx context.Context, cipher wrapping.Wrapper) error
const op = "authtoken.(writableAuthToken).encrypt"
// structwrapping doesn't support embedding, so we'll pass in the store.Entry directly
if err := structwrapping.WrapStruct(ctx, cipher, at.AuthToken, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Encrypt))
return errors.WrapDeprecated(err, op, errors.WithCode(errors.Encrypt))
}
at.KeyId = cipher.KeyID()
return nil
@@ -85,7 +85,7 @@ func (at *AuthToken) decrypt(ctx context.Context, cipher wrapping.Wrapper) error
const op = "authtoken.(AuthToken).decrypt"
// structwrapping doesn't support embedding, so we'll pass in the store.Entry directly
if err := structwrapping.UnwrapStruct(ctx, cipher, at.AuthToken, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt))
return errors.WrapDeprecated(err, op, errors.WithCode(errors.Decrypt))
}
return nil
}
@@ -102,7 +102,7 @@ func NewAuthTokenId() (string, error) {
const op = "authtoken.newAuthTokenId"
id, err := db.NewPublicId(AuthTokenPrefix)
if err != nil {
return "", errors.Wrap(err, op)
return "", errors.WrapDeprecated(err, op)
}
return id, nil
}
@@ -113,7 +113,7 @@ func newAuthToken(opt ...Option) (*AuthToken, error) {
const op = "authtoken.newAuthToken"
token, err := base62.Random(tokenLength)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Io))
return nil, errors.WrapDeprecated(err, op, errors.WithCode(errors.Io))
}
opts := getOpts(opt...)
@@ -139,22 +139,22 @@ func EncryptToken(ctx context.Context, kmsCache *kms.Kms, scopeId, publicId, tok
marshaledS1Info, err := proto.Marshal(s1Info)
if err != nil {
return "", errors.Wrap(err, op, errors.WithMsg("marshaling encrypted token"), errors.WithCode(errors.Encode))
return "", errors.WrapDeprecated(err, op, errors.WithMsg("marshaling encrypted token"), errors.WithCode(errors.Encode))
}
tokenWrapper, err := kmsCache.GetWrapper(ctx, scopeId, kms.KeyPurposeTokens)
if err != nil {
return "", errors.Wrap(err, op, errors.WithMsg("unable to get wrapper"))
return "", errors.WrapDeprecated(err, op, errors.WithMsg("unable to get wrapper"))
}
blobInfo, err := tokenWrapper.Encrypt(ctx, []byte(marshaledS1Info), []byte(publicId))
if err != nil {
return "", errors.Wrap(err, op, errors.WithMsg("marshaling token info"), errors.WithCode(errors.Encrypt))
return "", errors.WrapDeprecated(err, op, errors.WithMsg("marshaling token info"), errors.WithCode(errors.Encrypt))
}
marshaledBlob, err := proto.Marshal(blobInfo)
if err != nil {
return "", errors.Wrap(err, op, errors.WithMsg("marshaling encrypted token"), errors.WithCode(errors.Encode))
return "", errors.WrapDeprecated(err, op, errors.WithMsg("marshaling encrypted token"), errors.WithCode(errors.Encode))
}
encoded := base58.FastBase58Encoding(marshaledBlob)
+44 -44
View File
@@ -35,11 +35,11 @@ func NewRepository(r db.Reader, w db.Writer, kms *kms.Kms, opt ...Option) (*Repo
const op = "authtoken.NewRepository"
switch {
case r == nil:
return nil, errors.New(errors.InvalidParameter, op, "nil db reader")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "nil db reader")
case w == nil:
return nil, errors.New(errors.InvalidParameter, op, "nil db writer")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "nil db writer")
case kms == nil:
return nil, errors.New(errors.InvalidParameter, op, "nil kms")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "nil kms")
}
opts := getOpts(opt...)
@@ -63,24 +63,24 @@ func NewRepository(r db.Reader, w db.Writer, kms *kms.Kms, opt ...Option) (*Repo
func (r *Repository) CreateAuthToken(ctx context.Context, withIamUser *iam.User, withAuthAccountId string, opt ...Option) (*AuthToken, error) {
const op = "authtoken.(Repository).CreateAuthToken"
if withIamUser == nil || withIamUser.User == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing user")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing user")
}
if withIamUser.GetPublicId() == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing user id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing user id")
}
if withAuthAccountId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing auth account id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth account id")
}
at, err := newAuthToken()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
at.AuthAccountId = withAuthAccountId
opts := getOpts(opt...)
if opts.withPublicId == "" {
id, err := NewAuthTokenId()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
opts.withPublicId = id
}
@@ -95,14 +95,14 @@ func (r *Repository) CreateAuthToken(ctx context.Context, withIamUser *iam.User,
databaseWrapper, err := r.kms.GetWrapper(ctx, withIamUser.GetScopeId(), kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
// We truncate the expiration time to the nearest second to make testing in different platforms with
// different time resolutions easier.
expiration, err := ptypes.TimestampProto(time.Now().Add(r.timeToLiveDuration).Truncate(time.Second))
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.InvalidTimeStamp))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.InvalidTimeStamp))
}
at.ExpirationTime = &timestamp.Timestamp{Timestamp: expiration}
@@ -115,10 +115,10 @@ func (r *Repository) CreateAuthToken(ctx context.Context, withIamUser *iam.User,
acct := allocAuthAccount()
acct.PublicId = withAuthAccountId
if err := read.LookupByPublicId(ctx, acct); err != nil {
return errors.Wrap(err, op, errors.WithMsg("auth account lookup"))
return errors.Wrap(ctx, err, op, errors.WithMsg("auth account lookup"))
}
if acct.GetIamUserId() != withIamUser.GetPublicId() {
return errors.New(errors.InvalidParameter, op,
return errors.New(ctx, errors.InvalidParameter, op,
fmt.Sprintf("auth account %q mismatch with iam user %q", withAuthAccountId, withIamUser.GetPublicId()))
}
at.ScopeId = acct.GetScopeId()
@@ -127,11 +127,11 @@ func (r *Repository) CreateAuthToken(ctx context.Context, withIamUser *iam.User,
newAuthToken = at.clone()
if err := newAuthToken.encrypt(ctx, databaseWrapper); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
// tokens are not replicated, so they don't need oplog entries.
if err := w.Create(ctx, newAuthToken); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
newAuthToken.CtToken = nil
@@ -140,7 +140,7 @@ func (r *Repository) CreateAuthToken(ctx context.Context, withIamUser *iam.User,
)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return newAuthToken, nil
}
@@ -151,7 +151,7 @@ func (r *Repository) CreateAuthToken(ctx context.Context, withIamUser *iam.User,
func (r *Repository) LookupAuthToken(ctx context.Context, id string, opt ...Option) (*AuthToken, error) {
const op = "authtoken.(Repository).LookupAuthToken"
if id == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
opts := getOpts(opt...)
@@ -163,17 +163,17 @@ func (r *Repository) LookupAuthToken(ctx context.Context, id string, opt ...Opti
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
at := atv.toAuthToken()
if opts.withTokenValue {
databaseWrapper, err := r.kms.GetWrapper(ctx, at.GetScopeId(), kms.KeyPurposeDatabase, kms.WithKeyId(at.GetKeyId()))
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("unable to get database wrapper"))
}
if err := at.decrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
}
@@ -192,10 +192,10 @@ func (r *Repository) LookupAuthToken(ctx context.Context, id string, opt ...Opti
func (r *Repository) ValidateToken(ctx context.Context, id, token string, opt ...Option) (*AuthToken, error) {
const op = "authtoken.(Repository).ValidateToken"
if token == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing token")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing token")
}
if id == "" {
return nil, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
retAT, err := r.LookupAuthToken(ctx, id, withTokenValue())
@@ -204,7 +204,7 @@ func (r *Repository) ValidateToken(ctx context.Context, id, token string, opt ..
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if retAT == nil {
return nil, nil
@@ -213,11 +213,11 @@ func (r *Repository) ValidateToken(ctx context.Context, id, token string, opt ..
// If the token is too old or stale invalidate it and return nothing.
exp, err := ptypes.Timestamp(retAT.GetExpirationTime().GetTimestamp())
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("expiration time"), errors.WithCode(errors.InvalidTimeStamp))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("expiration time"), errors.WithCode(errors.InvalidTimeStamp))
}
lastAccessed, err := ptypes.Timestamp(retAT.GetApproximateLastAccessTime().GetTimestamp())
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("last accessed time"), errors.WithCode(errors.InvalidTimeStamp))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("last accessed time"), errors.WithCode(errors.InvalidTimeStamp))
}
now := time.Now()
@@ -234,13 +234,13 @@ func (r *Repository) ValidateToken(ctx context.Context, id, token string, opt ..
delAt := retAT.clone()
// tokens are not replicated, so they don't need oplog entries.
if _, err := w.Delete(ctx, delAt); err != nil {
return errors.Wrap(err, op, errors.WithMsg("delete auth token"))
return errors.Wrap(ctx, err, op, errors.WithMsg("delete auth token"))
}
retAT = nil
return nil
})
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return nil, nil
}
@@ -271,10 +271,10 @@ func (r *Repository) ValidateToken(ctx context.Context, id, token string, opt ..
[]string{"ApproximateLastAccessTime"},
)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsUpdated > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been updated")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been updated")
}
return nil
},
@@ -282,7 +282,7 @@ func (r *Repository) ValidateToken(ctx context.Context, id, token string, opt ..
}
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg(id))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(id))
}
return retAT, nil
}
@@ -292,7 +292,7 @@ func (r *Repository) ValidateToken(ctx context.Context, id, token string, opt ..
func (r *Repository) ListAuthTokens(ctx context.Context, withScopeIds []string, opt ...Option) ([]*AuthToken, error) {
const op = "authtoken.(Repository).ListAuthTokens"
if len(withScopeIds) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
opts := getOpts(opt...)
@@ -300,7 +300,7 @@ func (r *Repository) ListAuthTokens(ctx context.Context, withScopeIds []string,
// to convert them before returning them
var atvs []*authTokenView
if err := r.reader.SearchWhere(ctx, &atvs, "auth_account_id in (select public_id from auth_account where scope_id in (?))", []interface{}{withScopeIds}, db.WithLimit(opts.withLimit)); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
authTokens := make([]*AuthToken, 0, len(atvs))
for _, atv := range atvs {
@@ -317,7 +317,7 @@ func (r *Repository) ListAuthTokens(ctx context.Context, withScopeIds []string,
func (r *Repository) DeleteAuthToken(ctx context.Context, id string, opt ...Option) (int, error) {
const op = "authtoken.(Repository).DeleteAuthToken"
if id == "" {
return db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
at, err := r.LookupAuthToken(ctx, id)
@@ -325,7 +325,7 @@ func (r *Repository) DeleteAuthToken(ctx context.Context, id string, opt ...Opti
if errors.IsNotFoundError(err) {
return db.NoRowsAffected, nil
}
return db.NoRowsAffected, errors.Wrap(err, op)
return db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
if at == nil {
return db.NoRowsAffected, nil
@@ -341,17 +341,17 @@ func (r *Repository) DeleteAuthToken(ctx context.Context, id string, opt ...Opti
// tokens are not replicated, so they don't need oplog entries.
rowsDeleted, err = w.Delete(ctx, deleteAT)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsDeleted > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been deleted")
}
return nil
},
)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(id))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(id))
}
return rowsDeleted, nil
@@ -366,7 +366,7 @@ func (r *Repository) DeleteAuthToken(ctx context.Context, id string, opt ...Opti
func (r *Repository) IssueAuthToken(ctx context.Context, tokenRequestId string) (*AuthToken, error) {
const op = "authtoken.(Repository).IssueAuthToken"
if tokenRequestId == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing token request id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing token request id")
}
var at *AuthToken
@@ -383,16 +383,16 @@ func (r *Repository) IssueAuthToken(ctx context.Context, tokenRequestId string)
// trigger to set ApproximateLastAccessTime to the commit timestamp.
rowsUpdated, err := w.Update(ctx, at, []string{"Status"}, []string{"ApproximateLastAccessTime"}, db.WithWhere("status = ?", PendingStatus))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rowsUpdated == 0 {
return errors.New(errors.RecordNotFound, op, "pending auth token not found")
return errors.New(ctx, errors.RecordNotFound, op, "pending auth token not found")
}
if rowsUpdated > 1 {
return errors.New(errors.Internal, op, fmt.Sprintf("should have updated 1 row and we attempted to update %d rows", rowsUpdated))
return errors.New(ctx, errors.Internal, op, fmt.Sprintf("should have updated 1 row and we attempted to update %d rows", rowsUpdated))
}
if at.Status != string(IssuedStatus) {
return errors.New(errors.Internal, op, "updated auth token status != issued")
return errors.New(ctx, errors.Internal, op, "updated auth token status != issued")
}
// we need a new repo, that's using the same reader/writer as this TxHandler
@@ -403,10 +403,10 @@ func (r *Repository) IssueAuthToken(ctx context.Context, tokenRequestId string)
}
at, err = txRepo.LookupAuthToken(ctx, at.PublicId, withTokenValue())
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if at == nil {
return errors.New(errors.RecordNotFound, op, "issued auth token not found")
return errors.New(ctx, errors.RecordNotFound, op, "issued auth token not found")
}
return nil
})
@@ -433,7 +433,7 @@ func (r *Repository) CloseExpiredPendingTokens(ctx context.Context) (int, error)
var err error
tokensClosed, err = w.Exec(ctx, sql, args)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
},
+3 -1
View File
@@ -348,12 +348,13 @@ func (b *Server) createInitialOidcAuthMethod(ctx context.Context) (*oidc.AuthMet
}
// Create the auth method
oidcRepo, err := oidc.NewRepository(rw, rw, kmsCache)
oidcRepo, err := oidc.NewRepository(ctx, rw, rw, kmsCache)
if err != nil {
return nil, fmt.Errorf("error creating oidc repo: %w", err)
}
authMethod, err := oidc.NewAuthMethod(
ctx,
scope.Global.String(),
b.DevOidcSetup.clientId,
b.DevOidcSetup.clientSecret,
@@ -395,6 +396,7 @@ func (b *Server) createInitialOidcAuthMethod(ctx context.Context) (*oidc.AuthMet
{
createAndLinkAccount := func(loginName, userId, accountId, typ string) error {
acct, err := oidc.NewAccount(
ctx,
b.DevOidcSetup.authMethod.GetPublicId(),
loginName,
oidc.WithDescription(fmt.Sprintf("Initial %s OIDC account", typ)),
+9 -9
View File
@@ -145,18 +145,18 @@ func (b *Server) SetupEventing(logger hclog.Logger, serializationLock *sync.Mute
const op = "base.(Server).SetupEventing"
if logger == nil {
return berrors.New(berrors.InvalidParameter, op, "missing logger")
return berrors.NewDeprecated(berrors.InvalidParameter, op, "missing logger")
}
if serializationLock == nil {
return berrors.New(berrors.InvalidParameter, op, "missing serialization lock")
return berrors.NewDeprecated(berrors.InvalidParameter, op, "missing serialization lock")
}
if serverName == "" {
return berrors.New(berrors.InvalidParameter, op, "missing server name")
return berrors.NewDeprecated(berrors.InvalidParameter, op, "missing server name")
}
opts := getOpts(opt...)
if opts.withEventerConfig != nil {
if err := opts.withEventerConfig.Validate(); err != nil {
return berrors.Wrap(err, op, berrors.WithMsg("invalid eventer config"))
return berrors.WrapDeprecated(err, op, berrors.WithMsg("invalid eventer config"))
}
}
if opts.withEventerConfig == nil {
@@ -165,7 +165,7 @@ func (b *Server) SetupEventing(logger hclog.Logger, serializationLock *sync.Mute
if opts.withEventFlags != nil {
if err := opts.withEventFlags.Validate(); err != nil {
return berrors.Wrap(err, op, berrors.WithMsg("invalid event flags"))
return berrors.WrapDeprecated(err, op, berrors.WithMsg("invalid event flags"))
}
if opts.withEventFlags.Format != "" {
for i := 0; i < len(opts.withEventerConfig.Sinks); i++ {
@@ -195,12 +195,12 @@ func (b *Server) SetupEventing(logger hclog.Logger, serializationLock *sync.Mute
e, err := event.NewEventer(logger, serializationLock, serverName, *opts.withEventerConfig)
if err != nil {
return berrors.Wrap(err, op, berrors.WithMsg("unable to create eventer"))
return berrors.WrapDeprecated(err, op, berrors.WithMsg("unable to create eventer"))
}
b.Eventer = e
if err := event.InitSysEventer(logger, serializationLock, serverName, event.WithEventer(e)); err != nil {
return berrors.Wrap(err, op, berrors.WithMsg("unable to initialize system eventer"))
return berrors.WrapDeprecated(err, op, berrors.WithMsg("unable to initialize system eventer"))
}
return nil
@@ -210,11 +210,11 @@ func (b *Server) SetupEventing(logger hclog.Logger, serializationLock *sync.Mute
func (b *Server) AddEventerToContext(ctx context.Context) (context.Context, error) {
const op = "base.(Server).AddEventerToContext"
if b.Eventer == nil {
return nil, berrors.New(berrors.InvalidParameter, op, "missing server eventer")
return nil, berrors.NewDeprecated(berrors.InvalidParameter, op, "missing server eventer")
}
e, err := event.NewEventerContext(ctx, b.Eventer)
if err != nil {
return nil, berrors.Wrap(err, op, berrors.WithMsg("unable to add eventer to context"))
return nil, berrors.WrapDeprecated(err, op, berrors.WithMsg("unable to add eventer to context"))
}
return e, nil
}
+1 -1
View File
@@ -500,7 +500,7 @@ func (c *InitCommand) verifyOplogIsEmpty() error {
var empty bool
r.Scan(&empty)
if !empty {
return errors.New(errors.MigrationIntegrity, op, "oplog_entry is not empty")
return errors.NewDeprecated(errors.MigrationIntegrity, op, "oplog_entry is not empty")
}
return nil
}
+2 -1
View File
@@ -321,6 +321,7 @@ func (c *Command) AutocompleteFlags() complete.Flags {
func (c *Command) Run(args []string) int {
const op = "dev.(Command).Run"
ctx := context.TODO()
c.CombineLogs = c.flagCombineLogs
var err error
@@ -579,7 +580,7 @@ func (c *Command) Run(args []string) int {
}
var err error
c.controller, err = controller.New(conf)
c.controller, err = controller.New(ctx, conf)
if err != nil {
c.UI.Error(fmt.Errorf("Error initializing controller: %w", err).Error())
return base.CommandCliError
+5 -4
View File
@@ -133,6 +133,7 @@ func (c *Command) AutocompleteFlags() complete.Flags {
}
func (c *Command) Run(args []string) int {
ctx := context.TODO()
c.CombineLogs = c.flagCombineLogs
if result := c.ParseFlagsAndConfig(args); result > 0 {
@@ -453,7 +454,7 @@ func (c *Command) Run(args []string) int {
c.ReleaseLogGate()
if c.Config.Controller != nil {
if err := c.StartController(); err != nil {
if err := c.StartController(ctx); err != nil {
c.UI.Error(err.Error())
return base.CommandCliError
}
@@ -536,14 +537,14 @@ func (c *Command) ParseFlagsAndConfig(args []string) int {
return base.CommandSuccess
}
func (c *Command) StartController() error {
func (c *Command) StartController(ctx context.Context) error {
conf := &controller.Config{
RawConfig: c.Config,
Server: c.Server,
}
var err error
c.controller, err = controller.New(conf)
c.controller, err = controller.New(ctx, conf)
if err != nil {
return fmt.Errorf("Error initializing controller: %w", err)
}
@@ -735,5 +736,5 @@ func (c *Command) verifyKmsSetup() error {
return nil
}
}
return errors.New(errors.MigrationIntegrity, op, "can't find global scoped root key")
return errors.NewDeprecated(errors.MigrationIntegrity, op, "can't find global scoped root key")
}
@@ -27,7 +27,7 @@ type ClientCertificate struct {
func NewClientCertificate(certificate []byte, key KeySecret) (*ClientCertificate, error) {
const op = "vault.NewClientCertificate"
if len(certificate) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "no certificate")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "no certificate")
}
certificateCopy := make([]byte, len(certificate))
@@ -77,14 +77,14 @@ func (c *ClientCertificate) SetTableName(n string) {
func (c *ClientCertificate) encrypt(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "vault.(ClientCertificate).encrypt"
if len(c.CertificateKey) == 0 {
errors.New(errors.InvalidParameter, op, "no certificate key defined")
errors.New(ctx, errors.InvalidParameter, op, "no certificate key defined")
}
if err := structwrapping.WrapStruct(ctx, cipher, c.ClientCertificate, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Encrypt))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt))
}
c.KeyId = cipher.KeyID()
if err := c.hmacCertificateKey(ctx, cipher); err != nil {
errors.Wrap(err, op)
errors.Wrap(ctx, err, op)
}
return nil
}
@@ -92,7 +92,7 @@ func (c *ClientCertificate) encrypt(ctx context.Context, cipher wrapping.Wrapper
func (c *ClientCertificate) decrypt(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "vault.(ClientCertificate).decrypt"
if err := structwrapping.UnwrapStruct(ctx, cipher, c.ClientCertificate, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt))
}
return nil
}
@@ -100,15 +100,15 @@ func (c *ClientCertificate) decrypt(ctx context.Context, cipher wrapping.Wrapper
func (c *ClientCertificate) hmacCertificateKey(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "vault.(ClientCertificate).hmacCertificateKey"
if cipher == nil {
return errors.New(errors.InvalidParameter, op, "missing cipher")
return errors.New(ctx, errors.InvalidParameter, op, "missing cipher")
}
reader, err := kms.NewDerivedReader(cipher, 32, []byte(c.StoreId), nil)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
key, _, err := ed25519.GenerateKey(reader)
if err != nil {
return errors.New(errors.Encrypt, op, "unable to generate derived key")
return errors.New(ctx, errors.Encrypt, op, "unable to generate derived key")
}
mac := hmac.New(sha256.New, key)
_, _ = mac.Write(c.CertificateKey)
+3 -3
View File
@@ -48,13 +48,13 @@ type Credential struct {
func newCredential(libraryId, sessionId, externalId string, tokenHmac []byte, expiration time.Duration) (*Credential, error) {
const op = "vault.newCredential"
if libraryId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no library id")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "no library id")
}
if sessionId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no session id")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "no session id")
}
if len(tokenHmac) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "no tokenHmac")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "no tokenHmac")
}
status := string(ActiveCredential)
@@ -182,7 +182,7 @@ func (cs *CredentialStore) client() (*client, error) {
c, err := newClient(clientConfig)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.WrapDeprecated(err, op)
}
return c, nil
}
+92 -92
View File
@@ -32,45 +32,45 @@ func RegisterJobs(ctx context.Context, scheduler *scheduler.Scheduler, r db.Read
const op = "vault.RegisterJobs"
tokenRenewal, err := newTokenRenewalJob(r, w, kms, logger)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err = scheduler.RegisterJob(ctx, tokenRenewal); err != nil {
return errors.Wrap(err, op, errors.WithMsg("token renewal job"))
return errors.Wrap(ctx, err, op, errors.WithMsg("token renewal job"))
}
tokenRevoke, err := newTokenRevocationJob(r, w, kms, logger)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err = scheduler.RegisterJob(ctx, tokenRevoke); err != nil {
return errors.Wrap(err, op, errors.WithMsg("token revocation job"))
return errors.Wrap(ctx, err, op, errors.WithMsg("token revocation job"))
}
credRenewal, err := newCredentialRenewalJob(r, w, kms, logger)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err = scheduler.RegisterJob(ctx, credRenewal); err != nil {
return errors.Wrap(err, op, errors.WithMsg("credential renewal job"))
return errors.Wrap(ctx, err, op, errors.WithMsg("credential renewal job"))
}
credRevoke, err := newCredentialRevocationJob(r, w, kms, logger)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err = scheduler.RegisterJob(ctx, credRevoke); err != nil {
return errors.Wrap(err, op, errors.WithMsg("credential revocation job"))
return errors.Wrap(ctx, err, op, errors.WithMsg("credential revocation job"))
}
credStoreCleanup, err := newCredentialStoreCleanupJob(r, w, kms, logger)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err = scheduler.RegisterJob(ctx, credStoreCleanup); err != nil {
return errors.Wrap(err, op, errors.WithMsg("credential store cleanup job"))
return errors.Wrap(ctx, err, op, errors.WithMsg("credential store cleanup job"))
}
credCleanup, err := newCredentialCleanupJob(w)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err = scheduler.RegisterJob(ctx, credCleanup); err != nil {
return errors.Wrap(err, op, errors.WithMsg("credential cleanup job"))
return errors.Wrap(ctx, err, op, errors.WithMsg("credential cleanup job"))
}
return nil
}
@@ -97,13 +97,13 @@ func newTokenRenewalJob(r db.Reader, w db.Writer, kms *kms.Kms, logger hclog.Log
const op = "vault.newTokenRenewalJob"
switch {
case r == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Reader")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Reader")
case w == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Writer")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Writer")
case kms == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing kms")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing kms")
case logger == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing logger")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing logger")
}
opts := getOpts(opt...)
@@ -135,13 +135,13 @@ func (r *TokenRenewalJob) Status() scheduler.JobStatus {
func (r *TokenRenewalJob) Run(ctx context.Context) error {
const op = "vault.(TokenRenewalJob).Run"
if !r.running.CAS(r.running.Load(), true) {
return errors.New(errors.JobAlreadyRunning, op, "job already running")
return errors.New(ctx, errors.JobAlreadyRunning, op, "job already running")
}
defer r.running.Store(false)
// Verify context is not done before running
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
var ps []*privateStore
@@ -150,7 +150,7 @@ func (r *TokenRenewalJob) Run(ctx context.Context) error {
// set to renew in sequence.
err := r.reader.SearchWhere(ctx, &ps, `token_renewal_time < wt_add_seconds_to_now(?)`, []interface{}{renewalWindow.Seconds()}, db.WithLimit(r.limit))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
// Set numProcessed and numTokens for status report
@@ -159,7 +159,7 @@ func (r *TokenRenewalJob) Run(ctx context.Context) error {
for _, s := range ps {
// Verify context is not done before renewing next token
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err := r.renewToken(ctx, s); err != nil {
event.WriteError(ctx, op, err, event.WithInfoMsg("error renewing token", "credential store id", s.StoreId, "token status", s.TokenStatus))
@@ -174,10 +174,10 @@ func (r *TokenRenewalJob) renewToken(ctx context.Context, s *privateStore) error
const op = "vault.(TokenRenewalJob).renewToken"
databaseWrapper, err := r.kms.GetWrapper(ctx, s.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err = s.decrypt(ctx, databaseWrapper); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
token := s.token()
@@ -188,7 +188,7 @@ func (r *TokenRenewalJob) renewToken(ctx context.Context, s *privateStore) error
vc, err := s.client()
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
var respErr *vault.ResponseError
@@ -200,10 +200,10 @@ func (r *TokenRenewalJob) renewToken(ctx context.Context, s *privateStore) error
query, values := token.updateStatusQuery(ExpiredToken)
numRows, err := r.writer.Exec(ctx, query, values)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if numRows != 1 {
return errors.New(errors.Unknown, op, "token expired but failed to update repo")
return errors.New(ctx, errors.Unknown, op, "token expired but failed to update repo")
}
if s.TokenStatus == string(CurrentToken) {
event.WriteSysEvent(ctx, op, "Vault credential store current token has expired", "credential store id", s.StoreId)
@@ -212,28 +212,28 @@ func (r *TokenRenewalJob) renewToken(ctx context.Context, s *privateStore) error
// Set credentials associated with this token to expired as Vault will already cascade delete them
_, err = r.writer.Exec(ctx, updateCredentialStatusByTokenQuery, []interface{}{ExpiredCredential, token.TokenHmac})
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("error updating credentials to revoked after revoking token"))
return errors.Wrap(ctx, err, op, errors.WithMsg("error updating credentials to revoked after revoking token"))
}
return nil
}
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to renew vault token"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to renew vault token"))
}
tokenExpires, err := renewedToken.TokenTTL()
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get vault token expiration"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get vault token expiration"))
}
token.expiration = tokenExpires
query, values := token.updateExpirationQuery()
numRows, err := r.writer.Exec(ctx, query, values)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if numRows != 1 {
return errors.New(errors.Unknown, op, "token renewed but failed to update repo")
return errors.New(ctx, errors.Unknown, op, "token renewed but failed to update repo")
}
return nil
@@ -244,7 +244,7 @@ func (r *TokenRenewalJob) NextRunIn() (time.Duration, error) {
const op = "vault.(TokenRenewalJob).NextRunIn"
next, err := nextRenewal(r)
if err != nil {
return defaultNextRunIn, errors.Wrap(err, op)
return defaultNextRunIn, errors.WrapDeprecated(err, op)
}
return next, nil
@@ -262,12 +262,12 @@ func nextRenewal(j scheduler.Job) (time.Duration, error) {
query = credentialRenewalNextRunInQuery
r = job.reader
default:
return 0, errors.New(errors.Unknown, op, "unknown job")
return 0, errors.NewDeprecated(errors.Unknown, op, "unknown job")
}
rows, err := r.Query(context.Background(), query, nil)
if err != nil {
return 0, errors.Wrap(err, op)
return 0, errors.WrapDeprecated(err, op)
}
defer rows.Close()
@@ -278,7 +278,7 @@ func nextRenewal(j scheduler.Job) (time.Duration, error) {
var n NextRenewal
err = r.ScanRows(rows, &n)
if err != nil {
return 0, errors.Wrap(err, op)
return 0, errors.WrapDeprecated(err, op)
}
if n.RenewalIn < 0 {
// If we are past the next renewal time, return 0 to schedule immediately
@@ -323,13 +323,13 @@ func newTokenRevocationJob(r db.Reader, w db.Writer, kms *kms.Kms, logger hclog.
const op = "vault.newTokenRevocationJob"
switch {
case r == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Reader")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Reader")
case w == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Writer")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Writer")
case kms == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing kms")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing kms")
case logger == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing logger")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing logger")
}
opts := getOpts(opt...)
@@ -361,13 +361,13 @@ func (r *TokenRevocationJob) Status() scheduler.JobStatus {
func (r *TokenRevocationJob) Run(ctx context.Context) error {
const op = "vault.(TokenRevocationJob).Run"
if !r.running.CAS(r.running.Load(), true) {
return errors.New(errors.JobAlreadyRunning, op, "job already running")
return errors.New(ctx, errors.JobAlreadyRunning, op, "job already running")
}
defer r.running.Store(false)
// Verify context is not done before running
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
// Fetch all tokens in the revoke state as well as all tokens in the maintaining state
@@ -385,7 +385,7 @@ or
var ps []*privateStore
err := r.reader.SearchWhere(ctx, &ps, where, nil, db.WithLimit(r.limit))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
// Set numProcessed and numTokens for s report
@@ -393,7 +393,7 @@ or
for _, s := range ps {
// Verify context is not done before renewing next token
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err := r.revokeToken(ctx, s); err != nil {
event.WriteError(ctx, op, err, event.WithInfoMsg("error revoking token", "credential store id", s.StoreId))
@@ -408,10 +408,10 @@ func (r *TokenRevocationJob) revokeToken(ctx context.Context, s *privateStore) e
const op = "vault.(TokenRevocationJob).revokeToken"
databaseWrapper, err := r.kms.GetWrapper(ctx, s.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err = s.decrypt(ctx, databaseWrapper); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
token := s.token()
@@ -422,7 +422,7 @@ func (r *TokenRevocationJob) revokeToken(ctx context.Context, s *privateStore) e
vc, err := s.client()
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
var respErr *vault.ResponseError
@@ -433,22 +433,22 @@ func (r *TokenRevocationJob) revokeToken(ctx context.Context, s *privateStore) e
err = nil
}
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to revoke vault token"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to revoke vault token"))
}
query, values := token.updateStatusQuery(RevokedToken)
numRows, err := r.writer.Exec(ctx, query, values)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if numRows != 1 {
return errors.New(errors.Unknown, op, "token revoked but failed to update repo")
return errors.New(ctx, errors.Unknown, op, "token revoked but failed to update repo")
}
// Set credentials associated with this token to revoked as Vault will already cascade revoke them
_, err = r.writer.Exec(ctx, updateCredentialStatusByTokenQuery, []interface{}{RevokedCredential, token.TokenHmac})
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("error updating credentials to revoked after revoking token"))
return errors.Wrap(ctx, err, op, errors.WithMsg("error updating credentials to revoked after revoking token"))
}
return nil
@@ -491,13 +491,13 @@ func newCredentialRenewalJob(r db.Reader, w db.Writer, kms *kms.Kms, logger hclo
const op = "vault.newCredentialRenewalJob"
switch {
case r == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Reader")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Reader")
case w == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Writer")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Writer")
case kms == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing kms")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing kms")
case logger == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing logger")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing logger")
}
opts := getOpts(opt...)
@@ -529,13 +529,13 @@ func (r *CredentialRenewalJob) Status() scheduler.JobStatus {
func (r *CredentialRenewalJob) Run(ctx context.Context) error {
const op = "vault.(CredentialRenewalJob).Run"
if !r.running.CAS(r.running.Load(), true) {
return errors.New(errors.JobAlreadyRunning, op, "job already running")
return errors.New(ctx, errors.JobAlreadyRunning, op, "job already running")
}
defer r.running.Store(false)
// Verify context is not done before running
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
var creds []*privateCredential
@@ -544,7 +544,7 @@ func (r *CredentialRenewalJob) Run(ctx context.Context) error {
// multiple credentials set to renew in sequence.
err := r.reader.SearchWhere(ctx, &creds, `renewal_time < wt_add_seconds_to_now(?) and status = ?`, []interface{}{renewalWindow.Seconds(), ActiveCredential}, db.WithLimit(r.limit))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
// Set numProcessed and numTokens for status report
@@ -552,7 +552,7 @@ func (r *CredentialRenewalJob) Run(ctx context.Context) error {
for _, c := range creds {
// Verify context is not done before renewing next token
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err := r.renewCred(ctx, c); err != nil {
@@ -569,15 +569,15 @@ func (r *CredentialRenewalJob) renewCred(ctx context.Context, c *privateCredenti
const op = "vault.(CredentialRenewalJob).renewCred"
databaseWrapper, err := r.kms.GetWrapper(ctx, c.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err = c.decrypt(ctx, databaseWrapper); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
vc, err := c.client()
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
cred := c.toCredential()
@@ -591,25 +591,25 @@ func (r *CredentialRenewalJob) renewCred(ctx context.Context, c *privateCredenti
query, values := cred.updateStatusQuery(ExpiredCredential)
numRows, err := r.writer.Exec(ctx, query, values)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if numRows != 1 {
return errors.New(errors.Unknown, op, "credential expired but failed to update repo")
return errors.New(ctx, errors.Unknown, op, "credential expired but failed to update repo")
}
return nil
}
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to renew credential"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to renew credential"))
}
cred.expiration = time.Duration(renewedCred.LeaseDuration) * time.Second
query, values := cred.updateExpirationQuery()
numRows, err := r.writer.Exec(ctx, query, values)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if numRows != 1 {
return errors.New(errors.Unknown, op, "credential renewed but failed to update repo")
return errors.New(ctx, errors.Unknown, op, "credential renewed but failed to update repo")
}
return nil
@@ -620,7 +620,7 @@ func (r *CredentialRenewalJob) NextRunIn() (time.Duration, error) {
const op = "vault.(CredentialRenewalJob).NextRunIn"
next, err := nextRenewal(r)
if err != nil {
return defaultNextRunIn, errors.Wrap(err, op)
return defaultNextRunIn, errors.WrapDeprecated(err, op)
}
return next, nil
@@ -659,13 +659,13 @@ func newCredentialRevocationJob(r db.Reader, w db.Writer, kms *kms.Kms, logger h
const op = "vault.newCredentialRevocationJob"
switch {
case r == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Reader")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Reader")
case w == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Writer")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Writer")
case kms == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing kms")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing kms")
case logger == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing logger")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing logger")
}
opts := getOpts(opt...)
@@ -697,19 +697,19 @@ func (r *CredentialRevocationJob) Status() scheduler.JobStatus {
func (r *CredentialRevocationJob) Run(ctx context.Context) error {
const op = "vault.(CredentialRevocationJob).Run"
if !r.running.CAS(r.running.Load(), true) {
return errors.New(errors.JobAlreadyRunning, op, "job already running")
return errors.New(ctx, errors.JobAlreadyRunning, op, "job already running")
}
defer r.running.Store(false)
// Verify context is not done before running
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
var creds []*privateCredential
err := r.reader.SearchWhere(ctx, &creds, "status = ?", []interface{}{RevokeCredential}, db.WithLimit(r.limit))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
// Set numProcessed and numTokens for status report
@@ -717,7 +717,7 @@ func (r *CredentialRevocationJob) Run(ctx context.Context) error {
for _, c := range creds {
// Verify context is not done before renewing next token
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err := r.revokeCred(ctx, c); err != nil {
event.WriteError(ctx, op, err, event.WithInfoMsg("error revoking credential", "credential id", c.PublicId))
@@ -732,15 +732,15 @@ func (r *CredentialRevocationJob) revokeCred(ctx context.Context, c *privateCred
const op = "vault.(CredentialRenewalJob).revokeCred"
databaseWrapper, err := r.kms.GetWrapper(ctx, c.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err = c.decrypt(ctx, databaseWrapper); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
vc, err := c.client()
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
cred := c.toCredential()
@@ -752,16 +752,16 @@ func (r *CredentialRevocationJob) revokeCred(ctx context.Context, c *privateCred
err = nil
}
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to revoke credential"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to revoke credential"))
}
query, values := cred.updateStatusQuery(RevokedCredential)
numRows, err := r.writer.Exec(ctx, query, values)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if numRows != 1 {
return errors.New(errors.Unknown, op, "credential revoked but failed to update repo")
return errors.New(ctx, errors.Unknown, op, "credential revoked but failed to update repo")
}
return nil
@@ -805,13 +805,13 @@ func newCredentialStoreCleanupJob(r db.Reader, w db.Writer, kms *kms.Kms, logger
const op = "vault.newCredentialStoreCleanupJob"
switch {
case r == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Reader")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Reader")
case w == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing db.Writer")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Writer")
case kms == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing kms")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing kms")
case logger == nil:
return nil, errors.New(errors.InvalidParameter, op, "missing logger")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing logger")
}
opts := getOpts(opt...)
@@ -842,13 +842,13 @@ func (r *CredentialStoreCleanupJob) Status() scheduler.JobStatus {
func (r *CredentialStoreCleanupJob) Run(ctx context.Context) error {
const op = "vault.(CredentialStoreCleanupJob).Run"
if !r.running.CAS(r.running.Load(), true) {
return errors.New(errors.JobAlreadyRunning, op, "job already running")
return errors.New(ctx, errors.JobAlreadyRunning, op, "job already running")
}
defer r.running.Store(false)
// Verify context is not done before running
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
// TODO (lcr 06/2021): Oplog does not currently support bulk
@@ -857,7 +857,7 @@ func (r *CredentialStoreCleanupJob) Run(ctx context.Context) error {
var stores []*CredentialStore
err := r.reader.SearchWhere(ctx, &stores, credStoreCleanupWhereClause, []interface{}{RevokeToken}, db.WithLimit(r.limit))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
// Set numProcessed and numStores for status report
@@ -865,7 +865,7 @@ func (r *CredentialStoreCleanupJob) Run(ctx context.Context) error {
for _, store := range stores {
// Verify context is not done before renewing next token
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
oplogWrapper, err := r.kms.GetWrapper(ctx, store.ScopeId, kms.KeyPurposeOplog)
@@ -918,7 +918,7 @@ type CredentialCleanupJob struct {
func newCredentialCleanupJob(w db.Writer) (*CredentialCleanupJob, error) {
const op = "vault.newCredentialCleanupJob"
if w == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing db.Writer")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing db.Writer")
}
return &CredentialCleanupJob{
@@ -942,18 +942,18 @@ func (r *CredentialCleanupJob) Status() scheduler.JobStatus {
func (r *CredentialCleanupJob) Run(ctx context.Context) error {
const op = "vault.(CredentialCleanupJob).Run"
if !r.running.CAS(r.running.Load(), true) {
return errors.New(errors.JobAlreadyRunning, op, "job already running")
return errors.New(ctx, errors.JobAlreadyRunning, op, "job already running")
}
defer r.running.Store(false)
// Verify context is not done before running
if err := ctx.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
numRows, err := r.writer.Exec(ctx, credCleanupQuery, nil)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
r.numCreds = numRows
@@ -57,7 +57,7 @@ func (pc *privateCredential) decrypt(ctx context.Context, cipher wrapping.Wrappe
CtToken: pc.CtToken,
}
if err := structwrapping.UnwrapStruct(ctx, cipher, ptkv, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("token"))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("token"))
}
pc.Token = ptkv.Token
}
@@ -71,7 +71,7 @@ func (pc *privateCredential) decrypt(ctx context.Context, cipher wrapping.Wrappe
CtKey: pc.CtClientKey,
}
if err := structwrapping.UnwrapStruct(ctx, cipher, pckv, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("client certificate"))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("client certificate"))
}
pc.ClientKey = pckv.Key
}
@@ -96,7 +96,7 @@ func (pc *privateCredential) client() (*client, error) {
client, err := newClient(clientConfig)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to create vault client"))
return nil, errors.WrapDeprecated(err, op, errors.WithMsg("unable to create vault client"))
}
return client, nil
}
+10 -10
View File
@@ -112,7 +112,7 @@ func (pl *privateLibrary) decrypt(ctx context.Context, cipher wrapping.Wrapper)
CtToken: pl.CtToken,
}
if err := structwrapping.UnwrapStruct(ctx, cipher, ptkv, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("token"))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("token"))
}
pl.Token = ptkv.Token
}
@@ -126,7 +126,7 @@ func (pl *privateLibrary) decrypt(ctx context.Context, cipher wrapping.Wrapper)
CtKey: pl.CtClientKey,
}
if err := structwrapping.UnwrapStruct(ctx, cipher, pckv, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("client certificate"))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("client certificate"))
}
pl.ClientKey = pckv.Key
}
@@ -151,7 +151,7 @@ func (pl *privateLibrary) client() (*client, error) {
client, err := newClient(clientConfig)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to create vault client"))
return nil, errors.WrapDeprecated(err, op, errors.WithMsg("unable to create vault client"))
}
return client, nil
}
@@ -166,7 +166,7 @@ func (r *Repository) getPrivateLibraries(ctx context.Context, requests []credent
mapper, err := newMapper(requests)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
libIds := mapper.libIds()
@@ -181,7 +181,7 @@ func (r *Repository) getPrivateLibraries(ctx context.Context, requests []credent
}
rows, err := r.reader.Query(ctx, query, params)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("query failed"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("query failed"))
}
defer rows.Close()
@@ -189,11 +189,11 @@ func (r *Repository) getPrivateLibraries(ctx context.Context, requests []credent
for rows.Next() {
var lib privateLibrary
if err := r.reader.ScanRows(rows, &lib); err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("scan row failed"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("scan row failed"))
}
purps := mapper.get(lib.GetPublicId())
if len(purps) == 0 {
return nil, errors.E(errors.WithCode(errors.InvalidParameter), errors.WithMsg("unknown library"))
return nil, errors.E(ctx, errors.WithCode(errors.InvalidParameter), errors.WithMsg("unknown library"))
}
for _, purp := range purps {
cp := lib.clone()
@@ -205,11 +205,11 @@ func (r *Repository) getPrivateLibraries(ctx context.Context, requests []credent
for _, pl := range libs {
databaseWrapper, err := r.kms.GetWrapper(ctx, pl.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err := pl.decrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
}
@@ -236,7 +236,7 @@ func newMapper(requests []credential.Request) (*requestMap, error) {
if purps, ok := ids[req.SourceId]; ok {
for _, purp := range purps {
if purp == req.Purpose {
return nil, errors.E(errors.WithCode(errors.InvalidParameter), errors.WithMsg("duplicate library and purpose"))
return nil, errors.EDeprecated(errors.WithCode(errors.InvalidParameter), errors.WithMsg("duplicate library and purpose"))
}
}
}
+10 -10
View File
@@ -24,16 +24,16 @@ func (r *Repository) listRevokePrivateStores(ctx context.Context, opt ...Option)
var stores []*privateStore
where, values := "token_status = ?", []interface{}{"revoke"}
if err := r.reader.SearchWhere(ctx, &stores, where, values, db.WithLimit(limit)); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
for _, store := range stores {
databaseWrapper, err := r.kms.GetWrapper(ctx, store.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err := store.decrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
}
return stores, nil
@@ -42,23 +42,23 @@ func (r *Repository) listRevokePrivateStores(ctx context.Context, opt ...Option)
func (r *Repository) lookupPrivateStore(ctx context.Context, publicId string) (*privateStore, error) {
const op = "vault.(Repository).lookupPrivateStore"
if publicId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no public id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no public id")
}
ps := allocPrivateStore()
if err := r.reader.LookupWhere(ctx, &ps, "public_id = ? and token_status = ?", publicId, CurrentToken); err != nil {
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("failed for: %s", publicId)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("failed for: %s", publicId)))
}
databaseWrapper, err := r.kms.GetWrapper(ctx, ps.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err := ps.decrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return ps, nil
@@ -159,7 +159,7 @@ func (ps *privateStore) decrypt(ctx context.Context, cipher wrapping.Wrapper) er
CtToken: ps.CtToken,
}
if err := structwrapping.UnwrapStruct(ctx, cipher, ptkv, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("token"))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("token"))
}
ps.Token = ptkv.Token
}
@@ -173,7 +173,7 @@ func (ps *privateStore) decrypt(ctx context.Context, cipher wrapping.Wrapper) er
CtKey: ps.CtClientKey,
}
if err := structwrapping.UnwrapStruct(ctx, cipher, pckv, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("client certificate"))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt), errors.WithMsg("client certificate"))
}
ps.ClientKey = pckv.Key
}
@@ -198,7 +198,7 @@ func (ps *privateStore) client() (*client, error) {
client, err := newClient(clientConfig)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to create vault client"))
return nil, errors.WrapDeprecated(err, op, errors.WithMsg("unable to create vault client"))
}
return client, nil
}
+3 -3
View File
@@ -25,7 +25,7 @@ const (
func newCredentialStoreId() (string, error) {
id, err := db.NewPublicId(CredentialStorePrefix)
if err != nil {
return "", errors.Wrap(err, "vault.newCredentialStoreId")
return "", errors.WrapDeprecated(err, "vault.newCredentialStoreId")
}
return id, nil
}
@@ -33,7 +33,7 @@ func newCredentialStoreId() (string, error) {
func newCredentialId() (string, error) {
id, err := db.NewPublicId(DynamicCredentialPrefix)
if err != nil {
return "", errors.Wrap(err, "vault.newCredentialId")
return "", errors.WrapDeprecated(err, "vault.newCredentialId")
}
return id, nil
}
@@ -41,7 +41,7 @@ func newCredentialId() (string, error) {
func newCredentialLibraryId() (string, error) {
id, err := db.NewPublicId(CredentialLibraryPrefix)
if err != nil {
return "", errors.Wrap(err, "vault.newCredentialLibraryId")
return "", errors.WrapDeprecated(err, "vault.newCredentialLibraryId")
}
return id, nil
}
+4 -4
View File
@@ -27,13 +27,13 @@ func NewRepository(r db.Reader, w db.Writer, kms *kms.Kms, scheduler *scheduler.
const op = "vault.NewRepository"
switch {
case r == nil:
return nil, errors.New(errors.InvalidParameter, op, "db.Reader")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "db.Reader")
case w == nil:
return nil, errors.New(errors.InvalidParameter, op, "db.Writer")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "db.Writer")
case kms == nil:
return nil, errors.New(errors.InvalidParameter, op, "kms")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "kms")
case scheduler == nil:
return nil, errors.New(errors.InvalidParameter, op, "scheduler")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "scheduler")
}
opts := getOpts(opt...)
@@ -25,22 +25,22 @@ import (
func (r *Repository) CreateCredentialLibrary(ctx context.Context, scopeId string, l *CredentialLibrary, _ ...Option) (*CredentialLibrary, error) {
const op = "vault.(Repository).CreateCredentialLibrary"
if l == nil {
return nil, errors.New(errors.InvalidParameter, op, "nil CredentialLibrary")
return nil, errors.New(ctx, errors.InvalidParameter, op, "nil CredentialLibrary")
}
if l.CredentialLibrary == nil {
return nil, errors.New(errors.InvalidParameter, op, "nil embedded l")
return nil, errors.New(ctx, errors.InvalidParameter, op, "nil embedded l")
}
if l.StoreId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no store id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no store id")
}
if l.VaultPath == "" {
return nil, errors.New(errors.InvalidParameter, op, "no vault path")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no vault path")
}
if l.PublicId != "" {
return nil, errors.New(errors.InvalidParameter, op, "public id not empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "public id not empty")
}
if scopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no scope id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no scope id")
}
l = l.clone()
@@ -50,13 +50,13 @@ func (r *Repository) CreateCredentialLibrary(ctx context.Context, scopeId string
id, err := newCredentialLibraryId()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
l.PublicId = id
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
}
var newCredentialLibrary *CredentialLibrary
@@ -65,7 +65,7 @@ func (r *Repository) CreateCredentialLibrary(ctx context.Context, scopeId string
newCredentialLibrary = l.clone()
err := w.Create(ctx, newCredentialLibrary, db.WithOplog(oplogWrapper, l.oplog(oplog.OpType_OP_TYPE_CREATE)))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
},
@@ -73,9 +73,9 @@ func (r *Repository) CreateCredentialLibrary(ctx context.Context, scopeId string
if err != nil {
if errors.IsUniqueError(err) {
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in credential store: %s: name %s already exists", l.StoreId, l.Name)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("in credential store: %s: name %s already exists", l.StoreId, l.Name)))
}
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in credential store: %s", l.StoreId)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("in credential store: %s", l.StoreId)))
}
return newCredentialLibrary, nil
}
@@ -97,19 +97,19 @@ func (r *Repository) CreateCredentialLibrary(ctx context.Context, scopeId string
func (r *Repository) UpdateCredentialLibrary(ctx context.Context, scopeId string, l *CredentialLibrary, version uint32, fieldMaskPaths []string, _ ...Option) (*CredentialLibrary, int, error) {
const op = "vault.(Repository).UpdateCredentialLibrary"
if l == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing CredentialLibrary")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing CredentialLibrary")
}
if l.CredentialLibrary == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing embedded CredentialLibrary")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing embedded CredentialLibrary")
}
if l.PublicId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
if version == 0 {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing version")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing version")
}
if scopeId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
l = l.clone()
@@ -121,7 +121,7 @@ func (r *Repository) UpdateCredentialLibrary(ctx context.Context, scopeId string
case strings.EqualFold(httpMethodField, f):
case strings.EqualFold(httpRequestBodyField, f):
default:
return nil, db.NoRowsAffected, errors.New(errors.InvalidFieldMask, op, f)
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, f)
}
}
var dbMask, nullFields []string
@@ -144,12 +144,12 @@ func (r *Repository) UpdateCredentialLibrary(ctx context.Context, scopeId string
}
if len(dbMask) == 0 && len(nullFields) == 0 {
return nil, db.NoRowsAffected, errors.New(errors.EmptyFieldMask, op, "missing field mask")
return nil, db.NoRowsAffected, errors.New(ctx, errors.EmptyFieldMask, op, "missing field mask")
}
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithCode(errors.Encrypt),
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt),
errors.WithMsg("unable to get oplog wrapper"))
}
@@ -163,7 +163,7 @@ func (r *Repository) UpdateCredentialLibrary(ctx context.Context, scopeId string
db.WithOplog(oplogWrapper, l.oplog(oplog.OpType_OP_TYPE_UPDATE)),
db.WithVersion(&version))
if err == nil && rowsUpdated > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 resource would have been updated")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 resource would have been updated")
}
return err
},
@@ -171,10 +171,10 @@ func (r *Repository) UpdateCredentialLibrary(ctx context.Context, scopeId string
if err != nil {
if errors.IsUniqueError(err) {
return nil, db.NoRowsAffected, errors.New(errors.NotUnique, op,
return nil, db.NoRowsAffected, errors.New(ctx, errors.NotUnique, op,
fmt.Sprintf("name %s already exists: %s", l.Name, l.PublicId))
}
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(l.PublicId))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(l.PublicId))
}
return returnedCredentialLibrary, rowsUpdated, nil
@@ -185,7 +185,7 @@ func (r *Repository) UpdateCredentialLibrary(ctx context.Context, scopeId string
func (r *Repository) LookupCredentialLibrary(ctx context.Context, publicId string, _ ...Option) (*CredentialLibrary, error) {
const op = "vault.(Repository).LookupCredentialLibrary"
if publicId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no public id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no public id")
}
l := allocCredentialLibrary()
l.PublicId = publicId
@@ -193,7 +193,7 @@ func (r *Repository) LookupCredentialLibrary(ctx context.Context, publicId strin
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("failed for: %s", publicId)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("failed for: %s", publicId)))
}
return l, nil
}
@@ -203,10 +203,10 @@ func (r *Repository) LookupCredentialLibrary(ctx context.Context, publicId strin
func (r *Repository) DeleteCredentialLibrary(ctx context.Context, scopeId string, publicId string, _ ...Option) (int, error) {
const op = "vault.(Repository).DeleteCredentialLibrary"
if publicId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no public id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "no public id")
}
if scopeId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no scope id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "no scope id")
}
l := allocCredentialLibrary()
@@ -214,7 +214,7 @@ func (r *Repository) DeleteCredentialLibrary(ctx context.Context, scopeId string
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
}
var rowsDeleted int
@@ -224,14 +224,14 @@ func (r *Repository) DeleteCredentialLibrary(ctx context.Context, scopeId string
dl := l.clone()
rowsDeleted, err = w.Delete(ctx, dl, db.WithOplog(oplogWrapper, l.oplog(oplog.OpType_OP_TYPE_DELETE)))
if err == nil && rowsDeleted > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 CredentialLibrary would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 CredentialLibrary would have been deleted")
}
return err
},
)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("delete failed for %s", l.PublicId)))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("delete failed for %s", l.PublicId)))
}
return rowsDeleted, nil
@@ -242,7 +242,7 @@ func (r *Repository) DeleteCredentialLibrary(ctx context.Context, scopeId string
func (r *Repository) ListCredentialLibraries(ctx context.Context, storeId string, opt ...Option) ([]*CredentialLibrary, error) {
const op = "vault.(Repository).ListCredentialLibraries"
if storeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no storeId")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no storeId")
}
opts := getOpts(opt...)
limit := r.defaultLimit
@@ -253,7 +253,7 @@ func (r *Repository) ListCredentialLibraries(ctx context.Context, storeId string
var libs []*CredentialLibrary
err := r.reader.SearchWhere(ctx, &libs, "store_id = ?", []interface{}{storeId}, db.WithLimit(limit))
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
return libs, nil
}
@@ -41,32 +41,32 @@ import (
func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialStore, _ ...Option) (*CredentialStore, error) {
const op = "vault.(Repository).CreateCredentialStore"
if cs == nil {
return nil, errors.New(errors.InvalidParameter, op, "nil CredentialStore")
return nil, errors.New(ctx, errors.InvalidParameter, op, "nil CredentialStore")
}
if cs.CredentialStore == nil {
return nil, errors.New(errors.InvalidParameter, op, "nil embedded CredentialStore")
return nil, errors.New(ctx, errors.InvalidParameter, op, "nil embedded CredentialStore")
}
if cs.ScopeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no scope id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no scope id")
}
if len(cs.inputToken) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "no vault token")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no vault token")
}
if cs.VaultAddress == "" {
return nil, errors.New(errors.InvalidParameter, op, "no vault address")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no vault address")
}
if cs.PublicId != "" {
return nil, errors.New(errors.InvalidParameter, op, "public id not empty")
return nil, errors.New(ctx, errors.InvalidParameter, op, "public id not empty")
}
if cs.clientCert != nil && len(cs.clientCert.CertificateKey) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "client certificate without private key")
return nil, errors.New(ctx, errors.InvalidParameter, op, "client certificate without private key")
}
cs = cs.clone()
id, err := newCredentialStoreId()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
cs.PublicId = id
if cs.clientCert != nil {
@@ -75,11 +75,11 @@ func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialSt
client, err := cs.client()
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to create vault client"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create vault client"))
}
tokenLookup, err := client.lookupToken()
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to lookup vault token"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to lookup vault token"))
}
if err := validateTokenLookup(op, tokenLookup); err != nil {
return nil, err
@@ -87,27 +87,27 @@ func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialSt
available, err := client.capabilities(requiredCapabilities.paths())
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get vault capabilities"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get vault capabilities"))
}
missing := available.missing(requiredCapabilities)
if len(missing) > 0 {
return nil,
errors.New(errors.VaultTokenMissingCapabilities, op, fmt.Sprintf("missing capabilites: %v", missing))
errors.New(ctx, errors.VaultTokenMissingCapabilities, op, fmt.Sprintf("missing capabilites: %v", missing))
}
renewedToken, err := client.renewToken()
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to renew vault token"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to renew vault token"))
}
tokenExpires, err := renewedToken.TokenTTL()
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get vault token expiration"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get vault token expiration"))
}
accessor, err := renewedToken.TokenAccessor()
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get vault token accessor"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get vault token accessor"))
}
token, err := newToken(id, cs.inputToken, []byte(accessor), tokenExpires)
@@ -117,20 +117,20 @@ func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialSt
oplogWrapper, err := r.kms.GetWrapper(ctx, cs.ScopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
}
databaseWrapper, err := r.kms.GetWrapper(ctx, cs.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
// encrypt
if err := token.encrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
if cs.clientCert != nil {
if err := cs.clientCert.encrypt(ctx, databaseWrapper); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
}
@@ -142,14 +142,14 @@ func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialSt
msgs := make([]*oplog.Message, 0, 3)
ticket, err := w.GetTicket(cs)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
// insert credential store
newCredentialStore = cs.clone()
var csOplogMsg oplog.Message
if err := w.Create(ctx, newCredentialStore, db.NewOplogMsg(&csOplogMsg)); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
msgs = append(msgs, &csOplogMsg)
@@ -158,10 +158,10 @@ func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialSt
query, values := newToken.insertQuery()
rows, err := w.Exec(ctx, query, values)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rows > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 token would have been created")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 token would have been created")
}
msgs = append(msgs, newToken.oplogMessage(db.CreateOp))
@@ -175,7 +175,7 @@ func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialSt
newClientCertificate = cs.clientCert.clone()
var clientCertOplogMsg oplog.Message
if err := w.Create(ctx, newClientCertificate, db.NewOplogMsg(&clientCertOplogMsg)); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
msgs = append(msgs, &clientCertOplogMsg)
@@ -186,7 +186,7 @@ func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialSt
}
metadata := cs.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 errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog"))
}
return nil
},
@@ -194,9 +194,9 @@ func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialSt
if err != nil {
if errors.IsUniqueError(err) {
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in scope: %s: name %s already exists", cs.ScopeId, cs.Name)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("in scope: %s: name %s already exists", cs.ScopeId, cs.Name)))
}
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in scope: %s", cs.ScopeId)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("in scope: %s", cs.ScopeId)))
}
// Best effort update next run time of token renewal job, but an error should not
@@ -209,33 +209,33 @@ func (r *Repository) CreateCredentialStore(ctx context.Context, cs *CredentialSt
func validateTokenLookup(op errors.Op, s *vault.Secret) error {
if s.Data == nil {
return errors.New(errors.InvalidParameter, op, "vault secret is not a token lookup")
return errors.NewDeprecated(errors.InvalidParameter, op, "vault secret is not a token lookup")
}
if s.Data["renewable"] == nil {
return errors.E(errors.WithCode(errors.VaultTokenNotRenewable), errors.WithOp(op))
return errors.EDeprecated(errors.WithCode(errors.VaultTokenNotRenewable), errors.WithOp(op))
}
renewable, err := parseutil.ParseBool(s.Data["renewable"])
if err != nil {
return errors.Wrap(err, op)
return errors.WrapDeprecated(err, op)
}
if !renewable {
return errors.E(errors.WithCode(errors.VaultTokenNotRenewable), errors.WithOp(op))
return errors.EDeprecated(errors.WithCode(errors.VaultTokenNotRenewable), errors.WithOp(op))
}
if s.Data["orphan"] == nil {
return errors.E(errors.WithCode(errors.VaultTokenNotOrphan), errors.WithOp(op))
return errors.EDeprecated(errors.WithCode(errors.VaultTokenNotOrphan), errors.WithOp(op))
}
orphan, err := parseutil.ParseBool(s.Data["orphan"])
if err != nil {
return errors.Wrap(err, op)
return errors.WrapDeprecated(err, op)
}
if !orphan {
return errors.E(errors.WithCode(errors.VaultTokenNotOrphan), errors.WithOp(op))
return errors.EDeprecated(errors.WithCode(errors.VaultTokenNotOrphan), errors.WithOp(op))
}
if s.Data["period"] == nil {
return errors.E(errors.WithCode(errors.VaultTokenNotPeriodic), errors.WithOp(op))
return errors.EDeprecated(errors.WithCode(errors.VaultTokenNotPeriodic), errors.WithOp(op))
}
return nil
@@ -246,7 +246,7 @@ func validateTokenLookup(op errors.Op, s *vault.Secret) error {
func (r *Repository) LookupCredentialStore(ctx context.Context, publicId string, _ ...Option) (*CredentialStore, error) {
const op = "vault.(Repository).LookupCredentialStore"
if publicId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no public id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no public id")
}
agg := allocPublicStore()
agg.PublicId = publicId
@@ -254,7 +254,7 @@ func (r *Repository) LookupCredentialStore(ctx context.Context, publicId string,
if errors.IsNotFoundError(err) {
return nil, nil
}
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("failed for: %s", publicId)))
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("failed for: %s", publicId)))
}
return agg.toCredentialStore(), nil
}
@@ -343,19 +343,19 @@ func (ps *publicStore) GetPublicId() string { return ps.PublicId }
func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialStore, version uint32, fieldMaskPaths []string, _ ...Option) (*CredentialStore, int, error) {
const op = "vault.(Repository).UpdateCredentialStore"
if cs == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing CredentialStore")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing CredentialStore")
}
if cs.CredentialStore == nil {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing embedded CredentialStore")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing embedded CredentialStore")
}
if cs.PublicId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidPublicId, op, "missing public id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidPublicId, op, "missing public id")
}
if version == 0 {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing version")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing version")
}
if cs.ScopeId == "" {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing scope id")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
}
cs = cs.clone()
@@ -378,7 +378,7 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
validateToken = true
}
default:
return nil, db.NoRowsAffected, errors.New(errors.InvalidFieldMask, op, f)
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, f)
}
}
dbMask, nullFields := dbcommon.BuildUpdatePaths(
@@ -410,10 +410,10 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
fieldMaskPaths, nil,
)
if len(certNullFields) != 0 && len(certNullFields) != 2 {
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "attempting to unset a required field on a client cert")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "attempting to unset a required field on a client cert")
}
if len(append(dbMask, certDbMask...)) == 0 && len(append(nullFields, certNullFields...)) == 0 {
return nil, db.NoRowsAffected, errors.New(errors.EmptyFieldMask, op, "missing field mask")
return nil, db.NoRowsAffected, errors.New(ctx, errors.EmptyFieldMask, op, "missing field mask")
}
var filteredDbMask, filteredNullFields []string
@@ -427,7 +427,7 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
for _, f := range nullFields {
switch {
case strings.EqualFold(tokenField, f):
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "attempting to unset the value for token")
return nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "attempting to unset the value for token")
default:
filteredNullFields = append(filteredNullFields, f)
}
@@ -436,20 +436,20 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
oplogWrapper, err := r.kms.GetWrapper(ctx, cs.ScopeId, kms.KeyPurposeOplog)
if err != nil {
return nil, db.NoRowsAffected,
errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
}
databaseWrapper, err := r.kms.GetWrapper(ctx, cs.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, db.NoRowsAffected,
errors.Wrap(err, op, errors.WithMsg("unable to get database wrapper"))
errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
ps, err := r.lookupPrivateStore(ctx, cs.GetPublicId())
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to lookup private credential store"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to lookup private credential store"))
}
if ps == nil {
return nil, db.NoRowsAffected, errors.New(errors.RecordNotFound, op, fmt.Sprintf("credential store %s", cs.PublicId))
return nil, db.NoRowsAffected, errors.New(ctx, errors.RecordNotFound, op, fmt.Sprintf("credential store %s", cs.PublicId))
}
origStore := ps.toCredentialStore()
origStore.inputToken = ps.Token
@@ -457,60 +457,60 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
origStore.clientCert, err = NewClientCertificate(ps.ClientCert, ps.ClientKey)
}
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("can't recreate client certificate for vault client creation"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("can't recreate client certificate for vault client creation"))
}
updatedStore := origStore.applyUpdate(cs, fieldMaskPaths)
if len(certDbMask) > 0 && updatedStore.clientCert != nil {
if err := updatedStore.clientCert.encrypt(ctx, databaseWrapper); err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
}
var token *Token
client, err := updatedStore.client()
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get client for updated store"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get client for updated store"))
}
if validateToken {
tokenLookup, err := client.lookupToken()
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("cannot lookup token for updated store"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("cannot lookup token for updated store"))
}
if err := validateTokenLookup(op, tokenLookup); err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
available, err := client.capabilities(requiredCapabilities.paths())
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get vault capabilities"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get vault capabilities"))
}
missing := available.missing(requiredCapabilities)
if len(missing) > 0 {
return nil,
db.NoRowsAffected,
errors.New(errors.VaultTokenMissingCapabilities, op, fmt.Sprintf("missing capabilites: %v", missing))
errors.New(ctx, errors.VaultTokenMissingCapabilities, op, fmt.Sprintf("missing capabilites: %v", missing))
}
}
if updateToken {
renewedToken, err := client.renewToken()
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to renew vault token"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to renew vault token"))
}
tokenExpires, err := renewedToken.TokenTTL()
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get vault token expiration"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get vault token expiration"))
}
accessor, err := renewedToken.TokenAccessor()
if err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get vault token accessor"))
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get vault token accessor"))
}
if token, err = newToken(cs.GetPublicId(), cs.inputToken, []byte(accessor), tokenExpires); err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
// encrypt token
if err := token.encrypt(ctx, databaseWrapper); err != nil {
return nil, db.NoRowsAffected, errors.Wrap(err, op)
return nil, db.NoRowsAffected, errors.Wrap(ctx, err, op)
}
}
@@ -521,7 +521,7 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
msgs := make([]*oplog.Message, 0, 3)
ticket, err := w.GetTicket(cs)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
cs := cs.clone()
@@ -535,30 +535,30 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
cs.Version = version + 1
rowsUpdated, err = w.Update(ctx, cs, []string{"Version"}, nil, db.NewOplogMsg(&csOplogMsg), db.WithVersion(&version))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to update credential store version"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update credential store version"))
}
switch rowsUpdated {
case 1:
case 0:
return nil
default:
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("updated credential store version and %d rows updated", rowsUpdated))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated credential store version and %d rows updated", rowsUpdated))
}
default:
rowsUpdated, err = w.Update(ctx, cs, filteredDbMask, filteredNullFields, db.NewOplogMsg(&csOplogMsg), db.WithVersion(&version))
if err != nil {
if errors.IsUniqueError(err) {
return errors.New(errors.NotUnique, op,
return errors.New(ctx, errors.NotUnique, op,
fmt.Sprintf("name %s already exists: %s", cs.Name, cs.PublicId))
}
return errors.Wrap(err, op, errors.WithMsg("unable to update credential store"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to update credential store"))
}
switch rowsUpdated {
case 1:
case 0:
return nil
default:
return errors.New(errors.MultipleRecords, op, fmt.Sprintf("updated credential store and %d rows updated", rowsUpdated))
return errors.New(ctx, errors.MultipleRecords, op, fmt.Sprintf("updated credential store and %d rows updated", rowsUpdated))
}
}
msgs = append(msgs, &csOplogMsg)
@@ -571,23 +571,23 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
query, values := deleteCert.deleteQuery()
rows, err := w.Exec(ctx, query, values)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to delete client certificate"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to delete client certificate"))
}
if rows > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 client certificate would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 client certificate would have been deleted")
}
msgs = append(msgs, deleteCert.oplogMessage(db.DeleteOp))
case len(certDbMask) > 0:
if updatedStore.clientCert == nil {
return errors.New(errors.InvalidParameter, op, "updated cert")
return errors.New(ctx, errors.InvalidParameter, op, "updated cert")
}
query, values := updatedStore.clientCert.insertQuery()
rows, err := w.Exec(ctx, query, values)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to upsert client certificate"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to upsert client certificate"))
}
if rows > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 client certificate would have been upserted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 client certificate would have been upserted")
}
}
@@ -596,13 +596,13 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
rows, err := w.Exec(ctx, query, values)
if err != nil {
if errors.IsUniqueError(err) {
return errors.New(errors.NotUnique, op,
return errors.New(ctx, errors.NotUnique, op,
fmt.Sprintf("token already exists"))
}
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rows > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 token would have been created")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 token would have been created")
}
msgs = append(msgs, token.oplogMessage(db.CreateOp))
}
@@ -611,13 +611,13 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
agg := allocPublicStore()
agg.PublicId = publicId
if err := reader.LookupByPublicId(ctx, agg); err != nil {
return errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("unable to lookup credential store: %s", publicId)))
return errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("unable to lookup credential store: %s", publicId)))
}
returnedCredentialStore = agg.toCredentialStore()
metadata := cs.oplog(oplog.OpType_OP_TYPE_UPDATE)
if err := w.WriteOplogEntryWith(ctx, oplogWrapper, ticket, metadata, msgs); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog"))
}
return nil
},
@@ -642,7 +642,7 @@ func (r *Repository) UpdateCredentialStore(ctx context.Context, cs *CredentialSt
func (r *Repository) ListCredentialStores(ctx context.Context, scopeIds []string, opt ...Option) ([]*CredentialStore, error) {
const op = "vault.(Repository).ListCredentialStores"
if len(scopeIds) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "no scopeIds")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no scopeIds")
}
opts := getOpts(opt...)
limit := r.defaultLimit
@@ -653,7 +653,7 @@ func (r *Repository) ListCredentialStores(ctx context.Context, scopeIds []string
var credentialStores []*publicStore
err := r.reader.SearchWhere(ctx, &credentialStores, "scope_id in (?)", []interface{}{scopeIds}, db.WithLimit(limit))
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
var out []*CredentialStore
for _, ca := range credentialStores {
@@ -667,7 +667,7 @@ func (r *Repository) ListCredentialStores(ctx context.Context, scopeIds []string
func (r *Repository) DeleteCredentialStore(ctx context.Context, publicId string, _ ...Option) (int, error) {
const op = "vault.(Repository).DeleteCredentialStore"
if publicId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no public id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "no public id")
}
cs := allocCredentialStore()
@@ -676,15 +676,15 @@ func (r *Repository) DeleteCredentialStore(ctx context.Context, publicId string,
if errors.IsNotFoundError(err) {
return db.NoRowsAffected, nil
}
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("failed for %s", publicId)))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("failed for %s", publicId)))
}
if cs.ScopeId == "" {
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no scope id")
return db.NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "no scope id")
}
oplogWrapper, err := r.kms.GetWrapper(ctx, cs.ScopeId, kms.KeyPurposeOplog)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get oplog wrapper"))
}
var rows int
@@ -695,15 +695,15 @@ func (r *Repository) DeleteCredentialStore(ctx context.Context, publicId string,
var msgs []*oplog.Message
ticket, err := w.GetTicket(cs)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
rows, err = w.Exec(ctx, query, values)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if rows > 1 {
return errors.New(errors.MultipleRecords, op, "more than 1 credential store would have been deleted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 credential store would have been deleted")
}
msg := cs.oplogMessage(db.UpdateOp)
msg.FieldMaskPaths = []string{"DeleteTime"}
@@ -711,7 +711,7 @@ func (r *Repository) DeleteCredentialStore(ctx context.Context, publicId string,
metadata := cs.oplog(oplog.OpType_OP_TYPE_UPDATE)
if err := w.WriteOplogEntryWith(ctx, oplogWrapper, ticket, metadata, msgs); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog"))
}
return nil
@@ -719,7 +719,7 @@ func (r *Repository) DeleteCredentialStore(ctx context.Context, publicId string,
)
if err != nil {
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("delete failed for %s", cs.PublicId)))
return db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("delete failed for %s", cs.PublicId)))
}
if rows > 0 {
@@ -18,15 +18,15 @@ var _ credential.Issuer = (*Repository)(nil)
func (r *Repository) Issue(ctx context.Context, sessionId string, requests []credential.Request) ([]credential.Dynamic, error) {
const op = "vault.(Repository).Issue"
if sessionId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no session id")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no session id")
}
if len(requests) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "no requests")
return nil, errors.New(ctx, errors.InvalidParameter, op, "no requests")
}
libs, err := r.getPrivateLibraries(ctx, requests)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
// TODO(mgaffney)(ICU-1329) 05/2021: if any error occurs, mark all credentials
@@ -40,12 +40,12 @@ func (r *Repository) Issue(ctx context.Context, sessionId string, requests []cre
// if there is no way to save it in the database.
credId, err := newCredentialId()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
client, err := lib.client()
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
var secret *vault.Secret
@@ -55,13 +55,13 @@ func (r *Repository) Issue(ctx context.Context, sessionId string, requests []cre
case MethodPost:
secret, err = client.post(lib.VaultPath, lib.HttpRequestBody)
default:
return nil, errors.New(errors.Internal, op, fmt.Sprintf("unknown http method: library: %s", lib.PublicId))
return nil, errors.New(ctx, errors.Internal, op, fmt.Sprintf("unknown http method: library: %s", lib.PublicId))
}
if err != nil {
// TODO(mgaffney) 05/2021: detect if the error is because of an
// expired or invalid token
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
leaseDuration := time.Duration(secret.LeaseDuration) * time.Second
@@ -70,7 +70,7 @@ func (r *Repository) Issue(ctx context.Context, sessionId string, requests []cre
}
cred, err := newCredential(lib.GetPublicId(), sessionId, secret.LeaseID, lib.TokenHmac, leaseDuration)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
cred.PublicId = credId
cred.IsRenewable = secret.Renewable
@@ -82,24 +82,24 @@ func (r *Repository) Issue(ctx context.Context, sessionId string, requests []cre
rowsInserted, err := w.Exec(ctx, insertQuery, insertQueryValues)
switch {
case err != nil:
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
case rowsInserted > 1:
return errors.New(errors.MultipleRecords, op, "more than 1 credential would have been inserted")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 credential would have been inserted")
}
rowsUpdated, err := w.Exec(ctx, updateQuery, updateQueryValues)
switch {
case err != nil:
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
case rowsUpdated == 0:
return errors.New(errors.InvalidDynamicCredential, op, "no matching dynamic credential for session found")
return errors.New(ctx, errors.InvalidDynamicCredential, op, "no matching dynamic credential for session found")
case rowsUpdated > 1:
return errors.New(errors.MultipleRecords, op, "more than 1 session credential would have been updated")
return errors.New(ctx, errors.MultipleRecords, op, "more than 1 session credential would have been updated")
}
return nil
},
); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
creds = append(creds, &actualCredential{
@@ -125,13 +125,13 @@ var _ credential.Revoker = (*Repository)(nil)
func (r *Repository) Revoke(ctx context.Context, sessionId string) error {
const op = "vault.(Repository).Revoke"
if sessionId == "" {
return errors.New(errors.InvalidParameter, op, "no session id")
return errors.New(ctx, errors.InvalidParameter, op, "no session id")
}
_, err := r.writer.DoTx(ctx, db.StdRetryCnt, db.ExpBackoff{},
func(_ db.Reader, w db.Writer) error {
if _, err := w.Exec(ctx, revokeCredentialsQuery, []interface{}{sessionId}); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
},
+16 -16
View File
@@ -47,7 +47,7 @@ type client struct {
func newClient(c *clientConfig) (*client, error) {
const op = "vault.newClient"
if !c.isValid() {
return nil, errors.New(errors.InvalidParameter, op, "invalid configuration")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "invalid configuration")
}
vc := vault.DefaultConfig()
vc.Address = c.Addr
@@ -58,14 +58,14 @@ func newClient(c *clientConfig) (*client, error) {
tlsConfig := vc.HttpClient.Transport.(*http.Transport).TLSClientConfig
tlsConfig.InsecureSkipVerify = c.TlsSkipVerify
if err := rootcerts.ConfigureTLS(tlsConfig, rootConfig); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.WrapDeprecated(err, op)
}
}
if c.isClientTLS() {
clientCert, err := tls.X509KeyPair(c.ClientCert, c.ClientKey)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.WrapDeprecated(err, op)
}
tlsConfig := vc.HttpClient.Transport.(*http.Transport).TLSClientConfig
tlsConfig.GetClientCertificate = func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
@@ -75,7 +75,7 @@ func newClient(c *clientConfig) (*client, error) {
vClient, err := vault.NewClient(vc)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.WrapDeprecated(err, op)
}
vClient.SetToken(string(c.Token))
@@ -94,11 +94,11 @@ func (c *client) ping() error {
h, err := c.cl.Sys().Health()
switch {
case err != nil:
return errors.Wrap(err, op, errors.WithCode(errors.Unknown), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
return errors.WrapDeprecated(err, op, errors.WithCode(errors.Unknown), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
case h == nil:
return errors.New(errors.Unavailable, op, fmt.Sprintf("no repsonse: vault: %s", c.cl.Address()))
return errors.NewDeprecated(errors.Unavailable, op, fmt.Sprintf("no repsonse: vault: %s", c.cl.Address()))
case !h.Initialized || h.Sealed:
return errors.New(errors.Unavailable, op, fmt.Sprintf("vault (%s): initialized: %t, sealed: %t ", c.cl.Address(), h.Initialized, h.Sealed))
return errors.NewDeprecated(errors.Unavailable, op, fmt.Sprintf("vault (%s): initialized: %t, sealed: %t ", c.cl.Address(), h.Initialized, h.Sealed))
}
return nil
@@ -112,7 +112,7 @@ func (c *client) renewToken() (*vault.Secret, error) {
const op = "vault.(client).renewToken"
t, err := c.cl.Auth().Token().RenewSelf(0)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Unknown), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
return nil, errors.WrapDeprecated(err, op, errors.WithCode(errors.Unknown), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
}
return t, nil
}
@@ -124,7 +124,7 @@ func (c *client) revokeToken() error {
const op = "vault.(client).revokeToken"
// The `token` parameter is kept for backwards compatibility but is ignored, so use ""
if err := c.cl.Auth().Token().RevokeSelf(""); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Unknown), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
return errors.WrapDeprecated(err, op, errors.WithCode(errors.Unknown), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
}
return nil
}
@@ -137,7 +137,7 @@ func (c *client) renewLease(leaseId string, leaseDuration time.Duration) (*vault
const op = "vault.(client).renewLease"
t, err := c.cl.Sys().Renew(leaseId, int(leaseDuration.Round(time.Second).Seconds()))
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.VaultCredentialRequest), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
return nil, errors.WrapDeprecated(err, op, errors.WithCode(errors.VaultCredentialRequest), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
}
return t, nil
}
@@ -148,7 +148,7 @@ func (c *client) renewLease(leaseId string, leaseDuration time.Duration) (*vault
func (c *client) revokeLease(leaseId string) error {
const op = "vault.(client).revokeLease"
if err := c.cl.Sys().Revoke(leaseId); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Unknown), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
return errors.WrapDeprecated(err, op, errors.WithCode(errors.Unknown), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
}
return nil
}
@@ -161,7 +161,7 @@ func (c *client) lookupToken() (*vault.Secret, error) {
const op = "vault.(client).lookupToken"
t, err := c.cl.Auth().Token().LookupSelf()
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.Unknown), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
return nil, errors.WrapDeprecated(err, op, errors.WithCode(errors.Unknown), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
}
return t, nil
}
@@ -178,7 +178,7 @@ func (c *client) get(path string) (*vault.Secret, error) {
const op = "vault.(client).get"
s, err := c.cl.Logical().Read(path)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.VaultCredentialRequest), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
return nil, errors.WrapDeprecated(err, op, errors.WithCode(errors.VaultCredentialRequest), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
}
return s, nil
}
@@ -193,7 +193,7 @@ func (c *client) post(path string, data []byte) (*vault.Secret, error) {
}
s, err := c.cl.Logical().WriteBytes(path, data)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithCode(errors.VaultCredentialRequest), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
return nil, errors.WrapDeprecated(err, op, errors.WithCode(errors.VaultCredentialRequest), errors.WithMsg(fmt.Sprintf("vault: %s", c.cl.Address())))
}
return s, nil
}
@@ -205,7 +205,7 @@ func (c *client) post(path string, data []byte) (*vault.Secret, error) {
func (c *client) capabilities(paths []string) (pathCapabilities, error) {
const op = "vault.(client).capabilities"
if len(paths) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "empty paths")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "empty paths")
}
body := map[string]string{
"paths": strings.Join(paths, ","),
@@ -230,7 +230,7 @@ func (c *client) capabilities(paths []string) (pathCapabilities, error) {
return nil, err
}
if secret == nil || secret.Data == nil {
return nil, errors.New(errors.Unknown, op, "data from Vault is empty")
return nil, errors.NewDeprecated(errors.Unknown, op, "data from Vault is empty")
}
var res map[string][]string
+6 -6
View File
@@ -56,16 +56,16 @@ type Token struct {
func newToken(storeId string, token TokenSecret, accessor []byte, expiration time.Duration) (*Token, error) {
const op = "vault.newToken"
if storeId == "" {
return nil, errors.New(errors.InvalidParameter, op, "no store id")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "no store id")
}
if len(token) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "no vault token")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "no vault token")
}
if len(accessor) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "no vault token accessor")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "no vault token accessor")
}
if expiration == 0 {
return nil, errors.New(errors.InvalidParameter, op, "no expiration")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "no expiration")
}
tokenCopy := make(TokenSecret, len(token))
@@ -120,7 +120,7 @@ func (t *Token) SetTableName(n string) {
func (t *Token) encrypt(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "vault.(Token).encrypt"
if err := structwrapping.WrapStruct(ctx, cipher, t.Token, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Encrypt))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt))
}
t.KeyId = cipher.KeyID()
return nil
@@ -129,7 +129,7 @@ func (t *Token) encrypt(ctx context.Context, cipher wrapping.Wrapper) error {
func (t *Token) decrypt(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "vault.(Token).decrypt"
if err := structwrapping.UnwrapStruct(ctx, cipher, t.Token, nil); err != nil {
return errors.Wrap(err, op, errors.WithCode(errors.Decrypt))
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Decrypt))
}
return nil
}
+8 -8
View File
@@ -19,7 +19,7 @@ import (
func UpdateFields(i interface{}, fieldMaskPaths []string, setToNullPaths []string) (map[string]interface{}, error) {
const op = "common.UpdateFields"
if i == nil {
return nil, errors.New(errors.InvalidParameter, op, "interface is missing")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "interface is missing")
}
if fieldMaskPaths == nil {
fieldMaskPaths = []string{}
@@ -28,15 +28,15 @@ func UpdateFields(i interface{}, fieldMaskPaths []string, setToNullPaths []strin
setToNullPaths = []string{}
}
if len(fieldMaskPaths) == 0 && len(setToNullPaths) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "both fieldMaskPaths and setToNullPaths are zero len")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "both fieldMaskPaths and setToNullPaths are zero len")
}
inter, maskPaths, nullPaths, err := Intersection(fieldMaskPaths, setToNullPaths)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.WrapDeprecated(err, op)
}
if len(inter) != 0 {
return nil, errors.New(errors.InvalidParameter, op, "fieldMashPaths and setToNullPaths cannot intersect")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "fieldMashPaths and setToNullPaths cannot intersect")
}
updateFields := map[string]interface{}{} // case sensitive update fields to values
@@ -87,11 +87,11 @@ func UpdateFields(i interface{}, fieldMaskPaths []string, setToNullPaths []strin
}
if missing := findMissingPaths(setToNullPaths, found); len(missing) != 0 {
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("null paths not found in resource: %s", missing))
return nil, errors.NewDeprecated(errors.InvalidParameter, op, fmt.Sprintf("null paths not found in resource: %s", missing))
}
if missing := findMissingPaths(fieldMaskPaths, found); len(missing) != 0 {
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("field mask paths not found in resource: %s", missing))
return nil, errors.NewDeprecated(errors.InvalidParameter, op, fmt.Sprintf("field mask paths not found in resource: %s", missing))
}
return updateFields, nil
@@ -114,10 +114,10 @@ func findMissingPaths(paths []string, foundPaths map[string]struct{}) []string {
func Intersection(av, bv []string) ([]string, map[string]string, map[string]string, error) {
const op = "common.Intersection"
if av == nil {
return nil, nil, nil, errors.New(errors.InvalidParameter, op, "av is missing")
return nil, nil, nil, errors.NewDeprecated(errors.InvalidParameter, op, "av is missing")
}
if bv == nil {
return nil, nil, nil, errors.New(errors.InvalidParameter, op, "bv is missing")
return nil, nil, nil, errors.NewDeprecated(errors.InvalidParameter, op, "bv is missing")
}
if len(av) == 0 && len(bv) == 0 {
return []string{}, map[string]string{}, map[string]string{}, nil
+2 -2
View File
@@ -22,7 +22,7 @@ func NewPublicId(prefix string, opt ...Option) (string, error) {
func newId(prefix string, opt ...Option) (string, error) {
const op = "db.newId"
if prefix == "" {
return "", errors.New(errors.InvalidParameter, op, "missing prefix")
return "", errors.NewDeprecated(errors.InvalidParameter, op, "missing prefix")
}
var publicId string
var err error
@@ -35,7 +35,7 @@ func newId(prefix string, opt ...Option) (string, error) {
publicId, err = base62.Random(10)
}
if err != nil {
return "", errors.Wrap(err, op, errors.WithMsg("unable to generate id"), errors.WithCode(errors.Io))
return "", errors.WrapDeprecated(err, op, errors.WithMsg("unable to generate id"), errors.WithCode(errors.Io))
}
return fmt.Sprintf("%s_%s", prefix, publicId), nil
}
+142 -142
View File
@@ -206,14 +206,14 @@ func New(underlying *gorm.DB) *Db {
// Exec will execute the sql with the values as parameters. The int returned
// is the number of rows affected by the sql. No options are currently
// supported.
func (rw *Db) Exec(_ context.Context, sql string, values []interface{}, _ ...Option) (int, error) {
func (rw *Db) Exec(ctx context.Context, sql string, values []interface{}, _ ...Option) (int, error) {
const op = "db.Exec"
if sql == "" {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing sql")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing sql")
}
gormDb := rw.underlying.Exec(sql, values...)
if gormDb.Error != nil {
return NoRowsAffected, errors.Wrap(gormDb.Error, op)
return NoRowsAffected, errors.Wrap(ctx, gormDb.Error, op)
}
return int(gormDb.RowsAffected), nil
}
@@ -222,14 +222,14 @@ func (rw *Db) Exec(_ context.Context, sql string, values []interface{}, _ ...Opt
// operate within the context of any ongoing transaction for the db.Reader. The
// caller must close the returned *sql.Rows. Query can/should be used in
// combination with ScanRows.
func (rw *Db) Query(_ context.Context, sql string, values []interface{}, _ ...Option) (*sql.Rows, error) {
func (rw *Db) Query(ctx context.Context, sql string, values []interface{}, _ ...Option) (*sql.Rows, error) {
const op = "db.Query"
if sql == "" {
return nil, errors.New(errors.InvalidParameter, op, "missing sql")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing sql")
}
gormDb := rw.underlying.Raw(sql, values...)
if gormDb.Error != nil {
return nil, errors.Wrap(gormDb.Error, op)
return nil, errors.Wrap(ctx, gormDb.Error, op)
}
return gormDb.Rows()
}
@@ -238,10 +238,10 @@ func (rw *Db) Query(_ context.Context, sql string, values []interface{}, _ ...Op
func (rw *Db) ScanRows(rows *sql.Rows, result interface{}) error {
const op = "db.ScanRows"
if rw.underlying == nil {
return errors.New(errors.InvalidParameter, op, "missing underlying db")
return errors.NewDeprecated(errors.InvalidParameter, op, "missing underlying db")
}
if isNil(result) {
return errors.New(errors.InvalidParameter, op, "missing result")
return errors.NewDeprecated(errors.InvalidParameter, op, "missing result")
}
return rw.underlying.ScanRows(rows, result)
}
@@ -255,7 +255,7 @@ func (rw *Db) lookupAfterWrite(ctx context.Context, i interface{}, opt ...Option
return nil
}
if err := rw.LookupById(ctx, i, opt...); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -267,21 +267,21 @@ func (rw *Db) lookupAfterWrite(ctx context.Context, i interface{}, opt ...Option
func (rw *Db) Create(ctx context.Context, i interface{}, opt ...Option) error {
const op = "db.Create"
if rw.underlying == nil {
return errors.New(errors.InvalidParameter, op, "missing underlying db")
return errors.New(ctx, errors.InvalidParameter, op, "missing underlying db")
}
if isNil(i) {
return errors.New(errors.InvalidParameter, op, "missing interface")
return errors.New(ctx, errors.InvalidParameter, op, "missing interface")
}
opts := GetOpts(opt...)
withOplog := opts.withOplog
if withOplog && opts.newOplogMsg != nil {
return errors.New(errors.InvalidParameter, op, "both WithOplog and NewOplogMsg options have been specified")
return errors.New(ctx, errors.InvalidParameter, op, "both WithOplog and NewOplogMsg options have been specified")
}
if withOplog {
// let's validate oplog options before we start writing to the database
_, err := validateOplogArgs(i, opts)
_, err := validateOplogArgs(ctx, i, opts)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
return errors.Wrap(ctx, err, op, errors.WithMsg("oplog validation failed"))
}
}
// these fields should be nil, since they are not writeable and we want the
@@ -291,7 +291,7 @@ func (rw *Db) Create(ctx context.Context, i interface{}, opt ...Option) error {
if !opts.withSkipVetForWrite {
if vetter, ok := i.(VetForWriter); ok {
if err := vetter.VetForWrite(ctx, rw, CreateOp); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
}
}
@@ -300,26 +300,26 @@ func (rw *Db) Create(ctx context.Context, i interface{}, opt ...Option) error {
var err error
ticket, err = rw.GetTicket(i)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
}
if err := rw.underlying.Create(i).Error; err != nil {
return errors.Wrap(err, op, errors.WithMsg("create failed"))
return errors.Wrap(ctx, err, op, errors.WithMsg("create failed"))
}
if withOplog {
if err := rw.addOplog(ctx, CreateOp, opts, ticket, i); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
}
if opts.newOplogMsg != nil {
msg, err := rw.newOplogMessage(ctx, CreateOp, i)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("returning oplog failed"))
return errors.Wrap(ctx, err, op, errors.WithMsg("returning oplog failed"))
}
*opts.newOplogMsg = *msg
}
if err := rw.lookupAfterWrite(ctx, i, opt...); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -330,20 +330,20 @@ func (rw *Db) Create(ctx context.Context, i interface{}, opt ...Option) error {
func (rw *Db) CreateItems(ctx context.Context, createItems []interface{}, opt ...Option) error {
const op = "db.CreateItems"
if rw.underlying == nil {
return errors.New(errors.InvalidParameter, op, "missing underlying db")
return errors.New(ctx, errors.InvalidParameter, op, "missing underlying db")
}
if len(createItems) == 0 {
return errors.New(errors.InvalidParameter, op, "missing interfaces")
return errors.New(ctx, errors.InvalidParameter, op, "missing interfaces")
}
opts := GetOpts(opt...)
if opts.withLookup {
return errors.New(errors.InvalidParameter, op, "with lookup not a supported option")
return errors.New(ctx, errors.InvalidParameter, op, "with lookup not a supported option")
}
if opts.newOplogMsg != nil {
return errors.New(errors.InvalidParameter, op, "new oplog msg (singular) is not a supported option")
return errors.New(ctx, errors.InvalidParameter, op, "new oplog msg (singular) is not a supported option")
}
if opts.withOplog && opts.newOplogMsgs != nil {
return errors.New(errors.InvalidParameter, op, "both WithOplog and NewOplogMsgs options have been specified")
return errors.New(ctx, errors.InvalidParameter, op, "both WithOplog and NewOplogMsgs options have been specified")
}
// verify that createItems are all the same type.
var foundType reflect.Type
@@ -353,34 +353,34 @@ func (rw *Db) CreateItems(ctx context.Context, createItems []interface{}, opt ..
}
currentType := reflect.TypeOf(v)
if foundType != currentType {
return errors.New(errors.InvalidParameter, op, fmt.Sprintf("create items contains disparate types. item %d is not a %s", i, foundType.Name()))
return errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("create items contains disparate types. item %d is not a %s", i, foundType.Name()))
}
}
var ticket *store.Ticket
if opts.withOplog {
_, err := validateOplogArgs(createItems[0], opts)
_, err := validateOplogArgs(ctx, createItems[0], opts)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
return errors.Wrap(ctx, err, op, errors.WithMsg("oplog validation failed"))
}
ticket, err = rw.GetTicket(createItems[0])
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
}
for _, item := range createItems {
if err := rw.Create(ctx, item); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
}
if opts.withOplog {
if err := rw.addOplogForItems(ctx, CreateOp, opts, ticket, createItems); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to add oplog"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to add oplog"))
}
}
if opts.newOplogMsgs != nil {
msgs, err := rw.oplogMsgsForItems(ctx, CreateOp, opts, createItems)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("returning oplog msgs failed"))
return errors.Wrap(ctx, err, op, errors.WithMsg("returning oplog msgs failed"))
}
*opts.newOplogMsgs = append(*opts.newOplogMsgs, msgs...)
}
@@ -409,59 +409,59 @@ func (rw *Db) CreateItems(ctx context.Context, createItems []interface{}, opt ..
func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string, setToNullPaths []string, opt ...Option) (int, error) {
const op = "db.Update"
if rw.underlying == nil {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing underlying db")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing underlying db")
}
if isNil(i) {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing interface")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing interface")
}
if len(fieldMaskPaths) == 0 && len(setToNullPaths) == 0 {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "both fieldMaskPaths and setToNullPaths are missing")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "both fieldMaskPaths and setToNullPaths are missing")
}
opts := GetOpts(opt...)
withOplog := opts.withOplog
if withOplog && opts.newOplogMsg != nil {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "both WithOplog and NewOplogMsg options have been specified")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "both WithOplog and NewOplogMsg options have been specified")
}
// we need to filter out some non-updatable fields (like: CreateTime, etc)
fieldMaskPaths = filterPaths(fieldMaskPaths)
setToNullPaths = filterPaths(setToNullPaths)
if len(fieldMaskPaths) == 0 && len(setToNullPaths) == 0 {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "after filtering non-updated fields, there are no fields left in fieldMaskPaths or setToNullPaths")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "after filtering non-updated fields, there are no fields left in fieldMaskPaths or setToNullPaths")
}
updateFields, err := common.UpdateFields(i, fieldMaskPaths, setToNullPaths)
if err != nil {
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("getting update fields failed"))
return NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("getting update fields failed"))
}
if len(updateFields) == 0 {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, fmt.Sprintf("no fields matched using fieldMaskPaths %s", fieldMaskPaths))
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("no fields matched using fieldMaskPaths %s", fieldMaskPaths))
}
// This is not a boundary scope, but rather a gorm Scope:
// https://godoc.org/github.com/jinzhu/gorm#DB.NewScope
scope := rw.underlying.NewScope(i)
if scope.PrimaryKeyZero() {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "primary key is not set")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "primary key is not set")
}
for _, f := range scope.PrimaryFields() {
if contains(fieldMaskPaths, f.Name) {
return NoRowsAffected, errors.New(errors.InvalidFieldMask, op, fmt.Sprintf("not allowed on primary key field %s", f.Name))
return NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, fmt.Sprintf("not allowed on primary key field %s", f.Name))
}
}
if withOplog {
// let's validate oplog options before we start writing to the database
_, err := validateOplogArgs(i, opts)
_, err := validateOplogArgs(ctx, i, opts)
if err != nil {
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
return NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("oplog validation failed"))
}
}
if !opts.withSkipVetForWrite {
if vetter, ok := i.(VetForWriter); ok {
if err := vetter.VetForWrite(ctx, rw, UpdateOp, WithFieldMaskPaths(fieldMaskPaths), WithNullPaths(setToNullPaths)); err != nil {
return NoRowsAffected, errors.Wrap(err, op)
return NoRowsAffected, errors.Wrap(ctx, err, op)
}
}
}
@@ -470,7 +470,7 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
var err error
ticket, err = rw.GetTicket(i)
if err != nil {
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
return NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
}
var underlying *gorm.DB
@@ -480,10 +480,10 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
var args []interface{}
if opts.WithVersion != nil {
if *opts.WithVersion == 0 {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "with version option is zero")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "with version option is zero")
}
if _, ok := scope.FieldByName("version"); !ok {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, fmt.Sprintf("%s does not have a version field", scope.TableName()))
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("%s does not have a version field", scope.TableName()))
}
where, args = append(where, "version = ?"), append(args, opts.WithVersion)
}
@@ -496,9 +496,9 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
}
if underlying.Error != nil {
if underlying.Error == gorm.ErrRecordNotFound {
return NoRowsAffected, errors.E(errors.WithCode(errors.RecordNotFound), errors.WithOp(op))
return NoRowsAffected, errors.E(ctx, errors.WithCode(errors.RecordNotFound), errors.WithOp(op))
}
return NoRowsAffected, errors.Wrap(underlying.Error, op)
return NoRowsAffected, errors.Wrap(ctx, underlying.Error, op)
}
rowsUpdated := int(underlying.RowsAffected)
if rowsUpdated > 0 && (withOplog || opts.newOplogMsg != nil) {
@@ -516,13 +516,13 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
}
if withOplog {
if err := rw.addOplog(ctx, UpdateOp, oplogOpts, ticket, i); err != nil {
return rowsUpdated, errors.Wrap(err, op, errors.WithMsg("add oplog failed"))
return rowsUpdated, errors.Wrap(ctx, err, op, errors.WithMsg("add oplog failed"))
}
}
if opts.newOplogMsg != nil {
msg, err := rw.newOplogMessage(ctx, UpdateOp, i, WithFieldMaskPaths(oplogFieldMasks), WithNullPaths(oplogNullPaths))
if err != nil {
return rowsUpdated, errors.Wrap(err, op, errors.WithMsg("returning oplog failed"))
return rowsUpdated, errors.Wrap(ctx, err, op, errors.WithMsg("returning oplog failed"))
}
*opts.newOplogMsg = *msg
}
@@ -531,7 +531,7 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
// from the db
opt = append(opt, WithLookup(true))
if err := rw.lookupAfterWrite(ctx, i, opt...); err != nil {
return NoRowsAffected, errors.Wrap(err, op)
return NoRowsAffected, errors.Wrap(ctx, err, op)
}
return rowsUpdated, nil
}
@@ -544,28 +544,28 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, error) {
const op = "db.Delete"
if rw.underlying == nil {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing underlying db")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing underlying db")
}
if isNil(i) {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing interface")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing interface")
}
opts := GetOpts(opt...)
withOplog := opts.withOplog
if withOplog && opts.newOplogMsg != nil {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "both WithOplog and NewOplogMsg options have been specified")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "both WithOplog and NewOplogMsg options have been specified")
}
// This is not a boundary scope, but rather a gorm Scope:
// https://godoc.org/github.com/jinzhu/gorm#DB.NewScope
scope := rw.underlying.NewScope(i)
if opts.withWhereClause == "" {
if scope.PrimaryKeyZero() {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "primary key is not set")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "primary key is not set")
}
}
if withOplog {
_, err := validateOplogArgs(i, opts)
_, err := validateOplogArgs(ctx, i, opts)
if err != nil {
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
return NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("oplog validation failed"))
}
}
var ticket *store.Ticket
@@ -573,7 +573,7 @@ func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, er
var err error
ticket, err = rw.GetTicket(i)
if err != nil {
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
return NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
}
db := rw.underlying
@@ -582,19 +582,19 @@ func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, er
}
db = db.Delete(i)
if db.Error != nil {
return NoRowsAffected, errors.Wrap(db.Error, op)
return NoRowsAffected, errors.Wrap(ctx, db.Error, op)
}
rowsDeleted := int(db.RowsAffected)
if rowsDeleted > 0 && (withOplog || opts.newOplogMsg != nil) {
if withOplog {
if err := rw.addOplog(ctx, DeleteOp, opts, ticket, i); err != nil {
return rowsDeleted, errors.Wrap(err, op, errors.WithMsg("add oplog failed"))
return rowsDeleted, errors.Wrap(ctx, err, op, errors.WithMsg("add oplog failed"))
}
}
if opts.newOplogMsg != nil {
msg, err := rw.newOplogMessage(ctx, DeleteOp, i)
if err != nil {
return rowsDeleted, errors.Wrap(err, op, errors.WithMsg("returning oplog failed"))
return rowsDeleted, errors.Wrap(ctx, err, op, errors.WithMsg("returning oplog failed"))
}
*opts.newOplogMsg = *msg
}
@@ -608,17 +608,17 @@ func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, er
func (rw *Db) DeleteItems(ctx context.Context, deleteItems []interface{}, opt ...Option) (int, error) {
const op = "db.DeleteItems"
if rw.underlying == nil {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "missing underlying db")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "missing underlying db")
}
if len(deleteItems) == 0 {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "no interfaces to delete")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "no interfaces to delete")
}
opts := GetOpts(opt...)
if opts.newOplogMsg != nil {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "new oplog msg (singular) is not a supported option")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "new oplog msg (singular) is not a supported option")
}
if opts.withOplog && opts.newOplogMsgs != nil {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, "both WithOplog and NewOplogMsgs options have been specified")
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, "both WithOplog and NewOplogMsgs options have been specified")
}
// verify that createItems are all the same type.
var foundType reflect.Type
@@ -628,19 +628,19 @@ func (rw *Db) DeleteItems(ctx context.Context, deleteItems []interface{}, opt ..
}
currentType := reflect.TypeOf(v)
if foundType != currentType {
return NoRowsAffected, errors.New(errors.InvalidParameter, op, fmt.Sprintf("items contain disparate types. item %d is not a %s", i, foundType.Name()))
return NoRowsAffected, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("items contain disparate types. item %d is not a %s", i, foundType.Name()))
}
}
var ticket *store.Ticket
if opts.withOplog {
_, err := validateOplogArgs(deleteItems[0], opts)
_, err := validateOplogArgs(ctx, deleteItems[0], opts)
if err != nil {
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
return NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("oplog validation failed"))
}
ticket, err = rw.GetTicket(deleteItems[0])
if err != nil {
return NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
return NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
}
rowsDeleted := 0
@@ -650,20 +650,20 @@ func (rw *Db) DeleteItems(ctx context.Context, deleteItems []interface{}, opt ..
// relationship between Create and CreateItems).
underlying := rw.underlying.Delete(item)
if underlying.Error != nil {
return rowsDeleted, errors.Wrap(underlying.Error, op)
return rowsDeleted, errors.Wrap(ctx, underlying.Error, op)
}
rowsDeleted += int(underlying.RowsAffected)
}
if rowsDeleted > 0 && (opts.withOplog || opts.newOplogMsgs != nil) {
if opts.withOplog {
if err := rw.addOplogForItems(ctx, DeleteOp, opts, ticket, deleteItems); err != nil {
return rowsDeleted, errors.Wrap(err, op, errors.WithMsg("unable to add oplog"))
return rowsDeleted, errors.Wrap(ctx, err, op, errors.WithMsg("unable to add oplog"))
}
}
if opts.newOplogMsgs != nil {
msgs, err := rw.oplogMsgsForItems(ctx, DeleteOp, opts, deleteItems)
if err != nil {
return rowsDeleted, errors.Wrap(err, op, errors.WithMsg("returning oplog msgs failed"))
return rowsDeleted, errors.Wrap(ctx, err, op, errors.WithMsg("returning oplog msgs failed"))
}
*opts.newOplogMsgs = append(*opts.newOplogMsgs, msgs...)
}
@@ -671,18 +671,18 @@ func (rw *Db) DeleteItems(ctx context.Context, deleteItems []interface{}, opt ..
return rowsDeleted, nil
}
func validateOplogArgs(i interface{}, opts Options) (oplog.ReplayableMessage, error) {
func validateOplogArgs(ctx context.Context, i interface{}, opts Options) (oplog.ReplayableMessage, error) {
const op = "db.validateOplogArgs"
oplogArgs := opts.oplogOpts
if oplogArgs.wrapper == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing wrapper")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing wrapper")
}
if len(oplogArgs.metadata) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "missing metadata")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing metadata")
}
replayable, ok := i.(oplog.ReplayableMessage)
if !ok {
return nil, errors.E(errors.WithOp(op), errors.WithMsg("not a replayable message"))
return nil, errors.E(ctx, errors.WithOp(op), errors.WithMsg("not a replayable message"))
}
return replayable, nil
}
@@ -690,15 +690,15 @@ func validateOplogArgs(i interface{}, opts Options) (oplog.ReplayableMessage, er
func (rw *Db) getTicketFor(aggregateName string) (*store.Ticket, error) {
const op = "db.getTicketFor"
if rw.underlying == nil {
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("%s: underlying db missing", aggregateName))
return nil, errors.NewDeprecated(errors.InvalidParameter, op, fmt.Sprintf("%s: underlying db missing", aggregateName))
}
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true))
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("%s: unable to get Ticketer", aggregateName)))
return nil, errors.WrapDeprecated(err, op, errors.WithMsg(fmt.Sprintf("%s: unable to get Ticketer", aggregateName)))
}
ticket, err := ticketer.GetTicket(aggregateName)
if err != nil {
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("%s: unable to get ticket", aggregateName)))
return nil, errors.WrapDeprecated(err, op, errors.WithMsg(fmt.Sprintf("%s: unable to get ticket", aggregateName)))
}
return ticket, nil
}
@@ -708,14 +708,14 @@ func (rw *Db) getTicketFor(aggregateName string) (*store.Ticket, error) {
func (rw *Db) GetTicket(i interface{}) (*store.Ticket, error) {
const op = "db.GetTicket"
if rw.underlying == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing underlying db")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing underlying db")
}
if isNil(i) {
return nil, errors.New(errors.InvalidParameter, op, "missing interface")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing interface")
}
replayable, ok := i.(oplog.ReplayableMessage)
if !ok {
return nil, errors.New(errors.InvalidParameter, op, "not a replayable message")
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "not a replayable message")
}
return rw.getTicketFor(replayable.TableName())
}
@@ -723,7 +723,7 @@ func (rw *Db) GetTicket(i interface{}) (*store.Ticket, error) {
func (rw *Db) oplogMsgsForItems(ctx context.Context, opType OpType, opts Options, items []interface{}) ([]*oplog.Message, error) {
const op = "db.oplogMsgsForItems"
if len(items) == 0 {
return nil, errors.New(errors.InvalidParameter, op, "missing items")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing items")
}
oplogMsgs := []*oplog.Message{}
var foundType reflect.Type
@@ -733,11 +733,11 @@ func (rw *Db) oplogMsgsForItems(ctx context.Context, opType OpType, opts Options
}
currentType := reflect.TypeOf(item)
if foundType != currentType {
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("items contains disparate types. item (%d) %s is not a %s", i, currentType, foundType))
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("items contains disparate types. item (%d) %s is not a %s", i, currentType, foundType))
}
msg, err := rw.newOplogMessage(ctx, opType, item, WithFieldMaskPaths(opts.WithFieldMaskPaths), WithNullPaths(opts.WithNullPaths))
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
oplogMsgs = append(oplogMsgs, msg)
}
@@ -751,30 +751,30 @@ func (rw *Db) addOplogForItems(ctx context.Context, opType OpType, opts Options,
const op = "db.addOplogForItems"
oplogArgs := opts.oplogOpts
if ticket == nil {
return errors.New(errors.InvalidParameter, op, "missing ticket")
return errors.New(ctx, errors.InvalidParameter, op, "missing ticket")
}
if len(items) == 0 {
return errors.New(errors.InvalidParameter, op, "missing items")
return errors.New(ctx, errors.InvalidParameter, op, "missing items")
}
if oplogArgs.metadata == nil {
return errors.New(errors.InvalidParameter, op, "missing metadata")
return errors.New(ctx, errors.InvalidParameter, op, "missing metadata")
}
if oplogArgs.wrapper == nil {
return errors.New(errors.InvalidParameter, op, "missing wrapper")
return errors.New(ctx, errors.InvalidParameter, op, "missing wrapper")
}
oplogMsgs, err := rw.oplogMsgsForItems(ctx, opType, opts, items)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
replayable, err := validateOplogArgs(items[0], opts)
replayable, err := validateOplogArgs(ctx, items[0], opts)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("oplog validation failed"))
return errors.Wrap(ctx, err, op, errors.WithMsg("oplog validation failed"))
}
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get Ticketer"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get Ticketer"))
}
entry, err := oplog.NewEntry(
replayable.TableName(),
@@ -783,7 +783,7 @@ func (rw *Db) addOplogForItems(ctx context.Context, opType OpType, opts Options,
ticketer,
)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to create oplog entry"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to create oplog entry"))
}
if err := entry.WriteEntryWith(
ctx,
@@ -791,7 +791,7 @@ func (rw *Db) addOplogForItems(ctx context.Context, opType OpType, opts Options,
ticket,
oplogMsgs...,
); err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog entry"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog entry"))
}
return nil
}
@@ -799,16 +799,16 @@ func (rw *Db) addOplogForItems(ctx context.Context, opType OpType, opts Options,
func (rw *Db) addOplog(ctx context.Context, opType OpType, opts Options, ticket *store.Ticket, i interface{}) error {
const op = "db.addOplog"
oplogArgs := opts.oplogOpts
replayable, err := validateOplogArgs(i, opts)
replayable, err := validateOplogArgs(ctx, i, opts)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if ticket == nil {
return errors.New(errors.InvalidParameter, op, "missing ticket")
return errors.New(ctx, errors.InvalidParameter, op, "missing ticket")
}
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get Ticketer"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get Ticketer"))
}
entry, err := oplog.NewEntry(
replayable.TableName(),
@@ -817,11 +817,11 @@ func (rw *Db) addOplog(ctx context.Context, opType OpType, opts Options, ticket
ticketer,
)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
msg, err := rw.newOplogMessage(ctx, opType, i, WithFieldMaskPaths(opts.WithFieldMaskPaths), WithNullPaths(opts.WithNullPaths))
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
err = entry.WriteEntryWith(
ctx,
@@ -830,7 +830,7 @@ func (rw *Db) addOplog(ctx context.Context, opType OpType, opts Options, ticket
msg,
)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog entry"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog entry"))
}
return nil
}
@@ -840,24 +840,24 @@ func (rw *Db) addOplog(ctx context.Context, opType OpType, opts Options, ticket
func (rw *Db) WriteOplogEntryWith(ctx context.Context, wrapper wrapping.Wrapper, ticket *store.Ticket, metadata oplog.Metadata, msgs []*oplog.Message, _ ...Option) error {
const op = "db.WriteOplogEntryWith"
if wrapper == nil {
return errors.New(errors.InvalidParameter, op, "missing wrapper")
return errors.New(ctx, errors.InvalidParameter, op, "missing wrapper")
}
if ticket == nil {
return errors.New(errors.InvalidParameter, op, "missing ticket")
return errors.New(ctx, errors.InvalidParameter, op, "missing ticket")
}
if len(msgs) == 0 {
return errors.New(errors.InvalidParameter, op, "missing msgs")
return errors.New(ctx, errors.InvalidParameter, op, "missing msgs")
}
if rw.underlying == nil {
return errors.New(errors.InvalidParameter, op, "missing underlying db")
return errors.New(ctx, errors.InvalidParameter, op, "missing underlying db")
}
if len(metadata) == 0 {
return errors.New(errors.InvalidParameter, op, "missing metadata")
return errors.New(ctx, errors.InvalidParameter, op, "missing metadata")
}
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true))
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to get Ticketer"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get Ticketer"))
}
entry, err := oplog.NewEntry(
@@ -867,7 +867,7 @@ func (rw *Db) WriteOplogEntryWith(ctx context.Context, wrapper wrapping.Wrapper,
ticketer,
)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to create oplog entry"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to create oplog entry"))
}
err = entry.WriteEntryWith(
ctx,
@@ -876,17 +876,17 @@ func (rw *Db) WriteOplogEntryWith(ctx context.Context, wrapper wrapping.Wrapper,
msgs...,
)
if err != nil {
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog entry"))
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to write oplog entry"))
}
return nil
}
func (rw *Db) newOplogMessage(_ context.Context, opType OpType, i interface{}, opt ...Option) (*oplog.Message, error) {
func (rw *Db) newOplogMessage(ctx context.Context, opType OpType, i interface{}, opt ...Option) (*oplog.Message, error) {
const op = "db.newOplogMessage"
opts := GetOpts(opt...)
replayable, ok := i.(oplog.ReplayableMessage)
if !ok {
return nil, errors.New(errors.InvalidParameter, op, "not a replayable interface")
return nil, errors.New(ctx, errors.InvalidParameter, op, "not a replayable interface")
}
msg := oplog.Message{
Message: i.(proto.Message),
@@ -902,7 +902,7 @@ func (rw *Db) newOplogMessage(_ context.Context, opType OpType, i interface{}, o
case DeleteOp:
msg.OpType = oplog.OpType_OP_TYPE_DELETE
default:
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("operation type %v is not supported", opType))
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("operation type %v is not supported", opType))
}
return &msg, nil
}
@@ -914,12 +914,12 @@ func (rw *Db) newOplogMessage(_ context.Context, opType OpType, i interface{}, o
func (w *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, Handler TxHandler) (RetryInfo, error) {
const op = "db.DoTx"
if w.underlying == nil {
return RetryInfo{}, errors.New(errors.InvalidParameter, op, "missing underlying db")
return RetryInfo{}, errors.New(ctx, errors.InvalidParameter, op, "missing underlying db")
}
info := RetryInfo{}
for attempts := uint(1); ; attempts++ {
if attempts > retries+1 {
return info, errors.New(errors.MaxRetries, op, fmt.Sprintf("Too many retries: %d of %d", attempts-1, retries+1))
return info, errors.New(ctx, errors.MaxRetries, op, fmt.Sprintf("Too many retries: %d of %d", attempts-1, retries+1))
}
// step one of this, start a transaction...
@@ -928,7 +928,7 @@ func (w *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, Handler Tx
rw := &Db{newTx}
if err := Handler(rw, rw); err != nil {
if err := newTx.Rollback().Error; err != nil {
return info, errors.Wrap(err, op)
return info, errors.Wrap(ctx, err, op)
}
if errors.Match(errors.T(errors.TicketAlreadyRedeemed), err) {
d := backOff.Duration(attempts)
@@ -937,14 +937,14 @@ func (w *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, Handler Tx
time.Sleep(d)
continue
}
return info, errors.Wrap(err, op)
return info, errors.Wrap(ctx, err, op, errors.WithoutEvent())
}
if err := newTx.Commit().Error; err != nil {
if err := newTx.Rollback().Error; err != nil {
return info, errors.Wrap(err, op)
return info, errors.Wrap(ctx, err, op)
}
return info, errors.Wrap(err, op)
return info, errors.Wrap(ctx, err, op)
}
return info, nil // it all worked!!!
}
@@ -952,28 +952,28 @@ func (w *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, Handler Tx
// LookupByPublicId will lookup resource by its public_id or private_id, which
// must be unique. Options are ignored.
func (rw *Db) LookupById(_ context.Context, resourceWithIder interface{}, _ ...Option) error {
func (rw *Db) LookupById(ctx context.Context, resourceWithIder interface{}, _ ...Option) error {
const op = "db.LookupById"
if rw.underlying == nil {
return errors.New(errors.InvalidParameter, op, "missing underlying db")
return errors.New(ctx, errors.InvalidParameter, op, "missing underlying db")
}
if reflect.ValueOf(resourceWithIder).Kind() != reflect.Ptr {
return errors.New(errors.InvalidParameter, op, "interface parameter must to be a pointer")
return errors.New(ctx, errors.InvalidParameter, op, "interface parameter must to be a pointer")
}
primaryKey, where, err := primaryKeyWhere(resourceWithIder)
primaryKey, where, err := primaryKeyWhere(ctx, resourceWithIder)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err := rw.underlying.Where(where, primaryKey).First(resourceWithIder).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return errors.E(errors.WithCode(errors.RecordNotFound), errors.WithOp(op))
return errors.E(ctx, errors.WithCode(errors.RecordNotFound), errors.WithOp(op))
}
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
func primaryKeyWhere(resourceWithIder interface{}) (pkey string, w string, e error) {
func primaryKeyWhere(ctx context.Context, resourceWithIder interface{}) (pkey string, w string, e error) {
const op = "db.primaryKeyWhere"
var primaryKey, where string
switch resourceType := resourceWithIder.(type) {
@@ -984,10 +984,10 @@ func primaryKeyWhere(resourceWithIder interface{}) (pkey string, w string, e err
primaryKey = resourceType.GetPrivateId()
where = "private_id = ?"
default:
return "", "", errors.New(errors.InvalidParameter, op, fmt.Sprintf("unsupported interface type %T", resourceWithIder))
return "", "", errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("unsupported interface type %T", resourceWithIder))
}
if primaryKey == "" {
return "", "", errors.New(errors.InvalidParameter, op, "missing primary key")
return "", "", errors.New(ctx, errors.InvalidParameter, op, "missing primary key")
}
return primaryKey, where, nil
}
@@ -999,19 +999,19 @@ func (rw *Db) LookupByPublicId(ctx context.Context, resource ResourcePublicIder,
}
// LookupWhere will lookup the first resource using a where clause with parameters (it only returns the first one)
func (rw *Db) LookupWhere(_ context.Context, resource interface{}, where string, args ...interface{}) error {
func (rw *Db) LookupWhere(ctx context.Context, resource interface{}, where string, args ...interface{}) error {
const op = "db.LookupWhere"
if rw.underlying == nil {
return errors.New(errors.InvalidParameter, op, "missing underlying db")
return errors.New(ctx, errors.InvalidParameter, op, "missing underlying db")
}
if reflect.ValueOf(resource).Kind() != reflect.Ptr {
return errors.New(errors.InvalidParameter, op, "interface parameter must to be a pointer")
return errors.New(ctx, errors.InvalidParameter, op, "interface parameter must to be a pointer")
}
if err := rw.underlying.Where(where, args...).First(resource).Error; err != nil {
if err == gorm.ErrRecordNotFound {
return errors.E(errors.WithCode(errors.RecordNotFound), errors.WithOp(op))
return errors.E(ctx, errors.WithCode(errors.RecordNotFound), errors.WithOp(op))
}
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -1023,17 +1023,17 @@ func (rw *Db) LookupWhere(_ context.Context, resource interface{}, where string,
// Supports the WithLimit option. If WithLimit < 0, then unlimited results are returned.
// If WithLimit == 0, then default limits are used for results.
// Supports the WithOrder option.
func (rw *Db) SearchWhere(_ context.Context, resources interface{}, where string, args []interface{}, opt ...Option) error {
func (rw *Db) SearchWhere(ctx context.Context, resources interface{}, where string, args []interface{}, opt ...Option) error {
const op = "db.SearchWhere"
opts := GetOpts(opt...)
if rw.underlying == nil {
return errors.New(errors.InvalidParameter, op, "missing underlying db")
return errors.New(ctx, errors.InvalidParameter, op, "missing underlying db")
}
if where == "" && len(args) > 0 {
return errors.New(errors.InvalidParameter, op, "args provided with empty where")
return errors.New(ctx, errors.InvalidParameter, op, "args provided with empty where")
}
if reflect.ValueOf(resources).Kind() != reflect.Ptr {
return errors.New(errors.InvalidParameter, op, "interface parameter must to be a pointer")
return errors.New(ctx, errors.InvalidParameter, op, "interface parameter must to be a pointer")
}
var err error
db := rw.underlying.Order(opts.withOrder)
@@ -1055,7 +1055,7 @@ func (rw *Db) SearchWhere(_ context.Context, resources interface{}, where string
err = db.Find(resources).Error
if err != nil {
// searching with a slice parameter does not return a gorm.ErrRecordNotFound
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -1127,11 +1127,11 @@ func Clear(i interface{}, fields []string, depth int) error {
switch v.Kind() {
case reflect.Ptr:
if v.IsNil() || v.Elem().Kind() != reflect.Struct {
return errors.E(errors.WithCode(errors.InvalidParameter), errors.WithOp(op))
return errors.EDeprecated(errors.WithCode(errors.InvalidParameter), errors.WithOp(op), errors.WithoutEvent())
}
clear(v, fm, depth)
default:
return errors.E(errors.WithCode(errors.InvalidParameter), errors.WithOp(op))
return errors.EDeprecated(errors.WithCode(errors.InvalidParameter), errors.WithOp(op), errors.WithoutEvent())
}
return nil
}
+6 -5
View File
@@ -1066,6 +1066,7 @@ func TestDb_Exec(t *testing.T) {
func TestDb_DoTx(t *testing.T) {
t.Parallel()
ctx := context.TODO()
db, _ := TestSetup(t, "postgres")
t.Run("valid-with-10-retries", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
@@ -1075,7 +1076,7 @@ func TestDb_DoTx(t *testing.T) {
func(Reader, Writer) error {
attempts += 1
if attempts < 9 {
return errors.E(errors.WithCode(errors.TicketAlreadyRedeemed))
return errors.E(ctx, errors.WithCode(errors.TicketAlreadyRedeemed))
}
return nil
})
@@ -1091,7 +1092,7 @@ func TestDb_DoTx(t *testing.T) {
func(Reader, Writer) error {
attempts += 1
if attempts < 2 {
return errors.E(errors.WithCode(errors.TicketAlreadyRedeemed))
return errors.E(ctx, errors.WithCode(errors.TicketAlreadyRedeemed))
}
return nil
})
@@ -1107,7 +1108,7 @@ func TestDb_DoTx(t *testing.T) {
func(Reader, Writer) error {
attempts += 1
if attempts < 3 {
return errors.E(errors.WithCode(errors.TicketAlreadyRedeemed))
return errors.E(ctx, errors.WithCode(errors.TicketAlreadyRedeemed))
}
return nil
})
@@ -1123,7 +1124,7 @@ func TestDb_DoTx(t *testing.T) {
func(Reader, Writer) error {
attempts += 1
if attempts < 4 {
return errors.E(errors.WithCode(errors.TicketAlreadyRedeemed))
return errors.E(ctx, errors.WithCode(errors.TicketAlreadyRedeemed))
}
return nil
})
@@ -1163,7 +1164,7 @@ func TestDb_DoTx(t *testing.T) {
attempts := 0
got, err := w.DoTx(context.Background(), 2, ExpBackoff{}, func(Reader, Writer) error {
attempts += 1
return errors.E(errors.WithCode(errors.TicketAlreadyRedeemed))
return errors.E(ctx, errors.WithCode(errors.TicketAlreadyRedeemed))
})
require.Error(err)
assert.Equal(3, got.Retries)
+22 -22
View File
@@ -63,10 +63,10 @@ func NewManager(ctx context.Context, dialect string, db *sql.DB, opt ...Option)
var err error
dbM.driver, err = postgres.New(ctx, db)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
default:
return nil, errors.New(errors.InvalidParameter, op, fmt.Sprintf("unknown dialect %q", dialect))
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("unknown dialect %q", dialect))
}
return &dbM, nil
}
@@ -92,7 +92,7 @@ func (b *Manager) CurrentState(ctx context.Context) (*State, error) {
v, initialized, dirty, err := b.driver.CurrentState(ctx)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
dbS.InitializationStarted = initialized
dbS.DatabaseSchemaVersion = v
@@ -106,7 +106,7 @@ func (b *Manager) CurrentState(ctx context.Context) (*State, error) {
func (b *Manager) SharedLock(ctx context.Context) error {
const op = "schema.(Manager).SharedLock"
if err := b.driver.TrySharedLock(ctx); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -117,7 +117,7 @@ func (b *Manager) SharedLock(ctx context.Context) error {
func (b *Manager) SharedUnlock(ctx context.Context) error {
const op = "schema.(Manager).SharedUnlock"
if err := b.driver.UnlockShared(ctx); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -127,7 +127,7 @@ func (b *Manager) SharedUnlock(ctx context.Context) error {
func (b *Manager) ExclusiveLock(ctx context.Context) error {
const op = "schema.(Manager).ExclusiveLock"
if err := b.driver.TryLock(ctx); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -138,7 +138,7 @@ func (b *Manager) ExclusiveLock(ctx context.Context) error {
func (b *Manager) ExclusiveUnlock(ctx context.Context) error {
const op = "schema.(Manager).ExclusiveUnlock"
if err := b.driver.Unlock(ctx); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -151,27 +151,27 @@ func (b *Manager) RollForward(ctx context.Context) error {
// Capturing a lock that this session to the db already possesses is okay.
if err := b.driver.Lock(ctx); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
defer func() {
if err := b.driver.Unlock(ctx); err != nil {
// I'm not sure this is ideal, but we have to rollback the current
// transaction if we're unable to release the lock
panic(errors.Wrap(err, op))
panic(errors.Wrap(ctx, err, op))
}
}()
curVersion, _, dirty, err := b.driver.CurrentState(ctx)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if dirty {
return errors.New(errors.NotSpecificIntegrity, op, fmt.Sprintf("schema is dirty with version %d", curVersion))
return errors.New(ctx, errors.NotSpecificIntegrity, op, fmt.Sprintf("schema is dirty with version %d", curVersion))
}
if err = b.runMigrations(ctx, newStatementProvider(b.dialect, curVersion, WithMigrationStates(b.migrationStates))); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -187,10 +187,10 @@ func (b *Manager) runMigrations(ctx context.Context, qp *statementProvider) erro
const op = "schema.(Manager).runMigrations"
if err := b.driver.StartRun(ctx); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if err := b.driver.EnsureVersionTable(ctx); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
for qp.Next() {
select {
@@ -201,16 +201,16 @@ func (b *Manager) runMigrations(ctx context.Context, qp *statementProvider) erro
err = multierror.Append(err, rbErr)
}
}
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
default:
// context is not done yet. Continue on to the next query to execute.
}
if err := b.driver.Run(ctx, bytes.NewReader(qp.ReadUp()), qp.Version()); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
}
if err := b.driver.CommitRun(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -230,11 +230,11 @@ func GetMigrationLog(ctx context.Context, d *sql.DB, opt ...Option) ([]LogEntry,
const op = "schema.GetMigrationLog"
const sql = "select id, create_time, migration_version, entry from log_migration where migration_version in (select max(version) from boundary_schema_version)"
if d == nil {
return nil, errors.New(errors.InvalidParameter, op, "missing sql db")
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing sql db")
}
rows, err := d.QueryContext(ctx, sql)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
defer rows.Close()
@@ -242,19 +242,19 @@ func GetMigrationLog(ctx context.Context, d *sql.DB, opt ...Option) ([]LogEntry,
for rows.Next() {
var e LogEntry
if err := rows.Scan(&e.Id, &e.CreateTime, &e.MigrationVersion, &e.Entry); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
entries = append(entries, e)
}
if rows.Err() != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
opts := getOpts(opt...)
if opts.withDeleteLog {
// this truncate could change to a delete if FKs are needed in the future
_, err = d.ExecContext(ctx, "truncate log_migration")
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
}
return entries, nil
@@ -24,11 +24,11 @@ func Test_AuthMethodSubtypes(t *testing.T) {
kmsCache := kms.TestKms(t, conn, rootWrapper)
iamRepo := iam.TestRepo(t, conn, rootWrapper)
org, _ := iam.TestScopes(t, iamRepo)
oidcRepo, err := oidc.NewRepository(rw, rw, kmsCache)
oidcRepo, err := oidc.NewRepository(ctx, rw, rw, kmsCache)
require.NoError(err)
// test oidc subtype insert
oidcAm, err := oidc.NewAuthMethod(org.PublicId, "alice-rp", "fido", oidc.WithName("alice"))
oidcAm, err := oidc.NewAuthMethod(ctx, org.PublicId, "alice-rp", "fido", oidc.WithName("alice"))
require.NoError(err)
oidcAm, err = oidcRepo.CreateAuthMethod(ctx, oidcAm)
require.NoError(err)
+36 -36
View File
@@ -66,11 +66,11 @@ type Postgres struct {
func New(ctx context.Context, instance *sql.DB) (*Postgres, error) {
const op = "postgres.New"
if err := instance.PingContext(ctx); err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
conn, err := instance.Conn(ctx)
if err != nil {
return nil, errors.Wrap(err, op)
return nil, errors.Wrap(ctx, err, op)
}
px := &Postgres{
@@ -87,14 +87,14 @@ func (p *Postgres) TrySharedLock(ctx context.Context) error {
const query = "select pg_try_advisory_lock_shared($1)"
r := p.conn.QueryRowContext(ctx, query, schemaAccessLockId)
if r.Err() != nil {
return errors.Wrap(r.Err(), op)
return errors.Wrap(ctx, r.Err(), op)
}
var gotLock bool
if err := r.Scan(&gotLock); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if !gotLock {
return errors.New(errors.MigrationLock, op, "Lock failed")
return errors.New(ctx, errors.MigrationLock, op, "Lock failed")
}
return nil
}
@@ -106,14 +106,14 @@ func (p *Postgres) TryLock(ctx context.Context) error {
const query = "select pg_try_advisory_lock($1)"
r := p.conn.QueryRowContext(ctx, query, schemaAccessLockId)
if r.Err() != nil {
return errors.Wrap(r.Err(), op)
return errors.Wrap(ctx, r.Err(), op)
}
var gotLock bool
if err := r.Scan(&gotLock); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if !gotLock {
return errors.New(errors.MigrationLock, op, "Lock failed")
return errors.New(ctx, errors.MigrationLock, op, "Lock failed")
}
return nil
}
@@ -124,7 +124,7 @@ func (p *Postgres) Lock(ctx context.Context) error {
const op = "postgres.(Postgres).Lock"
const query = "select pg_advisory_lock($1)"
if _, err := p.conn.ExecContext(ctx, query, schemaAccessLockId); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -135,7 +135,7 @@ func (p *Postgres) Unlock(ctx context.Context) error {
const op = "postgres.(Postgres).Unlock"
const query = `select pg_advisory_unlock($1)`
if _, err := p.conn.ExecContext(ctx, query, schemaAccessLockId); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -146,7 +146,7 @@ func (p *Postgres) UnlockShared(ctx context.Context) error {
const op = "postgres.(Postgres).UnlockShared"
query := `select pg_advisory_unlock_shared($1)`
if _, err := p.conn.ExecContext(ctx, query, schemaAccessLockId); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
}
@@ -159,10 +159,10 @@ func (p *Postgres) Rollback() error {
p.tx = nil
}()
if p.tx == nil {
return errors.New(errors.MigrationIntegrity, op, "no pending transaction")
return errors.NewDeprecated(errors.MigrationIntegrity, op, "no pending transaction")
}
if err := p.tx.Rollback(); err != nil {
return errors.Wrap(err, op)
return errors.WrapDeprecated(err, op)
}
return nil
}
@@ -184,13 +184,13 @@ func (p *Postgres) CommitRun() error {
p.tx = nil
}()
if p.tx == nil {
return errors.New(errors.MigrationIntegrity, op, "no pending transaction")
return errors.NewDeprecated(errors.MigrationIntegrity, op, "no pending transaction")
}
if err := p.tx.Commit(); err != nil {
if errRollback := p.tx.Rollback(); errRollback != nil {
err = multierror.Append(err, errRollback)
}
return errors.Wrap(err, op)
return errors.WrapDeprecated(err, op)
}
return nil
}
@@ -207,7 +207,7 @@ func (p *Postgres) Run(ctx context.Context, migration io.Reader, version int) er
const op = "postgres.(Postgres).Run"
migr, err := ioutil.ReadAll(migration)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
// Run migration
query := string(migr)
@@ -225,7 +225,7 @@ func (p *Postgres) Run(ctx context.Context, migration io.Reader, version int) er
// set the version first, so logs will be associated with this new version.
// if there's an error, it will get rollback
if err := p.setVersion(ctx, version, false); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if _, err := extr.ExecContext(ctx, query); err != nil {
@@ -249,9 +249,9 @@ func (p *Postgres) Run(ctx context.Context, migration io.Reader, version int) er
message = fmt.Sprintf("%s, %s", message, pgErr.Detail)
}
message = fmt.Sprintf("%s, on line %v: %s", message, line, migr)
return errors.Wrap(err, op, errors.WithMsg(message))
return errors.Wrap(ctx, err, op, errors.WithMsg(message))
}
return errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("migration failed: %s", migr)))
return errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("migration failed: %s", migr)))
}
return nil
@@ -314,7 +314,7 @@ func (p *Postgres) setVersion(ctx context.Context, version int, dirty bool) erro
if errRollback := rollback(); errRollback != nil {
err = multierror.Append(err, errRollback)
}
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
// Also re-write the schema Version for nil dirty versions to prevent
@@ -327,13 +327,13 @@ func (p *Postgres) setVersion(ctx context.Context, version int, dirty bool) erro
if errRollback := rollback(); errRollback != nil {
err = multierror.Append(err, errRollback)
}
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
}
if p.tx == nil {
if err := tx.Commit(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
}
return nil
@@ -351,7 +351,7 @@ func (p *Postgres) CurrentState(ctx context.Context) (version int, previouslyRan
tableQuery := `select table_name from information_schema.tables where table_schema=(select current_schema()) and table_name in ('schema_migrations', '` + defaultMigrationsTable + `')`
tableResult, err := p.conn.QueryContext(ctx, tableQuery)
if err != nil {
return nilVersion, previouslyRan, dirty, errors.Wrap(err, op)
return nilVersion, previouslyRan, dirty, errors.Wrap(ctx, err, op)
}
defer tableResult.Close()
if !tableResult.Next() {
@@ -361,17 +361,17 @@ func (p *Postgres) CurrentState(ctx context.Context) (version int, previouslyRan
tableName := defaultMigrationsTable
if err := tableResult.Scan(&tableName); err != nil {
return nilVersion, previouslyRan, dirty, errors.Wrap(err, op)
return nilVersion, previouslyRan, dirty, errors.Wrap(ctx, err, op)
}
previouslyRan = true
if tableResult.Next() {
return nilVersion, previouslyRan, dirty, errors.New(errors.MigrationIntegrity, op, "both old and new migration tables exist")
return nilVersion, previouslyRan, dirty, errors.New(ctx, errors.MigrationIntegrity, op, "both old and new migration tables exist")
}
query := `select version, dirty from ` + pq.QuoteIdentifier(tableName)
results, err := p.conn.QueryContext(ctx, query)
if err != nil {
return nilVersion, previouslyRan, dirty, errors.Wrap(err, op)
return nilVersion, previouslyRan, dirty, errors.Wrap(ctx, err, op)
}
defer results.Close()
if !results.Next() {
@@ -379,10 +379,10 @@ func (p *Postgres) CurrentState(ctx context.Context) (version int, previouslyRan
return nilVersion, previouslyRan, dirty, nil
}
if err := results.Scan(&version, &dirty); err != nil {
return nilVersion, previouslyRan, dirty, errors.Wrap(err, op)
return nilVersion, previouslyRan, dirty, errors.Wrap(ctx, err, op)
}
if results.Next() {
return nilVersion, previouslyRan, dirty, errors.New(errors.MigrationIntegrity, op, "to many versions in version table")
return nilVersion, previouslyRan, dirty, errors.New(ctx, errors.MigrationIntegrity, op, "to many versions in version table")
}
return version, previouslyRan, dirty, nil
}
@@ -393,12 +393,12 @@ func (p *Postgres) drop(ctx context.Context) (err error) {
query := `select table_name from information_schema.tables where table_schema=(select current_schema()) and table_type='BASE TABLE'`
tables, err := p.conn.QueryContext(ctx, query)
if err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
defer func() {
if errClose := tables.Close(); errClose != nil {
err = multierror.Append(err, errClose)
err = errors.Wrap(err, op)
err = errors.Wrap(ctx, err, op)
}
}()
@@ -407,14 +407,14 @@ func (p *Postgres) drop(ctx context.Context) (err error) {
for tables.Next() {
var tableName string
if err := tables.Scan(&tableName); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if len(tableName) > 0 {
tableNames = append(tableNames, tableName)
}
}
if err := tables.Err(); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if len(tableNames) > 0 {
@@ -422,7 +422,7 @@ func (p *Postgres) drop(ctx context.Context) (err error) {
for _, t := range tableNames {
query = `drop table if exists ` + pq.QuoteIdentifier(t) + ` cascade`
if _, err := p.conn.ExecContext(ctx, query); err != nil {
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
}
}
@@ -450,7 +450,7 @@ func (p *Postgres) EnsureVersionTable(ctx context.Context) (err error) {
if wpErr := rollback(); wpErr != nil {
err = multierror.Append(err, wpErr)
}
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
if exists {
return nil
@@ -461,7 +461,7 @@ func (p *Postgres) EnsureVersionTable(ctx context.Context) (err error) {
if wpErr := rollback(); wpErr != nil {
err = multierror.Append(err, wpErr)
}
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
createStmt := `create table if not exists ` + pq.QuoteIdentifier(defaultMigrationsTable) + ` (version bigint primary key, dirty boolean not null)`
@@ -469,7 +469,7 @@ func (p *Postgres) EnsureVersionTable(ctx context.Context) (err error) {
if wpErr := rollback(); wpErr != nil {
err = multierror.Append(err, wpErr)
}
return errors.Wrap(err, op)
return errors.Wrap(ctx, err, op)
}
return nil
+5 -5
View File
@@ -15,20 +15,20 @@ func MigrateStore(ctx context.Context, dialect string, url string, opt ...Option
d, err := sql.Open(dialect, url)
if err != nil {
return false, errors.Wrap(err, op)
return false, errors.Wrap(ctx, err, op)
}
sMan, err := NewManager(ctx, dialect, d, opt...)
if err != nil {
return false, errors.Wrap(err, op)
return false, errors.Wrap(ctx, err, op)
}
st, err := sMan.CurrentState(ctx)
if err != nil {
return false, errors.Wrap(err, op)
return false, errors.Wrap(ctx, err, op)
}
if st.Dirty {
return false, errors.New(errors.MigrationIntegrity, op, "db marked dirty")
return false, errors.New(ctx, errors.MigrationIntegrity, op, "db marked dirty")
}
if st.InitializationStarted && st.DatabaseSchemaVersion == st.BinarySchemaVersion {
@@ -36,7 +36,7 @@ func MigrateStore(ctx context.Context, dialect string, url string, opt ...Option
}
if err := sMan.RollForward(ctx); err != nil {
return false, errors.Wrap(err, op)
return false, errors.Wrap(ctx, err, op)
}
return true, nil
+80 -14
View File
@@ -1,10 +1,13 @@
package errors
import (
"context"
"errors"
"fmt"
"runtime"
"strings"
"github.com/hashicorp/boundary/internal/observability/event"
"github.com/lib/pq"
)
@@ -35,6 +38,9 @@ type Err struct {
// E creates a new Err with provided code and supports the options of:
//
// * WithoutEvent - allows you to specify that an error event should not be
// emitted.
//
// * WithOp() - allows you to specify an optional Op (operation).
//
// * WithMsg() - allows you to specify an optional error msg, if the default
@@ -46,7 +52,8 @@ type Err struct {
//
// * WithCode() - allows you to specify an optional Code, this code will be prioritized
// over a code used from WithWrap().
func E(opt ...Option) error {
func E(ctx context.Context, opt ...Option) error {
// nil ctx is allowed and tested for in unit tests
opts := GetOpts(opt...)
var code Code
@@ -62,19 +69,55 @@ func E(opt ...Option) error {
code = opts.withCode
}
return &Err{
err = &Err{
Code: code,
Op: opts.withOp,
Wrapped: opts.withErrWrapped,
Msg: opts.withErrMsg,
}
if opts.withoutEvent {
return err
}
{
// events require an Op, but we don't want to change the error specified
// by the caller. So we'll build a new event and conditionally set a
// reasonable Op based on the call stack.
eventErr := &Err{
Code: err.Code,
Op: err.Op,
Wrapped: err.Wrapped,
Msg: err.Msg,
}
if eventErr.Op == "" {
const has = "github.com/hashicorp/boundary/internal/errors."
const trim = "github.com/hashicorp/boundary/"
for i := 0; i < 5; i++ {
pc, _, _, ok := runtime.Caller(i)
details := runtime.FuncForPC(pc)
if ok && details != nil {
if strings.HasPrefix(details.Name(), has) {
continue
}
eventErr.Op = Op(strings.TrimPrefix(details.Name(), trim))
break
}
}
if eventErr.Op == "" {
eventErr.Op = "unknown operation"
}
}
event.WriteError(ctx, event.Op(err.Op), eventErr)
}
return err
}
// New creates a new Err with provided code, op and msg
// It supports the options of:
//
// * WithWrap() - allows you to specify an error to wrap
func New(c Code, op Op, msg string, opt ...Option) error {
func New(ctx context.Context, c Code, op Op, msg string, opt ...Option) error {
if c != Unknown {
opt = append(opt, WithCode(c))
}
@@ -84,8 +127,7 @@ func New(c Code, op Op, msg string, opt ...Option) error {
if msg != "" {
opt = append(opt, WithMsg(msg))
}
return E(opt...)
return E(ctx, opt...)
}
// Wrap creates a new Err from the provided err and op,
@@ -94,7 +136,7 @@ func New(c Code, op Op, msg string, opt ...Option) error {
//
// * WithMsg() - allows you to specify an optional error msg, if the default
// msg for the error Code is not sufficient.
func Wrap(e error, op Op, opt ...Option) error {
func Wrap(ctx context.Context, e error, op Op, opt ...Option) error {
if op != "" {
opt = append(opt, WithOp(op))
}
@@ -109,7 +151,31 @@ func Wrap(e error, op Op, opt ...Option) error {
opt = append(opt, WithWrap(e))
}
return E(opt...)
return E(ctx, opt...)
}
// EDeprecated is the legacy version of E which does not
// create an event. Please refrain from using this.
// When all calls are moved from EDeprecated to
// E, please update ICU-1883
func EDeprecated(opt ...Option) error {
return E(context.TODO(), opt...)
}
// NewDeprecated is the legacy version of New which does not
// create an event. Please refrain from using this.
// When all calls are moved from NewDeprecated to
// New, please update ICU-1883
func NewDeprecated(c Code, op Op, msg string, opt ...Option) error {
return New(context.TODO(), c, op, msg, opt...)
}
// WrapDeprecated is the legacy version of New which does not
// create an event. Please refrain from using this.
// When all calls are moved from WrapDeprecated to
// New, please update ICU-1884
func WrapDeprecated(e error, op Op, opt ...Option) error {
return Wrap(context.TODO(), e, op, opt...)
}
// Convert will convert the error to a Boundary *Err (returning it as an error)
@@ -130,24 +196,24 @@ func Convert(e error) *Err {
if pqError.Code.Class() == "23" { // class of integrity constraint violations
switch pqError.Code {
case "23505": // unique_violation
return E(WithMsg(pqError.Message), WithWrap(E(WithCode(NotUnique), WithMsg("unique constraint violation")))).(*Err)
return E(context.TODO(), WithoutEvent(), WithMsg(pqError.Message), WithWrap(EDeprecated(WithCode(NotUnique), WithMsg("unique constraint violation")))).(*Err)
case "23502": // not_null_violation
msg := fmt.Sprintf("%s must not be empty", pqError.Column)
return E(WithMsg(msg), WithWrap(E(WithCode(NotNull), WithMsg("not null constraint violated")))).(*Err)
return E(context.TODO(), WithoutEvent(), WithMsg(msg), WithWrap(EDeprecated(WithCode(NotNull), WithMsg("not null constraint violated")))).(*Err)
case "23514": // check_violation
msg := fmt.Sprintf("%s constraint failed", pqError.Constraint)
return E(WithMsg(msg), WithWrap(E(WithCode(CheckConstraint), WithMsg("check constraint violated")))).(*Err)
return E(context.TODO(), WithoutEvent(), WithMsg(msg), WithWrap(EDeprecated(WithCode(CheckConstraint), WithMsg("check constraint violated")))).(*Err)
default:
return E(WithCode(NotSpecificIntegrity), WithMsg(pqError.Message)).(*Err)
return E(context.TODO(), WithoutEvent(), WithCode(NotSpecificIntegrity), WithMsg(pqError.Message)).(*Err)
}
}
switch pqError.Code {
case "42P01":
return E(WithCode(MissingTable), WithMsg(pqError.Message)).(*Err)
return E(context.TODO(), WithoutEvent(), WithCode(MissingTable), WithMsg(pqError.Message)).(*Err)
case "42703":
return E(WithCode(ColumnNotFound), WithMsg(pqError.Message)).(*Err)
return E(context.TODO(), WithoutEvent(), WithCode(ColumnNotFound), WithMsg(pqError.Message)).(*Err)
case "P0001":
return E(WithCode(Exception), WithMsg(pqError.Message)).(*Err)
return E(context.TODO(), WithoutEvent(), WithCode(Exception), WithMsg(pqError.Message)).(*Err)
}
}
// unfortunately, we can't help.
+54 -23
View File
@@ -15,7 +15,7 @@ import (
func Test_ErrorE(t *testing.T) {
t.Parallel()
errRecordNotFound := errors.E(errors.WithCode(errors.RecordNotFound))
errRecordNotFound := errors.E(context.TODO(), errors.WithoutEvent(), errors.WithCode(errors.RecordNotFound))
tests := []struct {
name string
opt []errors.Option
@@ -77,11 +77,24 @@ func Test_ErrorE(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
err := errors.E(tt.opt...)
err := errors.EDeprecated(tt.opt...)
require.Error(err)
assert.Equal(tt.want, err)
err = errors.E(context.TODO(), tt.opt...)
require.Error(err)
assert.Equal(tt.want, err)
})
}
t.Run("nil-context", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
//nolint SA1012 intentionally passing a nil context.
err := errors.E(nil, errors.WithCode(errors.InvalidParameter))
require.Error(err)
assert.Equal(&errors.Err{
Code: errors.InvalidParameter,
}, err)
})
}
func Test_NewError(t *testing.T) {
@@ -100,15 +113,25 @@ func Test_NewError(t *testing.T) {
op: "alice.Bob",
msg: "test msg",
opt: []errors.Option{
errors.WithWrap(errors.E(errors.WithCode(errors.RecordNotFound))),
errors.WithWrap(errors.E(context.TODO(), errors.WithoutEvent(), errors.WithCode(errors.RecordNotFound))),
},
want: &errors.Err{
Op: "alice.Bob",
Wrapped: errors.E(errors.WithCode(errors.RecordNotFound)),
Wrapped: errors.E(context.TODO(), errors.WithoutEvent(), errors.WithCode(errors.RecordNotFound)),
Msg: "test msg",
Code: errors.InvalidParameter,
},
},
{
name: "empty-op",
code: errors.InvalidParameter,
op: "",
msg: "test msg",
want: &errors.Err{
Msg: "test msg",
Code: errors.InvalidParameter,
},
},
{
name: "no-options",
opt: nil,
@@ -142,7 +165,11 @@ func Test_NewError(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
err := errors.New(tt.code, tt.op, tt.msg, tt.opt...)
err := errors.NewDeprecated(tt.code, tt.op, tt.msg, tt.opt...)
require.Error(err)
assert.Equal(tt.want, err)
err = errors.New(context.TODO(), tt.code, tt.op, tt.msg, tt.opt...)
require.Error(err)
assert.Equal(tt.want, err)
})
@@ -151,7 +178,7 @@ func Test_NewError(t *testing.T) {
func Test_WrapError(t *testing.T) {
t.Parallel()
testErr := errors.E(errors.WithCode(errors.InvalidParameter), errors.WithOp("alice.Bob"), errors.WithMsg("test msg"))
testErr := errors.E(context.TODO(), errors.WithoutEvent(), errors.WithCode(errors.InvalidParameter), errors.WithOp("alice.Bob"), errors.WithMsg("test msg"))
tests := []struct {
name string
opt []errors.Option
@@ -232,7 +259,7 @@ func Test_WrapError(t *testing.T) {
Message: "test msg",
},
want: &errors.Err{
Wrapped: errors.E(errors.WithCode(errors.NotSpecificIntegrity), errors.WithMsg("test msg")),
Wrapped: errors.E(context.TODO(), errors.WithoutEvent(), errors.WithCode(errors.NotSpecificIntegrity), errors.WithMsg("test msg")),
Code: errors.NotSpecificIntegrity,
},
},
@@ -240,7 +267,11 @@ func Test_WrapError(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
err := errors.Wrap(tt.err, tt.op, tt.opt...)
err := errors.WrapDeprecated(tt.err, tt.op, tt.opt...)
require.Error(err)
assert.Equal(tt.want, err)
err = errors.Wrap(context.TODO(), tt.err, tt.op, tt.opt...)
require.Error(err)
assert.Equal(tt.want, err)
})
@@ -261,12 +292,12 @@ func TestError_Info(t *testing.T) {
},
{
name: "Unknown",
err: errors.E().(*errors.Err),
err: errors.E(context.TODO()).(*errors.Err),
want: errors.Unknown,
},
{
name: "InvalidParameter",
err: errors.E(errors.WithCode(errors.InvalidParameter)).(*errors.Err),
err: errors.E(context.TODO(), errors.WithCode(errors.InvalidParameter)).(*errors.Err),
want: errors.InvalidParameter,
},
}
@@ -287,37 +318,37 @@ func TestError_Error(t *testing.T) {
}{
{
name: "msg",
err: errors.E(errors.WithMsg("test msg")),
err: errors.E(context.TODO(), errors.WithoutEvent(), errors.WithMsg("test msg")),
want: "test msg: unknown: error #0",
},
{
name: "code",
err: errors.E(errors.WithCode(errors.CheckConstraint)),
err: errors.E(context.TODO(), errors.WithoutEvent(), errors.WithCode(errors.CheckConstraint)),
want: "constraint check failed, integrity violation: error #1000",
},
{
name: "op-msg-and-code",
err: errors.E(errors.WithCode(errors.CheckConstraint), errors.WithOp("alice.bob"), errors.WithMsg("test msg")),
err: errors.E(context.TODO(), errors.WithoutEvent(), errors.WithCode(errors.CheckConstraint), errors.WithOp("alice.bob"), errors.WithMsg("test msg")),
want: "alice.bob: test msg: integrity violation: error #1000",
},
{
name: "unknown",
err: errors.E(),
err: errors.EDeprecated(),
want: "unknown, unknown: error #0",
},
{
name: "wrapped-no-code",
err: errors.E(errors.WithWrap(errors.E(errors.WithCode(errors.InvalidParameter), errors.WithMsg("wrapped msg"))), errors.WithMsg("test msg")),
err: errors.E(context.TODO(), errors.WithoutEvent(), errors.WithWrap(errors.EDeprecated(errors.WithCode(errors.InvalidParameter), errors.WithMsg("wrapped msg"))), errors.WithMsg("test msg")),
want: "test msg: wrapped msg: parameter violation: error #100",
},
{
name: "wrapped-different-error-codes",
err: errors.E(errors.WithCode(errors.CheckConstraint), errors.WithWrap(errors.E(errors.WithCode(errors.InvalidParameter), errors.WithMsg("wrapped msg"))), errors.WithMsg("test msg")),
err: errors.E(context.TODO(), errors.WithoutEvent(), errors.WithCode(errors.CheckConstraint), errors.WithWrap(errors.EDeprecated(errors.WithCode(errors.InvalidParameter), errors.WithMsg("wrapped msg"))), errors.WithMsg("test msg")),
want: "test msg: integrity violation: error #1000: wrapped msg: parameter violation: error #100",
},
{
name: "wrapped-same-error-codes",
err: errors.E(errors.WithCode(errors.CheckConstraint), errors.WithWrap(errors.E(errors.WithCode(errors.CheckConstraint), errors.WithMsg("wrapped msg"))), errors.WithMsg("test msg")),
err: errors.E(context.TODO(), errors.WithoutEvent(), errors.WithCode(errors.CheckConstraint), errors.WithWrap(errors.EDeprecated(errors.WithCode(errors.CheckConstraint), errors.WithMsg("wrapped msg"))), errors.WithMsg("test msg")),
want: "test msg: wrapped msg: integrity violation: error #1000",
},
}
@@ -325,7 +356,7 @@ func TestError_Error(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
assert := assert.New(t)
got := tt.err.Error()
assert.Equal(tt.want, got)
assert.Contains(got, tt.want)
})
}
t.Run("nil *Err", func(t *testing.T) {
@@ -338,8 +369,8 @@ func TestError_Error(t *testing.T) {
func TestError_Unwrap(t *testing.T) {
t.Parallel()
testErr := errors.E(errors.WithMsg("test error"))
errInvalidParameter := errors.E(errors.WithCode(errors.InvalidParameter), errors.WithMsg("test error"))
testErr := errors.EDeprecated(errors.WithMsg("test error"))
errInvalidParameter := errors.EDeprecated(errors.WithCode(errors.InvalidParameter), errors.WithMsg("test error"))
tests := []struct {
name string
@@ -349,7 +380,7 @@ func TestError_Unwrap(t *testing.T) {
}{
{
name: "ErrInvalidParameter",
err: errors.E(errors.WithWrap(errInvalidParameter)),
err: errors.EDeprecated(errors.WithWrap(errInvalidParameter)),
want: errInvalidParameter,
wantIsErr: errInvalidParameter,
},
@@ -380,7 +411,7 @@ func TestError_Unwrap(t *testing.T) {
func TestConvertError(t *testing.T) {
t.Parallel()
testErr := errors.E(errors.WithCode(errors.InvalidParameter), errors.WithOp("alice.Bob"), errors.WithMsg("test msg"))
testErr := errors.EDeprecated(errors.WithCode(errors.InvalidParameter), errors.WithOp("alice.Bob"), errors.WithMsg("test msg"))
const (
createTable = `
create table if not exists test_table (
@@ -421,7 +452,7 @@ func TestConvertError(t *testing.T) {
e: &pq.Error{
Code: pq.ErrorCode("23001"),
},
wantErr: errors.E(errors.WithCode(errors.NotSpecificIntegrity)),
wantErr: errors.EDeprecated(errors.WithCode(errors.NotSpecificIntegrity)),
},
{
name: "convert-domain-error",
+14 -13
View File
@@ -40,12 +40,13 @@ func TestError_IsUnique(t *testing.T) {
},
{
name: "CodeUnique",
in: errors.E(errors.WithCode(errors.NotUnique)),
in: errors.E(context.TODO(), errors.WithCode(errors.NotUnique)),
want: true,
},
{
name: "wrapped-pq-is-unique",
in: errors.E(
context.TODO(),
errors.WithWrap(&pq.Error{
Code: pq.ErrorCode("23505"),
}),
@@ -54,12 +55,12 @@ func TestError_IsUnique(t *testing.T) {
},
{
name: "RecordNotFound",
in: errors.E(errors.WithCode(errors.RecordNotFound)),
in: errors.E(context.TODO(), errors.WithCode(errors.RecordNotFound)),
want: false,
},
{
name: "conflicting-wrapped-code",
in: errors.E(errors.WithCode(errors.NotNull), errors.WithWrap(errors.E(errors.WithCode(errors.NotUnique)))),
in: errors.E(context.TODO(), errors.WithCode(errors.NotNull), errors.WithWrap(errors.E(context.TODO(), errors.WithCode(errors.NotUnique)))),
want: false,
},
}
@@ -102,12 +103,12 @@ func TestError_IsCheckConstraint(t *testing.T) {
},
{
name: "ErrCodeCheckConstraint",
in: errors.E(errors.WithCode(errors.CheckConstraint)),
in: errors.E(context.TODO(), errors.WithCode(errors.CheckConstraint)),
want: true,
},
{
name: "wrapped-pq-is-check-constraint",
in: errors.E(errors.WithCode(errors.CheckConstraint),
in: errors.E(context.TODO(), errors.WithCode(errors.CheckConstraint),
errors.WithWrap(&pq.Error{
Code: pq.ErrorCode("23514"),
}),
@@ -116,12 +117,12 @@ func TestError_IsCheckConstraint(t *testing.T) {
},
{
name: "RecordNotFound",
in: errors.E(errors.WithCode(errors.RecordNotFound)),
in: errors.E(context.TODO(), errors.WithCode(errors.RecordNotFound)),
want: false,
},
{
name: "conflicting-wrapped-code",
in: errors.E(errors.WithCode(errors.NotNull), errors.WithWrap(errors.E(errors.WithCode(errors.CheckConstraint)))),
in: errors.E(context.TODO(), errors.WithCode(errors.NotNull), errors.WithWrap(errors.E(context.TODO(), errors.WithCode(errors.CheckConstraint)))),
want: false,
},
}
@@ -171,12 +172,12 @@ func TestError_IsNotNullError(t *testing.T) {
},
{
name: "ErrCodeNotNull",
in: errors.E(errors.WithCode(errors.NotNull)),
in: errors.E(context.TODO(), errors.WithCode(errors.NotNull)),
want: true,
},
{
name: "wrapped-pq-is-not-null",
in: errors.E(errors.WithCode(errors.NotNull),
in: errors.E(context.TODO(), errors.WithCode(errors.NotNull),
errors.WithWrap(&pq.Error{
Code: pq.ErrorCode("23502"),
}),
@@ -185,12 +186,12 @@ func TestError_IsNotNullError(t *testing.T) {
},
{
name: "RecordNotFound",
in: errors.E(errors.WithCode(errors.RecordNotFound)),
in: errors.E(context.TODO(), errors.WithCode(errors.RecordNotFound)),
want: false,
},
{
name: "conflicting-wrapped-code",
in: errors.E(errors.WithCode(errors.CheckConstraint), errors.WithWrap(errors.E(errors.WithCode(errors.NotNull)))),
in: errors.E(context.TODO(), errors.WithCode(errors.CheckConstraint), errors.WithWrap(errors.E(context.TODO(), errors.WithCode(errors.NotNull)))),
want: false,
},
}
@@ -270,7 +271,7 @@ func TestError_IsNotFoundError(t *testing.T) {
},
{
name: "not-found-error",
in: errors.E(errors.WithCode(errors.RecordNotFound)),
in: errors.E(context.TODO(), errors.WithCode(errors.RecordNotFound)),
want: true,
},
{
@@ -280,7 +281,7 @@ func TestError_IsNotFoundError(t *testing.T) {
},
{
name: "conflicting-wrapped-code",
in: errors.E(errors.WithCode(errors.NotNull), errors.WithWrap(errors.E(errors.WithCode(errors.RecordNotFound)))),
in: errors.E(context.TODO(), errors.WithCode(errors.NotNull), errors.WithWrap(errors.E(context.TODO(), errors.WithCode(errors.RecordNotFound)))),
want: false,
},
}
+15 -14
View File
@@ -1,6 +1,7 @@
package errors
import (
"context"
stderrors "errors"
"testing"
@@ -140,8 +141,8 @@ func TestTemplate_Error(t *testing.T) {
func TestMatch(t *testing.T) {
t.Parallel()
stdErr := stderrors.New("test error")
errInvalidFieldMask := E(WithCode(InvalidFieldMask), WithMsg("test invalid field mask error"))
errNotUnique := E(WithCode(NotUnique), WithMsg("test not unique error"))
errInvalidFieldMask := E(context.TODO(), WithCode(InvalidFieldMask), WithMsg("test invalid field mask error"))
errNotUnique := E(context.TODO(), WithCode(NotUnique), WithMsg("test not unique error"))
tests := []struct {
name string
@@ -152,7 +153,7 @@ func TestMatch(t *testing.T) {
{
name: "nil template",
template: nil,
err: E(WithCode(NotUnique), WithMsg("this thing was must be unique")),
err: E(context.TODO(), WithCode(NotUnique), WithMsg("this thing was must be unique")),
want: false,
},
{
@@ -164,7 +165,7 @@ func TestMatch(t *testing.T) {
{
name: "match on Kind only",
template: T(Integrity),
err: E(
err: E(context.TODO(),
WithCode(NotUnique),
WithMsg("this thing must be unique"),
WithOp("alice.Bob"),
@@ -175,7 +176,7 @@ func TestMatch(t *testing.T) {
{
name: "no match on Kind only",
template: T(Integrity),
err: E(
err: E(context.TODO(),
WithCode(RecordNotFound),
WithMsg("this thing is missing"),
WithOp("alice.Bob"),
@@ -186,7 +187,7 @@ func TestMatch(t *testing.T) {
{
name: "match on Code only",
template: T(NotUnique),
err: E(
err: E(context.TODO(),
WithCode(NotUnique),
WithMsg("this thing must be unique"),
WithOp("alice.Bob"),
@@ -197,7 +198,7 @@ func TestMatch(t *testing.T) {
{
name: "no match on Code only",
template: T(NotUnique),
err: E(
err: E(context.TODO(),
WithCode(RecordNotFound),
WithMsg("this thing is missing"),
WithOp("alice.Bob"),
@@ -208,7 +209,7 @@ func TestMatch(t *testing.T) {
{
name: "match on Op only",
template: T(Op("alice.Bob")),
err: E(
err: E(context.TODO(),
WithCode(NotUnique),
WithMsg("this thing must be unique"),
WithOp("alice.Bob"),
@@ -219,7 +220,7 @@ func TestMatch(t *testing.T) {
{
name: "no match on Op only",
template: T(Op("alice.Alice")),
err: E(
err: E(context.TODO(),
WithCode(RecordNotFound),
WithMsg("this thing is missing"),
WithOp("alice.Bob"),
@@ -236,7 +237,7 @@ func TestMatch(t *testing.T) {
errInvalidFieldMask,
Op("alice.Bob"),
),
err: E(
err: E(context.TODO(),
WithCode(InvalidParameter),
WithMsg("this thing must be unique"),
WithOp("alice.Bob"),
@@ -247,7 +248,7 @@ func TestMatch(t *testing.T) {
{
name: "match on Wrapped only",
template: T(errInvalidFieldMask),
err: E(
err: E(context.TODO(),
WithCode(NotUnique),
WithMsg("this thing must be unique"),
WithOp("alice.Bob"),
@@ -258,7 +259,7 @@ func TestMatch(t *testing.T) {
{
name: "no match on Wrapped only",
template: T(errNotUnique),
err: E(
err: E(context.TODO(),
WithCode(RecordNotFound),
WithMsg("this thing is missing"),
WithOp("alice.Bob"),
@@ -269,7 +270,7 @@ func TestMatch(t *testing.T) {
{
name: "match on Wrapped only stderror",
template: T(stdErr),
err: E(
err: E(context.TODO(),
WithCode(NotUnique),
WithMsg("this thing must be unique"),
WithOp("alice.Bob"),
@@ -280,7 +281,7 @@ func TestMatch(t *testing.T) {
{
name: "no match on Wrapped only stderror",
template: T(stderrors.New("no match")),
err: E(
err: E(context.TODO(),
WithCode(RecordNotFound),
WithMsg("this thing is missing"),
WithOp("alice.Bob"),
+7
View File
@@ -18,6 +18,7 @@ type Options struct {
withErrWrapped error
withErrMsg string
withOp Op
withoutEvent bool
}
func getDefaultOptions() Options {
@@ -55,3 +56,9 @@ func WithCode(code Code) Option {
o.withCode = code
}
}
func WithoutEvent() Option {
return func(o *Options) {
o.withoutEvent = true
}
}
+15 -1
View File
@@ -1,6 +1,7 @@
package errors
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
@@ -30,7 +31,7 @@ func Test_getOpts(t *testing.T) {
testOpts.withErrWrapped = nil
assert.Equal(opts, testOpts)
testErr := E(WithCode(InvalidParameter), WithMsg("test error"))
testErr := E(context.TODO(), WithCode(InvalidParameter), WithMsg("test error"))
// try setting it
opts = GetOpts(WithWrap(testErr))
@@ -63,4 +64,17 @@ func Test_getOpts(t *testing.T) {
testOpts.withCode = NotUnique
assert.Equal(opts, testOpts)
})
t.Run("WithoutEvent", func(t *testing.T) {
assert := assert.New(t)
// test default
opts := GetOpts()
testOpts := getDefaultOptions()
testOpts.withoutEvent = false
assert.Equal(opts, testOpts)
// try setting it
opts = GetOpts(WithoutEvent())
testOpts.withoutEvent = true
assert.Equal(opts, testOpts)
})
}
+1 -1
View File
@@ -23,7 +23,7 @@ type Host struct {
// ignored.
func NewHost(catalogId string, opt ...Option) (*Host, error) {
if catalogId == "" {
return nil, errors.New(errors.InvalidParameter, "static.NewHost", "no catalog id")
return nil, errors.NewDeprecated(errors.InvalidParameter, "static.NewHost", "no catalog id")
}
opts := getOpts(opt...)
+1 -1
View File
@@ -19,7 +19,7 @@ type HostCatalog struct {
// ignored.
func NewHostCatalog(scopeId string, opt ...Option) (*HostCatalog, error) {
if scopeId == "" {
return nil, errors.New(errors.InvalidParameter, "static.NewHostCatalog", "no scope id")
return nil, errors.NewDeprecated(errors.InvalidParameter, "static.NewHostCatalog", "no scope id")
}
opts := getOpts(opt...)
Loaded 100 of 227 files, more files were not shown because too many files have changed in this diff. Show more