Add some common account bits and change over some getOpts -> GetOpts funcs (#2565) (#2566)

This is a precursor to another upcoming PR that will make use of these
changes, but it makes that PR more manageable.
This commit is contained in:
Jeff Mitchell authored and GitHub committed 2022-10-25 21:33:31 -04:00
1 parent f57454b6b9
commit b86430c2af
16 files changed
+101 -27

No files matched your search

+6
View File
@@ -112,6 +112,12 @@ func (a *Account) SetTableName(n string) {
a.tableName = n
}
// GetLoginName returns the login name, which will always be empty as this type
// doesn't currently support login name
func (a *Account) GetLoginName() string {
return ""
}
// oplog will create oplog metadata for the Account.
func (c *Account) oplog(op oplog.OpType, authMethodScopeId string) oplog.Metadata {
metadata := oplog.Metadata{
+14 -2
View File
@@ -33,11 +33,11 @@ func NewAccount(authMethodId string, opt ...Option) (*Account, error) {
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing auth method id")
}
opts := getOpts(opt...)
opts := GetOpts(opt...)
a := &Account{
Account: &store.Account{
AuthMethodId: authMethodId,
LoginName: opts.withLoginName,
LoginName: opts.WithLoginName,
Name: opts.withName,
Description: opts.withDescription,
},
@@ -65,6 +65,18 @@ func (a *Account) SetTableName(n string) {
a.tableName = n
}
// GetEmail returns the email, which will always be empty as this type doesn't
// currently support email
func (a *Account) GetEmail() string {
return ""
}
// GetSubject returns the subject, which will always be empty as this type
// doesn't currently support subject
func (a *Account) GetSubject() string {
return ""
}
func (a *Account) oplog(op oplog.OpType) oplog.Metadata {
metadata := oplog.Metadata{
"resource-public-id": []string{a.GetPublicId()},
+1 -1
View File
@@ -30,7 +30,7 @@ func NewAuthMethod(scopeId string, opt ...Option) (*AuthMethod, error) {
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing scope id")
}
opts := getOpts(opt...)
opts := GetOpts(opt...)
a := &AuthMethod{
AuthMethod: &store.AuthMethod{
ScopeId: scopeId,
+4 -4
View File
@@ -1,7 +1,7 @@
package password
// getOpts - iterate the inbound Options and return a struct.
func getOpts(opt ...Option) options {
// GetOpts - iterate the inbound Options and return a struct.
func GetOpts(opt ...Option) options {
opts := getDefaultOptions()
for _, o := range opt {
o(&opts)
@@ -16,7 +16,7 @@ type Option func(*options)
type options struct {
withName string
withDescription string
withLoginName string
WithLoginName string
withLimit int
withConfig Configuration
withPublicId string
@@ -56,7 +56,7 @@ func WithName(name string) Option {
// WithLoginName provides an optional login name.
func WithLoginName(loginName string) Option {
return func(o *options) {
o.withLoginName = loginName
o.WithLoginName = loginName
}
}
+9 -9
View File
@@ -10,37 +10,37 @@ import (
func Test_GetOpts(t *testing.T) {
t.Parallel()
t.Run("WithPublicId", func(t *testing.T) {
opts := getOpts(WithPublicId("test id"))
opts := GetOpts(WithPublicId("test id"))
testOpts := getDefaultOptions()
testOpts.withPublicId = "test id"
assert.Equal(t, opts, testOpts)
})
t.Run("WithLoginName", func(t *testing.T) {
opts := getOpts(WithLoginName("test"))
opts := GetOpts(WithLoginName("test"))
testOpts := getDefaultOptions()
testOpts.withLoginName = "test"
testOpts.WithLoginName = "test"
assert.Equal(t, opts, testOpts)
})
t.Run("WithName", func(t *testing.T) {
opts := getOpts(WithName("test"))
opts := GetOpts(WithName("test"))
testOpts := getDefaultOptions()
testOpts.withName = "test"
assert.Equal(t, opts, testOpts)
})
t.Run("WithDescription", func(t *testing.T) {
opts := getOpts(WithDescription("test desc"))
opts := GetOpts(WithDescription("test desc"))
testOpts := getDefaultOptions()
testOpts.withDescription = "test desc"
assert.Equal(t, opts, testOpts)
})
t.Run("WithLimit", func(t *testing.T) {
opts := getOpts(WithLimit(5))
opts := GetOpts(WithLimit(5))
testOpts := getDefaultOptions()
testOpts.withLimit = 5
assert.Equal(t, opts, testOpts)
})
t.Run("WithPassword", func(t *testing.T) {
opts := getOpts(WithPassword("test password"))
opts := GetOpts(WithPassword("test password"))
testOpts := getDefaultOptions()
testOpts.password = "test password"
testOpts.withPassword = true
@@ -49,7 +49,7 @@ func Test_GetOpts(t *testing.T) {
t.Run("WithConfiguration", func(t *testing.T) {
conf := NewArgon2Configuration()
conf.KeyLength = conf.KeyLength * 2
opts := getOpts(WithConfiguration(conf))
opts := GetOpts(WithConfiguration(conf))
testOpts := getDefaultOptions()
c, ok := testOpts.withConfig.(*Argon2Configuration)
require.True(t, ok, "need an Argon2Configuration")
@@ -59,7 +59,7 @@ func Test_GetOpts(t *testing.T) {
})
t.Run("WithOrderByCreateTime", func(t *testing.T) {
assert := assert.New(t)
opts := getOpts(WithOrderByCreateTime(true))
opts := GetOpts(WithOrderByCreateTime(true))
testOpts := getDefaultOptions()
testOpts.withOrderByCreateTime = true
testOpts.ascending = true
+1 -1
View File
@@ -33,7 +33,7 @@ func NewRepository(r db.Reader, w db.Writer, kms *kms.Kms, opt ...Option) (*Repo
return nil, errors.NewDeprecated(errors.InvalidParameter, op, "missing kms")
}
opts := getOpts(opt...)
opts := GetOpts(opt...)
if opts.withLimit == 0 {
// zero signals the boundary defaults should be used.
opts.withLimit = db.DefaultLimit
+2 -2
View File
@@ -57,7 +57,7 @@ func (r *Repository) CreateAccount(ctx context.Context, scopeId string, a *Accou
return nil, errors.New(ctx, errors.TooShort, op, fmt.Sprintf("username: %s, must be longer than %d", a.LoginName, cc.MinLoginNameLength))
}
opts := getOpts(opt...)
opts := GetOpts(opt...)
a = a.clone()
if opts.withPublicId != "" {
@@ -148,7 +148,7 @@ func (r *Repository) ListAccounts(ctx context.Context, withAuthMethodId string,
if withAuthMethodId == "" {
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing auth method id")
}
opts := getOpts(opt...)
opts := GetOpts(opt...)
limit := r.defaultLimit
if opts.withLimit != 0 {
// non-zero signals an override of the default limit for the repo.
@@ -251,7 +251,7 @@ func TestRepository_CreateAccount(t *testing.T) {
assert.NoError(db.TestVerifyOplog(t, rw, got.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second)))
opts := getOpts(tt.opts...)
opts := GetOpts(tt.opts...)
if opts.withPassword {
authAcct, err := repo.Authenticate(context.Background(), org.GetPublicId(), tt.in.AuthMethodId, tt.in.LoginName, opts.password)
require.NoError(err)
@@ -38,7 +38,7 @@ func (r *Repository) CreateAuthMethod(ctx context.Context, m *AuthMethod, opt ..
}
m = m.Clone()
opts := getOpts(opt...)
opts := GetOpts(opt...)
if opts.withPublicId != "" {
if !strings.HasPrefix(opts.withPublicId, AuthMethodPrefix+"_") {
@@ -307,7 +307,7 @@ func (r *Repository) getAuthMethods(ctx context.Context, authMethodId string, sc
}
dbArgs := []db.Option{}
opts := getOpts(opt...)
opts := GetOpts(opt...)
limit := r.defaultLimit
if opts.withLimit != 0 {
// non-zero signals an override of the default limit for the repo.
+3
View File
@@ -17,6 +17,9 @@ type AuthMethod interface {
type Account interface {
boundary.Resource
GetAuthMethodId() string
GetLoginName() string
GetEmail() string
GetSubject() string
}
type ManagedGroup interface {
+22
View File
@@ -3,7 +3,9 @@ package authtoken
import (
"time"
"github.com/hashicorp/boundary/internal/auth/password"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/iam"
)
var (
@@ -31,6 +33,8 @@ type options struct {
withLimit int
withStatus Status
withPublicId string
withPasswordOptions []password.Option
withIamOptions []iam.Option
}
func getDefaultOptions() options {
@@ -91,3 +95,21 @@ func WithPublicId(id string) Option {
o.withPublicId = id
}
}
// WithPasswordOptions allows passing through options for the password package.
// This is useful for things like tests where you may use testing helper
// functions in this package but they also create password resources.
func WithPasswordOptions(with ...password.Option) Option {
return func(o *options) {
o.withPasswordOptions = with
}
}
// WithIamOptions allows passing through options for the IAM package. This is
// useful for things like tests where you may use testing helper functions in
// this package but they also create IAM resources.
func WithIamOptions(with ...iam.Option) Option {
return func(o *options) {
o.withIamOptions = with
}
}
+18
View File
@@ -4,6 +4,8 @@ import (
"testing"
"time"
"github.com/hashicorp/boundary/internal/auth/password"
"github.com/hashicorp/boundary/internal/iam"
"github.com/stretchr/testify/assert"
)
@@ -50,4 +52,20 @@ func Test_GetOpts(t *testing.T) {
testOpts.withPublicId = "test-id"
assert.Equal(opts, testOpts)
})
t.Run("WithPasswordOptions", func(t *testing.T) {
assert := assert.New(t)
opts := getDefaultOptions()
assert.Empty(opts.withPasswordOptions)
opts = getOpts(WithPasswordOptions(password.WithName("foobar")))
assert.NotEmpty(opts.withPasswordOptions)
})
t.Run("WithIamOptions", func(t *testing.T) {
assert := assert.New(t)
opts := getDefaultOptions()
assert.Empty(opts.withIamOptions)
opts = getOpts(WithIamOptions(iam.WithName("foobar")))
assert.NotEmpty(opts.withIamOptions)
})
}
+10 -2
View File
@@ -16,17 +16,25 @@ import (
// then creates an auth token against it
func TestAuthToken(t testing.TB, conn *db.DB, kms *kms.Kms, scopeId string, opt ...Option) *AuthToken {
t.Helper()
opts := getOpts(opt...)
passwordOpts := password.GetOpts(opts.withPasswordOptions...)
loginName := passwordOpts.WithLoginName
if loginName == "" {
loginName = "name1"
}
authMethod := password.TestAuthMethods(t, conn, scopeId, 1)[0]
// auth account is only used to join auth method to user.
// We don't do anything else with the auth account in the test setup.
acct := password.TestAccount(t, conn, authMethod.GetPublicId(), "name1")
acct := password.TestAccount(t, conn, authMethod.GetPublicId(), loginName, opts.withPasswordOptions...)
ctx := context.Background()
rw := db.New(conn)
iamRepo, err := iam.NewRepository(rw, rw, kms)
require.NoError(t, err)
u := iam.TestUser(t, iamRepo, scopeId, iam.WithAccountIds(acct.PublicId))
u := iam.TestUser(t, iamRepo, scopeId, append(opts.withIamOptions, iam.WithAccountIds(acct.PublicId))...)
repo, err := NewRepository(rw, rw, kms)
require.NoError(t, err)
+1 -1
View File
@@ -17,7 +17,7 @@ type (
AuthTokenRepoFactory = oidc.AuthTokenRepoFactory
VaultCredentialRepoFactory = func() (*vault.Repository, error)
StaticCredentialRepoFactory = func() (*credstatic.Repository, error)
IamRepoFactory func() (*iam.Repository, error)
IamRepoFactory = iam.IamRepoFactory
OidcAuthRepoFactory = oidc.OidcRepoFactory
PasswordAuthRepoFactory func() (*password.Repository, error)
ServersRepoFactory func() (*server.Repository, error)
@@ -39,7 +39,7 @@ type registryEntry struct {
}
type registry struct {
sync.Map
*sync.Map
}
func (r registry) get(s subtypes.Subtype) (*registryEntry, error) {
@@ -91,7 +91,9 @@ func (r registry) setAttributes(s subtypes.Subtype, in target.Target, out *pb.Ta
return re.setAttrFunc(in, out)
}
var subtypeRegistry = registry{}
var subtypeRegistry = registry{
Map: new(sync.Map),
}
// Register registers a subtype for used by the service handler.
func Register(s subtypes.Subtype, maskManager handlers.MaskManager, af attributeFunc, sf setAttributeFunc) {
+3
View File
@@ -11,6 +11,9 @@ import (
"github.com/hashicorp/boundary/internal/types/scope"
)
// IamRepoFactory is a factory function that returns a repository and any error
type IamRepoFactory func() (*Repository, error)
// Resource declares the shared behavior of IAM Resources
type Resource interface {
// GetPublicId is the resource ID used to access the resource via an API