Add uid to few events (#9332)

# Which Problems Are Solved

When implementing simple stateless event processor, `the
user.grant.changed` bears too little information: just grant id and list
of role keys. This makes it impossible to change a users permissions
solely based on available role keys and requires to either:

- Store a mapping grant id -> user id, making a service stateful
- Make an extra call to zitadel to resolve user id by grant id (And it
doesn't seem that such an endpoint exists)

Same with `user.grant.removed` events.

# How the Problems Are Solved

Added `userId` field to `user.grant.changed` and `user.grant.removed`
events

# Additional Changes

`user.grant.removed` now has `projectId` and `grantId` as well

# Additional Context

- Closes #9113
This commit is contained in:
Vlad Zagvozdkin 2025-02-11 23:09:50 +05:00 committed by GitHub
parent 6ef0fcb4d6
commit 13f9d2d142
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 15 additions and 10 deletions

View File

@ -108,7 +108,7 @@ func (c *Commands) changeUserGrant(ctx context.Context, userGrant *domain.UserGr
if cascade { if cascade {
return usergrant.NewUserGrantCascadeChangedEvent(ctx, userGrantAgg, userGrant.RoleKeys), existingUserGrant, nil return usergrant.NewUserGrantCascadeChangedEvent(ctx, userGrantAgg, userGrant.RoleKeys), existingUserGrant, nil
} }
return usergrant.NewUserGrantChangedEvent(ctx, userGrantAgg, userGrant.RoleKeys), existingUserGrant, nil return usergrant.NewUserGrantChangedEvent(ctx, userGrantAgg, existingUserGrant.UserID, userGrant.RoleKeys), existingUserGrant, nil
} }
func (c *Commands) removeRoleFromUserGrant(ctx context.Context, userGrantID string, roleKeys []string, cascade bool) (_ eventstore.Command, err error) { func (c *Commands) removeRoleFromUserGrant(ctx context.Context, userGrantID string, roleKeys []string, cascade bool) (_ eventstore.Command, err error) {
@ -141,7 +141,7 @@ func (c *Commands) removeRoleFromUserGrant(ctx context.Context, userGrantID stri
return usergrant.NewUserGrantCascadeChangedEvent(ctx, userGrantAgg, existingUserGrant.RoleKeys), nil return usergrant.NewUserGrantCascadeChangedEvent(ctx, userGrantAgg, existingUserGrant.RoleKeys), nil
} }
return usergrant.NewUserGrantChangedEvent(ctx, userGrantAgg, existingUserGrant.RoleKeys), nil return usergrant.NewUserGrantChangedEvent(ctx, userGrantAgg, existingUserGrant.UserID, existingUserGrant.RoleKeys), nil
} }
func (c *Commands) DeactivateUserGrant(ctx context.Context, grantID, resourceOwner string) (objectDetails *domain.ObjectDetails, err error) { func (c *Commands) DeactivateUserGrant(ctx context.Context, grantID, resourceOwner string) (objectDetails *domain.ObjectDetails, err error) {

View File

@ -1073,6 +1073,7 @@ func TestCommandSide_ChangeUserGrant(t *testing.T) {
expectPush( expectPush(
usergrant.NewUserGrantChangedEvent(context.Background(), usergrant.NewUserGrantChangedEvent(context.Background(),
&usergrant.NewAggregate("usergrant1", "org1").Aggregate, &usergrant.NewAggregate("usergrant1", "org1").Aggregate,
"user1",
[]string{"rolekey1", "rolekey2"}, []string{"rolekey1", "rolekey2"},
), ),
), ),
@ -1167,6 +1168,7 @@ func TestCommandSide_ChangeUserGrant(t *testing.T) {
expectPush( expectPush(
usergrant.NewUserGrantChangedEvent(context.Background(), usergrant.NewUserGrantChangedEvent(context.Background(),
&usergrant.NewAggregate("usergrant1", "org1").Aggregate, &usergrant.NewAggregate("usergrant1", "org1").Aggregate,
"user1",
[]string{"rolekey1", "rolekey2"}, []string{"rolekey1", "rolekey2"},
), ),
), ),

View File

@ -85,6 +85,7 @@ func UserGrantAddedEventMapper(event eventstore.Event) (eventstore.Event, error)
type UserGrantChangedEvent struct { type UserGrantChangedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
UserID string `json:"userId"`
RoleKeys []string `json:"roleKeys"` RoleKeys []string `json:"roleKeys"`
} }
@ -99,6 +100,7 @@ func (e *UserGrantChangedEvent) UniqueConstraints() []*eventstore.UniqueConstrai
func NewUserGrantChangedEvent( func NewUserGrantChangedEvent(
ctx context.Context, ctx context.Context,
aggregate *eventstore.Aggregate, aggregate *eventstore.Aggregate,
userID string,
roleKeys []string) *UserGrantChangedEvent { roleKeys []string) *UserGrantChangedEvent {
return &UserGrantChangedEvent{ return &UserGrantChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
@ -106,6 +108,7 @@ func NewUserGrantChangedEvent(
aggregate, aggregate,
UserGrantChangedType, UserGrantChangedType,
), ),
UserID: userID,
RoleKeys: roleKeys, RoleKeys: roleKeys,
} }
} }
@ -165,17 +168,17 @@ func UserGrantCascadeChangedEventMapper(event eventstore.Event) (eventstore.Even
type UserGrantRemovedEvent struct { type UserGrantRemovedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
userID string `json:"-"` UserID string `json:"userId,omitempty"`
projectID string `json:"-"` ProjectID string `json:"projectId,omitempty"`
projectGrantID string `json:"-"` ProjectGrantID string `json:"grantId,omitempty"`
} }
func (e *UserGrantRemovedEvent) Payload() interface{} { func (e *UserGrantRemovedEvent) Payload() interface{} {
return nil return e
} }
func (e *UserGrantRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint { func (e *UserGrantRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
return []*eventstore.UniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.Aggregate().ResourceOwner, e.userID, e.projectID, e.projectGrantID)} return []*eventstore.UniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.Aggregate().ResourceOwner, e.UserID, e.ProjectID, e.ProjectGrantID)}
} }
func NewUserGrantRemovedEvent( func NewUserGrantRemovedEvent(
@ -191,9 +194,9 @@ func NewUserGrantRemovedEvent(
aggregate, aggregate,
UserGrantRemovedType, UserGrantRemovedType,
), ),
userID: userID, UserID: userID,
projectID: projectID, ProjectID: projectID,
projectGrantID: projectGrantID, ProjectGrantID: projectGrantID,
} }
} }