Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion core/invitation/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,12 +247,15 @@ func (s Service) createRelations(ctx context.Context, invitationID uuid.UUID, or
}

func (s Service) Delete(ctx context.Context, id uuid.UUID) error {
// Remove every relation anchored on the invitation object, not just the org
// one. createRelations writes both a user (app/invitation:<id>#user) and an
// org (app/invitation:<id>#org) tuple; filtering by org alone leaked the user
// tuple on every accept/expire/delete. Omitting RelationName matches both.
err := s.relationService.Delete(ctx, relation.Relation{
Object: relation.Object{
ID: id.String(),
Namespace: schema.InvitationNamespace,
},
RelationName: schema.OrganizationRelationName,
})
if err != nil {
return fmt.Errorf("failed to delete relation for invitation: %w", err)
Expand Down
8 changes: 8 additions & 0 deletions test/e2e/regression/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2319,6 +2319,14 @@ func (s *APIRegressionTestSuite) TestInvitationAPI() {
}))
s.Assert().Error(err)

// no SpiceDB relation should linger on the invitation object after accept:
// both the #user and #org tuples must be gone, not just #org (gap #1661.3)
leftoverInviteRelations, err := s.testBench.AdminClient.ListRelations(ctxOrgAdminAuth, connect.NewRequest(&frontierv1beta1.ListRelationsRequest{
Object: schema.JoinNamespaceAndResourceID(schema.InvitationNamespace, createdInvite.GetId()),
}))
s.Assert().NoError(err)
s.Assert().Empty(leftoverInviteRelations.Msg.GetRelations())

// should be part of group
listGroupUsersAfterAccept, err := s.testBench.Client.ListGroupUsers(ctxOrgAdminAuth, connect.NewRequest(&frontierv1beta1.ListGroupUsersRequest{
Id: createGroupResp.Msg.GetGroup().GetId(),
Expand Down
Loading