2021-06-01 14:12:34 -05:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
2023-02-02 17:15:17 -08:00
2021-06-01 14:12:34 -05:00
package oidc
import (
"context"
"fmt"
2024-01-03 14:35:54 -05:00
"slices"
2021-06-01 14:12:34 -05:00
"strings"
"testing"
"time"
2024-01-03 14:35:54 -05: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"
2021-06-01 14:12:34 -05:00
"github.com/hashicorp/boundary/internal/auth/oidc/store"
"github.com/hashicorp/boundary/internal/db"
dbassert "github.com/hashicorp/boundary/internal/db/assert"
2024-01-03 14:35:54 -05:00
"github.com/hashicorp/boundary/internal/db/timestamp"
2021-06-01 14:12:34 -05:00
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/internal/kms"
"github.com/hashicorp/boundary/internal/oplog"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2024-01-03 14:35:54 -05:00
"google.golang.org/protobuf/types/known/timestamppb"
2021-06-01 14:12:34 -05:00
)
func TestRepository_CreateManagedGroup ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
kmsCache := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
ctx := context . Background ()
databaseWrapper , err := kmsCache . GetWrapper ( ctx , org . PublicId , kms . KeyPurposeDatabase )
require . NoError ( t , err )
authMethod := TestAuthMethod (
t , conn , databaseWrapper , org . GetPublicId (), ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
tests := [] struct {
name string
scopeId string
in * ManagedGroup
opts [] Option
want * ManagedGroup
wantIsErr errors . Code
wantErrMsg string
wantErrContains string
}{
{
name : "nil-ManagedGroup" ,
scopeId : org . GetPublicId (),
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).CreateManagedGroup: missing ManagedGroup: parameter violation: error #100" ,
},
{
name : "nil-embedded-ManagedGroup" ,
scopeId : org . GetPublicId (),
in : & ManagedGroup {},
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).CreateManagedGroup: missing embedded ManagedGroup: parameter violation: error #100" ,
},
{
name : "invalid-no-auth-method-id" ,
scopeId : org . GetPublicId (),
in : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {},
},
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).CreateManagedGroup: missing auth method id: parameter violation: error #100" ,
},
{
name : "invalid-no-filter" ,
scopeId : org . GetPublicId (),
in : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
AuthMethodId : authMethod . PublicId ,
},
},
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).CreateManagedGroup: missing filter: parameter violation: error #100" ,
},
{
name : "invalid-public-id-set" ,
scopeId : org . GetPublicId (),
in : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
AuthMethodId : authMethod . PublicId ,
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
PublicId : "mgoidc_OOOOOOOOOO" ,
},
},
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).CreateManagedGroup: public id must be empty: parameter violation: error #100" ,
},
{
name : "no-scope" ,
in : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
AuthMethodId : authMethod . PublicId ,
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
},
},
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).CreateManagedGroup: missing scope id: parameter violation: error #100" ,
},
{
name : "valid-no-options" ,
scopeId : org . GetPublicId (),
in : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
AuthMethodId : authMethod . PublicId ,
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
},
},
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
AuthMethodId : authMethod . PublicId ,
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
},
},
},
{
name : "valid-with-name" ,
scopeId : org . GetPublicId (),
in : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
AuthMethodId : authMethod . PublicId ,
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
Name : "test-name-repo" ,
},
},
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
AuthMethodId : authMethod . PublicId ,
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
Name : "test-name-repo" ,
},
},
},
{
name : "valid-with-description" ,
scopeId : org . GetPublicId (),
in : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
AuthMethodId : authMethod . PublicId ,
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
Description : ( "test-description-repo" ),
Name : "myname" ,
},
},
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
AuthMethodId : authMethod . PublicId ,
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
Description : ( "test-description-repo" ),
Name : "myname" ,
},
},
},
{
name : "duplicate-name" ,
scopeId : org . GetPublicId (),
in : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
AuthMethodId : authMethod . PublicId ,
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
Description : ( "test-description-repo" ),
Name : "myname" ,
},
},
wantIsErr : errors . NotUnique ,
wantErrContains : `name "myname" already exists` ,
},
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2021-07-29 18:52:56 -06:00
repo , err := NewRepository ( ctx , rw , rw , kmsCache )
2021-06-01 14:12:34 -05:00
assert . NoError ( err )
require . NotNil ( repo )
got , err := repo . CreateManagedGroup ( context . Background (), tt . scopeId , tt . in , tt . opts ... )
if tt . wantIsErr != 0 {
require . Error ( err )
assert . Truef ( errors . Match ( errors . T ( tt . wantIsErr ), err ), "Unexpected error %s" , err )
if tt . wantErrContains != "" {
assert . True ( strings . Contains ( err . Error (), tt . wantErrContains ))
} else {
assert . Equal ( tt . wantErrMsg , err . Error ())
}
return
}
require . NoError ( err )
assert . Empty ( tt . in . PublicId )
require . NotNil ( got )
2023-03-10 15:06:39 -05:00
assertPublicId ( t , globals . OidcManagedGroupPrefix , got . PublicId )
2021-06-01 14:12:34 -05: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 )
assert . NoError ( db . TestVerifyOplog ( t , rw , got . PublicId , db . WithOperation ( oplog . OpType_OP_TYPE_CREATE ), db . WithCreateNotBefore ( 10 * time . Second )))
})
}
}
func TestRepository_LookupManagedGroup ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
kmsCache := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
ctx := context . Background ()
databaseWrapper , err := kmsCache . GetWrapper ( ctx , org . PublicId , kms . KeyPurposeDatabase )
require . NoError ( t , err )
authMethod := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
2021-06-04 09:44:57 -05:00
mg := TestManagedGroup ( t , conn , authMethod , TestFakeManagedGroupFilter )
2021-06-01 14:12:34 -05:00
2021-07-29 18:52:56 -06:00
newMgId , err := newManagedGroupId ( ctx )
2021-06-01 14:12:34 -05:00
require . NoError ( t , err )
tests := [] struct {
name string
in string
want * ManagedGroup
wantIsErr errors . Code
wantErrMsg string
}{
{
name : "With no public id" ,
wantIsErr : errors . InvalidPublicId ,
wantErrMsg : "oidc.(Repository).LookupManagedGroup: missing public id: parameter violation: error #102" ,
},
{
name : "With non existing mg id" ,
in : newMgId ,
},
{
name : "With existing mg id" ,
in : mg . GetPublicId (),
want : mg ,
},
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2021-07-29 18:52:56 -06:00
repo , err := NewRepository ( ctx , rw , rw , kmsCache )
2021-06-01 14:12:34 -05:00
assert . NoError ( err )
require . NotNil ( repo )
got , err := repo . LookupManagedGroup ( context . Background (), tt . in )
if tt . wantIsErr != 0 {
assert . Truef ( errors . Match ( errors . T ( tt . wantIsErr ), err ), "Unexpected error %s" , err )
assert . Equal ( tt . wantErrMsg , err . Error ())
return
}
require . NoError ( err )
assert . EqualValues ( tt . want , got )
})
}
}
func TestRepository_DeleteManagedGroup ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
ctx := context . Background ()
kmsCache := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
databaseWrapper , err := kmsCache . GetWrapper ( ctx , org . PublicId , kms . KeyPurposeDatabase )
require . NoError ( t , err )
authMethod := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
2021-06-04 09:44:57 -05:00
mg := TestManagedGroup ( t , conn , authMethod , TestFakeManagedGroupFilter )
2021-07-29 18:52:56 -06:00
newMgId , err := newManagedGroupId ( ctx )
2021-06-01 14:12:34 -05:00
require . NoError ( t , err )
tests := [] struct {
name string
scopeId string
in string
want int
wantIsErr errors . Code
wantErrMsg string
}{
{
name : "With no scope id" ,
scopeId : "" ,
in : mg . GetPublicId (),
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).DeleteManagedGroup: missing scope id: parameter violation: error #100" ,
},
{
name : "With no public id" ,
scopeId : org . GetPublicId (),
wantIsErr : errors . InvalidPublicId ,
wantErrMsg : "oidc.(Repository).DeleteManagedGroup: missing public id: parameter violation: error #102" ,
},
{
name : "With non existing managed group id" ,
scopeId : org . GetPublicId (),
in : newMgId ,
want : 0 ,
},
{
name : "With existing managed group id" ,
scopeId : org . GetPublicId (),
in : mg . 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 )
2021-07-29 18:52:56 -06:00
repo , err := NewRepository ( ctx , rw , rw , kmsCache )
2021-06-01 14:12:34 -05:00
assert . NoError ( err )
require . NotNil ( repo )
got , err := repo . DeleteManagedGroup ( context . Background (), tt . scopeId , tt . in )
if tt . wantIsErr != 0 {
assert . Truef ( errors . Match ( errors . T ( tt . wantIsErr ), err ), "Unexpected error %s" , err )
assert . Equal ( tt . wantErrMsg , err . Error ())
return
}
require . NoError ( err )
assert . EqualValues ( tt . want , got )
})
}
}
func TestRepository_ListManagedGroups ( t * testing . T ) {
2024-01-03 14:35:54 -05:00
oldReadTimeout := globals . RefreshReadLookbackDuration
globals . RefreshReadLookbackDuration = 0
t . Cleanup ( func () {
globals . RefreshReadLookbackDuration = oldReadTimeout
})
2021-06-01 14:12:34 -05:00
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
ctx := context . Background ()
kmsCache := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
databaseWrapper , err := kmsCache . GetWrapper ( ctx , org . PublicId , kms . KeyPurposeDatabase )
require . NoError ( t , err )
2024-01-03 14:35:54 -05:00
repo , err := NewRepository ( ctx , rw , rw , kmsCache )
assert . NoError ( t , err )
require . NotNil ( t , repo )
2021-06-01 14:12:34 -05:00
authMethod1 := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice1.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
authMethod2 := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice2.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
authMethod3 := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice3.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
mgs1 := [] * ManagedGroup {
2021-06-04 09:44:57 -05:00
TestManagedGroup ( t , conn , authMethod1 , TestFakeManagedGroupFilter ),
TestManagedGroup ( t , conn , authMethod1 , TestFakeManagedGroupFilter ),
TestManagedGroup ( t , conn , authMethod1 , TestFakeManagedGroupFilter ),
2021-06-01 14:12:34 -05:00
}
mgs2 := [] * ManagedGroup {
2021-06-04 09:44:57 -05:00
TestManagedGroup ( t , conn , authMethod2 , TestFakeManagedGroupFilter ),
TestManagedGroup ( t , conn , authMethod2 , TestFakeManagedGroupFilter ),
TestManagedGroup ( t , conn , authMethod2 , TestFakeManagedGroupFilter ),
2021-06-01 14:12:34 -05:00
}
2024-01-03 14:35:54 -05:00
slices . Reverse ( mgs1 )
slices . Reverse ( mgs2 )
cmpOpts := [] cmp . Option {
cmpopts . IgnoreUnexported (
ManagedGroup {},
store . ManagedGroup {},
timestamp . Timestamp {},
timestamppb . Timestamp {},
),
}
2021-06-01 14:12:34 -05:00
tests := [] struct {
name string
in string
opts [] Option
want [] * ManagedGroup
wantIsErr errors . Code
wantErrMsg string
}{
{
name : "With no auth method id" ,
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).ListManagedGroups: missing auth method id: parameter violation: error #100" ,
},
{
name : "With no managed groups" ,
in : authMethod3 . GetPublicId (),
want : [] * ManagedGroup {},
},
{
name : "With first auth method id" ,
in : authMethod1 . GetPublicId (),
want : mgs1 ,
},
{
name : "With first auth method id" ,
in : authMethod2 . GetPublicId (),
want : mgs2 ,
},
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . name , func ( t * testing . T ) {
2024-01-03 14:35:54 -05:00
got , ttime , err := repo . ListManagedGroups ( context . Background (), tt . in , tt . opts ... )
2021-06-01 14:12:34 -05:00
if tt . wantIsErr != 0 {
2024-01-03 14:35:54 -05:00
assert . Truef ( t , errors . Match ( errors . T ( tt . wantIsErr ), err ), "Unexpected error %s" , err )
assert . Equal ( t , tt . wantErrMsg , err . Error ())
2021-06-01 14:12:34 -05:00
return
}
2024-01-03 14:35:54 -05:00
require . NoError ( t , err )
// Transaction timestamp should be within ~10 seconds of now
assert . True ( t , time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( t , time . Now (). After ( ttime . Add ( - 10 * time . Second )))
2021-06-01 14:12:34 -05:00
2024-01-03 14:35:54 -05:00
assert . EqualValues ( t , tt . want , got )
2021-06-01 14:12:34 -05:00
})
}
2024-01-03 14:35:54 -05:00
t . Run ( "validation" , func ( t * testing . T ) {
t . Parallel ()
t . Run ( "missing auth method id" , func ( t * testing . T ) {
t . Parallel ()
_ , _ , err := repo . ListManagedGroups ( ctx , "" , WithLimit ( 1 ))
require . ErrorContains ( t , err , "missing auth method id" )
})
})
t . Run ( "success-without-after-item" , func ( t * testing . T ) {
t . Parallel ()
resp , ttime , err := repo . ListManagedGroups ( ctx , authMethod1 . PublicId , WithLimit ( 10 ))
require . NoError ( t , err )
// Transaction timestamp should be within ~10 seconds of now
assert . True ( t , time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( t , time . Now (). After ( ttime . Add ( - 10 * time . Second )))
require . Empty ( t , cmp . Diff ( resp , mgs1 , cmpOpts ... ))
})
t . Run ( "success-with-after-item" , func ( t * testing . T ) {
t . Parallel ()
resp , ttime , err := repo . ListManagedGroups ( ctx , authMethod1 . PublicId , WithStartPageAfterItem ( mgs1 [ 0 ]), WithLimit ( 10 ))
require . NoError ( t , err )
// Transaction timestamp should be within ~10 seconds of now
assert . True ( t , time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( t , time . Now (). After ( ttime . Add ( - 10 * time . Second )))
require . Empty ( t , cmp . Diff ( resp , mgs1 [ 1 :], cmpOpts ... ))
})
2021-06-01 14:12:34 -05:00
}
func TestRepository_ListManagedGroups_Limits ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
ctx := context . Background ()
kmsCache := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
databaseWrapper , err := kmsCache . GetWrapper ( ctx , org . PublicId , kms . KeyPurposeDatabase )
require . NoError ( t , err )
am := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice1.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
mgCount := 10
for i := 0 ; i < mgCount ; i ++ {
TestManagedGroup ( t , conn , am , fmt . Sprintf ( `"/foo/%d" == "bar"` , i ))
}
tests := [] struct {
name string
repoOpts [] Option
listOpts [] Option
wantLen int
}{
{
name : "With no limits" ,
wantLen : mgCount ,
},
{
name : "With repo limit" ,
repoOpts : [] Option { WithLimit ( 3 )},
wantLen : 3 ,
},
{
name : "With negative repo limit" ,
repoOpts : [] Option { WithLimit ( - 1 )},
wantLen : mgCount ,
},
{
name : "With List limit" ,
listOpts : [] Option { WithLimit ( 3 )},
wantLen : 3 ,
},
{
name : "With negative List limit" ,
listOpts : [] Option { WithLimit ( - 1 )},
wantLen : mgCount ,
},
{
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 )
2021-07-29 18:52:56 -06:00
repo , err := NewRepository ( ctx , rw , rw , kmsCache , tt . repoOpts ... )
2021-06-01 14:12:34 -05:00
assert . NoError ( err )
require . NotNil ( repo )
2024-01-03 14:35:54 -05:00
got , ttime , err := repo . ListManagedGroups ( context . Background (), am . GetPublicId (), tt . listOpts ... )
2021-06-01 14:12:34 -05:00
require . NoError ( err )
2024-01-03 14:35:54 -05: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 )))
2021-06-01 14:12:34 -05:00
assert . Len ( got , tt . wantLen )
})
}
}
2024-01-03 14:35:54 -05:00
func TestRepository_ListManagedGroupsRefresh ( t * testing . T ) {
oldReadTimeout := globals . RefreshReadLookbackDuration
globals . RefreshReadLookbackDuration = 0
t . Cleanup ( func () {
globals . RefreshReadLookbackDuration = oldReadTimeout
})
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
ctx := context . Background ()
kmsCache := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
databaseWrapper , err := kmsCache . GetWrapper ( ctx , org . PublicId , kms . KeyPurposeDatabase )
require . NoError ( t , err )
authMethod1 := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice1.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
authMethod2 := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice2.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
mgs1 := [] * ManagedGroup {
TestManagedGroup ( t , conn , authMethod1 , TestFakeManagedGroupFilter ),
TestManagedGroup ( t , conn , authMethod1 , TestFakeManagedGroupFilter ),
TestManagedGroup ( t , conn , authMethod1 , TestFakeManagedGroupFilter ),
}
mgs2 := [] * ManagedGroup {
TestManagedGroup ( t , conn , authMethod2 , TestFakeManagedGroupFilter ),
TestManagedGroup ( t , conn , authMethod2 , TestFakeManagedGroupFilter ),
TestManagedGroup ( t , conn , authMethod2 , TestFakeManagedGroupFilter ),
}
slices . Reverse ( mgs1 )
slices . Reverse ( mgs2 )
fiveDaysAgo := time . Now (). AddDate ( 0 , 0 , - 5 )
cmpOpts := [] cmp . Option {
cmpopts . IgnoreUnexported (
ManagedGroup {},
store . ManagedGroup {},
timestamp . Timestamp {},
timestamppb . Timestamp {},
),
cmpopts . SortSlices ( func ( i , j string ) bool { return i < j }),
}
repo , err := NewRepository ( ctx , rw , rw , kmsCache )
require . NotNil ( t , repo )
assert . NoError ( t , err )
t . Run ( "validation" , func ( t * testing . T ) {
t . Parallel ()
t . Run ( "missing updated after" , func ( t * testing . T ) {
t . Parallel ()
_ , _ , err := repo . ListManagedGroupsRefresh ( ctx , authMethod1 . PublicId , time . Time {}, WithLimit ( 1 ))
require . ErrorContains ( t , err , "missing updated after time" )
})
t . Run ( "missing auth method id" , func ( t * testing . T ) {
t . Parallel ()
_ , _ , err := repo . ListManagedGroupsRefresh ( ctx , "" , fiveDaysAgo , WithLimit ( 1 ))
require . ErrorContains ( t , err , "missing auth method id" )
})
})
t . Run ( "success-without-after-item" , func ( t * testing . T ) {
t . Parallel ()
resp , ttime , err := repo . ListManagedGroupsRefresh ( ctx , authMethod1 . PublicId , fiveDaysAgo , WithLimit ( 10 ))
require . NoError ( t , err )
// Transaction timestamp should be within ~10 seconds of now
assert . True ( t , time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( t , time . Now (). After ( ttime . Add ( - 10 * time . Second )))
require . Empty ( t , cmp . Diff ( resp , mgs1 , cmpOpts ... ))
})
t . Run ( "success-with-after-item" , func ( t * testing . T ) {
t . Parallel ()
resp , ttime , err := repo . ListManagedGroupsRefresh ( ctx , authMethod1 . PublicId , fiveDaysAgo , WithStartPageAfterItem ( mgs1 [ 0 ]), WithLimit ( 10 ))
require . NoError ( t , err )
// Transaction timestamp should be within ~10 seconds of now
assert . True ( t , time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( t , time . Now (). After ( ttime . Add ( - 10 * time . Second )))
require . Empty ( t , cmp . Diff ( resp , mgs1 [ 1 :], cmpOpts ... ))
})
t . Run ( "success-without-after-item-recent-updated-after" , func ( t * testing . T ) {
t . Parallel ()
resp , ttime , err := repo . ListManagedGroupsRefresh ( ctx , authMethod1 . PublicId , mgs1 [ len ( mgs1 ) - 1 ]. GetUpdateTime (). AsTime (), WithLimit ( 10 ))
require . NoError ( t , err )
// Transaction timestamp should be within ~10 seconds of now
assert . True ( t , time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( t , time . Now (). After ( ttime . Add ( - 10 * time . Second )))
require . Empty ( t , cmp . Diff ( resp , mgs1 [: len ( mgs1 ) - 1 ], cmpOpts ... ))
})
t . Run ( "success-with-after-item-recent-updated-after" , func ( t * testing . T ) {
t . Parallel ()
resp , ttime , err := repo . ListManagedGroupsRefresh ( ctx , authMethod1 . PublicId , mgs1 [ len ( mgs1 ) - 1 ]. GetUpdateTime (). AsTime (), WithStartPageAfterItem ( mgs1 [ 0 ]), WithLimit ( 10 ))
require . NoError ( t , err )
// Transaction timestamp should be within ~10 seconds of now
assert . True ( t , time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( t , time . Now (). After ( ttime . Add ( - 10 * time . Second )))
require . Empty ( t , cmp . Diff ( resp , mgs1 [ 1 : len ( mgs1 ) - 1 ], cmpOpts ... ))
})
}
2021-06-01 14:12:34 -05:00
func TestRepository_UpdateManagedGroup ( t * testing . T ) {
ctx := context . Background ()
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
kmsCache := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
databaseWrapper , err := kmsCache . GetWrapper ( ctx , org . PublicId , kms . KeyPurposeDatabase )
require . NoError ( t , err )
am := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
changeName := func ( s string ) func ( * ManagedGroup ) * ManagedGroup {
return func ( mg * ManagedGroup ) * ManagedGroup {
mg . Name = s
return mg
}
}
changeDescription := func ( s string ) func ( * ManagedGroup ) * ManagedGroup {
return func ( mg * ManagedGroup ) * ManagedGroup {
mg . Description = s
return mg
}
}
changeFilter := func ( s string ) func ( * ManagedGroup ) * ManagedGroup {
return func ( mg * ManagedGroup ) * ManagedGroup {
mg . Filter = s
return mg
}
}
makeNil := func () func ( * ManagedGroup ) * ManagedGroup {
return func ( mg * ManagedGroup ) * ManagedGroup {
return nil
}
}
makeEmbeddedNil := func () func ( * ManagedGroup ) * ManagedGroup {
return func ( mg * ManagedGroup ) * ManagedGroup {
return & ManagedGroup {}
}
}
deletePublicId := func () func ( * ManagedGroup ) * ManagedGroup {
return func ( mg * ManagedGroup ) * ManagedGroup {
mg . PublicId = ""
return mg
}
}
nonExistentPublicId := func () func ( * ManagedGroup ) * ManagedGroup {
return func ( mg * ManagedGroup ) * ManagedGroup {
mg . PublicId = "abcd_OOOOOOOOOO"
return mg
}
}
combine := func ( fns ... func ( mg * ManagedGroup ) * ManagedGroup ) func ( * ManagedGroup ) * ManagedGroup {
return func ( mg * ManagedGroup ) * ManagedGroup {
for _ , fn := range fns {
mg = fn ( mg )
}
return mg
}
}
tests := [] struct {
name string
scopeId string
version uint32
orig * ManagedGroup
chgFn func ( * ManagedGroup ) * ManagedGroup
masks [] string
want * ManagedGroup
wantCount int
wantIsErr errors . Code
wantErrMsg string
wantErrContains string
}{
{
name : "nil-ManagedGroup" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {},
},
chgFn : makeNil (),
masks : [] string { NameField , DescriptionField },
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).UpdateManagedGroup: missing ManagedGroup: parameter violation: error #100" ,
},
{
name : "nil-embedded-ManagedGroup" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {},
},
chgFn : makeEmbeddedNil (),
masks : [] string { NameField , DescriptionField },
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).UpdateManagedGroup: missing embedded ManagedGroup: parameter violation: error #100" ,
},
{
name : "no-scope-id" ,
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "no-scope-id-test-name-repo" ,
},
},
chgFn : changeName ( "no-scope-id-test-update-name-repo" ),
masks : [] string { NameField },
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).UpdateManagedGroup: missing scope id: parameter violation: error #100" ,
},
{
name : "missing-version" ,
scopeId : org . GetPublicId (),
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "missing-version-test-name-repo" ,
},
},
chgFn : changeName ( "test-update-name-repo" ),
masks : [] string { NameField },
wantIsErr : errors . InvalidParameter ,
wantErrMsg : "oidc.(Repository).UpdateManagedGroup: missing version: parameter violation: error #100" ,
},
{
name : "no-public-id" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {},
},
chgFn : deletePublicId (),
masks : [] string { NameField , DescriptionField },
wantIsErr : errors . InvalidPublicId ,
wantErrMsg : "oidc.(Repository).UpdateManagedGroup: missing public id: parameter violation: error #102" ,
},
{
name : "updating-non-existent-ManagedGroup" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "updating-non-existent-ManagedGroup-test-name-repo" ,
},
},
chgFn : combine ( nonExistentPublicId (), changeName ( "updating-non-existent-ManagedGroup-test-update-name-repo" )),
masks : [] string { NameField },
wantIsErr : errors . RecordNotFound ,
2022-01-05 14:38:38 -05:00
wantErrMsg : "oidc.(Repository).UpdateManagedGroup: abcd_OOOOOOOOOO: db.DoTx: oidc.(Repository).UpdateManagedGroup: db.Update: record not found, search issue: error #1100: dbw.Update: dbw.lookupAfterWrite: dbw.LookupById: record not found" ,
2021-06-01 14:12:34 -05:00
},
{
name : "empty-field-mask" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "empty-field-mask-test-name-repo" ,
},
},
chgFn : changeName ( "empty-field-mask-test-update-name-repo" ),
wantIsErr : errors . EmptyFieldMask ,
wantErrMsg : "oidc.(Repository).UpdateManagedGroup: missing field mask: parameter violation: error #104" ,
},
{
name : "read-only-fields-in-field-mask" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "read-only-fields-in-field-mask-test-name-repo" ,
},
},
chgFn : changeName ( "read-only-fields-in-field-mask-test-update-name-repo" ),
masks : [] string { "PublicId" , "CreateTime" , "UpdateTime" , "AuthMethodId" },
wantIsErr : errors . InvalidFieldMask ,
wantErrMsg : "oidc.(Repository).UpdateManagedGroup: PublicId: parameter violation: error #103" ,
},
{
name : "unknown-field-in-field-mask" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "unknown-field-in-field-mask-test-name-repo" ,
},
},
chgFn : changeName ( "unknown-field-in-field-mask-test-update-name-repo" ),
masks : [] string { "Bilbo" },
wantIsErr : errors . InvalidFieldMask ,
wantErrMsg : "oidc.(Repository).UpdateManagedGroup: Bilbo: parameter violation: error #103" ,
},
{
name : "change-name" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "change-name-test-name-repo" ,
},
},
chgFn : changeName ( "change-name-test-update-name-repo" ),
masks : [] string { NameField },
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "change-name-test-update-name-repo" ,
},
},
wantCount : 1 ,
},
{
name : "change-description" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Description : "test-description-repo" ,
},
},
chgFn : changeDescription ( "test-update-description-repo" ),
masks : [] string { DescriptionField },
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Description : "test-update-description-repo" ,
},
},
wantCount : 1 ,
},
{
name : "change-filter" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
},
},
chgFn : changeFilter ( `"/zip" == "zap"` ),
masks : [] string { FilterField },
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Filter : `"/zip" == "zap"` ,
},
},
wantCount : 1 ,
},
{
name : "change-name-and-description" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "change-name-and-description-test-name-repo" ,
Description : "test-description-repo" ,
},
},
chgFn : combine ( changeDescription ( "test-update-description-repo" ), changeName ( "change-name-and-description-test-update-name-repo" )),
masks : [] string { NameField , DescriptionField },
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "change-name-and-description-test-update-name-repo" ,
Description : "test-update-description-repo" ,
},
},
wantCount : 1 ,
},
{
name : "delete-name" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "delete-name-test-name-repo" ,
Description : "test-description-repo" ,
},
},
masks : [] string { NameField },
chgFn : combine ( changeDescription ( "test-update-description-repo" ), changeName ( "" )),
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Description : "test-description-repo" ,
},
},
wantCount : 1 ,
},
{
name : "delete-description" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "delete-description-test-name-repo" ,
Description : "test-description-repo" ,
},
},
masks : [] string { DescriptionField },
chgFn : combine ( changeDescription ( "" ), changeName ( "test-update-name-repo" )),
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "delete-description-test-name-repo" ,
},
},
wantCount : 1 ,
},
{
name : "delete-filter" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
2021-06-04 09:44:57 -05:00
Filter : TestFakeManagedGroupFilter ,
2021-06-01 14:12:34 -05:00
},
},
masks : [] string { FilterField },
chgFn : combine ( changeFilter ( "" )),
wantIsErr : errors . NotNull ,
wantErrContains : "oidc.(Repository).UpdateManagedGroup: db.Update: filter must not be empty: not null constraint violated: integrity violation: error #1001" ,
},
{
name : "do-not-delete-name" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "do-not-delete-name-test-name-repo" ,
Description : "test-description-repo" ,
},
},
masks : [] string { DescriptionField },
chgFn : combine ( changeDescription ( "test-update-description-repo" ), changeName ( "" )),
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "do-not-delete-name-test-name-repo" ,
Description : "test-update-description-repo" ,
},
},
wantCount : 1 ,
},
{
name : "do-not-delete-description" ,
scopeId : org . GetPublicId (),
version : 1 ,
orig : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "do-not-delete-description-test-name-repo" ,
Description : "test-description-repo" ,
},
},
masks : [] string { NameField },
chgFn : combine ( changeDescription ( "" ), changeName ( "do-not-delete-description-test-update-name-repo" )),
want : & ManagedGroup {
ManagedGroup : & store . ManagedGroup {
Name : "do-not-delete-description-test-update-name-repo" ,
Description : "test-description-repo" ,
},
},
wantCount : 1 ,
},
}
for _ , tt := range tests {
tt := tt
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ), require . New ( t )
2021-07-29 18:52:56 -06:00
repo , err := NewRepository ( ctx , rw , rw , kmsCache )
2021-06-01 14:12:34 -05:00
assert . NoError ( err )
require . NotNil ( repo )
2021-06-04 09:44:57 -05:00
orig := TestManagedGroup ( t , conn , am , TestFakeManagedGroupFilter , WithName ( tt . orig . GetName ()), WithDescription ( tt . orig . GetDescription ()))
2021-06-01 14:12:34 -05:00
tt . orig . AuthMethodId = am . PublicId
if tt . chgFn != nil {
orig = tt . chgFn ( orig )
}
got , gotCount , err := repo . UpdateManagedGroup ( context . Background (), tt . scopeId , orig , tt . version , tt . masks )
if tt . wantIsErr != 0 {
assert . Truef ( errors . Match ( errors . T ( tt . wantIsErr ), err ), "want err: %q got: %q" , tt . wantIsErr , err )
if tt . wantErrContains != "" {
assert . True ( strings . Contains ( err . Error (), tt . wantErrContains ))
} else {
assert . Equal ( tt . wantErrMsg , err . Error ())
}
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 . OidcManagedGroupPrefix , got . PublicId )
2021-06-01 14:12:34 -05: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 )
2021-06-01 14:12:34 -05: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 )))
}
})
}
}
2024-01-03 14:35:54 -05:00
func TestRepository_estimatedCountManagedGroups ( t * testing . T ) {
oldReadTimeout := globals . RefreshReadLookbackDuration
globals . RefreshReadLookbackDuration = 0
t . Cleanup ( func () {
globals . RefreshReadLookbackDuration = oldReadTimeout
})
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
ctx := context . Background ()
kmsCache := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
databaseWrapper , err := kmsCache . GetWrapper ( ctx , org . PublicId , kms . KeyPurposeDatabase )
require . NoError ( t , err )
repo , err := NewRepository ( ctx , rw , rw , kmsCache )
assert . NoError ( t , err )
sqlDb , err := conn . SqlDB ( ctx )
require . NoError ( t , err )
// Check total entries at start, expect 0
numItems , err := repo . estimatedManagedGroupCount ( ctx )
require . NoError ( t , err )
assert . Equal ( t , 0 , numItems )
// create managed group and check count, expect 1
authMethod1 := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice1.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
mg := TestManagedGroup ( t , conn , authMethod1 , TestFakeManagedGroupFilter )
_ , err = sqlDb . ExecContext ( ctx , "analyze" )
require . NoError ( t , err )
numItems , err = repo . estimatedManagedGroupCount ( ctx )
require . NoError ( t , err )
assert . Equal ( t , 1 , numItems )
// Delete managed group and check count, expect 0 again
_ , err = repo . DeleteManagedGroup ( ctx , org . GetPublicId (), mg . GetPublicId ())
require . NoError ( t , err )
_ , err = sqlDb . ExecContext ( ctx , "analyze" )
require . NoError ( t , err )
numItems , err = repo . estimatedManagedGroupCount ( ctx )
require . NoError ( t , err )
assert . Equal ( t , 0 , numItems )
}
func TestRepository_listDeletedIdsManagedGroups ( t * testing . T ) {
oldReadTimeout := globals . RefreshReadLookbackDuration
globals . RefreshReadLookbackDuration = 0
t . Cleanup ( func () {
globals . RefreshReadLookbackDuration = oldReadTimeout
})
conn , _ := db . TestSetup ( t , "postgres" )
rw := db . New ( conn )
wrapper := db . TestWrapper ( t )
ctx := context . Background ()
kmsCache := kms . TestKms ( t , conn , wrapper )
iamRepo := iam . TestRepo ( t , conn , wrapper )
org , _ := iam . TestScopes ( t , iamRepo )
databaseWrapper , err := kmsCache . GetWrapper ( ctx , org . PublicId , kms . KeyPurposeDatabase )
require . NoError ( t , err )
repo , err := NewRepository ( ctx , rw , rw , kmsCache )
assert . NoError ( t , err )
sqlDb , err := conn . SqlDB ( ctx )
require . NoError ( t , err )
// Check total entries at start, expect 0
numItems , err := repo . estimatedManagedGroupCount ( ctx )
require . NoError ( t , err )
assert . Equal ( t , 0 , numItems )
// create managed group and check count, expect 1
authMethod1 := TestAuthMethod (
t , conn , databaseWrapper , org . PublicId , ActivePrivateState ,
"alice-rp" , "fido" ,
WithSigningAlgs ( RS256 ),
WithIssuer ( TestConvertToUrls ( t , "https://www.alice1.com" )[ 0 ]),
WithApiUrl ( TestConvertToUrls ( t , "https://www.alice.com/callback" )[ 0 ]),
)
mg := TestManagedGroup ( t , conn , authMethod1 , TestFakeManagedGroupFilter )
_ , err = sqlDb . ExecContext ( ctx , "analyze" )
require . NoError ( t , err )
deletedIds , ttime , err := repo . listDeletedManagedGroupIds ( ctx , time . Now (). AddDate ( - 1 , 0 , 0 ))
require . NoError ( t , err )
require . Empty ( t , deletedIds )
// Transaction timestamp should be within ~10 seconds of now
assert . True ( t , time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( t , time . Now (). After ( ttime . Add ( - 10 * time . Second )))
// Delete mg and check count, expect 1 entry
_ , err = repo . DeleteManagedGroup ( ctx , org . GetPublicId (), mg . GetPublicId ())
require . NoError ( t , err )
_ , err = sqlDb . ExecContext ( ctx , "analyze" )
require . NoError ( t , err )
deletedIds , ttime , err = repo . listDeletedManagedGroupIds ( ctx , time . Now (). AddDate ( - 1 , 0 , 0 ))
require . NoError ( t , err )
assert . Empty (
t ,
cmp . Diff (
[] string { mg . GetPublicId ()},
deletedIds ,
cmpopts . SortSlices ( func ( i , j string ) bool { return i < j }),
),
)
// Transaction timestamp should be within ~10 seconds of now
assert . True ( t , time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( t , time . Now (). After ( ttime . Add ( - 10 * time . Second )))
// Try again with the time set to now, expect no entries
deletedIds , ttime , err = repo . listDeletedManagedGroupIds ( ctx , time . Now ())
require . NoError ( t , err )
require . Empty ( t , deletedIds )
assert . True ( t , time . Now (). Before ( ttime . Add ( 10 * time . Second )))
assert . True ( t , time . Now (). After ( ttime . Add ( - 10 * time . Second )))
}