mirror of
https://github.com/zitadel/zitadel.git
synced 2025-05-17 15:48:19 +00:00
fix: add details to ListUsers for user results (#8255)
# Which Problems Are Solved In User v2 API, the ListUsers endpoint doesn't provide the information to which organization the user belongs to. # How the Problems Are Solved Add the details to the user results from the ListUsers endpoint, so that the OrgID is also included as ResourceOwner. # Additional Changes None # Additional Context Closes #8172
This commit is contained in:
parent
19a8ab02ad
commit
fb2d4545b9
@ -61,6 +61,11 @@ func UsersToPb(users []*query.User, assetPrefix string) []*user.User {
|
|||||||
func userToPb(userQ *query.User, assetPrefix string) *user.User {
|
func userToPb(userQ *query.User, assetPrefix string) *user.User {
|
||||||
return &user.User{
|
return &user.User{
|
||||||
UserId: userQ.ID,
|
UserId: userQ.ID,
|
||||||
|
Details: object.DomainToDetailsPb(&domain.ObjectDetails{
|
||||||
|
Sequence: userQ.Sequence,
|
||||||
|
EventDate: userQ.ChangeDate,
|
||||||
|
ResourceOwner: userQ.ResourceOwner,
|
||||||
|
}),
|
||||||
State: userStateToPb(userQ.State),
|
State: userStateToPb(userQ.State),
|
||||||
Username: userQ.Username,
|
Username: userQ.Username,
|
||||||
LoginNames: userQ.LoginNames,
|
LoginNames: userQ.LoginNames,
|
||||||
|
@ -23,7 +23,7 @@ func TestServer_GetUserByID(t *testing.T) {
|
|||||||
type args struct {
|
type args struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
req *user.GetUserByIDRequest
|
req *user.GetUserByIDRequest
|
||||||
dep func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*timestamppb.Timestamp, error)
|
dep func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*userAttr, error)
|
||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@ -38,7 +38,7 @@ func TestServer_GetUserByID(t *testing.T) {
|
|||||||
&user.GetUserByIDRequest{
|
&user.GetUserByIDRequest{
|
||||||
UserId: "",
|
UserId: "",
|
||||||
},
|
},
|
||||||
func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*timestamppb.Timestamp, error) {
|
func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*userAttr, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -51,7 +51,7 @@ func TestServer_GetUserByID(t *testing.T) {
|
|||||||
&user.GetUserByIDRequest{
|
&user.GetUserByIDRequest{
|
||||||
UserId: "unknown",
|
UserId: "unknown",
|
||||||
},
|
},
|
||||||
func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*timestamppb.Timestamp, error) {
|
func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*userAttr, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -62,10 +62,10 @@ func TestServer_GetUserByID(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
IamCTX,
|
IamCTX,
|
||||||
&user.GetUserByIDRequest{},
|
&user.GetUserByIDRequest{},
|
||||||
func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*timestamppb.Timestamp, error) {
|
func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*userAttr, error) {
|
||||||
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
||||||
request.UserId = resp.GetUserId()
|
request.UserId = resp.GetUserId()
|
||||||
return nil, nil
|
return &userAttr{resp.GetUserId(), username, nil, resp.GetDetails()}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
want: &user.GetUserByIDResponse{
|
want: &user.GetUserByIDResponse{
|
||||||
@ -106,11 +106,11 @@ func TestServer_GetUserByID(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
IamCTX,
|
IamCTX,
|
||||||
&user.GetUserByIDRequest{},
|
&user.GetUserByIDRequest{},
|
||||||
func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*timestamppb.Timestamp, error) {
|
func(ctx context.Context, username string, request *user.GetUserByIDRequest) (*userAttr, error) {
|
||||||
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
||||||
request.UserId = resp.GetUserId()
|
request.UserId = resp.GetUserId()
|
||||||
changed := Tester.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true)
|
details := Tester.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true)
|
||||||
return changed, nil
|
return &userAttr{resp.GetUserId(), username, details.GetChangeDate(), resp.GetDetails()}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
want: &user.GetUserByIDResponse{
|
want: &user.GetUserByIDResponse{
|
||||||
@ -152,7 +152,7 @@ func TestServer_GetUserByID(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
username := fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())
|
username := fmt.Sprintf("%d@mouse.com", time.Now().UnixNano())
|
||||||
changed, err := tt.args.dep(tt.args.ctx, username, tt.args.req)
|
userAttr, err := tt.args.dep(tt.args.ctx, username, 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 {
|
||||||
@ -168,14 +168,15 @@ func TestServer_GetUserByID(t *testing.T) {
|
|||||||
if getErr != nil {
|
if getErr != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
tt.want.User.UserId = tt.args.req.GetUserId()
|
tt.want.User.Details = userAttr.Details
|
||||||
tt.want.User.Username = username
|
tt.want.User.UserId = userAttr.UserID
|
||||||
tt.want.User.PreferredLoginName = username
|
tt.want.User.Username = userAttr.Username
|
||||||
tt.want.User.LoginNames = []string{username}
|
tt.want.User.PreferredLoginName = userAttr.Username
|
||||||
|
tt.want.User.LoginNames = []string{userAttr.Username}
|
||||||
if human := tt.want.User.GetHuman(); human != nil {
|
if human := tt.want.User.GetHuman(); human != nil {
|
||||||
human.Email.Email = username
|
human.Email.Email = userAttr.Username
|
||||||
if tt.want.User.GetHuman().GetPasswordChanged() != nil {
|
if tt.want.User.GetHuman().GetPasswordChanged() != nil {
|
||||||
human.PasswordChanged = changed
|
human.PasswordChanged = userAttr.Changed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert.Equal(ttt, tt.want.User, got.User)
|
assert.Equal(ttt, tt.want.User, got.User)
|
||||||
@ -311,6 +312,9 @@ func TestServer_GetUserByID_Permission(t *testing.T) {
|
|||||||
if human := tt.want.User.GetHuman(); human != nil {
|
if human := tt.want.User.GetHuman(); human != nil {
|
||||||
human.Email.Email = newOrgOwnerEmail
|
human.Email.Email = newOrgOwnerEmail
|
||||||
}
|
}
|
||||||
|
// details tested in GetUserByID
|
||||||
|
tt.want.User.Details = got.User.GetDetails()
|
||||||
|
|
||||||
assert.Equal(t, tt.want.User, got.User)
|
assert.Equal(t, tt.want.User, got.User)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -321,6 +325,7 @@ type userAttr struct {
|
|||||||
UserID string
|
UserID string
|
||||||
Username string
|
Username string
|
||||||
Changed *timestamppb.Timestamp
|
Changed *timestamppb.Timestamp
|
||||||
|
Details *object.Details
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_ListUsers(t *testing.T) {
|
func TestServer_ListUsers(t *testing.T) {
|
||||||
@ -374,7 +379,7 @@ func TestServer_ListUsers(t *testing.T) {
|
|||||||
for i, username := range usernames {
|
for i, username := range usernames {
|
||||||
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
||||||
userIDs[i] = resp.GetUserId()
|
userIDs[i] = resp.GetUserId()
|
||||||
infos[i] = userAttr{resp.GetUserId(), username, nil}
|
infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()}
|
||||||
}
|
}
|
||||||
request.Queries = append(request.Queries, InUserIDsQuery(userIDs))
|
request.Queries = append(request.Queries, InUserIDsQuery(userIDs))
|
||||||
return infos, nil
|
return infos, nil
|
||||||
@ -428,8 +433,8 @@ func TestServer_ListUsers(t *testing.T) {
|
|||||||
for i, username := range usernames {
|
for i, username := range usernames {
|
||||||
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
||||||
userIDs[i] = resp.GetUserId()
|
userIDs[i] = resp.GetUserId()
|
||||||
changed := Tester.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true)
|
details := Tester.SetUserPassword(ctx, resp.GetUserId(), integration.UserPassword, true)
|
||||||
infos[i] = userAttr{resp.GetUserId(), username, changed}
|
infos[i] = userAttr{resp.GetUserId(), username, details.GetChangeDate(), resp.GetDetails()}
|
||||||
}
|
}
|
||||||
request.Queries = append(request.Queries, InUserIDsQuery(userIDs))
|
request.Queries = append(request.Queries, InUserIDsQuery(userIDs))
|
||||||
return infos, nil
|
return infos, nil
|
||||||
@ -485,7 +490,7 @@ func TestServer_ListUsers(t *testing.T) {
|
|||||||
for i, username := range usernames {
|
for i, username := range usernames {
|
||||||
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
||||||
userIDs[i] = resp.GetUserId()
|
userIDs[i] = resp.GetUserId()
|
||||||
infos[i] = userAttr{resp.GetUserId(), username, nil}
|
infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()}
|
||||||
}
|
}
|
||||||
request.Queries = append(request.Queries, InUserIDsQuery(userIDs))
|
request.Queries = append(request.Queries, InUserIDsQuery(userIDs))
|
||||||
return infos, nil
|
return infos, nil
|
||||||
@ -581,7 +586,7 @@ func TestServer_ListUsers(t *testing.T) {
|
|||||||
for i, username := range usernames {
|
for i, username := range usernames {
|
||||||
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
resp := Tester.CreateHumanUserVerified(ctx, orgResp.OrganizationId, username)
|
||||||
userIDs[i] = resp.GetUserId()
|
userIDs[i] = resp.GetUserId()
|
||||||
infos[i] = userAttr{resp.GetUserId(), username, nil}
|
infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()}
|
||||||
request.Queries = append(request.Queries, UsernameQuery(username))
|
request.Queries = append(request.Queries, UsernameQuery(username))
|
||||||
}
|
}
|
||||||
return infos, nil
|
return infos, nil
|
||||||
@ -633,7 +638,7 @@ func TestServer_ListUsers(t *testing.T) {
|
|||||||
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)
|
||||||
infos[i] = userAttr{resp.GetUserId(), username, nil}
|
infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()}
|
||||||
}
|
}
|
||||||
request.Queries = append(request.Queries, InUserEmailsQuery(usernames))
|
request.Queries = append(request.Queries, InUserEmailsQuery(usernames))
|
||||||
return infos, nil
|
return infos, nil
|
||||||
@ -685,7 +690,7 @@ func TestServer_ListUsers(t *testing.T) {
|
|||||||
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)
|
||||||
infos[i] = userAttr{resp.GetUserId(), username, nil}
|
infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()}
|
||||||
}
|
}
|
||||||
request.Queries = append(request.Queries, InUserEmailsQuery(usernames))
|
request.Queries = append(request.Queries, InUserEmailsQuery(usernames))
|
||||||
return infos, nil
|
return infos, nil
|
||||||
@ -800,7 +805,7 @@ func TestServer_ListUsers(t *testing.T) {
|
|||||||
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)
|
||||||
infos[i] = userAttr{resp.GetUserId(), username, nil}
|
infos[i] = userAttr{resp.GetUserId(), username, nil, resp.GetDetails()}
|
||||||
}
|
}
|
||||||
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
|
request.Queries = append(request.Queries, OrganizationIdQuery(orgResp.OrganizationId))
|
||||||
request.Queries = append(request.Queries, InUserEmailsQuery(usernames))
|
request.Queries = append(request.Queries, InUserEmailsQuery(usernames))
|
||||||
@ -920,6 +925,7 @@ func TestServer_ListUsers(t *testing.T) {
|
|||||||
human.PasswordChanged = infos[i].Changed
|
human.PasswordChanged = infos[i].Changed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tt.want.Result[i].Details = infos[i].Details
|
||||||
}
|
}
|
||||||
for i := range tt.want.Result {
|
for i := range tt.want.Result {
|
||||||
assert.Contains(ttt, got.Result, tt.want.Result[i])
|
assert.Contains(ttt, got.Result, tt.want.Result[i])
|
||||||
|
@ -17,7 +17,6 @@ import (
|
|||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/protobuf/types/known/durationpb"
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
"google.golang.org/protobuf/types/known/structpb"
|
"google.golang.org/protobuf/types/known/structpb"
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
|
||||||
|
|
||||||
"github.com/zitadel/zitadel/internal/api/authz"
|
"github.com/zitadel/zitadel/internal/api/authz"
|
||||||
"github.com/zitadel/zitadel/internal/command"
|
"github.com/zitadel/zitadel/internal/command"
|
||||||
@ -312,7 +311,7 @@ func (s *Tester) RegisterUserU2F(ctx context.Context, userID string) {
|
|||||||
logging.OnError(err).Fatal("create user u2f")
|
logging.OnError(err).Fatal("create user u2f")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Tester) SetUserPassword(ctx context.Context, userID, password string, changeRequired bool) *timestamppb.Timestamp {
|
func (s *Tester) SetUserPassword(ctx context.Context, userID, password string, changeRequired bool) *object.Details {
|
||||||
resp, err := s.Client.UserV2.SetPassword(ctx, &user.SetPasswordRequest{
|
resp, err := s.Client.UserV2.SetPassword(ctx, &user.SetPasswordRequest{
|
||||||
UserId: userID,
|
UserId: userID,
|
||||||
NewPassword: &user.Password{
|
NewPassword: &user.Password{
|
||||||
@ -321,7 +320,7 @@ func (s *Tester) SetUserPassword(ctx context.Context, userID, password string, c
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
logging.OnError(err).Fatal("set user password")
|
logging.OnError(err).Fatal("set user password")
|
||||||
return resp.GetDetails().GetChangeDate()
|
return resp.GetDetails()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Tester) AddGenericOAuthProvider(t *testing.T, ctx context.Context) string {
|
func (s *Tester) AddGenericOAuthProvider(t *testing.T, ctx context.Context) string {
|
||||||
|
@ -183,6 +183,7 @@ message User {
|
|||||||
example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\"";
|
example: "\"d654e6ba-70a3-48ef-a95d-37c8d8a7901a\"";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
zitadel.object.v2beta.Details details = 8;
|
||||||
UserState state = 2 [
|
UserState state = 2 [
|
||||||
(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";
|
||||||
|
@ -989,6 +989,7 @@ message GetUserByIDRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message GetUserByIDResponse {
|
message GetUserByIDResponse {
|
||||||
|
//deprecated: details is moved into user
|
||||||
zitadel.object.v2beta.Details details = 1;
|
zitadel.object.v2beta.Details details = 1;
|
||||||
zitadel.user.v2beta.User user = 2;
|
zitadel.user.v2beta.User user = 2;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user