2021-02-11 13:32:45 -06:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
2023-02-02 17:15:17 -08:00
2020-07-24 10:23:35 -04:00
package password
import (
"context"
2023-12-21 20:44:16 -08:00
"slices"
2020-07-24 10:23:35 -04:00
"testing"
2020-07-31 11:18:41 -04:00
"time"
2020-07-24 10:23:35 -04:00
2023-12-21 20:44:16 -08:00
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
2023-03-10 15:06:39 -05:00
"github.com/hashicorp/boundary/globals"
2020-08-10 17:15:02 -04:00
"github.com/hashicorp/boundary/internal/auth/password/store"
"github.com/hashicorp/boundary/internal/db"
2020-08-11 10:12:36 -04:00
dbassert "github.com/hashicorp/boundary/internal/db/assert"
2023-12-21 20:44:16 -08:00
"github.com/hashicorp/boundary/internal/db/timestamp"
2020-11-05 16:54:03 -05:00
"github.com/hashicorp/boundary/internal/errors"
2020-08-10 17:15:02 -04:00
"github.com/hashicorp/boundary/internal/iam"
2020-08-19 16:47:18 -04:00
"github.com/hashicorp/boundary/internal/kms"
2020-08-10 17:15:02 -04:00
"github.com/hashicorp/boundary/internal/oplog"
2020-07-24 10:23:35 -04:00
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2023-12-21 20:44:16 -08:00
"google.golang.org/protobuf/types/known/timestamppb"
2020-07-24 10:23:35 -04:00
)
2020-08-11 17:25:00 -04:00
func TestCheckLoginName ( t * testing . T ) {
2021-01-07 10:02:32 -05:00
tests := [] struct {
2020-07-24 10:23:35 -04:00
in string
want bool
}{
{ "" , false },
{ " leading-spaces" , false },
{ "trailing-spaces " , false },
{ "contains spaces" , false },
{ "NotLowerCase" , false },
2020-08-11 17:25:00 -04:00
{ "valid.loginname" , true },
2020-12-02 09:56:19 -08:00
{ "valid-loginname" , true },
{ "validloginname" , true },
2020-07-24 10:23:35 -04:00
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . in , func ( t * testing . T ) {
2020-08-11 17:25:00 -04:00
assert . Equal ( t , tt . want , validLoginName ( tt . in ))
2020-07-24 10:23:35 -04:00
})
}
}
func TestRepository_CreateAccount ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
2020-08-19 16:47:18 -04:00
kms := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
2020-07-31 11:43:03 -07:00
authMethods := TestAuthMethods ( t , conn , org . GetPublicId (), 1 )
2020-07-24 10:23:35 -04:00
authMethod := authMethods [ 0 ]
2021-01-07 10:02:32 -05:00
tests := [] struct {
2021-02-11 13:32:45 -06:00
name string
in * Account
opts [] Option
want * Account
wantIsErr errors . Code
wantErrMsg string
2020-07-24 10:23:35 -04:00
}{
{
2021-02-11 13:32:45 -06:00
name : "nil-Account" ,
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).CreateAccount: missing Account: parameter violation: error #100" ,
2020-07-24 10:23:35 -04:00
},
{
2021-02-11 13:32:45 -06:00
name : "nil-embedded-Account" ,
in : & Account {},
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).CreateAccount: missing embedded Account: parameter violation: error #100" ,
2020-07-24 10:23:35 -04:00
},
{
name : "invalid-no-scope-id" ,
in : & Account {
Account : & store . Account {},
},
2021-02-11 13:32:45 -06:00
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).CreateAccount: missing auth method id: parameter violation: error #100" ,
2020-07-24 10:23:35 -04:00
},
{
name : "invalid-public-id-set" ,
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-25 00:21:08 -04:00
PublicId : "hcst_OOOOOOOOOO" ,
2020-07-24 10:23:35 -04:00
},
},
2021-02-11 13:32:45 -06:00
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).CreateAccount: public id must be empty: parameter violation: error #100" ,
2020-07-24 10:23:35 -04:00
},
{
2020-08-11 17:25:00 -04:00
name : "invalid-loginname-uppercase" ,
2020-07-24 10:23:35 -04:00
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-11 17:25:00 -04:00
LoginName : "KaZmiErcZak11" ,
2020-07-24 10:23:35 -04:00
},
},
2021-02-11 13:32:45 -06:00
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).CreateAccount: login name must be all-lowercase alphanumeric, period or hyphen. got: KaZmiErcZak11: parameter violation: error #100" ,
2020-07-24 10:23:35 -04:00
},
{
2020-08-11 17:25:00 -04:00
name : "invalid-loginname-leading-space" ,
2020-07-24 10:23:35 -04:00
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-11 17:25:00 -04:00
LoginName : " kazmierczak12" ,
2020-07-24 10:23:35 -04:00
},
},
2021-02-11 13:32:45 -06:00
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).CreateAccount: login name must be all-lowercase alphanumeric, period or hyphen. got: kazmierczak12: parameter violation: error #100" ,
2020-07-24 10:23:35 -04:00
},
{
2020-08-11 17:25:00 -04:00
name : "invalid-loginname-trailing-space" ,
2020-07-24 10:23:35 -04:00
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak13 " ,
2020-07-24 10:23:35 -04:00
},
},
2021-02-11 13:32:45 -06:00
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).CreateAccount: login name must be all-lowercase alphanumeric, period or hyphen. got: kazmierczak13 : parameter violation: error #100" ,
2020-07-24 10:23:35 -04:00
},
{
2020-08-11 17:25:00 -04:00
name : "invalid-loginname-space-in-name" ,
2020-07-24 10:23:35 -04:00
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-11 17:25:00 -04:00
LoginName : "kazmier czak14" ,
2020-07-24 10:23:35 -04:00
},
},
2021-02-11 13:32:45 -06:00
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).CreateAccount: login name must be all-lowercase alphanumeric, period or hyphen. got: kazmier czak14: parameter violation: error #100" ,
2020-07-24 10:23:35 -04:00
},
2020-07-31 11:18:41 -04:00
{
2020-08-11 17:25:00 -04:00
name : "invalid-loginname-too-short" ,
2020-07-31 11:18:41 -04:00
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-11 17:25:00 -04:00
LoginName : "ka" ,
2020-07-31 11:18:41 -04:00
},
},
2021-02-11 13:32:45 -06:00
wantIsErr : errors . TooShort ,
wantErrMsg : "password.(Repository).CreateAccount: username: ka, must be longer than 3: integrity violation: error #113" ,
2020-07-31 11:18:41 -04:00
},
{
2020-08-07 21:14:07 -04:00
name : "invalid-password-too-short" ,
2020-07-31 11:18:41 -04:00
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak123" ,
2020-07-31 11:18:41 -04:00
},
},
opts : [] Option {
WithPassword ( "a" ),
},
2021-02-11 13:32:45 -06:00
wantIsErr : errors . PasswordTooShort ,
wantErrMsg : "password.(Repository).CreateAccount: must be longer than 8: password violation: error #200" ,
2020-07-31 11:18:41 -04:00
},
2020-07-24 10:23:35 -04:00
{
name : "valid-no-options" ,
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak" ,
2020-07-24 10:23:35 -04:00
},
},
want : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak" ,
2020-07-24 10:23:35 -04:00
},
},
},
{
name : "valid-with-name" ,
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
Name : "test-name-repo" ,
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak1" ,
2020-07-24 10:23:35 -04:00
},
},
want : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
Name : "test-name-repo" ,
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak1" ,
2020-07-24 10:23:35 -04:00
},
},
},
{
name : "valid-with-description" ,
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
Description : ( "test-description-repo" ),
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak2" ,
2020-07-24 10:23:35 -04:00
},
},
want : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
Description : ( "test-description-repo" ),
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak2" ,
2020-07-24 10:23:35 -04:00
},
},
},
2020-07-31 11:18:41 -04:00
{
name : "valid-with-password" ,
in : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak3" ,
2020-07-31 11:18:41 -04:00
},
},
opts : [] Option {
WithPassword ( "1234567890" ),
},
want : & Account {
Account : & store . Account {
AuthMethodId : authMethod . PublicId ,
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak3" ,
2020-07-31 11:18:41 -04:00
},
},
},
2020-07-24 10:23:35 -04:00
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( context . Background (), rw , rw , kms )
2020-07-24 10:23:35 -04:00
assert . NoError ( err )
require . NotNil ( repo )
2020-08-19 16:47:18 -04:00
got , err := repo . CreateAccount ( context . Background (), org . GetPublicId (), tt . in , tt . opts ... )
2021-02-11 13:32:45 -06:00
if tt . wantIsErr != 0 {
assert . Truef ( errors . Match ( errors . T ( tt . wantIsErr ), err ), "Unexpected error %s" , err )
assert . Equal ( tt . wantErrMsg , err . Error ())
2020-07-24 10:23:35 -04:00
return
}
require . NoError ( err )
assert . Empty ( tt . in . PublicId )
require . NotNil ( got )
2023-03-10 15:06:39 -05:00
assertPublicId ( t , globals . PasswordAccountPrefix , got . PublicId )
2020-07-24 10:23:35 -04:00
assert . NotSame ( tt . in , got )
assert . Equal ( tt . want . Name , got . Name )
assert . Equal ( tt . want . Description , got . Description )
assert . Equal ( got . CreateTime , got . UpdateTime )
2020-07-31 11:18:41 -04:00
assert . NoError ( db . TestVerifyOplog ( t , rw , got . PublicId , db . WithOperation ( oplog . OpType_OP_TYPE_CREATE ), db . WithCreateNotBefore ( 10 * time . Second )))
2022-10-25 21:33:31 -04:00
opts := GetOpts ( tt . opts ... )
2020-07-31 11:18:41 -04:00
if opts . withPassword {
2020-08-19 16:47:18 -04:00
authAcct , err := repo . Authenticate ( context . Background (), org . GetPublicId (), tt . in . AuthMethodId , tt . in . LoginName , opts . password )
2020-07-31 11:18:41 -04:00
require . NoError ( err )
assert . NoError ( db . TestVerifyOplog ( t , rw , authAcct . CredentialId , db . WithOperation ( oplog . OpType_OP_TYPE_CREATE ), db . WithCreateNotBefore ( 10 * time . Second )))
}
2020-07-24 10:23:35 -04:00
})
}
2021-02-11 13:32:45 -06:00
}
2021-02-12 11:44:37 -05:00
2021-02-11 13:32:45 -06:00
func TestRepository_CreateAccount_DuplicateNames ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
kms := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
2020-07-24 10:23:35 -04:00
t . Run ( "invalid-duplicate-names" , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( context . Background (), rw , rw , kms )
2020-07-24 10:23:35 -04:00
assert . NoError ( err )
require . NotNil ( repo )
2020-08-19 16:47:18 -04:00
org , _ := iam . TestScopes ( t , iamRepo )
2020-07-31 11:43:03 -07:00
authMethods := TestAuthMethods ( t , conn , org . GetPublicId (), 1 )
2020-07-24 10:23:35 -04:00
authMethod := authMethods [ 0 ]
in := & Account {
Account : & store . Account {
AuthMethodId : authMethod . GetPublicId (),
Name : "test-name-repo" ,
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak3" ,
2020-07-24 10:23:35 -04:00
},
}
2020-08-19 16:47:18 -04:00
got , err := repo . CreateAccount ( context . Background (), org . GetPublicId (), in )
2020-07-24 10:23:35 -04:00
require . NoError ( err )
require . NotNil ( got )
2023-03-10 15:06:39 -05:00
assertPublicId ( t , globals . PasswordAccountPrefix , got . PublicId )
2020-07-24 10:23:35 -04:00
assert . NotSame ( in , got )
assert . Equal ( in . Name , got . Name )
assert . Equal ( in . Description , got . Description )
assert . Equal ( got . CreateTime , got . UpdateTime )
2020-08-19 16:47:18 -04:00
got2 , err := repo . CreateAccount ( context . Background (), org . GetPublicId (), in )
2021-02-11 13:32:45 -06:00
assert . Truef ( errors . Match ( errors . T ( errors . NotUnique ), err ), "Unexpected error %s" , err )
2020-07-24 10:23:35 -04:00
assert . Nil ( got2 )
})
t . Run ( "valid-duplicate-names-diff-parents" , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( context . Background (), rw , rw , kms )
2020-07-24 10:23:35 -04:00
assert . NoError ( err )
require . NotNil ( repo )
2020-08-19 16:47:18 -04:00
org , _ := iam . TestScopes ( t , iamRepo )
2020-07-31 11:43:03 -07:00
authMethods := TestAuthMethods ( t , conn , org . GetPublicId (), 2 )
2020-07-24 10:23:35 -04:00
authMethoda , authMethodb := authMethods [ 0 ], authMethods [ 1 ]
in := & Account {
Account : & store . Account {
2020-08-11 17:25:00 -04:00
Name : "test-name-repo" ,
LoginName : "kazmierczak4" ,
2020-07-24 10:23:35 -04:00
},
}
in2 := in . clone ()
in . AuthMethodId = authMethoda . GetPublicId ()
2020-08-19 16:47:18 -04:00
got , err := repo . CreateAccount ( context . Background (), org . GetPublicId (), in )
2020-07-24 10:23:35 -04:00
require . NoError ( err )
require . NotNil ( got )
2023-03-10 15:06:39 -05:00
assertPublicId ( t , globals . PasswordAccountPrefix , got . PublicId )
2020-07-24 10:23:35 -04:00
assert . NotSame ( in , got )
assert . Equal ( in . Name , got . Name )
assert . Equal ( in . Description , got . Description )
assert . Equal ( got . CreateTime , got . UpdateTime )
in2 . AuthMethodId = authMethodb . GetPublicId ()
2020-08-19 16:47:18 -04:00
got2 , err := repo . CreateAccount ( context . Background (), org . GetPublicId (), in2 )
2020-07-24 10:23:35 -04:00
assert . NoError ( err )
require . NotNil ( got2 )
2023-03-10 15:06:39 -05:00
assertPublicId ( t , globals . PasswordAccountPrefix , got2 . PublicId )
2020-07-24 10:23:35 -04:00
assert . NotSame ( in2 , got2 )
assert . Equal ( in2 . Name , got2 . Name )
assert . Equal ( in2 . Description , got2 . Description )
assert . Equal ( got2 . CreateTime , got2 . UpdateTime )
})
}
2020-07-24 11:38:27 -07:00
func TestRepository_LookupAccount ( t * testing . T ) {
2023-06-06 17:09:08 -04:00
ctx := context . Background ()
2020-07-24 11:38:27 -07:00
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
2020-08-19 16:47:18 -04:00
kms := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
2020-07-31 11:43:03 -07:00
authMethod := TestAuthMethods ( t , conn , org . GetPublicId (), 1 )[ 0 ]
2021-04-20 20:33:56 -04:00
account := TestAccount ( t , conn , authMethod . GetPublicId (), "name1" )
2020-07-24 11:38:27 -07:00
2023-06-06 17:09:08 -04:00
newAcctId , err := newAccountId ( ctx )
2020-07-24 11:38:27 -07:00
require . NoError ( t , err )
2021-01-07 10:02:32 -05:00
tests := [] struct {
2021-02-11 13:32:45 -06:00
name string
in string
want * Account
wantIsErr errors . Code
wantErrMsg string
2020-07-24 11:38:27 -07:00
}{
{
2021-02-11 13:32:45 -06:00
name : "With no public id" ,
wantIsErr : errors . InvalidPublicId ,
wantErrMsg : "password.(Repository).LookupAccount: missing public id: parameter violation: error #102" ,
2020-07-24 11:38:27 -07:00
},
{
name : "With non existing account id" ,
in : newAcctId ,
},
{
name : "With existing account id" ,
in : account . GetPublicId (),
want : account ,
},
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( ctx , rw , rw , kms )
2020-07-24 11:38:27 -07:00
assert . NoError ( err )
require . NotNil ( repo )
2023-06-06 17:09:08 -04:00
got , err := repo . LookupAccount ( ctx , tt . in )
2021-02-11 13:32:45 -06:00
if tt . wantIsErr != 0 {
assert . Truef ( errors . Match ( errors . T ( tt . wantIsErr ), err ), "Unexpected error %s" , err )
assert . Equal ( tt . wantErrMsg , err . Error ())
2020-07-24 11:38:27 -07:00
return
}
require . NoError ( err )
assert . EqualValues ( tt . want , got )
})
}
}
2020-07-28 09:06:50 -07:00
func TestRepository_DeleteAccount ( t * testing . T ) {
2023-06-06 17:09:08 -04:00
ctx := context . Background ()
2020-07-28 09:06:50 -07:00
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
2020-08-19 16:47:18 -04:00
kms := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
2020-07-31 11:43:03 -07:00
authMethod := TestAuthMethods ( t , conn , org . GetPublicId (), 1 )[ 0 ]
2021-04-20 20:33:56 -04:00
account := TestAccount ( t , conn , authMethod . GetPublicId (), "name1" )
2020-07-28 09:06:50 -07:00
2023-06-06 17:09:08 -04:00
newAcctId , err := newAccountId ( ctx )
2020-07-28 09:06:50 -07:00
require . NoError ( t , err )
2021-01-07 10:02:32 -05:00
tests := [] struct {
2021-02-11 13:32:45 -06:00
name string
in string
want int
wantIsErr errors . Code
wantErrMsg string
2020-07-28 09:06:50 -07:00
}{
{
2021-02-11 13:32:45 -06:00
name : "With no public id" ,
wantIsErr : errors . InvalidPublicId ,
wantErrMsg : "password.(Repository).DeleteAccount: missing public id: parameter violation: error #102" ,
2020-07-28 09:06:50 -07:00
},
{
name : "With non existing account id" ,
in : newAcctId ,
want : 0 ,
},
{
name : "With existing account id" ,
in : account . GetPublicId (),
want : 1 ,
},
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( ctx , rw , rw , kms )
2020-07-28 09:06:50 -07:00
assert . NoError ( err )
require . NotNil ( repo )
2023-06-06 17:09:08 -04:00
got , err := repo . DeleteAccount ( ctx , org . GetPublicId (), tt . in )
2021-02-11 13:32:45 -06:00
if tt . wantIsErr != 0 {
assert . Truef ( errors . Match ( errors . T ( tt . wantIsErr ), err ), "Unexpected error %s" , err )
assert . Equal ( tt . wantErrMsg , err . Error ())
2020-07-28 09:06:50 -07:00
return
}
require . NoError ( err )
assert . EqualValues ( tt . want , got )
})
}
}
2020-07-24 11:38:27 -07:00
func TestRepository_ListAccounts ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
2020-08-19 16:47:18 -04:00
kms := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
2020-07-31 11:43:03 -07:00
authMethods := TestAuthMethods ( t , conn , org . GetPublicId (), 3 )
2021-04-20 20:33:56 -04:00
accounts1 := TestMultipleAccounts ( t , conn , authMethods [ 0 ]. GetPublicId (), 3 )
accounts2 := TestMultipleAccounts ( t , conn , authMethods [ 1 ]. GetPublicId (), 4 )
2020-07-24 11:38:27 -07:00
_ = accounts2
2023-12-21 20:44:16 -08:00
slices . Reverse ( accounts1 )
2020-07-24 11:38:27 -07:00
2021-01-07 10:02:32 -05:00
tests := [] struct {
2021-02-11 13:32:45 -06:00
name string
in string
opts [] Option
want [] * Account
wantIsErr errors . Code
wantErrMsg string
2020-07-24 11:38:27 -07:00
}{
{
2021-02-11 13:32:45 -06:00
name : "With no auth method id" ,
wantIsErr : errors . InvalidParameter ,
2023-12-21 20:44:16 -08:00
wantErrMsg : "password.(Repository).listAccounts: missing auth method id: parameter violation: error #100" ,
2020-07-24 11:38:27 -07:00
},
{
name : "With no accounts id" ,
in : authMethods [ 2 ]. GetPublicId (),
want : [] * Account {},
},
{
name : "With first auth method id" ,
in : authMethods [ 0 ]. GetPublicId (),
want : accounts1 ,
},
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( context . Background (), rw , rw , kms )
2020-07-24 11:38:27 -07:00
assert . NoError ( err )
require . NotNil ( repo )
2023-12-21 20:44:16 -08:00
got , ttime , err := repo . listAccounts ( context . Background (), tt . in , tt . opts ... )
2021-02-11 13:32:45 -06:00
if tt . wantIsErr != 0 {
assert . Truef ( errors . Match ( errors . T ( tt . wantIsErr ), err ), "Unexpected error %s" , err )
assert . Equal ( tt . wantErrMsg , err . Error ())
2020-07-24 11:38:27 -07:00
return
}
require . NoError ( err )
2023-12-21 20:44:16 -08:00
assert . Empty ( cmp . Diff ( tt . want , got , cmpopts . IgnoreUnexported ( Account {}, store . Account {}, timestamp . Timestamp {}, timestamppb . Timestamp {})))
// Transaction timestamp should be within ~10 seconds of now
assert . True ( time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( time . Now (). After ( ttime . Add ( - 10 * time . Second )))
2020-07-24 11:38:27 -07:00
})
}
}
func TestRepository_ListAccounts_Limits ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
2020-08-19 16:47:18 -04:00
kms := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
2020-07-31 11:43:03 -07:00
am := TestAuthMethods ( t , conn , org . GetPublicId (), 1 )[ 0 ]
2020-07-24 11:38:27 -07:00
accountCount := 10
2021-04-20 20:33:56 -04:00
_ = TestMultipleAccounts ( t , conn , am . GetPublicId (), accountCount )
2020-07-24 11:38:27 -07:00
2021-01-07 10:02:32 -05:00
tests := [] struct {
2020-07-24 11:38:27 -07:00
name string
repoOpts [] Option
listOpts [] Option
wantLen int
}{
{
name : "With no limits" ,
wantLen : accountCount ,
},
{
name : "With repo limit" ,
repoOpts : [] Option { WithLimit ( 3 )},
wantLen : 3 ,
},
{
name : "With negative repo limit" ,
repoOpts : [] Option { WithLimit ( - 1 )},
wantLen : accountCount ,
},
{
name : "With List limit" ,
listOpts : [] Option { WithLimit ( 3 )},
wantLen : 3 ,
},
{
name : "With negative List limit" ,
listOpts : [] Option { WithLimit ( - 1 )},
wantLen : accountCount ,
},
{
name : "With repo smaller than list limit" ,
repoOpts : [] Option { WithLimit ( 2 )},
listOpts : [] Option { WithLimit ( 6 )},
wantLen : 6 ,
},
{
name : "With repo larger than list limit" ,
repoOpts : [] Option { WithLimit ( 6 )},
listOpts : [] Option { WithLimit ( 2 )},
wantLen : 2 ,
},
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( context . Background (), rw , rw , kms , tt . repoOpts ... )
2020-07-24 11:38:27 -07:00
assert . NoError ( err )
require . NotNil ( repo )
2023-12-21 20:44:16 -08:00
got , ttime , err := repo . listAccounts ( context . Background (), am . GetPublicId (), tt . listOpts ... )
2020-07-24 11:38:27 -07:00
require . NoError ( err )
assert . Len ( got , tt . wantLen )
2023-12-21 20:44:16 -08:00
// Transaction timestamp should be within ~10 seconds of now
assert . True ( time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( time . Now (). After ( ttime . Add ( - 10 * time . Second )))
2020-07-24 11:38:27 -07:00
})
}
}
2020-08-11 10:12:36 -04:00
func TestRepository_UpdateAccount ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
2020-08-19 16:47:18 -04:00
kms := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
2021-09-30 09:17:27 -04:00
ctx := context . Background ()
2020-08-11 10:12:36 -04:00
2020-08-11 17:25:00 -04:00
changeLoginName := func ( s string ) func ( * Account ) * Account {
2020-08-11 10:12:36 -04:00
return func ( a * Account ) * Account {
2020-08-11 17:25:00 -04:00
a . LoginName = s
2020-08-11 10:12:36 -04:00
return a
}
}
changeName := func ( s string ) func ( * Account ) * Account {
return func ( a * Account ) * Account {
a . Name = s
return a
}
}
changeDescription := func ( s string ) func ( * Account ) * Account {
return func ( a * Account ) * Account {
a . Description = s
return a
}
}
makeNil := func () func ( * Account ) * Account {
return func ( a * Account ) * Account {
return nil
}
}
makeEmbeddedNil := func () func ( * Account ) * Account {
return func ( a * Account ) * Account {
return & Account {}
}
}
deletePublicId := func () func ( * Account ) * Account {
return func ( a * Account ) * Account {
a . PublicId = ""
return a
}
}
nonExistentPublicId := func () func ( * Account ) * Account {
return func ( a * Account ) * Account {
a . PublicId = "abcd_OOOOOOOOOO"
return a
}
}
combine := func ( fns ... func ( a * Account ) * Account ) func ( * Account ) * Account {
return func ( a * Account ) * Account {
for _ , fn := range fns {
a = fn ( a )
}
return a
}
}
2021-01-07 10:02:32 -05:00
tests := [] struct {
2021-02-11 13:32:45 -06:00
name string
orig * Account
chgFn func ( * Account ) * Account
masks [] string
want * Account
wantCount int
wantIsErr errors . Code
wantErrMsg string
2020-08-11 10:12:36 -04:00
}{
{
name : "nil-Account" ,
orig : & Account {
Account : & store . Account {},
},
2021-02-11 13:32:45 -06:00
chgFn : makeNil (),
masks : [] string { "Name" , "Description" },
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).UpdateAccount: missing Account: parameter violation: error #100" ,
2020-08-11 10:12:36 -04:00
},
{
name : "nil-embedded-Account" ,
orig : & Account {
Account : & store . Account {},
},
2021-02-11 13:32:45 -06:00
chgFn : makeEmbeddedNil (),
masks : [] string { "Name" , "Description" },
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).UpdateAccount: missing embedded Account: parameter violation: error #100" ,
2020-08-11 10:12:36 -04:00
},
{
name : "no-public-id" ,
orig : & Account {
Account : & store . Account {},
},
2021-02-11 13:32:45 -06:00
chgFn : deletePublicId (),
masks : [] string { "Name" , "Description" },
wantIsErr : errors . InvalidPublicId ,
wantErrMsg : "password.(Repository).UpdateAccount: missing public id: parameter violation: error #102" ,
2020-08-11 10:12:36 -04:00
},
{
name : "updating-non-existent-Account" ,
orig : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
},
},
2021-02-11 13:32:45 -06:00
chgFn : combine ( nonExistentPublicId (), changeName ( "test-update-name-repo" )),
masks : [] string { "Name" },
wantIsErr : errors . RecordNotFound ,
2022-01-05 14:38:38 -05:00
wantErrMsg : "password.(Repository).UpdateAccount: abcd_OOOOOOOOOO: db.DoTx: password.(Repository).UpdateAccount: db.Update: record not found, search issue: error #1100: dbw.Update: dbw.lookupAfterWrite: dbw.LookupById: record not found" ,
2020-08-11 10:12:36 -04:00
},
{
name : "empty-field-mask" ,
orig : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
},
},
2021-02-11 13:32:45 -06:00
chgFn : changeName ( "test-update-name-repo" ),
wantIsErr : errors . EmptyFieldMask ,
wantErrMsg : "password.(Repository).UpdateAccount: missing field mask: parameter violation: error #104" ,
2020-08-11 10:12:36 -04:00
},
{
name : "read-only-fields-in-field-mask" ,
orig : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
},
},
2021-02-11 13:32:45 -06:00
chgFn : changeName ( "test-update-name-repo" ),
masks : [] string { "PublicId" , "CreateTime" , "UpdateTime" , "AuthMethodId" },
wantIsErr : errors . InvalidFieldMask ,
wantErrMsg : "password.(Repository).UpdateAccount: PublicId: parameter violation: error #103" ,
2020-08-11 10:12:36 -04:00
},
{
name : "unknown-field-in-field-mask" ,
orig : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
},
},
2021-02-11 13:32:45 -06:00
chgFn : changeName ( "test-update-name-repo" ),
masks : [] string { "Bilbo" },
wantIsErr : errors . InvalidFieldMask ,
wantErrMsg : "password.(Repository).UpdateAccount: Bilbo: parameter violation: error #103" ,
2020-08-11 10:12:36 -04:00
},
{
name : "change-name" ,
orig : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
},
},
chgFn : changeName ( "test-update-name-repo" ),
masks : [] string { "Name" },
want : & Account {
Account : & store . Account {
Name : "test-update-name-repo" ,
},
},
wantCount : 1 ,
},
{
name : "change-description" ,
orig : & Account {
Account : & store . Account {
Description : "test-description-repo" ,
},
},
chgFn : changeDescription ( "test-update-description-repo" ),
masks : [] string { "Description" },
want : & Account {
Account : & store . Account {
Description : "test-update-description-repo" ,
},
},
wantCount : 1 ,
},
{
name : "change-name-and-description" ,
orig : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
Description : "test-description-repo" ,
},
},
chgFn : combine ( changeDescription ( "test-update-description-repo" ), changeName ( "test-update-name-repo" )),
masks : [] string { "Name" , "Description" },
want : & Account {
Account : & store . Account {
Name : "test-update-name-repo" ,
Description : "test-update-description-repo" ,
},
},
wantCount : 1 ,
},
{
name : "delete-name" ,
orig : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
Description : "test-description-repo" ,
},
},
masks : [] string { "Name" },
chgFn : combine ( changeDescription ( "test-update-description-repo" ), changeName ( "" )),
want : & Account {
Account : & store . Account {
Description : "test-description-repo" ,
},
},
wantCount : 1 ,
},
{
name : "delete-description" ,
orig : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
Description : "test-description-repo" ,
},
},
masks : [] string { "Description" },
chgFn : combine ( changeDescription ( "" ), changeName ( "test-update-name-repo" )),
want : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
},
},
wantCount : 1 ,
},
{
name : "do-not-delete-name" ,
orig : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
Description : "test-description-repo" ,
},
},
masks : [] string { "Description" },
chgFn : combine ( changeDescription ( "test-update-description-repo" ), changeName ( "" )),
want : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
Description : "test-update-description-repo" ,
},
},
wantCount : 1 ,
},
{
name : "do-not-delete-description" ,
orig : & Account {
Account : & store . Account {
Name : "test-name-repo" ,
Description : "test-description-repo" ,
},
},
masks : [] string { "Name" },
chgFn : combine ( changeDescription ( "" ), changeName ( "test-update-name-repo" )),
want : & Account {
Account : & store . Account {
Name : "test-update-name-repo" ,
Description : "test-description-repo" ,
},
},
wantCount : 1 ,
},
{
2020-08-11 17:25:00 -04:00
name : "change-login-name" ,
2020-08-11 10:12:36 -04:00
orig : & Account {
Account : & store . Account {
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak" ,
2020-08-11 10:12:36 -04:00
},
},
2020-08-11 17:25:00 -04:00
chgFn : changeLoginName ( "mothball" ),
masks : [] string { "LoginName" },
2020-08-11 10:12:36 -04:00
want : & Account {
Account : & store . Account {
2020-08-11 17:25:00 -04:00
LoginName : "mothball" ,
2020-08-11 10:12:36 -04:00
},
},
wantCount : 1 ,
},
{
2020-08-11 17:25:00 -04:00
name : "change-login-name-mixed-caps" ,
2020-08-11 10:12:36 -04:00
orig : & Account {
Account : & store . Account {
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak" ,
2020-08-11 10:12:36 -04:00
},
},
2021-02-11 13:32:45 -06:00
chgFn : changeLoginName ( "KaZmIeRcZaK" ),
masks : [] string { "LoginName" },
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).UpdateAccount: invalid username: must be all-lowercase alphanumeric, period or hyphen, got KaZmIeRcZaK: parameter violation: error #100" ,
2020-08-11 10:12:36 -04:00
},
{
2020-08-11 17:25:00 -04:00
name : "change-login-name-to-short" ,
2020-08-11 10:12:36 -04:00
orig : & Account {
Account : & store . Account {
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak" ,
2020-08-11 10:12:36 -04:00
},
},
2021-02-11 13:32:45 -06:00
chgFn : changeLoginName ( "ka" ),
masks : [] string { "LoginName" },
wantIsErr : errors . TooShort ,
wantErrMsg : "password.(Repository).UpdateAccount: username: ka, must be longer than 3: integrity violation: error #113" ,
2020-08-11 10:12:36 -04:00
},
{
2020-08-11 17:25:00 -04:00
name : "delete-login-name" ,
2020-08-11 10:12:36 -04:00
orig : & Account {
Account : & store . Account {
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak" ,
2020-08-11 10:12:36 -04:00
},
},
2021-02-11 13:32:45 -06:00
chgFn : changeLoginName ( "" ),
masks : [] string { "LoginName" },
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "password.(Repository).UpdateAccount: invalid username: must be all-lowercase alphanumeric, period or hyphen, got : parameter violation: error #100" ,
2020-08-11 10:12:36 -04:00
},
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( context . Background (), rw , rw , kms )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( repo )
2020-08-19 16:47:18 -04:00
org , _ := iam . TestScopes ( t , iamRepo )
2020-08-11 10:12:36 -04:00
am := TestAuthMethods ( t , conn , org . PublicId , 1 )[ 0 ]
tt . orig . AuthMethodId = am . PublicId
2020-08-11 17:25:00 -04:00
if tt . orig . LoginName == "" {
tt . orig . LoginName = "kazmierczak"
2020-08-11 10:12:36 -04:00
}
2020-08-19 16:47:18 -04:00
orig , err := repo . CreateAccount ( context . Background (), org . GetPublicId (), tt . orig )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( orig )
if tt . chgFn != nil {
orig = tt . chgFn ( orig )
}
2020-08-19 16:47:18 -04:00
got , gotCount , err := repo . UpdateAccount ( context . Background (), org . GetPublicId (), orig , 1 , tt . masks )
2020-12-21 10:07:34 -08:00
if tt . wantIsErr != 0 {
assert . Truef ( errors . Match ( errors . T ( tt . wantIsErr ), err ), "want err: %q got: %q" , tt . wantIsErr , err )
2021-02-11 13:32:45 -06:00
assert . Equal ( tt . wantErrMsg , err . Error ())
2020-08-11 10:12:36 -04:00
assert . Equal ( tt . wantCount , gotCount , "row count" )
assert . Nil ( got )
return
}
assert . NoError ( err )
assert . Empty ( tt . orig . PublicId )
if tt . wantCount == 0 {
assert . Equal ( tt . wantCount , gotCount , "row count" )
assert . Nil ( got )
return
}
require . NotNil ( got )
2023-03-10 15:06:39 -05:00
assertPublicId ( t , globals . PasswordAccountPrefix , got . PublicId )
2020-08-11 10:12:36 -04:00
assert . Equal ( tt . wantCount , gotCount , "row count" )
assert . NotSame ( tt . orig , got )
assert . Equal ( tt . orig . AuthMethodId , got . AuthMethodId )
2021-09-30 09:17:27 -04:00
underlyingDB , err := conn . SqlDB ( ctx )
2021-09-30 08:47:34 -04:00
require . NoError ( err )
dbassert := dbassert . New ( t , underlyingDB )
2020-08-11 10:12:36 -04:00
if tt . want . Name == "" {
dbassert . IsNull ( got , "name" )
return
}
assert . Equal ( tt . want . Name , got . Name )
if tt . want . Description == "" {
dbassert . IsNull ( got , "description" )
return
}
assert . Equal ( tt . want . Description , got . Description )
if tt . wantCount > 0 {
assert . NoError ( db . TestVerifyOplog ( t , rw , got . PublicId , db . WithOperation ( oplog . OpType_OP_TYPE_UPDATE ), db . WithCreateNotBefore ( 10 * time . Second )))
}
})
}
2021-02-11 13:32:45 -06:00
}
func TestRepository_UpdateAccount_DupeNames ( t * testing . T ) {
2023-06-06 17:09:08 -04:00
ctx := context . Background ()
2021-02-11 13:32:45 -06:00
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
kms := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
2020-08-11 10:12:36 -04:00
t . Run ( "invalid-duplicate-names" , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( ctx , rw , rw , kms )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( repo )
name := "test-dup-name"
2020-08-19 16:47:18 -04:00
org , _ := iam . TestScopes ( t , iamRepo )
2020-08-11 10:12:36 -04:00
am := TestAuthMethods ( t , conn , org . PublicId , 1 )[ 0 ]
2021-04-20 20:33:56 -04:00
acts := TestMultipleAccounts ( t , conn , am . PublicId , 2 )
2020-08-11 10:12:36 -04:00
aa := acts [ 0 ]
ab := acts [ 1 ]
aa . Name = name
2020-08-19 16:47:18 -04:00
got1 , gotCount1 , err := repo . UpdateAccount ( context . Background (), org . GetPublicId (), aa , 1 , [] string { "name" })
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( got1 )
assert . Equal ( name , got1 . Name )
assert . Equal ( 1 , gotCount1 , "row count" )
assert . NoError ( db . TestVerifyOplog ( t , rw , aa . PublicId , db . WithOperation ( oplog . OpType_OP_TYPE_UPDATE ), db . WithCreateNotBefore ( 10 * time . Second )))
ab . Name = name
2020-08-19 16:47:18 -04:00
got2 , gotCount2 , err := repo . UpdateAccount ( context . Background (), org . GetPublicId (), ab , 1 , [] string { "name" })
2021-02-11 13:32:45 -06:00
assert . Truef ( errors . Match ( errors . T ( errors . NotUnique ), err ), "Unexpected error %s" , err )
2020-08-11 10:12:36 -04:00
assert . Nil ( got2 )
assert . Equal ( db . NoRowsAffected , gotCount2 , "row count" )
err = db . TestVerifyOplog ( t , rw , ab . PublicId , db . WithOperation ( oplog . OpType_OP_TYPE_UPDATE ), db . WithCreateNotBefore ( 10 * time . Second ))
assert . Error ( err )
2020-12-21 10:07:34 -08:00
assert . True ( errors . IsNotFoundError ( err ))
2020-08-11 10:12:36 -04:00
})
t . Run ( "valid-duplicate-names-diff-AuthMethods" , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( ctx , rw , rw , kms )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( repo )
2020-08-19 16:47:18 -04:00
org , _ := iam . TestScopes ( t , iamRepo )
2020-08-11 10:12:36 -04:00
ams := TestAuthMethods ( t , conn , org . PublicId , 2 )
ama := ams [ 0 ]
amb := ams [ 1 ]
in := & Account {
Account : & store . Account {
Name : "test-name-repo" ,
},
}
in2 := in . clone ()
in . AuthMethodId = ama . PublicId
2020-08-11 17:25:00 -04:00
in . LoginName = "kazmierczak"
2020-08-19 16:47:18 -04:00
got , err := repo . CreateAccount ( context . Background (), org . GetPublicId (), in )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( got )
2023-03-10 15:06:39 -05:00
assertPublicId ( t , globals . PasswordAccountPrefix , got . PublicId )
2020-08-11 10:12:36 -04:00
assert . NotSame ( in , got )
assert . Equal ( in . Name , got . Name )
assert . Equal ( in . Description , got . Description )
in2 . AuthMethodId = amb . PublicId
2020-08-11 17:25:00 -04:00
in2 . LoginName = "kazmierczak2"
2020-08-11 10:12:36 -04:00
in2 . Name = "first-name"
2020-08-19 16:47:18 -04:00
got2 , err := repo . CreateAccount ( context . Background (), org . GetPublicId (), in2 )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( got2 )
got2 . Name = got . Name
2020-08-19 16:47:18 -04:00
got3 , gotCount3 , err := repo . UpdateAccount ( context . Background (), org . GetPublicId (), got2 , 1 , [] string { "name" })
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( got3 )
assert . NotSame ( got2 , got3 )
assert . Equal ( got . Name , got3 . Name )
assert . Equal ( got2 . Description , got3 . Description )
assert . Equal ( 1 , gotCount3 , "row count" )
assert . NoError ( db . TestVerifyOplog ( t , rw , got2 . PublicId , db . WithOperation ( oplog . OpType_OP_TYPE_UPDATE ), db . WithCreateNotBefore ( 10 * time . Second )))
})
2020-08-11 17:25:00 -04:00
t . Run ( "invalid-duplicate-loginnames" , func ( t * testing . T ) {
2020-08-11 10:12:36 -04:00
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( ctx , rw , rw , kms )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( repo )
2020-08-11 17:25:00 -04:00
loginName := "kazmierczak12"
2020-08-19 16:47:18 -04:00
org , _ := iam . TestScopes ( t , iamRepo )
2020-08-11 10:12:36 -04:00
am := TestAuthMethods ( t , conn , org . PublicId , 1 )[ 0 ]
2021-04-20 20:33:56 -04:00
acts := TestMultipleAccounts ( t , conn , am . PublicId , 2 )
2020-08-11 10:12:36 -04:00
aa := acts [ 0 ]
ab := acts [ 1 ]
2020-08-11 17:25:00 -04:00
aa . LoginName = loginName
2020-08-19 16:47:18 -04:00
got1 , gotCount1 , err := repo . UpdateAccount ( context . Background (), org . GetPublicId (), aa , 1 , [] string { "LoginName" })
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( got1 )
2020-08-11 17:25:00 -04:00
assert . Equal ( loginName , got1 . LoginName )
2020-08-11 10:12:36 -04:00
assert . Equal ( 1 , gotCount1 , "row count" )
assert . NoError ( db . TestVerifyOplog ( t , rw , aa . PublicId , db . WithOperation ( oplog . OpType_OP_TYPE_UPDATE ), db . WithCreateNotBefore ( 10 * time . Second )))
2020-08-11 17:25:00 -04:00
ab . LoginName = loginName
2020-08-19 16:47:18 -04:00
got2 , gotCount2 , err := repo . UpdateAccount ( context . Background (), org . GetPublicId (), ab , 1 , [] string { "LoginName" })
2021-02-11 13:32:45 -06:00
assert . Truef ( errors . Match ( errors . T ( errors . NotUnique ), err ), "Unexpected error %s" , err )
2020-08-11 10:12:36 -04:00
assert . Nil ( got2 )
assert . Equal ( db . NoRowsAffected , gotCount2 , "row count" )
err = db . TestVerifyOplog ( t , rw , ab . PublicId , db . WithOperation ( oplog . OpType_OP_TYPE_UPDATE ), db . WithCreateNotBefore ( 10 * time . Second ))
assert . Error ( err )
2020-12-21 10:07:34 -08:00
assert . True ( errors . IsNotFoundError ( err ))
2020-08-11 10:12:36 -04:00
})
2020-08-11 17:25:00 -04:00
t . Run ( "valid-duplicate-loginnames-diff-AuthMethods" , func ( t * testing . T ) {
2020-08-11 10:12:36 -04:00
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( ctx , rw , rw , kms )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( repo )
2020-08-19 16:47:18 -04:00
org , _ := iam . TestScopes ( t , iamRepo )
2020-08-11 10:12:36 -04:00
ams := TestAuthMethods ( t , conn , org . PublicId , 2 )
ama := ams [ 0 ]
amb := ams [ 1 ]
in := & Account {
Account : & store . Account {
2020-08-11 17:25:00 -04:00
LoginName : "kazmierczak" ,
2020-08-11 10:12:36 -04:00
},
}
in2 := in . clone ()
in . AuthMethodId = ama . PublicId
2020-08-19 16:47:18 -04:00
got , err := repo . CreateAccount ( context . Background (), org . GetPublicId (), in )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( got )
2023-03-10 15:06:39 -05:00
assertPublicId ( t , globals . PasswordAccountPrefix , got . PublicId )
2020-08-11 10:12:36 -04:00
assert . NotSame ( in , got )
2020-08-11 17:25:00 -04:00
assert . Equal ( in . LoginName , got . LoginName )
2020-08-11 10:12:36 -04:00
in2 . AuthMethodId = amb . PublicId
2020-08-11 17:25:00 -04:00
in2 . LoginName = "kazmierczak2"
2020-08-19 16:47:18 -04:00
got2 , err := repo . CreateAccount ( context . Background (), org . GetPublicId (), in2 )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( got2 )
2020-08-11 17:25:00 -04:00
got2 . LoginName = got . LoginName
2020-08-19 16:47:18 -04:00
got3 , gotCount3 , err := repo . UpdateAccount ( context . Background (), org . GetPublicId (), got2 , 1 , [] string { "LoginName" })
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( got3 )
assert . NotSame ( got2 , got3 )
2020-08-11 17:25:00 -04:00
assert . Equal ( got . LoginName , got3 . LoginName )
2020-08-11 10:12:36 -04:00
assert . Equal ( 1 , gotCount3 , "row count" )
assert . NoError ( db . TestVerifyOplog ( t , rw , got2 . PublicId , db . WithOperation ( oplog . OpType_OP_TYPE_UPDATE ), db . WithCreateNotBefore ( 10 * time . Second )))
})
t . Run ( "change-authmethod-id" , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2023-06-06 17:09:08 -04:00
repo , err := NewRepository ( ctx , rw , rw , kms )
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( repo )
2020-08-19 16:47:18 -04:00
org , _ := iam . TestScopes ( t , iamRepo )
2020-08-11 10:12:36 -04:00
ams := TestAuthMethods ( t , conn , org . PublicId , 2 )
ama := ams [ 0 ]
amb := ams [ 1 ]
2021-04-20 20:33:56 -04:00
aa := TestMultipleAccounts ( t , conn , ama . PublicId , 1 )[ 0 ]
ab := TestMultipleAccounts ( t , conn , amb . PublicId , 1 )[ 0 ]
2020-08-11 10:12:36 -04:00
assert . NotEqual ( aa . AuthMethodId , ab . AuthMethodId )
orig := aa . clone ()
aa . AuthMethodId = ab . AuthMethodId
assert . Equal ( aa . AuthMethodId , ab . AuthMethodId )
2020-08-19 16:47:18 -04:00
got1 , gotCount1 , err := repo . UpdateAccount ( context . Background (), org . GetPublicId (), aa , 1 , [] string { "name" })
2020-08-11 10:12:36 -04:00
assert . NoError ( err )
require . NotNil ( got1 )
assert . Equal ( orig . AuthMethodId , got1 . AuthMethodId )
assert . Equal ( 1 , gotCount1 , "row count" )
assert . NoError ( db . TestVerifyOplog ( t , rw , aa . PublicId , db . WithOperation ( oplog . OpType_OP_TYPE_UPDATE ), db . WithCreateNotBefore ( 10 * time . Second )))
})
}