@ -21,9 +21,12 @@ import (
iamStore "github.com/hashicorp/boundary/internal/iam/store"
"github.com/hashicorp/boundary/internal/kms"
"github.com/hashicorp/boundary/internal/oplog"
"github.com/hashicorp/boundary/internal/perms"
"github.com/hashicorp/boundary/internal/target"
"github.com/hashicorp/boundary/internal/target/tcp"
tcpStore "github.com/hashicorp/boundary/internal/target/tcp/store"
"github.com/hashicorp/boundary/internal/types/action"
"github.com/hashicorp/boundary/internal/types/resource"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
"github.com/jackc/pgconn"
"github.com/stretchr/testify/assert"
@ -39,10 +42,18 @@ func TestRepository_ListSession(t *testing.T) {
iamRepo := iam . TestRepo ( t , conn , wrapper )
rw := db . New ( conn )
kms := kms . TestKms ( t , conn , wrapper )
repo , err := NewRepository ( rw , rw , kms , WithLimit ( testLimit ) )
require . NoError ( t , err )
composedOf := TestSessionParams ( t , conn , wrapper , iamRepo )
listPerms := & perms . UserPermissions {
UserId : composedOf . UserId ,
Permissions : [ ] perms . Permission {
{
ScopeId : composedOf . ProjectId ,
Resource : resource . Session ,
Action : action . List ,
} ,
} ,
}
type args struct {
opt [ ] Option
}
@ -50,58 +61,85 @@ func TestRepository_ListSession(t *testing.T) {
name string
createCnt int
args args
perms * perms . UserPermissions
wantCnt int
wantErr bool
withConnections int
} {
{
name : "no-limit" ,
createCnt : repo. defaul tLimit + 1 ,
createCnt : tes tLimit + 1 ,
args : args {
opt : [ ] Option { WithLimit ( - 1 ) } ,
} ,
wantCnt : repo . defaultLimit + 1 ,
perms : listPerms ,
wantCnt : testLimit + 1 ,
wantErr : false ,
} ,
{
name : "default-limit" ,
createCnt : repo. defaul tLimit + 1 ,
createCnt : tes tLimit + 1 ,
args : args { } ,
wantCnt : repo . defaultLimit ,
perms : listPerms ,
wantCnt : testLimit ,
wantErr : false ,
} ,
{
name : "custom-limit" ,
createCnt : repo. defaul tLimit + 1 ,
createCnt : tes tLimit + 1 ,
args : args {
opt : [ ] Option { WithLimit ( 3 ) } ,
} ,
perms : listPerms ,
wantCnt : 3 ,
wantErr : false ,
} ,
{
name : "withProjectIds" ,
createCnt : repo . defaultLimit + 1 ,
args : args {
opt : [ ] Option { WithProjectIds ( [ ] string { composedOf . ProjectId } ) } ,
name : "withNoPerms" ,
createCnt : testLimit + 1 ,
args : args { } ,
perms : & perms . UserPermissions { } ,
wantCnt : 0 ,
wantErr : false ,
} ,
{
name : "withPermsDifferentScopeId" ,
createCnt : testLimit + 1 ,
args : args { } ,
perms : & perms . UserPermissions {
Permissions : [ ] perms . Permission {
{
ScopeId : "o_thisIsNotValid" ,
Resource : resource . Session ,
Action : action . List ,
} ,
} ,
} ,
wantCnt : repo . defaultLimit ,
wantCnt : 0 ,
wantErr : false ,
} ,
{
name : "bad-withProjectId" ,
createCnt : repo . defaultLimit + 1 ,
args : args {
opt : [ ] Option { WithProjectIds ( [ ] string { "o_thisIsNotValid" } ) } ,
name : "withPermsNonListAction" ,
createCnt : testLimit + 1 ,
args : args { } ,
perms : & perms . UserPermissions {
Permissions : [ ] perms . Permission {
{
ScopeId : composedOf . ProjectId ,
Resource : resource . Session ,
Action : action . Read ,
} ,
} ,
} ,
wantCnt : 0 ,
wantErr : false ,
} ,
{
name : "multiple-connections" ,
createCnt : repo . defaultLimit + 1 ,
createCnt : tes tLimit + 1 ,
args : args { } ,
wantCnt : repo . defaultLimit ,
perms : listPerms ,
wantCnt : testLimit ,
wantErr : false ,
withConnections : 3 ,
} ,
@ -109,6 +147,10 @@ func TestRepository_ListSession(t *testing.T) {
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ) , require . New ( t )
repo , err := NewRepository ( rw , rw , kms , WithLimit ( testLimit ) , WithPermissions ( tt . perms ) )
require . NoError ( err )
db . TestDeleteWhere ( t , conn , func ( ) interface { } { i := AllocSession ( ) ; return & i } ( ) , "1=1" )
testSessions := [ ] * Session { }
for i := 0 ; i < tt . createCnt ; i ++ {
@ -150,6 +192,10 @@ func TestRepository_ListSession(t *testing.T) {
for i := 0 ; i < wantCnt ; i ++ {
_ = TestSession ( t , conn , wrapper , composedOf )
}
repo , err := NewRepository ( rw , rw , kms , WithLimit ( testLimit ) , WithPermissions ( listPerms ) )
require . NoError ( err )
got , err := repo . ListSessions ( context . Background ( ) , WithOrderByCreateTime ( db . AscendingOrderBy ) )
require . NoError ( err )
assert . Equal ( wantCnt , len ( got ) )
@ -160,7 +206,7 @@ func TestRepository_ListSession(t *testing.T) {
assert . True ( first . Before ( second ) )
}
} )
t . Run ( " withUserId ", func ( t * testing . T ) {
t . Run ( " onlySelf ", func ( t * testing . T ) {
assert , require := assert . New ( t ) , require . New ( t )
db . TestDeleteWhere ( t , conn , func ( ) interface { } { i := AllocSession ( ) ; return & i } ( ) , "1=1" )
wantCnt := 5
@ -168,51 +214,25 @@ func TestRepository_ListSession(t *testing.T) {
_ = TestSession ( t , conn , wrapper , composedOf )
}
s := TestDefaultSession ( t , conn , wrapper , iamRepo )
p := & perms . UserPermissions {
UserId : s . UserId ,
Permissions : [ ] perms . Permission {
{
ScopeId : s . ProjectId ,
Resource : resource . Session ,
Action : action . List ,
OnlySelf : true ,
} ,
} ,
}
repo , err := NewRepository ( rw , rw , kms , WithLimit ( testLimit ) , WithPermissions ( p ) )
require . NoError ( err )
got , err := repo . ListSessions ( context . Background ( ) , WithUserId ( s . UserId ) )
require . NoError ( err )
assert . Equal ( 1 , len ( got ) )
assert . Equal ( s . UserId , got [ 0 ] . UserId )
} )
t . Run ( "withUserIdAndwithScopeId" , func ( t * testing . T ) {
assert , require := assert . New ( t ) , require . New ( t )
db . TestDeleteWhere ( t , conn , func ( ) interface { } { i := AllocSession ( ) ; return & i } ( ) , "1=1" )
wantCnt := 5
for i := 0 ; i < wantCnt ; i ++ {
// Scope 1 User 1
_ = TestSession ( t , conn , wrapper , composedOf )
}
// Scope 2 User 2
s := TestDefaultSession ( t , conn , wrapper , iamRepo )
// Scope 1 User 2
coDiffUser := composedOf
coDiffUser . AuthTokenId = s . AuthTokenId
coDiffUser . UserId = s . UserId
wantS := TestSession ( t , conn , wrapper , coDiffUser )
got , err := repo . ListSessions ( context . Background ( ) , WithUserId ( coDiffUser . UserId ) , WithProjectIds ( [ ] string { coDiffUser . ProjectId } ) )
require . NoError ( err )
assert . Equal ( 1 , len ( got ) )
assert . Equal ( wantS . UserId , got [ 0 ] . UserId )
assert . Equal ( wantS . ProjectId , got [ 0 ] . ProjectId )
} )
t . Run ( "WithSessionIds" , func ( t * testing . T ) {
assert , require := assert . New ( t ) , require . New ( t )
db . TestDeleteWhere ( t , conn , func ( ) interface { } { i := AllocSession ( ) ; return & i } ( ) , "1=1" )
testSessions := [ ] * Session { }
for i := 0 ; i < 10 ; i ++ {
s := TestSession ( t , conn , wrapper , composedOf )
_ = TestState ( t , conn , s . PublicId , StatusActive )
testSessions = append ( testSessions , s )
}
assert . Equal ( 10 , len ( testSessions ) )
withIds := [ ] string { testSessions [ 0 ] . PublicId , testSessions [ 1 ] . PublicId }
got , err := repo . ListSessions ( context . Background ( ) , WithSessionIds ( withIds ... ) , WithOrderByCreateTime ( db . AscendingOrderBy ) )
require . NoError ( err )
assert . Equal ( 2 , len ( got ) )
assert . Equal ( StatusActive , got [ 0 ] . States [ 0 ] . Status )
assert . Equal ( StatusPending , got [ 0 ] . States [ 1 ] . Status )
} )
}
func TestRepository_ListSessions_Multiple_Scopes ( t * testing . T ) {
@ -222,23 +242,29 @@ func TestRepository_ListSessions_Multiple_Scopes(t *testing.T) {
iamRepo := iam . TestRepo ( t , conn , wrapper )
rw := db . New ( conn )
kms := kms . TestKms ( t , conn , wrapper )
repo , err := NewRepository ( rw , rw , kms )
require . NoError ( t , err )
db . TestDeleteWhere ( t , conn , func ( ) interface { } { i := AllocSession ( ) ; return & i } ( ) , "1=1" )
const numPerScope = 10
var p rojs [ ] string
var p [ ] perms . Permission
for i := 0 ; i < numPerScope ; i ++ {
composedOf := TestSessionParams ( t , conn , wrapper , iamRepo )
projs = append ( projs , composedOf . ProjectId )
p = append ( p , perms . Permission {
ScopeId : composedOf . ProjectId ,
Resource : resource . Session ,
Action : action . List ,
} )
s := TestSession ( t , conn , wrapper , composedOf )
_ = TestState ( t , conn , s . PublicId , StatusActive )
}
got , err := repo . ListSessions ( context . Background ( ) , WithProjectIds ( projs ) )
repo , err := NewRepository ( rw , rw , kms , WithPermissions ( & perms . UserPermissions {
Permissions : p ,
} ) )
require . NoError ( t , err )
assert . Equal ( t , len ( projs ) , len ( got ) )
got , err := repo . ListSessions ( context . Background ( ) )
require . NoError ( t , err )
assert . Equal ( t , len ( p ) , len ( got ) )
}
func TestRepository_CreateSession ( t * testing . T ) {
@ -1623,232 +1649,3 @@ func TestRepository_deleteTerminated(t *testing.T) {
} )
}
}
func TestFetchAuthzProtectedSessionsByScopes ( t * testing . T ) {
conn , _ := db . TestSetup ( t , "postgres" )
ctx := context . Background ( )
wrapper := db . TestWrapper ( t )
iamRepo := iam . TestRepo ( t , conn , wrapper )
rw := db . New ( conn )
kms := kms . TestKms ( t , conn , wrapper )
repo , err := NewRepository ( rw , rw , kms )
require . NoError ( t , err )
composedOf := TestSessionParams ( t , conn , wrapper , iamRepo )
_ , pWithOtherSessions := iam . TestScopes ( t , iamRepo )
hcOther := static . TestCatalogs ( t , conn , pWithOtherSessions . GetPublicId ( ) , 1 ) [ 0 ]
hsOther := static . TestSets ( t , conn , hcOther . GetPublicId ( ) , 1 ) [ 0 ]
hOther := static . TestHosts ( t , conn , hcOther . GetPublicId ( ) , 1 ) [ 0 ]
static . TestSetMembers ( t , conn , hsOther . GetPublicId ( ) , [ ] * static . Host { hOther } )
tarOther := tcp . TestTarget ( ctx , t , conn , pWithOtherSessions . GetPublicId ( ) , "test" , target . WithHostSources ( [ ] string { hsOther . GetPublicId ( ) } ) )
composedOfOther := ComposedOf {
UserId : composedOf . UserId ,
HostId : hOther . GetPublicId ( ) ,
TargetId : tarOther . GetPublicId ( ) ,
HostSetId : hsOther . GetPublicId ( ) ,
AuthTokenId : composedOf . AuthTokenId ,
ProjectId : pWithOtherSessions . GetPublicId ( ) ,
Endpoint : "tcp://127.0.0.1:22" ,
}
type testCase struct {
name string
createCnt int
terminateCnt int
otherCnt int
otherTerminateCnt int
opts [ ] Option
reqScopes [ ] string
wantCnt int
wantOtherCnt int
wantErr bool
}
cases := [ ] testCase {
{
name : "NonTerminated/none" ,
createCnt : 0 ,
reqScopes : [ ] string { composedOf . ProjectId } ,
wantCnt : 0 ,
wantErr : false ,
} ,
{
name : "NonTerminated/one" ,
createCnt : 1 ,
reqScopes : [ ] string { composedOf . ProjectId } ,
wantCnt : 1 ,
wantErr : false ,
} ,
{
name : "NonTerminated/many" ,
createCnt : 5 ,
reqScopes : [ ] string { composedOf . ProjectId } ,
wantCnt : 5 ,
wantErr : false ,
} ,
{
name : "NonTerminated/many one terminated" ,
createCnt : 5 ,
terminateCnt : 1 ,
reqScopes : [ ] string { composedOf . ProjectId } ,
wantCnt : 4 ,
wantErr : false ,
} ,
{
name : "NonTerminated/many terminated" ,
createCnt : 5 ,
terminateCnt : 3 ,
reqScopes : [ ] string { composedOf . ProjectId } ,
wantCnt : 2 ,
wantErr : false ,
} ,
{
name : "NonTerminated/many multiple projects" ,
createCnt : 5 ,
terminateCnt : 3 ,
reqScopes : [ ] string { composedOf . ProjectId , composedOfOther . ProjectId } ,
wantCnt : 2 ,
wantErr : false ,
} ,
{
name : "NonTerminated/many multiple projects" ,
createCnt : 5 ,
terminateCnt : 3 ,
otherCnt : 3 ,
otherTerminateCnt : 1 ,
reqScopes : [ ] string { composedOf . ProjectId , composedOfOther . ProjectId } ,
wantCnt : 2 ,
wantOtherCnt : 2 ,
wantErr : false ,
} ,
{
name : "NonTerminated/no projects" ,
createCnt : 2 ,
terminateCnt : 1 ,
otherCnt : 2 ,
otherTerminateCnt : 1 ,
reqScopes : [ ] string { } ,
wantErr : true ,
} ,
{
name : "none" ,
opts : [ ] Option { WithTerminated ( true ) } ,
createCnt : 0 ,
reqScopes : [ ] string { composedOf . ProjectId } ,
wantCnt : 0 ,
wantErr : false ,
} ,
{
name : "one" ,
opts : [ ] Option { WithTerminated ( true ) } ,
createCnt : 1 ,
reqScopes : [ ] string { composedOf . ProjectId } ,
wantCnt : 1 ,
wantErr : false ,
} ,
{
name : "many" ,
opts : [ ] Option { WithTerminated ( true ) } ,
createCnt : 5 ,
reqScopes : [ ] string { composedOf . ProjectId } ,
wantCnt : 5 ,
wantErr : false ,
} ,
{
name : "many one terminated" ,
opts : [ ] Option { WithTerminated ( true ) } ,
createCnt : 5 ,
terminateCnt : 1 ,
reqScopes : [ ] string { composedOf . ProjectId } ,
wantCnt : 5 ,
wantErr : false ,
} ,
{
name : "many terminated" ,
opts : [ ] Option { WithTerminated ( true ) } ,
createCnt : 5 ,
terminateCnt : 3 ,
reqScopes : [ ] string { composedOf . ProjectId } ,
wantCnt : 5 ,
wantErr : false ,
} ,
{
name : "many multiple projects" ,
opts : [ ] Option { WithTerminated ( true ) } ,
createCnt : 5 ,
terminateCnt : 3 ,
reqScopes : [ ] string { composedOf . ProjectId , composedOfOther . ProjectId } ,
wantCnt : 5 ,
wantErr : false ,
} ,
{
name : "many multiple projects" ,
opts : [ ] Option { WithTerminated ( true ) } ,
createCnt : 5 ,
terminateCnt : 3 ,
otherCnt : 3 ,
otherTerminateCnt : 1 ,
reqScopes : [ ] string { composedOf . ProjectId , composedOfOther . ProjectId } ,
wantCnt : 5 ,
wantOtherCnt : 3 ,
wantErr : false ,
} ,
{
name : "no projects" ,
opts : [ ] Option { WithTerminated ( true ) } ,
createCnt : 2 ,
terminateCnt : 1 ,
otherCnt : 2 ,
otherTerminateCnt : 1 ,
reqScopes : [ ] string { } ,
wantErr : true ,
} ,
}
for _ , tt := range cases {
t . Run ( tt . name , func ( t * testing . T ) {
assert , require := assert . New ( t ) , require . New ( t )
db . TestDeleteWhere ( t , conn , func ( ) interface { } { i := AllocSession ( ) ; return & i } ( ) , "1=1" )
testSessions := [ ] * Session { }
for i := 0 ; i < tt . createCnt ; i ++ {
s := TestSession ( t , conn , wrapper , composedOf )
_ = TestState ( t , conn , s . PublicId , StatusActive )
testSessions = append ( testSessions , s )
}
for i := 0 ; i < tt . terminateCnt ; i ++ {
_ , err := repo . CancelSession ( ctx , testSessions [ i ] . PublicId , testSessions [ i ] . Version )
require . NoError ( err )
}
terminated , err := repo . TerminateCompletedSessions ( ctx )
require . NoError ( err )
require . Equal ( tt . terminateCnt , terminated )
otherTestSessions := [ ] * Session { }
for i := 0 ; i < tt . otherCnt ; i ++ {
s := TestSession ( t , conn , wrapper , composedOfOther )
_ = TestState ( t , conn , s . PublicId , StatusActive )
otherTestSessions = append ( otherTestSessions , s )
}
for i := 0 ; i < tt . otherTerminateCnt ; i ++ {
_ , err := repo . CancelSession ( ctx , otherTestSessions [ i ] . PublicId , otherTestSessions [ i ] . Version )
require . NoError ( err )
}
terminated , err = repo . TerminateCompletedSessions ( ctx )
require . NoError ( err )
require . Equal ( tt . otherTerminateCnt , terminated )
assert . Equal ( tt . otherCnt , len ( otherTestSessions ) )
got , err := repo . fetchAuthzProtectedSessionsByProject ( ctx , tt . reqScopes , tt . opts ... )
if tt . wantErr {
require . Error ( err )
return
}
require . NoError ( err )
assert . Equal ( tt . wantCnt , len ( got [ composedOf . ProjectId ] ) )
assert . Equal ( tt . wantOtherCnt , len ( got [ composedOfOther . ProjectId ] ) )
} )
}
}