fix: add organizationID query for user v2 ListUsers and clean up depeprecated attribute (#7593)

Add organizationID as query for ListUsers and clean up the deprecated Organisation attributes in other queries.

This PR removes the following fields from API requests (user service v2):

organisation from AddHumanUser (deprecated some time ago, organization still exists)
organization from GetUserByID
This commit is contained in:
Stefan Benz 2024-03-21 09:07:00 +01:00 committed by GitHub
parent 7e24a1adbc
commit 319ebe7898
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 217 additions and 143 deletions

View File

@ -44,30 +44,17 @@ func authorize(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo,
func orgIDAndDomainFromRequest(ctx context.Context, req interface{}) (id, domain string) { func orgIDAndDomainFromRequest(ctx context.Context, req interface{}) (id, domain string) {
orgID := grpc_util.GetHeader(ctx, http.ZitadelOrgID) orgID := grpc_util.GetHeader(ctx, http.ZitadelOrgID)
o, ok := req.(OrganizationFromRequest) oz, ok := req.(OrganizationFromRequest)
if !ok { if ok {
return orgID, "" id = oz.OrganizationFromRequest().ID
} domain = oz.OrganizationFromRequest().Domain
id = o.OrganizationFromRequest().ID if id != "" || domain != "" {
domain = o.OrganizationFromRequest().Domain return id, domain
if id != "" || domain != "" { }
return id, domain
}
// check if the deprecated organisation is used.
// to be removed before going GA (https://github.com/zitadel/zitadel/issues/6718)
id = o.OrganisationFromRequest().ID
domain = o.OrganisationFromRequest().Domain
if id != "" || domain != "" {
return id, domain
} }
return orgID, domain return orgID, domain
} }
// Deprecated: will be removed in favor of OrganizationFromRequest (https://github.com/zitadel/zitadel/issues/6718)
type OrganisationFromRequest interface {
OrganisationFromRequest() *Organization
}
type Organization struct { type Organization struct {
ID string ID string
Domain string Domain string
@ -75,5 +62,4 @@ type Organization struct {
type OrganizationFromRequest interface { type OrganizationFromRequest interface {
OrganizationFromRequest() *Organization OrganizationFromRequest() *Organization
OrganisationFromRequest
} }

View File

@ -239,8 +239,8 @@ func userQueryToQuery(query *user.SearchQuery, level uint8) (query.SearchQuery,
return typeQueryToQuery(q.TypeQuery) return typeQueryToQuery(q.TypeQuery)
case *user.SearchQuery_LoginNameQuery: case *user.SearchQuery_LoginNameQuery:
return loginNameQueryToQuery(q.LoginNameQuery) return loginNameQueryToQuery(q.LoginNameQuery)
case *user.SearchQuery_ResourceOwner: case *user.SearchQuery_OrganizationIdQuery:
return resourceOwnerQueryToQuery(q.ResourceOwner) return resourceOwnerQueryToQuery(q.OrganizationIdQuery)
case *user.SearchQuery_InUserIdsQuery: case *user.SearchQuery_InUserIdsQuery:
return inUserIdsQueryToQuery(q.InUserIdsQuery) return inUserIdsQueryToQuery(q.InUserIdsQuery)
case *user.SearchQuery_OrQuery: case *user.SearchQuery_OrQuery:
@ -292,8 +292,8 @@ func loginNameQueryToQuery(q *user.LoginNameQuery) (query.SearchQuery, error) {
return query.NewUserLoginNameExistsQuery(q.LoginName, object.TextMethodToQuery(q.Method)) return query.NewUserLoginNameExistsQuery(q.LoginName, object.TextMethodToQuery(q.Method))
} }
func resourceOwnerQueryToQuery(q *user.ResourceOwnerQuery) (query.SearchQuery, error) { func resourceOwnerQueryToQuery(q *user.OrganizationIdQuery) (query.SearchQuery, error) {
return query.NewUserResourceOwnerSearchQuery(q.OrgID, query.TextEquals) return query.NewUserResourceOwnerSearchQuery(q.OrganizationId, query.TextEquals)
} }
func inUserIdsQueryToQuery(q *user.InUserIDQuery) (query.SearchQuery, error) { func inUserIdsQueryToQuery(q *user.InUserIDQuery) (query.SearchQuery, error) {

View File

@ -37,11 +37,6 @@ func TestServer_GetUserByID(t *testing.T) {
args: args{ args: args{
IamCTX, IamCTX,
&user.GetUserByIDRequest{ &user.GetUserByIDRequest{
Organization: &object.Organization{
Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID,
},
},
UserId: "", UserId: "",
}, },
func(ctx context.Context, username string, request *user.GetUserByIDRequest) error { func(ctx context.Context, username string, request *user.GetUserByIDRequest) error {
@ -55,11 +50,6 @@ func TestServer_GetUserByID(t *testing.T) {
args: args{ args: args{
IamCTX, IamCTX,
&user.GetUserByIDRequest{ &user.GetUserByIDRequest{
Organization: &object.Organization{
Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID,
},
},
UserId: "unknown", UserId: "unknown",
}, },
func(ctx context.Context, username string, request *user.GetUserByIDRequest) error { func(ctx context.Context, username string, request *user.GetUserByIDRequest) error {
@ -72,13 +62,7 @@ func TestServer_GetUserByID(t *testing.T) {
name: "user by ID, ok", name: "user by ID, ok",
args: args{ args: args{
IamCTX, IamCTX,
&user.GetUserByIDRequest{ &user.GetUserByIDRequest{},
Organization: &object.Organization{
Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID,
},
},
},
func(ctx context.Context, username string, request *user.GetUserByIDRequest) error { func(ctx context.Context, username string, request *user.GetUserByIDRequest) error {
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
request.UserId = resp.GetUserId() request.UserId = resp.GetUserId()
@ -172,11 +156,6 @@ func TestServer_GetUserByID_Permission(t *testing.T) {
args: args{ args: args{
SystemCTX, SystemCTX,
&user.GetUserByIDRequest{ &user.GetUserByIDRequest{
Organization: &object.Organization{
Org: &object.Organization_OrgId{
OrgId: newOrg.GetOrganizationId(),
},
},
UserId: newUserID, UserId: newUserID,
}, },
}, },
@ -215,11 +194,6 @@ func TestServer_GetUserByID_Permission(t *testing.T) {
args: args{ args: args{
IamCTX, IamCTX,
&user.GetUserByIDRequest{ &user.GetUserByIDRequest{
Organization: &object.Organization{
Org: &object.Organization_OrgId{
OrgId: newOrg.GetOrganizationId(),
},
},
UserId: newUserID, UserId: newUserID,
}, },
}, },
@ -258,11 +232,6 @@ func TestServer_GetUserByID_Permission(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.GetUserByIDRequest{ &user.GetUserByIDRequest{
Organization: &object.Organization{
Org: &object.Organization_OrgId{
OrgId: newOrg.GetOrganizationId(),
},
},
UserId: newUserID, UserId: newUserID,
}, },
}, },
@ -273,11 +242,6 @@ func TestServer_GetUserByID_Permission(t *testing.T) {
args: args{ args: args{
UserCTX, UserCTX,
&user.GetUserByIDRequest{ &user.GetUserByIDRequest{
Organization: &object.Organization{
Org: &object.Organization_OrgId{
OrgId: newOrg.GetOrganizationId(),
},
},
UserId: newUserID, UserId: newUserID,
}, },
}, },
@ -316,7 +280,7 @@ func TestServer_ListUsers(t *testing.T) {
ctx context.Context ctx context.Context
count int count int
req *user.ListUsersRequest req *user.ListUsersRequest
dep func(ctx context.Context, org string, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) dep func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error)
} }
tests := []struct { tests := []struct {
name string name string
@ -330,7 +294,7 @@ func TestServer_ListUsers(t *testing.T) {
UserCTX, UserCTX,
0, 0,
&user.ListUsersRequest{}, &user.ListUsersRequest{},
func(ctx context.Context, org string, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) {
request.Queries = append(request.Queries, InUserIDsQuery([]string{userResp.UserId})) request.Queries = append(request.Queries, InUserIDsQuery([]string{userResp.UserId}))
return []userAttr{}, nil return []userAttr{}, nil
}, },
@ -350,7 +314,7 @@ func TestServer_ListUsers(t *testing.T) {
IamCTX, IamCTX,
1, 1,
&user.ListUsersRequest{}, &user.ListUsersRequest{},
func(ctx context.Context, org string, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) {
infos := make([]userAttr, len(usernames)) infos := make([]userAttr, len(usernames))
userIDs := make([]string, len(usernames)) userIDs := make([]string, len(usernames))
for i, username := range usernames { for i, username := range usernames {
@ -400,7 +364,7 @@ func TestServer_ListUsers(t *testing.T) {
IamCTX, IamCTX,
3, 3,
&user.ListUsersRequest{}, &user.ListUsersRequest{},
func(ctx context.Context, org string, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) {
infos := make([]userAttr, len(usernames)) infos := make([]userAttr, len(usernames))
userIDs := make([]string, len(usernames)) userIDs := make([]string, len(usernames))
for i, username := range usernames { for i, username := range usernames {
@ -492,7 +456,7 @@ func TestServer_ListUsers(t *testing.T) {
IamCTX, IamCTX,
1, 1,
&user.ListUsersRequest{}, &user.ListUsersRequest{},
func(ctx context.Context, org string, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) {
infos := make([]userAttr, len(usernames)) infos := make([]userAttr, len(usernames))
userIDs := make([]string, len(usernames)) userIDs := make([]string, len(usernames))
for i, username := range usernames { for i, username := range usernames {
@ -542,7 +506,7 @@ func TestServer_ListUsers(t *testing.T) {
IamCTX, IamCTX,
1, 1,
&user.ListUsersRequest{}, &user.ListUsersRequest{},
func(ctx context.Context, org string, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) {
infos := make([]userAttr, len(usernames)) infos := make([]userAttr, len(usernames))
for i, username := range usernames { for i, username := range usernames {
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
@ -590,7 +554,7 @@ func TestServer_ListUsers(t *testing.T) {
IamCTX, IamCTX,
3, 3,
&user.ListUsersRequest{}, &user.ListUsersRequest{},
func(ctx context.Context, org string, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) {
infos := make([]userAttr, len(usernames)) infos := make([]userAttr, len(usernames))
for i, username := range usernames { for i, username := range usernames {
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username) resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
@ -683,7 +647,7 @@ func TestServer_ListUsers(t *testing.T) {
InUserEmailsQuery([]string{"notfound"}), InUserEmailsQuery([]string{"notfound"}),
}, },
}, },
func(ctx context.Context, org string, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) { func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) {
return []userAttr{}, nil return []userAttr{}, nil
}, },
}, },
@ -696,6 +660,99 @@ func TestServer_ListUsers(t *testing.T) {
Result: []*user.User{}, Result: []*user.User{},
}, },
}, },
{
name: "list user resourceowner multiple, ok",
args: args{
IamCTX,
3,
&user.ListUsersRequest{},
func(ctx context.Context, usernames []string, request *user.ListUsersRequest) ([]userAttr, error) {
orgResp := Tester.CreateOrganization(ctx, fmt.Sprintf("ListUsersResourceowner%d", time.Now().UnixNano()), fmt.Sprintf("%d@mouse.com", time.Now().UnixNano()))
infos := make([]userAttr, len(usernames))
for i, username := range usernames {
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
infos[i] = userAttr{resp.GetUserId(), username}
}
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
request.Queries = append(request.Queries, InUserEmailsQuery(usernames))
return infos, nil
},
},
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{
Phone: "+41791234567",
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{
Phone: "+41791234567",
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{
Phone: "+41791234567",
IsVerified: true,
},
},
},
},
},
},
},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
@ -703,7 +760,7 @@ func TestServer_ListUsers(t *testing.T) {
for i := 0; i < tt.args.count; i++ { for i := 0; i < tt.args.count; i++ {
usernames[i] = fmt.Sprintf("%d%d@mouse.com", time.Now().UnixNano(), i) usernames[i] = fmt.Sprintf("%d%d@mouse.com", time.Now().UnixNano(), i)
} }
infos, err := tt.args.dep(tt.args.ctx, orgResp.OrganizationId, usernames, tt.args.req) infos, err := tt.args.dep(tt.args.ctx, usernames, tt.args.req)
require.NoError(t, err) require.NoError(t, err)
retryDuration := time.Minute retryDuration := time.Minute
if ctxDeadline, ok := CTX.Deadline(); ok { if ctxDeadline, ok := CTX.Deadline(); ok {
@ -768,3 +825,12 @@ func UsernameQuery(username string) *user.SearchQuery {
}, },
} }
} }
func OrganizationIdQuery(resourceowner string) *user.SearchQuery {
return &user.SearchQuery{Query: &user.SearchQuery_OrganizationIdQuery{
OrganizationIdQuery: &user.OrganizationIdQuery{
OrganizationId: resourceowner,
},
},
}
}

View File

@ -70,8 +70,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -111,8 +111,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -156,8 +156,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -202,8 +202,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -249,8 +249,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -290,8 +290,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -321,8 +321,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -355,8 +355,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -402,8 +402,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -454,8 +454,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -493,8 +493,8 @@ func TestServer_AddHumanUser(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: Tester.Organisation.ID, OrgId: Tester.Organisation.ID,
}, },
}, },
@ -572,8 +572,8 @@ func TestServer_AddHumanUser_Permission(t *testing.T) {
args: args{ args: args{
SystemCTX, SystemCTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: newOrg.GetOrganizationId(), OrgId: newOrg.GetOrganizationId(),
}, },
}, },
@ -613,8 +613,8 @@ func TestServer_AddHumanUser_Permission(t *testing.T) {
args: args{ args: args{
IamCTX, IamCTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: newOrg.GetOrganizationId(), OrgId: newOrg.GetOrganizationId(),
}, },
}, },
@ -654,8 +654,8 @@ func TestServer_AddHumanUser_Permission(t *testing.T) {
args: args{ args: args{
CTX, CTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: newOrg.GetOrganizationId(), OrgId: newOrg.GetOrganizationId(),
}, },
}, },
@ -690,8 +690,8 @@ func TestServer_AddHumanUser_Permission(t *testing.T) {
args: args{ args: args{
UserCTX, UserCTX,
&user.AddHumanUserRequest{ &user.AddHumanUserRequest{
Organisation: &object.Organisation{ Organization: &object.Organization{
Org: &object.Organisation_OrgId{ Org: &object.Organization_OrgId{
OrgId: newOrg.GetOrganizationId(), OrgId: newOrg.GetOrganizationId(),
}, },
}, },

View File

@ -1,13 +1,3 @@
package user package user
type SearchQuery_ResourceOwner struct {
ResourceOwner *ResourceOwnerQuery
}
func (SearchQuery_ResourceOwner) isSearchQuery_Query() {}
type ResourceOwnerQuery struct {
OrgID string
}
type UserType = isUser_Type type UserType = isUser_Type

View File

@ -1,12 +0,0 @@
package user
import "github.com/zitadel/zitadel/internal/api/grpc/server/middleware"
// OrganisationFromRequest implements deprecated [middleware.OrganisationFromRequest] interface.
// it will be removed before going GA (https://github.com/zitadel/zitadel/issues/6718)
func (r *AddHumanUserRequest) OrganisationFromRequest() *middleware.Organization {
return &middleware.Organization{
ID: r.GetOrganisation().GetOrgId(),
Domain: r.GetOrganisation().GetOrgDomain(),
}
}

View File

@ -29,9 +29,11 @@ message SearchQuery {
AndQuery and_query = 12; AndQuery and_query = 12;
NotQuery not_query = 13; NotQuery not_query = 13;
InUserEmailsQuery in_user_emails_query = 14; InUserEmailsQuery in_user_emails_query = 14;
OrganizationIdQuery organization_id_query = 15;
} }
} }
// Connect multiple sub-condition with and OR operator.
message OrQuery { message OrQuery {
repeated SearchQuery queries = 1 [ repeated SearchQuery queries = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@ -39,6 +41,8 @@ message OrQuery {
} }
]; ];
} }
// Connect multiple sub-condition with and AND operator.
message AndQuery { message AndQuery {
repeated SearchQuery queries = 1 [ repeated SearchQuery queries = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@ -47,6 +51,7 @@ message AndQuery {
]; ];
} }
// Negate the sub-condition.
message NotQuery { message NotQuery {
SearchQuery query = 1 [ SearchQuery query = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@ -55,6 +60,7 @@ message NotQuery {
]; ];
} }
// Query for users with ID in list of IDs.
message InUserIDQuery { message InUserIDQuery {
repeated string user_ids = 1 [ repeated string user_ids = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@ -64,10 +70,13 @@ message InUserIDQuery {
]; ];
} }
// Query for users with a specific user name.
message UserNameQuery { message UserNameQuery {
string user_name = 1 [ string user_name = 1 [
(validate.rules).string = {max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200; max_length: 200;
example: "\"gigi-giraffe\""; example: "\"gigi-giraffe\"";
} }
@ -80,10 +89,13 @@ message UserNameQuery {
]; ];
} }
// Query for users with a specific first name.
message FirstNameQuery { message FirstNameQuery {
string first_name = 1 [ string first_name = 1 [
(validate.rules).string = {max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200; max_length: 200;
example: "\"Gigi\""; example: "\"Gigi\"";
} }
@ -96,10 +108,13 @@ message FirstNameQuery {
]; ];
} }
// Query for users with a specific last name.
message LastNameQuery { message LastNameQuery {
string last_name = 1 [ string last_name = 1 [
(validate.rules).string = {max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200; max_length: 200;
example: "\"Giraffe\""; example: "\"Giraffe\"";
} }
@ -112,8 +127,17 @@ message LastNameQuery {
]; ];
} }
// Query for users with a specific nickname.
message NickNameQuery { message NickNameQuery {
string nick_name = 1 [(validate.rules).string = {max_len: 200}]; string nick_name = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"Gigi\"";
}
];
zitadel.object.v2beta.TextQueryMethod method = 2 [ zitadel.object.v2beta.TextQueryMethod method = 2 [
(validate.rules).enum.defined_only = true, (validate.rules).enum.defined_only = true,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@ -122,10 +146,13 @@ message NickNameQuery {
]; ];
} }
// Query for users with a specific display name.
message DisplayNameQuery { message DisplayNameQuery {
string display_name = 1 [ string display_name = 1 [
(validate.rules).string = {max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200; max_length: 200;
example: "\"Gigi Giraffe\""; example: "\"Gigi Giraffe\"";
} }
@ -138,11 +165,14 @@ message DisplayNameQuery {
]; ];
} }
// Query for users with a specific email.
message EmailQuery { message EmailQuery {
string email_address = 1 [ string email_address = 1 [
(validate.rules).string = {max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200, email: true},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "email address of the user. (spec: https://tools.ietf.org/html/rfc2822#section-3.4.1)" description: "email address of the user. (spec: https://tools.ietf.org/html/rfc2822#section-3.4.1)"
min_length: 1;
max_length: 200; max_length: 200;
example: "\"gigi@zitadel.com\""; example: "\"gigi@zitadel.com\"";
} }
@ -155,10 +185,13 @@ message EmailQuery {
]; ];
} }
// Query for users with a specific state.
message LoginNameQuery { message LoginNameQuery {
string login_name = 1 [ string login_name = 1 [
(validate.rules).string = {max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200; max_length: 200;
example: "\"gigi@zitadel.cloud\""; example: "\"gigi@zitadel.cloud\"";
} }
@ -171,26 +204,29 @@ message LoginNameQuery {
]; ];
} }
//UserStateQuery always equals // Query for users with a specific state.
message StateQuery { message StateQuery {
UserState state = 1 [ UserState state = 1 [
(validate.rules).enum.defined_only = true, (validate.rules).enum.defined_only = true,
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "current state of the user"; description: "current state of the user";
} }
]; ];
} }
//UserTypeQuery always equals // Query for users with a specific type.
message TypeQuery { message TypeQuery {
Type type = 1 [ Type type = 1 [
(validate.rules).enum.defined_only = true, (validate.rules).enum.defined_only = true,
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "the type of the user"; description: "the type of the user";
} }
]; ];
} }
// Query for users with email in list of emails.
message InUserEmailsQuery { message InUserEmailsQuery {
repeated string user_emails = 1 [ repeated string user_emails = 1 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@ -200,6 +236,19 @@ message InUserEmailsQuery {
]; ];
} }
// Query for users under a specific organization as resource owner.
message OrganizationIdQuery {
string organization_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED,
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
min_length: 1;
max_length: 200;
example: "\"69629023906488334\""
}
];
}
enum Type { enum Type {
TYPE_UNSPECIFIED = 0; TYPE_UNSPECIFIED = 0;
TYPE_HUMAN = 1; TYPE_HUMAN = 1;

View File

@ -157,7 +157,6 @@ service UserService {
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
summary: "User by ID"; summary: "User by ID";
description: "Returns the full user object (human or machine) including the profile, email, etc." description: "Returns the full user object (human or machine) including the profile, email, etc."
tags: "Users";
responses: { responses: {
key: "200" key: "200"
value: { value: {
@ -183,7 +182,6 @@ service UserService {
}; };
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = {
tags: "Users";
summary: "Search Users"; summary: "Search Users";
description: "Search for users. By default, we will return users of your organization. Make sure to include a limit and sorting for pagination." description: "Search for users. By default, we will return users of your organization. Make sure to include a limit and sorting for pagination."
responses: { responses: {
@ -897,7 +895,9 @@ service UserService {
} }
message AddHumanUserRequest{ message AddHumanUserRequest{
// optionally set your own id unique for the user reserved 3;
reserved "organisation";
// optionally set your own id unique for the user.
optional string user_id = 1 [ optional string user_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@ -906,7 +906,7 @@ message AddHumanUserRequest{
example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\""; example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\"";
} }
]; ];
// optionally set a unique username, if none is provided the email will be used // optionally set a unique username, if none is provided the email will be used.
optional string username = 2 [ optional string username = 2 [
(validate.rules).string = {min_len: 1, max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = { (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
@ -915,12 +915,6 @@ message AddHumanUserRequest{
example: "\"minnie-mouse\""; example: "\"minnie-mouse\"";
} }
]; ];
// deprecated: use organization (if both are set, organization will take precedence)
zitadel.object.v2beta.Organisation organisation = 3 [
(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {
description: "deprecated: use organization (if both are set, organization will take precedence)"
}
];
zitadel.object.v2beta.Organization organization = 11; zitadel.object.v2beta.Organization organization = 11;
SetHumanProfile profile = 4 [ SetHumanProfile profile = 4 [
(validate.rules).message.required = true, (validate.rules).message.required = true,
@ -947,6 +941,8 @@ message AddHumanUserResponse {
} }
message GetUserByIDRequest { message GetUserByIDRequest {
reserved 2;
reserved "organization";
string user_id = 1 [ string user_id = 1 [
(validate.rules).string = {min_len: 1, max_len: 200}, (validate.rules).string = {min_len: 1, max_len: 200},
(google.api.field_behavior) = REQUIRED, (google.api.field_behavior) = REQUIRED,
@ -957,7 +953,6 @@ message GetUserByIDRequest {
description: "User ID of the user you like to get." description: "User ID of the user you like to get."
} }
]; ];
zitadel.object.v2beta.Organization organization = 2;
} }
message GetUserByIDResponse { message GetUserByIDResponse {