2021-12-14 07:19:02 +00:00
package query
import (
2023-02-27 21:36:43 +00:00
"context"
2021-12-14 07:19:02 +00:00
"database/sql"
"database/sql/driver"
"errors"
"fmt"
"regexp"
"testing"
2022-11-30 16:01:17 +00:00
sq "github.com/Masterminds/squirrel"
2022-08-31 07:52:43 +00:00
"github.com/zitadel/zitadel/internal/database"
2021-12-14 07:19:02 +00:00
)
var (
membershipsStmt = regexp . QuoteMeta (
"SELECT memberships.user_id" +
", memberships.roles" +
", memberships.creation_date" +
", memberships.change_date" +
", memberships.sequence" +
", memberships.resource_owner" +
", memberships.org_id" +
2022-03-29 09:53:19 +00:00
", memberships.id" +
2021-12-14 07:19:02 +00:00
", memberships.project_id" +
", memberships.grant_id" +
2022-11-30 16:01:17 +00:00
", projections.project_grants3.granted_org_id" +
", projections.projects3.name" +
2023-09-07 04:54:51 +00:00
", projections.orgs1.name" +
2021-12-14 07:19:02 +00:00
", COUNT(*) OVER ()" +
" FROM (" +
"SELECT members.user_id" +
", members.roles" +
", members.creation_date" +
", members.change_date" +
", members.sequence" +
", members.resource_owner" +
2022-03-29 09:53:19 +00:00
", members.instance_id" +
2021-12-14 07:19:02 +00:00
", members.org_id" +
2022-08-31 07:52:43 +00:00
", NULL::TEXT AS id" +
", NULL::TEXT AS project_id" +
", NULL::TEXT AS grant_id" +
2022-11-30 16:01:17 +00:00
" FROM projections.org_members3 AS members" +
" WHERE members.owner_removed = $1 AND members.user_owner_removed = $2" +
2021-12-14 07:19:02 +00:00
" UNION ALL " +
"SELECT members.user_id" +
", members.roles" +
", members.creation_date" +
", members.change_date" +
", members.sequence" +
", members.resource_owner" +
2022-03-24 16:21:34 +00:00
", members.instance_id" +
2022-08-31 07:52:43 +00:00
", NULL::TEXT AS org_id" +
2022-03-29 09:53:19 +00:00
", members.id" +
2022-08-31 07:52:43 +00:00
", NULL::TEXT AS project_id" +
", NULL::TEXT AS grant_id" +
2022-11-30 16:01:17 +00:00
" FROM projections.instance_members3 AS members" +
" WHERE members.owner_removed = $3 AND members.user_owner_removed = $4" +
2021-12-14 07:19:02 +00:00
" UNION ALL " +
"SELECT members.user_id" +
", members.roles" +
", members.creation_date" +
", members.change_date" +
", members.sequence" +
", members.resource_owner" +
2022-03-29 09:53:19 +00:00
", members.instance_id" +
2022-08-31 07:52:43 +00:00
", NULL::TEXT AS org_id" +
", NULL::TEXT AS id" +
2021-12-14 07:19:02 +00:00
", members.project_id" +
2022-08-31 07:52:43 +00:00
", NULL::TEXT AS grant_id" +
2022-11-30 16:01:17 +00:00
" FROM projections.project_members3 AS members" +
" WHERE members.owner_removed = $5 AND members.user_owner_removed = $6" +
2021-12-14 07:19:02 +00:00
" UNION ALL " +
"SELECT members.user_id" +
", members.roles" +
", members.creation_date" +
", members.change_date" +
", members.sequence" +
", members.resource_owner" +
2022-03-29 09:53:19 +00:00
", members.instance_id" +
2022-08-31 07:52:43 +00:00
", NULL::TEXT AS org_id" +
", NULL::TEXT AS id" +
2021-12-14 07:19:02 +00:00
", members.project_id" +
", members.grant_id" +
2022-11-30 16:01:17 +00:00
" FROM projections.project_grant_members3 AS members" +
" WHERE members.granted_org_removed = $7 AND members.owner_removed = $8 AND members.user_owner_removed = $9" +
2021-12-14 07:19:02 +00:00
") AS memberships" +
2022-11-30 16:01:17 +00:00
" LEFT JOIN projections.projects3 ON memberships.project_id = projections.projects3.id AND memberships.instance_id = projections.projects3.instance_id" +
2023-09-07 04:54:51 +00:00
" LEFT JOIN projections.orgs1 ON memberships.org_id = projections.orgs1.id AND memberships.instance_id = projections.orgs1.instance_id" +
2023-02-27 21:36:43 +00:00
" LEFT JOIN projections.project_grants3 ON memberships.grant_id = projections.project_grants3.grant_id AND memberships.instance_id = projections.project_grants3.instance_id" +
` AS OF SYSTEM TIME '-1 ms' ` )
2021-12-14 07:19:02 +00:00
membershipCols = [ ] string {
"user_id" ,
"roles" ,
"creation_date" ,
"change_date" ,
"sequence" ,
"resource_owner" ,
"org_id" ,
2022-03-24 16:21:34 +00:00
"instance_id" ,
2021-12-14 07:19:02 +00:00
"project_id" ,
"grant_id" ,
2022-07-27 07:55:44 +00:00
"granted_org_id" ,
2021-12-16 13:25:38 +00:00
"name" , //project name
"name" , //org name
2021-12-14 07:19:02 +00:00
"count" ,
}
)
func Test_MembershipPrepares ( t * testing . T ) {
type want struct {
sqlExpectations sqlExpectation
err checkErr
}
tests := [ ] struct {
name string
prepare interface { }
want want
object interface { }
} {
{
name : "prepareMembershipsQuery no result" ,
2022-11-30 16:01:17 +00:00
prepare : prepareMembershipWrapper ( false ) ,
2021-12-14 07:19:02 +00:00
want : want {
sqlExpectations : mockQueries (
membershipsStmt ,
nil ,
nil ,
) ,
} ,
object : & Memberships { Memberships : [ ] * Membership { } } ,
} ,
{
2021-12-16 13:25:38 +00:00
name : "prepareMembershipsQuery one org member" ,
2022-11-30 16:01:17 +00:00
prepare : prepareMembershipWrapper ( false ) ,
2021-12-14 07:19:02 +00:00
want : want {
sqlExpectations : mockQueries (
membershipsStmt ,
membershipCols ,
[ ] [ ] driver . Value {
{
"user-id" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
testNow ,
testNow ,
uint64 ( 20211202 ) ,
"ro" ,
"org-id" ,
nil ,
nil ,
nil ,
nil ,
2022-07-27 07:55:44 +00:00
nil ,
2021-12-16 13:25:38 +00:00
"org-name" ,
2021-12-14 07:19:02 +00:00
} ,
} ,
) ,
} ,
object : & Memberships {
SearchResponse : SearchResponse {
Count : 1 ,
} ,
Memberships : [ ] * Membership {
{
UserID : "user-id" ,
2022-08-31 07:52:43 +00:00
Roles : database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211202 ,
ResourceOwner : "ro" ,
2021-12-16 13:25:38 +00:00
Org : & OrgMembership { OrgID : "org-id" , Name : "org-name" } ,
2021-12-14 07:19:02 +00:00
} ,
} ,
} ,
} ,
{
2022-03-24 16:21:34 +00:00
name : "prepareMembershipsQuery one instance member" ,
2022-11-30 16:01:17 +00:00
prepare : prepareMembershipWrapper ( false ) ,
2021-12-14 07:19:02 +00:00
want : want {
sqlExpectations : mockQueries (
membershipsStmt ,
membershipCols ,
[ ] [ ] driver . Value {
{
"user-id" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
testNow ,
testNow ,
uint64 ( 20211202 ) ,
"ro" ,
nil ,
"iam-id" ,
nil ,
nil ,
nil ,
nil ,
2022-07-27 07:55:44 +00:00
nil ,
2021-12-14 07:19:02 +00:00
} ,
} ,
) ,
} ,
object : & Memberships {
SearchResponse : SearchResponse {
Count : 1 ,
} ,
Memberships : [ ] * Membership {
{
UserID : "user-id" ,
2022-08-31 07:52:43 +00:00
Roles : database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211202 ,
ResourceOwner : "ro" ,
2021-12-16 13:25:38 +00:00
IAM : & IAMMembership { IAMID : "iam-id" , Name : "iam-id" } ,
2021-12-14 07:19:02 +00:00
} ,
} ,
} ,
} ,
{
2021-12-16 13:25:38 +00:00
name : "prepareMembershipsQuery one project member" ,
2022-11-30 16:01:17 +00:00
prepare : prepareMembershipWrapper ( false ) ,
2021-12-14 07:19:02 +00:00
want : want {
sqlExpectations : mockQueries (
membershipsStmt ,
membershipCols ,
[ ] [ ] driver . Value {
{
"user-id" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
testNow ,
testNow ,
uint64 ( 20211202 ) ,
"ro" ,
nil ,
nil ,
"project-id" ,
nil ,
2022-07-27 07:55:44 +00:00
nil ,
2021-12-16 13:25:38 +00:00
"project-name" ,
2021-12-14 07:19:02 +00:00
nil ,
} ,
} ,
) ,
} ,
object : & Memberships {
SearchResponse : SearchResponse {
Count : 1 ,
} ,
Memberships : [ ] * Membership {
{
UserID : "user-id" ,
2022-08-31 07:52:43 +00:00
Roles : database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211202 ,
ResourceOwner : "ro" ,
2021-12-16 13:25:38 +00:00
Project : & ProjectMembership { ProjectID : "project-id" , Name : "project-name" } ,
2021-12-14 07:19:02 +00:00
} ,
} ,
} ,
} ,
{
2021-12-16 13:25:38 +00:00
name : "prepareMembershipsQuery one project grant member" ,
2022-11-30 16:01:17 +00:00
prepare : prepareMembershipWrapper ( false ) ,
2021-12-14 07:19:02 +00:00
want : want {
sqlExpectations : mockQueries (
membershipsStmt ,
membershipCols ,
[ ] [ ] driver . Value {
{
"user-id" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
testNow ,
testNow ,
uint64 ( 20211202 ) ,
"ro" ,
nil ,
nil ,
"project-id" ,
"grant-id" ,
2022-07-27 07:55:44 +00:00
"granted-org-id" ,
2021-12-16 13:25:38 +00:00
"project-name" ,
2021-12-14 07:19:02 +00:00
nil ,
} ,
} ,
) ,
} ,
object : & Memberships {
SearchResponse : SearchResponse {
Count : 1 ,
} ,
Memberships : [ ] * Membership {
{
UserID : "user-id" ,
2022-08-31 07:52:43 +00:00
Roles : database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211202 ,
ResourceOwner : "ro" ,
ProjectGrant : & ProjectGrantMembership {
2022-07-27 07:55:44 +00:00
GrantID : "grant-id" ,
ProjectID : "project-id" ,
ProjectName : "project-name" ,
GrantedOrgID : "granted-org-id" ,
2021-12-14 07:19:02 +00:00
} ,
} ,
} ,
} ,
} ,
{
name : "prepareMembershipsQuery one for each member type" ,
2022-11-30 16:01:17 +00:00
prepare : prepareMembershipWrapper ( false ) ,
2021-12-14 07:19:02 +00:00
want : want {
sqlExpectations : mockQueries (
membershipsStmt ,
membershipCols ,
[ ] [ ] driver . Value {
{
"user-id" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
testNow ,
testNow ,
uint64 ( 20211202 ) ,
"ro" ,
"org-id" ,
nil ,
nil ,
nil ,
nil ,
2022-07-27 07:55:44 +00:00
nil ,
2021-12-16 13:25:38 +00:00
"org-name" ,
2021-12-14 07:19:02 +00:00
} ,
{
"user-id" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
testNow ,
testNow ,
uint64 ( 20211202 ) ,
"ro" ,
nil ,
"iam-id" ,
nil ,
nil ,
2021-12-16 13:25:38 +00:00
nil ,
2021-12-14 07:19:02 +00:00
nil ,
2022-07-27 07:55:44 +00:00
nil ,
2021-12-14 07:19:02 +00:00
} ,
{
"user-id" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
testNow ,
testNow ,
uint64 ( 20211202 ) ,
"ro" ,
nil ,
nil ,
"project-id" ,
nil ,
2022-07-27 07:55:44 +00:00
nil ,
2021-12-16 13:25:38 +00:00
"project-name" ,
2021-12-14 07:19:02 +00:00
nil ,
} ,
{
"user-id" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
testNow ,
testNow ,
uint64 ( 20211202 ) ,
"ro" ,
nil ,
nil ,
"project-id" ,
"grant-id" ,
2022-07-27 07:55:44 +00:00
"granted-org-id" ,
2021-12-16 13:25:38 +00:00
"project-name" ,
2021-12-14 07:19:02 +00:00
nil ,
} ,
} ,
) ,
} ,
object : & Memberships {
SearchResponse : SearchResponse {
Count : 4 ,
} ,
Memberships : [ ] * Membership {
{
UserID : "user-id" ,
2022-08-31 07:52:43 +00:00
Roles : database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211202 ,
ResourceOwner : "ro" ,
2021-12-16 13:25:38 +00:00
Org : & OrgMembership { OrgID : "org-id" , Name : "org-name" } ,
2021-12-14 07:19:02 +00:00
} ,
{
UserID : "user-id" ,
2022-08-31 07:52:43 +00:00
Roles : database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211202 ,
ResourceOwner : "ro" ,
2021-12-16 13:25:38 +00:00
IAM : & IAMMembership { IAMID : "iam-id" , Name : "iam-id" } ,
2021-12-14 07:19:02 +00:00
} ,
{
UserID : "user-id" ,
2022-08-31 07:52:43 +00:00
Roles : database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211202 ,
ResourceOwner : "ro" ,
2021-12-16 13:25:38 +00:00
Project : & ProjectMembership { ProjectID : "project-id" , Name : "project-name" } ,
2021-12-14 07:19:02 +00:00
} ,
{
UserID : "user-id" ,
2022-08-31 07:52:43 +00:00
Roles : database . StringArray { "role1" , "role2" } ,
2021-12-14 07:19:02 +00:00
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211202 ,
ResourceOwner : "ro" ,
ProjectGrant : & ProjectGrantMembership {
2022-07-27 07:55:44 +00:00
ProjectID : "project-id" ,
GrantID : "grant-id" ,
ProjectName : "project-name" ,
GrantedOrgID : "granted-org-id" ,
2021-12-14 07:19:02 +00:00
} ,
} ,
} ,
} ,
} ,
{
name : "prepareMembershipsQuery sql err" ,
2022-11-30 16:01:17 +00:00
prepare : prepareMembershipWrapper ( false ) ,
2021-12-14 07:19:02 +00:00
want : want {
sqlExpectations : mockQueryErr (
membershipsStmt ,
sql . ErrConnDone ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errors . Is ( err , sql . ErrConnDone ) {
return fmt . Errorf ( "err should be sql.ErrConnDone got: %w" , err ) , false
}
return nil , true
} ,
} ,
2023-08-22 10:49:22 +00:00
object : ( * Memberships ) ( nil ) ,
2021-12-14 07:19:02 +00:00
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
2023-02-27 21:36:43 +00:00
assertPrepare ( t , tt . prepare , tt . object , tt . want . sqlExpectations , tt . want . err , defaultPrepareArgs ... )
2021-12-14 07:19:02 +00:00
} )
}
}
2022-11-30 16:01:17 +00:00
2023-02-27 21:36:43 +00:00
func prepareMembershipWrapper ( withOwnerRemoved bool ) func ( ctx context . Context , db prepareDatabase ) ( sq . SelectBuilder , func ( * sql . Rows ) ( * Memberships , error ) ) {
return func ( ctx context . Context , db prepareDatabase ) ( sq . SelectBuilder , func ( * sql . Rows ) ( * Memberships , error ) ) {
builder , _ , fun := prepareMembershipsQuery ( ctx , db , withOwnerRemoved )
2022-11-30 16:01:17 +00:00
return builder , fun
}
}