feat(guestlinks): handling of SpaceShare unshared and expired events

This commit is contained in:
Alex Ababii committed 2026-10-23 09:17:16 +02:00
1 parent a189c79d48
commit e95ca276d2
5 files changed
+139 -3

No files matched your search

+2 -2
View File
@@ -25,8 +25,8 @@ links feature and start the service.
## Overview
- **Consumes** the share lifecycle events `ShareCreated`, `ShareRemoved` and
`ShareExpired`.
- **Consumes** the share lifecycle events `ShareCreated`, `ShareRemoved`,
`ShareExpired`, `SpaceShared`, `SpaceUnshared` and `SpaceMembershipExpired`.
- **Publishes** the `GuestTokenCreated` event (initial token) and the
`GuestTokenRenewed` event (refresh, carrying the new token and, when
authorized by a session, the PIN).
@@ -38,6 +38,8 @@ var _registeredEvents = []events.Unmarshaller{
events.ShareRemoved{},
events.ShareExpired{},
events.SpaceShared{},
events.SpaceUnshared{},
events.SpaceMembershipExpired{},
}
// Server is the entrypoint for the server command.
@@ -110,3 +110,43 @@ func (s *EventConsumer) handleSpaceShared(ctx context.Context, ev events.SpaceSh
Timestamp: time.Now(),
})
}
// handleSpaceUnshared handles a space unshared event.
func (s *EventConsumer) handleSpaceUnshared(ctx context.Context, ev events.SpaceUnshared) error {
_, span := tracer.Start(ctx, "handleSpaceUnshared")
defer span.End()
if ev.GranteeUserID == nil || ev.GranteeUserID.GetType() != user.UserType_USER_TYPE_GUEST {
s.log.Debug().Msg("space unshared event is not for a guest, skipping")
return nil
}
if ev.ShareID.GetOpaqueId() == "" {
s.log.Warn().Msg("space unshared event without share id, skipping")
return nil
}
s.log.Debug().Interface("event", ev).Msg("space unshared event received")
return s.authGuest.CleanupShare(ev.ShareID.GetOpaqueId())
}
// handleSpaceMembershipExpired handles a space membership expired event.
func (s *EventConsumer) handleSpaceMembershipExpired(ctx context.Context, ev events.SpaceMembershipExpired) error {
_, span := tracer.Start(ctx, "handleSpaceMembershipExpired")
defer span.End()
if ev.GranteeUserID == nil || ev.GranteeUserID.GetType() != user.UserType_USER_TYPE_GUEST {
s.log.Debug().Msg("space membership expired event is not for a guest, skipping")
return nil
}
if ev.ShareID.GetOpaqueId() == "" {
s.log.Warn().Msg("space membership expired event without share id, skipping")
return nil
}
s.log.Debug().Interface("event", ev).Msg("space membership expired event received")
return s.authGuest.CleanupShare(ev.ShareID.GetOpaqueId())
}
@@ -210,3 +210,94 @@ func TestHandleSpaceSharedSkipsEmptyShareID(t *testing.T) {
svcMock.AssertNotCalled(t, "CreateToken", mock.Anything, mock.Anything)
assert.Empty(t, bus.published)
}
func TestHandleSpaceUnshared(t *testing.T) {
svcMock := mocks.NewAuthGuest(t)
svcMock.On("CleanupShare", testShareID).Return(nil)
svc, _ := newConsumer(t, svcMock)
ev := events.SpaceUnshared{
ID: &provider.StorageSpaceId{OpaqueId: "storage$space"},
ShareID: &collaboration.ShareId{OpaqueId: testShareID},
Executant: &user.UserId{OpaqueId: "executant"},
GranteeUserID: &user.UserId{OpaqueId: "guest@example.org", Type: user.UserType_USER_TYPE_GUEST},
}
require.NoError(t, svc.handleSpaceUnshared(context.Background(), ev))
svcMock.AssertCalled(t, "CleanupShare", testShareID)
}
func TestHandleSpaceUnsharedSkipsNonGuest(t *testing.T) {
svcMock := mocks.NewAuthGuest(t)
svc, _ := newConsumer(t, svcMock)
ev := events.SpaceUnshared{
ID: &provider.StorageSpaceId{OpaqueId: "storage$space"},
ShareID: &collaboration.ShareId{OpaqueId: testShareID},
GranteeUserID: &user.UserId{OpaqueId: "user", Type: user.UserType_USER_TYPE_PRIMARY},
}
require.NoError(t, svc.handleSpaceUnshared(context.Background(), ev))
svcMock.AssertNotCalled(t, "CleanupShare", mock.Anything)
}
func TestHandleSpaceUnsharedSkipsEmptyShareID(t *testing.T) {
svcMock := mocks.NewAuthGuest(t)
svc, _ := newConsumer(t, svcMock)
ev := events.SpaceUnshared{
ID: &provider.StorageSpaceId{OpaqueId: "storage$space"},
GranteeUserID: &user.UserId{OpaqueId: "guest@example.org", Type: user.UserType_USER_TYPE_GUEST},
}
require.NoError(t, svc.handleSpaceUnshared(context.Background(), ev))
svcMock.AssertNotCalled(t, "CleanupShare", mock.Anything)
}
func TestHandleSpaceMembershipExpired(t *testing.T) {
svcMock := mocks.NewAuthGuest(t)
svcMock.On("CleanupShare", testShareID).Return(nil)
svc, _ := newConsumer(t, svcMock)
ev := events.SpaceMembershipExpired{
ShareID: &collaboration.ShareId{OpaqueId: testShareID},
SpaceID: &provider.StorageSpaceId{OpaqueId: "storage$space"},
GranteeUserID: &user.UserId{OpaqueId: "guest@example.org", Type: user.UserType_USER_TYPE_GUEST},
}
require.NoError(t, svc.handleSpaceMembershipExpired(context.Background(), ev))
svcMock.AssertCalled(t, "CleanupShare", testShareID)
}
func TestHandleSpaceMembershipExpiredSkipsNonGuest(t *testing.T) {
svcMock := mocks.NewAuthGuest(t)
svc, _ := newConsumer(t, svcMock)
ev := events.SpaceMembershipExpired{
ShareID: &collaboration.ShareId{OpaqueId: testShareID},
SpaceID: &provider.StorageSpaceId{OpaqueId: "storage$space"},
GranteeUserID: &user.UserId{OpaqueId: "user", Type: user.UserType_USER_TYPE_PRIMARY},
}
require.NoError(t, svc.handleSpaceMembershipExpired(context.Background(), ev))
svcMock.AssertNotCalled(t, "CleanupShare", mock.Anything)
}
func TestHandleSpaceMembershipExpiredSkipsEmptyShareID(t *testing.T) {
svcMock := mocks.NewAuthGuest(t)
svc, _ := newConsumer(t, svcMock)
ev := events.SpaceMembershipExpired{
SpaceID: &provider.StorageSpaceId{OpaqueId: "storage$space"},
GranteeUserID: &user.UserId{OpaqueId: "guest@example.org", Type: user.UserType_USER_TYPE_GUEST},
}
require.NoError(t, svc.handleSpaceMembershipExpired(context.Background(), ev))
svcMock.AssertNotCalled(t, "CleanupShare", mock.Anything)
}
@@ -138,7 +138,10 @@ func (s *EventConsumer) processEvent(e events.Event) error {
return s.handleShareExpired(ctx, ev)
case events.SpaceShared:
return s.handleSpaceShared(ctx, ev)
// Should we handle space share removed/expired events as well?
case events.SpaceUnshared:
return s.handleSpaceUnshared(ctx, ev)
case events.SpaceMembershipExpired:
return s.handleSpaceMembershipExpired(ctx, ev)
default:
s.log.Warn().
Str("eventtype", e.Type).