fix: adding code to test ListUsers with and without permission_check_v2 flag set (#9383)

# Which Problems Are Solved

Enhancing `v2/ListUsers()` tests by adding code to run all test with and
without `permission_check_v2` flag set

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/9356

---------

Co-authored-by: Iraq Jaber <IraqJaber@gmail.com>
This commit is contained in:
Iraq 2025-02-24 16:29:51 +00:00 committed by GitHub
parent 70234289cf
commit f2e82d57ac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 645 additions and 355 deletions

View File

@ -112,9 +112,6 @@ func (s *Server) getClaimedUserIDsOfOrgDomain(ctx context.Context, orgDomain str
if err != nil { if err != nil {
return nil, err return nil, err
} }
if err != nil {
return nil, err
}
userIDs := make([]string, len(users.Users)) userIDs := make([]string, len(users.Users))
for i, user := range users.Users { for i, user := range users.Users {
userIDs[i] = user.ID userIDs[i] = user.ID

View File

@ -4,6 +4,7 @@ package user_test
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"slices" "slices"
"testing" "testing"
@ -16,11 +17,61 @@ import (
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
"github.com/zitadel/zitadel/pkg/grpc/feature/v2"
"github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/object/v2"
"github.com/zitadel/zitadel/pkg/grpc/session/v2" "github.com/zitadel/zitadel/pkg/grpc/session/v2"
"github.com/zitadel/zitadel/pkg/grpc/user/v2" "github.com/zitadel/zitadel/pkg/grpc/user/v2"
) )
var (
permissionCheckV2SetFlagInital bool
permissionCheckV2SetFlag bool
)
type permissionCheckV2SettingsStruct struct {
TestNamePrependString string
SetFlag bool
}
var permissionCheckV2Settings []permissionCheckV2SettingsStruct = []permissionCheckV2SettingsStruct{
{
SetFlag: false,
TestNamePrependString: "permission_check_v2 IS NOT SET" + " ",
},
{
SetFlag: true,
TestNamePrependString: "permission_check_v2 IS SET" + " ",
},
}
func setPermissionCheckV2Flag(t *testing.T, setFlag bool) {
if permissionCheckV2SetFlagInital && permissionCheckV2SetFlag == setFlag {
return
}
_, err := Instance.Client.FeatureV2.SetInstanceFeatures(IamCTX, &feature.SetInstanceFeaturesRequest{
PermissionCheckV2: &setFlag,
})
require.NoError(t, err)
var flagSet bool
for i := 0; !flagSet || i < 6; i++ {
res, err := Instance.Client.FeatureV2.GetInstanceFeatures(IamCTX, &feature.GetInstanceFeaturesRequest{})
require.NoError(t, err)
if res.PermissionCheckV2.Enabled == setFlag {
flagSet = true
continue
}
time.Sleep(10 * time.Second)
}
if !flagSet {
require.NoError(t, errors.New("unable to set permission_check_v2 flag"))
}
permissionCheckV2SetFlagInital = true
permissionCheckV2SetFlag = setFlag
}
func TestServer_GetUserByID(t *testing.T) { func TestServer_GetUserByID(t *testing.T) {
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg-%s", gofakeit.AppName()), gofakeit.Email()) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg-%s", gofakeit.AppName()), gofakeit.Email())
type args struct { type args struct {
@ -372,6 +423,11 @@ func createUser(ctx context.Context, orgID string, passwordChangeRequired bool)
} }
func TestServer_ListUsers(t *testing.T) { func TestServer_ListUsers(t *testing.T) {
defer func() {
_, err := Instance.Client.FeatureV2.ResetInstanceFeatures(IamCTX, &feature.ResetInstanceFeaturesRequest{})
require.NoError(t, err)
}()
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg-%s", gofakeit.AppName()), gofakeit.Email()) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg-%s", gofakeit.AppName()), gofakeit.Email())
type args struct { type args struct {
ctx context.Context ctx context.Context
@ -470,13 +526,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user by id, ok", name: "list user by id, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, false) info := createUser(ctx, orgResp.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserIDsQuery([]string{info.UserID})) request.Queries = append(request.Queries, InUserIDsQuery([]string{info.UserID}))
return []userAttr{info} return []userAttr{info}
}, },
@ -516,13 +570,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user by id, passwordChangeRequired, ok", name: "list user by id, passwordChangeRequired, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, true) info := createUser(ctx, orgResp.OrganizationId, true)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserIDsQuery([]string{info.UserID})) request.Queries = append(request.Queries, InUserIDsQuery([]string{info.UserID}))
return []userAttr{info} return []userAttr{info}
}, },
@ -564,13 +616,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user by id multiple, ok", name: "list user by id multiple, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
infos := createUsers(ctx, orgResp.OrganizationId, 3, false) infos := createUsers(ctx, orgResp.OrganizationId, 3, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserIDsQuery(infos.userIDs())) request.Queries = append(request.Queries, InUserIDsQuery(infos.userIDs()))
return infos return infos
}, },
@ -623,7 +673,8 @@ func TestServer_ListUsers(t *testing.T) {
}, },
}, },
}, },
}, { },
{
State: user.UserState_USER_STATE_ACTIVE, State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{ Type: &user.User_Human{
Human: &user.HumanUser{ Human: &user.HumanUser{
@ -651,13 +702,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user by username, ok", name: "list user by username, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, false) info := createUser(ctx, orgResp.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, UsernameQuery(info.Username)) request.Queries = append(request.Queries, UsernameQuery(info.Username))
return []userAttr{info} return []userAttr{info}
}, },
@ -697,13 +746,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user in emails, ok", name: "list user in emails, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, false) info := createUser(ctx, orgResp.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserEmailsQuery([]string{info.Username})) request.Queries = append(request.Queries, InUserEmailsQuery([]string{info.Username}))
return []userAttr{info} return []userAttr{info}
}, },
@ -741,189 +788,12 @@ func TestServer_ListUsers(t *testing.T) {
}, },
{ {
name: "list user in emails multiple, ok", name: "list user in emails multiple, ok",
args: args{
IamCTX,
&user.ListUsersRequest{
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
infos := createUsers(ctx, orgResp.OrganizationId, 3, false)
request.Queries = append(request.Queries, InUserEmailsQuery(infos.emails()))
return infos
},
},
want: &user.ListUsersResponse{
Details: &object.ListDetails{
TotalResult: 3,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{
{
State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{
Human: &user.HumanUser{
Profile: &user.HumanProfile{
GivenName: "Mickey",
FamilyName: "Mouse",
NickName: gu.Ptr("Mickey"),
DisplayName: gu.Ptr("Mickey Mouse"),
PreferredLanguage: gu.Ptr("nl"),
Gender: user.Gender_GENDER_MALE.Enum(),
},
Email: &user.HumanEmail{
IsVerified: true,
},
Phone: &user.HumanPhone{
IsVerified: true,
},
},
},
}, {
State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{
Human: &user.HumanUser{
Profile: &user.HumanProfile{
GivenName: "Mickey",
FamilyName: "Mouse",
NickName: gu.Ptr("Mickey"),
DisplayName: gu.Ptr("Mickey Mouse"),
PreferredLanguage: gu.Ptr("nl"),
Gender: user.Gender_GENDER_MALE.Enum(),
},
Email: &user.HumanEmail{
IsVerified: true,
},
Phone: &user.HumanPhone{
IsVerified: true,
},
},
},
}, {
State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{
Human: &user.HumanUser{
Profile: &user.HumanProfile{
GivenName: "Mickey",
FamilyName: "Mouse",
NickName: gu.Ptr("Mickey"),
DisplayName: gu.Ptr("Mickey Mouse"),
PreferredLanguage: gu.Ptr("nl"),
Gender: user.Gender_GENDER_MALE.Enum(),
},
Email: &user.HumanEmail{
IsVerified: true,
},
Phone: &user.HumanPhone{
IsVerified: true,
},
},
},
},
},
},
},
{
name: "list user in emails no found, ok",
args: args{
IamCTX,
&user.ListUsersRequest{Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
InUserEmailsQuery([]string{"notfound"}),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
return []userAttr{}
},
},
want: &user.ListUsersResponse{
Details: &object.ListDetails{
TotalResult: 0,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{},
},
},
{
name: "list user phone, ok",
args: args{
IamCTX,
&user.ListUsersRequest{
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, false)
request.Queries = append(request.Queries, PhoneQuery(info.Phone))
return []userAttr{info}
},
},
want: &user.ListUsersResponse{
Details: &object.ListDetails{
TotalResult: 1,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{
{
State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{
Human: &user.HumanUser{
Profile: &user.HumanProfile{
GivenName: "Mickey",
FamilyName: "Mouse",
NickName: gu.Ptr("Mickey"),
DisplayName: gu.Ptr("Mickey Mouse"),
PreferredLanguage: gu.Ptr("nl"),
Gender: user.Gender_GENDER_MALE.Enum(),
},
Email: &user.HumanEmail{
IsVerified: true,
},
Phone: &user.HumanPhone{
IsVerified: true,
},
},
},
},
},
},
},
{
name: "list user in emails no found, ok",
args: args{
IamCTX,
&user.ListUsersRequest{Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
InUserEmailsQuery([]string{"notfound"}),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
return []userAttr{}
},
},
want: &user.ListUsersResponse{
Details: &object.ListDetails{
TotalResult: 0,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{},
},
},
{
name: "list user resourceowner multiple, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{}, &user.ListUsersRequest{},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
orgResp := Instance.CreateOrganization(ctx, fmt.Sprintf("ListUsersResourceowner-%s", gofakeit.AppName()), gofakeit.Email())
infos := createUsers(ctx, orgResp.OrganizationId, 3, false) infos := createUsers(ctx, orgResp.OrganizationId, 3, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId)) request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserEmailsQuery(infos.emails())) request.Queries = append(request.Queries, InUserEmailsQuery(infos.emails()))
return infos return infos
@ -1000,12 +870,264 @@ func TestServer_ListUsers(t *testing.T) {
}, },
}, },
}, },
{
name: "list user in emails no found, ok",
args: args{
IamCTX,
&user.ListUsersRequest{
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
InUserEmailsQuery([]string{"notfound"}),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
return []userAttr{}
},
},
want: &user.ListUsersResponse{
Details: &object.ListDetails{
TotalResult: 0,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{},
},
},
{
name: "list user phone, ok",
args: args{
IamCTX,
&user.ListUsersRequest{},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, PhoneQuery(info.Phone))
return []userAttr{info}
},
},
want: &user.ListUsersResponse{
Details: &object.ListDetails{
TotalResult: 1,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{
{
State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{
Human: &user.HumanUser{
Profile: &user.HumanProfile{
GivenName: "Mickey",
FamilyName: "Mouse",
NickName: gu.Ptr("Mickey"),
DisplayName: gu.Ptr("Mickey Mouse"),
PreferredLanguage: gu.Ptr("nl"),
Gender: user.Gender_GENDER_MALE.Enum(),
},
Email: &user.HumanEmail{
IsVerified: true,
},
Phone: &user.HumanPhone{
IsVerified: true,
},
},
},
},
},
},
},
{
name: "list user in emails no found, ok",
args: args{
IamCTX,
&user.ListUsersRequest{
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
InUserEmailsQuery([]string{"notfound"}),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
return []userAttr{}
},
},
want: &user.ListUsersResponse{
Details: &object.ListDetails{
TotalResult: 0,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{},
},
},
{
name: "list user resourceowner multiple, ok",
args: args{
IamCTX,
&user.ListUsersRequest{},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
orgResp := Instance.CreateOrganization(ctx, fmt.Sprintf("ListUsersResourceowner-%s", gofakeit.AppName()), gofakeit.Email())
infos := createUsers(ctx, orgResp.OrganizationId, 3, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserEmailsQuery(infos.emails()))
return infos
},
},
want: &user.ListUsersResponse{
Details: &object.ListDetails{
TotalResult: 3,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{
{
State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{
Human: &user.HumanUser{
Profile: &user.HumanProfile{
GivenName: "Mickey",
FamilyName: "Mouse",
NickName: gu.Ptr("Mickey"),
DisplayName: gu.Ptr("Mickey Mouse"),
PreferredLanguage: gu.Ptr("nl"),
Gender: user.Gender_GENDER_MALE.Enum(),
},
Email: &user.HumanEmail{
IsVerified: true,
},
Phone: &user.HumanPhone{
IsVerified: true,
},
},
},
}, {
State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{
Human: &user.HumanUser{
Profile: &user.HumanProfile{
GivenName: "Mickey",
FamilyName: "Mouse",
NickName: gu.Ptr("Mickey"),
DisplayName: gu.Ptr("Mickey Mouse"),
PreferredLanguage: gu.Ptr("nl"),
Gender: user.Gender_GENDER_MALE.Enum(),
},
Email: &user.HumanEmail{
IsVerified: true,
},
Phone: &user.HumanPhone{
IsVerified: true,
},
},
},
}, {
State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{
Human: &user.HumanUser{
Profile: &user.HumanProfile{
GivenName: "Mickey",
FamilyName: "Mouse",
NickName: gu.Ptr("Mickey"),
DisplayName: gu.Ptr("Mickey Mouse"),
PreferredLanguage: gu.Ptr("nl"),
Gender: user.Gender_GENDER_MALE.Enum(),
},
Email: &user.HumanEmail{
IsVerified: true,
},
Phone: &user.HumanPhone{
IsVerified: true,
},
},
},
},
},
},
},
{
name: "list user with org query",
args: args{
IamCTX,
&user.ListUsersRequest{},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
orgRespForOrgTests := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg-%s", gofakeit.AppName()), gofakeit.Email())
info := createUser(ctx, orgRespForOrgTests.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgRespForOrgTests.OrganizationId))
return []userAttr{info, {}}
},
},
want: &user.ListUsersResponse{
Details: &object.ListDetails{
TotalResult: 2,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{
{
State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{
Human: &user.HumanUser{
Profile: &user.HumanProfile{
GivenName: "Mickey",
FamilyName: "Mouse",
NickName: gu.Ptr("Mickey"),
DisplayName: gu.Ptr("Mickey Mouse"),
PreferredLanguage: gu.Ptr("nl"),
Gender: user.Gender_GENDER_MALE.Enum(),
},
Email: &user.HumanEmail{
IsVerified: true,
},
Phone: &user.HumanPhone{
IsVerified: true,
},
},
},
},
// this is the admin of the org craated in Instance.CreateOrganization()
nil,
},
},
},
{
name: "list user with wrong org query",
args: args{
IamCTX,
&user.ListUsersRequest{},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
orgRespForOrgTests := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg-%s", gofakeit.AppName()), gofakeit.Email())
orgRespForOrgTests2 := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg-%s", gofakeit.AppName()), gofakeit.Email())
// info := createUser(ctx, orgRespForOrgTests.OrganizationId, false)
createUser(ctx, orgRespForOrgTests.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgRespForOrgTests2.OrganizationId))
return []userAttr{{}}
},
},
want: &user.ListUsersResponse{
Details: &object.ListDetails{
TotalResult: 0,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{
// this is the admin of the org craated in Instance.CreateOrganization()
nil,
},
},
},
} }
for _, f := range permissionCheckV2Settings {
f := f
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(f.TestNamePrependString+tt.name, func(t *testing.T) {
setPermissionCheckV2Flag(t, f.SetFlag)
infos := tt.args.dep(IamCTX, tt.args.req) infos := tt.args.dep(IamCTX, tt.args.req)
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tt.args.ctx, time.Minute) retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tt.args.ctx, 10*time.Minute)
require.EventuallyWithT(t, func(ttt *assert.CollectT) { require.EventuallyWithT(t, func(ttt *assert.CollectT) {
got, err := Client.ListUsers(tt.args.ctx, tt.args.req) got, err := Client.ListUsers(tt.args.ctx, tt.args.req)
if tt.wantErr { if tt.wantErr {
@ -1016,13 +1138,14 @@ func TestServer_ListUsers(t *testing.T) {
// always only give back dependency infos which are required for the response // always only give back dependency infos which are required for the response
require.Len(ttt, tt.want.Result, len(infos)) require.Len(ttt, tt.want.Result, len(infos))
// always first check length, otherwise its failed anyway
if assert.Len(ttt, got.Result, len(tt.want.Result)) { if assert.Len(ttt, got.Result, len(tt.want.Result)) {
// totalResult is unrelated to the tests here so gets carried over, can vary from the count of results due to permissions
tt.want.Details.TotalResult = got.Details.TotalResult tt.want.Details.TotalResult = got.Details.TotalResult
// fill in userid and username as it is generated // fill in userid and username as it is generated
for i := range infos { for i := range infos {
if tt.want.Result[i] == nil {
continue
}
tt.want.Result[i].UserId = infos[i].UserID tt.want.Result[i].UserId = infos[i].UserID
tt.want.Result[i].Username = infos[i].Username tt.want.Result[i].Username = infos[i].Username
tt.want.Result[i].PreferredLoginName = infos[i].Username tt.want.Result[i].PreferredLoginName = infos[i].Username
@ -1037,6 +1160,9 @@ func TestServer_ListUsers(t *testing.T) {
tt.want.Result[i].Details = infos[i].Details tt.want.Result[i].Details = infos[i].Details
} }
for i := range tt.want.Result { for i := range tt.want.Result {
if tt.want.Result[i] == nil {
continue
}
assert.EqualExportedValues(ttt, got.Result[i], tt.want.Result[i]) assert.EqualExportedValues(ttt, got.Result[i], tt.want.Result[i])
} }
} }
@ -1045,9 +1171,11 @@ func TestServer_ListUsers(t *testing.T) {
}) })
} }
} }
}
func InUserIDsQuery(ids []string) *user.SearchQuery { func InUserIDsQuery(ids []string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_InUserIdsQuery{ return &user.SearchQuery{
Query: &user.SearchQuery_InUserIdsQuery{
InUserIdsQuery: &user.InUserIDQuery{ InUserIdsQuery: &user.InUserIDQuery{
UserIds: ids, UserIds: ids,
}, },
@ -1056,7 +1184,8 @@ func InUserIDsQuery(ids []string) *user.SearchQuery {
} }
func InUserEmailsQuery(emails []string) *user.SearchQuery { func InUserEmailsQuery(emails []string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_InUserEmailsQuery{ return &user.SearchQuery{
Query: &user.SearchQuery_InUserEmailsQuery{
InUserEmailsQuery: &user.InUserEmailsQuery{ InUserEmailsQuery: &user.InUserEmailsQuery{
UserEmails: emails, UserEmails: emails,
}, },
@ -1065,7 +1194,8 @@ func InUserEmailsQuery(emails []string) *user.SearchQuery {
} }
func PhoneQuery(number string) *user.SearchQuery { func PhoneQuery(number string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_PhoneQuery{ return &user.SearchQuery{
Query: &user.SearchQuery_PhoneQuery{
PhoneQuery: &user.PhoneQuery{ PhoneQuery: &user.PhoneQuery{
Number: number, Number: number,
}, },
@ -1074,7 +1204,8 @@ func PhoneQuery(number string) *user.SearchQuery {
} }
func UsernameQuery(username string) *user.SearchQuery { func UsernameQuery(username string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_UserNameQuery{ return &user.SearchQuery{
Query: &user.SearchQuery_UserNameQuery{
UserNameQuery: &user.UserNameQuery{ UserNameQuery: &user.UserNameQuery{
UserName: username, UserName: username,
}, },
@ -1083,7 +1214,8 @@ func UsernameQuery(username string) *user.SearchQuery {
} }
func OrganizationIdQuery(resourceowner string) *user.SearchQuery { func OrganizationIdQuery(resourceowner string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_OrganizationIdQuery{ return &user.SearchQuery{
Query: &user.SearchQuery_OrganizationIdQuery{
OrganizationIdQuery: &user.OrganizationIdQuery{ OrganizationIdQuery: &user.OrganizationIdQuery{
OrganizationId: resourceowner, OrganizationId: resourceowner,
}, },

View File

@ -4,6 +4,7 @@ package user_test
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"slices" "slices"
"testing" "testing"
@ -16,6 +17,7 @@ import (
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"github.com/zitadel/zitadel/internal/integration" "github.com/zitadel/zitadel/internal/integration"
"github.com/zitadel/zitadel/pkg/grpc/feature/v2"
"github.com/zitadel/zitadel/pkg/grpc/object/v2" "github.com/zitadel/zitadel/pkg/grpc/object/v2"
object_v2beta "github.com/zitadel/zitadel/pkg/grpc/object/v2beta" object_v2beta "github.com/zitadel/zitadel/pkg/grpc/object/v2beta"
"github.com/zitadel/zitadel/pkg/grpc/session/v2" "github.com/zitadel/zitadel/pkg/grpc/session/v2"
@ -30,6 +32,55 @@ func detailsV2ToV2beta(obj *object.Details) *object_v2beta.Details {
} }
} }
var (
permissionCheckV2SetFlagInital bool
permissionCheckV2SetFlag bool
)
type permissionCheckV2SettingsStruct struct {
TestNamePrependString string
SetFlag bool
}
var permissionCheckV2Settings []permissionCheckV2SettingsStruct = []permissionCheckV2SettingsStruct{
{
SetFlag: false,
TestNamePrependString: "permission_check_v2 IS NOT SET" + " ",
},
{
SetFlag: true,
TestNamePrependString: "permission_check_v2 IS SET" + " ",
},
}
func setPermissionCheckV2Flag(t *testing.T, setFlag bool) {
if permissionCheckV2SetFlagInital && permissionCheckV2SetFlag == setFlag {
return
}
_, err := Instance.Client.FeatureV2.SetInstanceFeatures(IamCTX, &feature.SetInstanceFeaturesRequest{
PermissionCheckV2: &setFlag,
})
require.NoError(t, err)
var flagSet bool
for i := 0; !flagSet || i < 6; i++ {
res, err := Instance.Client.FeatureV2.GetInstanceFeatures(IamCTX, &feature.GetInstanceFeaturesRequest{})
require.NoError(t, err)
if res.PermissionCheckV2.Enabled == setFlag {
flagSet = true
continue
}
time.Sleep(10 * time.Second)
}
if !flagSet {
require.NoError(t, errors.New("unable to set permission_check_v2 flag"))
}
permissionCheckV2SetFlagInital = true
permissionCheckV2SetFlag = setFlag
}
func TestServer_GetUserByID(t *testing.T) { func TestServer_GetUserByID(t *testing.T) {
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg-%s", gofakeit.AppName()), gofakeit.Email()) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg-%s", gofakeit.AppName()), gofakeit.Email())
type args struct { type args struct {
@ -382,6 +433,11 @@ func createUser(ctx context.Context, orgID string, passwordChangeRequired bool)
} }
func TestServer_ListUsers(t *testing.T) { func TestServer_ListUsers(t *testing.T) {
defer func() {
_, err := Instance.Client.FeatureV2.ResetInstanceFeatures(IamCTX, &feature.ResetInstanceFeaturesRequest{})
require.NoError(t, err)
}()
orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg-%s", gofakeit.AppName()), gofakeit.Email()) orgResp := Instance.CreateOrganization(IamCTX, fmt.Sprintf("ListUsersOrg-%s", gofakeit.AppName()), gofakeit.Email())
type args struct { type args struct {
ctx context.Context ctx context.Context
@ -480,13 +536,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user by id, ok", name: "list user by id, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, false) info := createUser(ctx, orgResp.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserIDsQuery([]string{info.UserID})) request.Queries = append(request.Queries, InUserIDsQuery([]string{info.UserID}))
return []userAttr{info} return []userAttr{info}
}, },
@ -526,13 +580,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user by id, passwordChangeRequired, ok", name: "list user by id, passwordChangeRequired, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, true) info := createUser(ctx, orgResp.OrganizationId, true)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserIDsQuery([]string{info.UserID})) request.Queries = append(request.Queries, InUserIDsQuery([]string{info.UserID}))
return []userAttr{info} return []userAttr{info}
}, },
@ -574,13 +626,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user by id multiple, ok", name: "list user by id multiple, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
infos := createUsers(ctx, orgResp.OrganizationId, 3, false) infos := createUsers(ctx, orgResp.OrganizationId, 3, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserIDsQuery(infos.userIDs())) request.Queries = append(request.Queries, InUserIDsQuery(infos.userIDs()))
return infos return infos
}, },
@ -612,7 +662,8 @@ func TestServer_ListUsers(t *testing.T) {
}, },
}, },
}, },
}, { },
{
State: user.UserState_USER_STATE_ACTIVE, State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{ Type: &user.User_Human{
Human: &user.HumanUser{ Human: &user.HumanUser{
@ -632,7 +683,8 @@ func TestServer_ListUsers(t *testing.T) {
}, },
}, },
}, },
}, { },
{
State: user.UserState_USER_STATE_ACTIVE, State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{ Type: &user.User_Human{
Human: &user.HumanUser{ Human: &user.HumanUser{
@ -660,13 +712,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user by username, ok", name: "list user by username, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, false) info := createUser(ctx, orgResp.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, UsernameQuery(info.Username)) request.Queries = append(request.Queries, UsernameQuery(info.Username))
return []userAttr{info} return []userAttr{info}
}, },
@ -713,6 +763,7 @@ func TestServer_ListUsers(t *testing.T) {
}, },
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, false) info := createUser(ctx, orgResp.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, InUserEmailsQuery([]string{info.Username})) request.Queries = append(request.Queries, InUserEmailsQuery([]string{info.Username}))
return []userAttr{info} return []userAttr{info}
}, },
@ -752,13 +803,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user in emails multiple, ok", name: "list user in emails multiple, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
infos := createUsers(ctx, orgResp.OrganizationId, 3, false) infos := createUsers(ctx, orgResp.OrganizationId, 3, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserEmailsQuery(infos.emails())) request.Queries = append(request.Queries, InUserEmailsQuery(infos.emails()))
return infos return infos
}, },
@ -838,7 +887,8 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user in emails no found, ok", name: "list user in emails no found, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{Queries: []*user.SearchQuery{ &user.ListUsersRequest{
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId), OrganizationIdQuery(orgResp.OrganizationId),
InUserEmailsQuery([]string{"notfound"}), InUserEmailsQuery([]string{"notfound"}),
}, },
@ -860,13 +910,11 @@ func TestServer_ListUsers(t *testing.T) {
name: "list user phone, ok", name: "list user phone, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.ListUsersRequest{ &user.ListUsersRequest{},
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs { func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
info := createUser(ctx, orgResp.OrganizationId, false) info := createUser(ctx, orgResp.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, PhoneQuery(info.Phone)) request.Queries = append(request.Queries, PhoneQuery(info.Phone))
return []userAttr{info} return []userAttr{info}
}, },
@ -902,6 +950,29 @@ func TestServer_ListUsers(t *testing.T) {
}, },
}, },
}, },
{
name: "list user in emails no found, ok",
args: args{
IamCTX,
&user.ListUsersRequest{
Queries: []*user.SearchQuery{
OrganizationIdQuery(orgResp.OrganizationId),
InUserEmailsQuery([]string{"notfound"}),
},
},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
return []userAttr{}
},
},
want: &user.ListUsersResponse{
Details: &object_v2beta.ListDetails{
TotalResult: 0,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{},
},
},
{ {
name: "list user resourceowner multiple, ok", name: "list user resourceowner multiple, ok",
args: args{ args: args{
@ -911,6 +982,7 @@ func TestServer_ListUsers(t *testing.T) {
orgResp := Instance.CreateOrganization(ctx, fmt.Sprintf("ListUsersResourceowner-%s", gofakeit.AppName()), gofakeit.Email()) orgResp := Instance.CreateOrganization(ctx, fmt.Sprintf("ListUsersResourceowner-%s", gofakeit.AppName()), gofakeit.Email())
infos := createUsers(ctx, orgResp.OrganizationId, 3, false) infos := createUsers(ctx, orgResp.OrganizationId, 3, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId)) request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserEmailsQuery(infos.emails())) request.Queries = append(request.Queries, InUserEmailsQuery(infos.emails()))
return infos return infos
@ -987,12 +1059,89 @@ func TestServer_ListUsers(t *testing.T) {
}, },
}, },
}, },
{
name: "list user with org query",
args: args{
IamCTX,
&user.ListUsersRequest{},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
orgRespForOrgTests := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg-%s", gofakeit.AppName()), gofakeit.Email())
info := createUser(ctx, orgRespForOrgTests.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgRespForOrgTests.OrganizationId))
return []userAttr{info, {}}
},
},
want: &user.ListUsersResponse{
Details: &object_v2beta.ListDetails{
TotalResult: 2,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{
{
State: user.UserState_USER_STATE_ACTIVE,
Type: &user.User_Human{
Human: &user.HumanUser{
Profile: &user.HumanProfile{
GivenName: "Mickey",
FamilyName: "Mouse",
NickName: gu.Ptr("Mickey"),
DisplayName: gu.Ptr("Mickey Mouse"),
PreferredLanguage: gu.Ptr("nl"),
Gender: user.Gender_GENDER_MALE.Enum(),
},
Email: &user.HumanEmail{
IsVerified: true,
},
Phone: &user.HumanPhone{
IsVerified: true,
},
},
},
},
// this is the admin of the org craated in Instance.CreateOrganization()
nil,
},
},
},
{
name: "list user with wrong org query",
args: args{
IamCTX,
&user.ListUsersRequest{},
func(ctx context.Context, request *user.ListUsersRequest) userAttrs {
orgRespForOrgTests := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg-%s", gofakeit.AppName()), gofakeit.Email())
orgRespForOrgTests2 := Instance.CreateOrganization(IamCTX, fmt.Sprintf("GetUserByIDOrg-%s", gofakeit.AppName()), gofakeit.Email())
// info := createUser(ctx, orgRespForOrgTests.OrganizationId, false)
createUser(ctx, orgRespForOrgTests.OrganizationId, false)
request.Queries = []*user.SearchQuery{}
request.Queries = append(request.Queries, OrganizationIdQuery(orgRespForOrgTests2.OrganizationId))
return []userAttr{{}}
},
},
want: &user.ListUsersResponse{
Details: &object_v2beta.ListDetails{
TotalResult: 0,
Timestamp: timestamppb.Now(),
},
SortingColumn: 0,
Result: []*user.User{
// this is the admin of the org craated in Instance.CreateOrganization()
nil,
},
},
},
} }
for _, f := range permissionCheckV2Settings {
f := f
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(f.TestNamePrependString+tt.name, func(t *testing.T) {
setPermissionCheckV2Flag(t, f.SetFlag)
infos := tt.args.dep(IamCTX, tt.args.req) infos := tt.args.dep(IamCTX, tt.args.req)
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tt.args.ctx, time.Minute) // retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tt.args.ctx, 10*time.Minute)
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(tt.args.ctx, 20*time.Second)
require.EventuallyWithT(t, func(ttt *assert.CollectT) { require.EventuallyWithT(t, func(ttt *assert.CollectT) {
got, err := Client.ListUsers(tt.args.ctx, tt.args.req) got, err := Client.ListUsers(tt.args.ctx, tt.args.req)
if tt.wantErr { if tt.wantErr {
@ -1010,6 +1159,9 @@ func TestServer_ListUsers(t *testing.T) {
// fill in userid and username as it is generated // fill in userid and username as it is generated
for i := range infos { for i := range infos {
if tt.want.Result[i] == nil {
continue
}
tt.want.Result[i].UserId = infos[i].UserID tt.want.Result[i].UserId = infos[i].UserID
tt.want.Result[i].Username = infos[i].Username tt.want.Result[i].Username = infos[i].Username
tt.want.Result[i].PreferredLoginName = infos[i].Username tt.want.Result[i].PreferredLoginName = infos[i].Username
@ -1024,6 +1176,9 @@ func TestServer_ListUsers(t *testing.T) {
tt.want.Result[i].Details = detailsV2ToV2beta(infos[i].Details) tt.want.Result[i].Details = detailsV2ToV2beta(infos[i].Details)
} }
for i := range tt.want.Result { for i := range tt.want.Result {
if tt.want.Result[i] == nil {
continue
}
assert.EqualExportedValues(ttt, got.Result[i], tt.want.Result[i]) assert.EqualExportedValues(ttt, got.Result[i], tt.want.Result[i])
} }
} }
@ -1032,9 +1187,11 @@ func TestServer_ListUsers(t *testing.T) {
}) })
} }
} }
}
func InUserIDsQuery(ids []string) *user.SearchQuery { func InUserIDsQuery(ids []string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_InUserIdsQuery{ return &user.SearchQuery{
Query: &user.SearchQuery_InUserIdsQuery{
InUserIdsQuery: &user.InUserIDQuery{ InUserIdsQuery: &user.InUserIDQuery{
UserIds: ids, UserIds: ids,
}, },
@ -1043,7 +1200,8 @@ func InUserIDsQuery(ids []string) *user.SearchQuery {
} }
func InUserEmailsQuery(emails []string) *user.SearchQuery { func InUserEmailsQuery(emails []string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_InUserEmailsQuery{ return &user.SearchQuery{
Query: &user.SearchQuery_InUserEmailsQuery{
InUserEmailsQuery: &user.InUserEmailsQuery{ InUserEmailsQuery: &user.InUserEmailsQuery{
UserEmails: emails, UserEmails: emails,
}, },
@ -1052,7 +1210,8 @@ func InUserEmailsQuery(emails []string) *user.SearchQuery {
} }
func PhoneQuery(number string) *user.SearchQuery { func PhoneQuery(number string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_PhoneQuery{ return &user.SearchQuery{
Query: &user.SearchQuery_PhoneQuery{
PhoneQuery: &user.PhoneQuery{ PhoneQuery: &user.PhoneQuery{
Number: number, Number: number,
}, },
@ -1061,7 +1220,8 @@ func PhoneQuery(number string) *user.SearchQuery {
} }
func UsernameQuery(username string) *user.SearchQuery { func UsernameQuery(username string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_UserNameQuery{ return &user.SearchQuery{
Query: &user.SearchQuery_UserNameQuery{
UserNameQuery: &user.UserNameQuery{ UserNameQuery: &user.UserNameQuery{
UserName: username, UserName: username,
}, },
@ -1070,7 +1230,8 @@ func UsernameQuery(username string) *user.SearchQuery {
} }
func OrganizationIdQuery(resourceowner string) *user.SearchQuery { func OrganizationIdQuery(resourceowner string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_OrganizationIdQuery{ return &user.SearchQuery{
Query: &user.SearchQuery_OrganizationIdQuery{
OrganizationIdQuery: &user.OrganizationIdQuery{ OrganizationIdQuery: &user.OrganizationIdQuery{
OrganizationId: resourceowner, OrganizationId: resourceowner,
}, },