diff --git a/audit/pkg/service/service.go b/audit/pkg/service/service.go index 5edc11122..f2f09766a 100644 --- a/audit/pkg/service/service.go +++ b/audit/pkg/service/service.go @@ -75,6 +75,16 @@ func StartAuditLogger(ctx context.Context, ch <-chan interface{}, log log.Logger auditEvent = types.ItemRestored(ev) case events.FileVersionRestored: auditEvent = types.FileVersionRestored(ev) + case events.SpaceCreated: + auditEvent = types.SpaceCreated(ev) + case events.SpaceRenamed: + auditEvent = types.SpaceRenamed(ev) + case events.SpaceDisabled: + auditEvent = types.SpaceDisabled(ev) + case events.SpaceEnabled: + auditEvent = types.SpaceEnabled(ev) + case events.SpaceDeleted: + auditEvent = types.SpaceDeleted(ev) default: log.Error().Interface("event", ev).Msg(fmt.Sprintf("can't handle event of type '%T'", ev)) continue diff --git a/audit/pkg/service/service_test.go b/audit/pkg/service/service_test.go index 0bd1d2296..2849ca699 100644 --- a/audit/pkg/service/service_test.go +++ b/audit/pkg/service/service_test.go @@ -412,6 +412,91 @@ var testCases = []struct { require.Equal(t, "v1", ev.Key) }, + }, { + Alias: "Space created", + SystemEvent: events.SpaceCreated{ + ID: &provider.StorageSpaceId{OpaqueId: "space-123"}, + Owner: userID("uid-123"), + Root: resourceID("sto-123", "iid-123"), + Name: "test-space", + Type: "project", + Quota: nil, // Quota not interesting atm + MTime: timestamp(10e9), + }, + CheckAuditEvent: func(t *testing.T, b []byte) { + ev := types.AuditEventSpaceCreated{} + require.NoError(t, json.Unmarshal(b, &ev)) + + // AuditEvent fields + checkBaseAuditEvent(t, ev.AuditEvent, "", "2286-11-20T17:46:40Z", "Space 'space-123' with name 'test-space' was created", "space_created") + // AuditEventSpaces fields + checkSpacesAuditEvent(t, ev.AuditEventSpaces, "space-123") + // AuditEventFileRestored fields + require.Equal(t, "uid-123", ev.Owner) + require.Equal(t, "sto-123!iid-123", ev.RootItem) + require.Equal(t, "test-space", ev.Name) + require.Equal(t, "project", ev.Type) + }, + }, { + Alias: "Space renamed", + SystemEvent: events.SpaceRenamed{ + ID: &provider.StorageSpaceId{OpaqueId: "space-123"}, + Owner: userID("uid-123"), + Name: "new-name", + }, + CheckAuditEvent: func(t *testing.T, b []byte) { + ev := types.AuditEventSpaceRenamed{} + require.NoError(t, json.Unmarshal(b, &ev)) + + // AuditEvent fields + checkBaseAuditEvent(t, ev.AuditEvent, "", "", "Space 'space-123' was renamed to 'new-name'", "space_renamed") + // AuditEventSpaces fields + checkSpacesAuditEvent(t, ev.AuditEventSpaces, "space-123") + // AuditEventSpaceRenamed fields + require.Equal(t, "new-name", ev.NewName) + }, + }, { + Alias: "Space disabled", + SystemEvent: events.SpaceDisabled{ + ID: &provider.StorageSpaceId{OpaqueId: "space-123"}, + }, + CheckAuditEvent: func(t *testing.T, b []byte) { + ev := types.AuditEventSpaceDisabled{} + require.NoError(t, json.Unmarshal(b, &ev)) + + // AuditEvent fields + checkBaseAuditEvent(t, ev.AuditEvent, "", "", "Space 'space-123' was disabled", "space_disabled") + // AuditEventSpaces fields + checkSpacesAuditEvent(t, ev.AuditEventSpaces, "space-123") + }, + }, { + Alias: "Space enabled", + SystemEvent: events.SpaceEnabled{ + ID: &provider.StorageSpaceId{OpaqueId: "space-123"}, + }, + CheckAuditEvent: func(t *testing.T, b []byte) { + ev := types.AuditEventSpaceEnabled{} + require.NoError(t, json.Unmarshal(b, &ev)) + + // AuditEvent fields + checkBaseAuditEvent(t, ev.AuditEvent, "", "", "Space 'space-123' was (re-) enabled", "space_enabled") + // AuditEventSpaces fields + checkSpacesAuditEvent(t, ev.AuditEventSpaces, "space-123") + }, + }, { + Alias: "Space deleted", + SystemEvent: events.SpaceDeleted{ + ID: &provider.StorageSpaceId{OpaqueId: "space-123"}, + }, + CheckAuditEvent: func(t *testing.T, b []byte) { + ev := types.AuditEventSpaceDeleted{} + require.NoError(t, json.Unmarshal(b, &ev)) + + // AuditEvent fields + checkBaseAuditEvent(t, ev.AuditEvent, "", "", "Space 'space-123' was deleted", "space_deleted") + // AuditEventSpaces fields + checkSpacesAuditEvent(t, ev.AuditEventSpaces, "space-123") + }, }, } @@ -467,6 +552,9 @@ func checkFilesAuditEvent(t *testing.T, ev types.AuditEventFiles, itemID string, require.Equal(t, path, ev.Path) } +func checkSpacesAuditEvent(t *testing.T, ev types.AuditEventSpaces, spaceID string) { + require.Equal(t, spaceID, ev.SpaceID) +} func shareID(id string) *collaboration.ShareId { return &collaboration.ShareId{ OpaqueId: id, diff --git a/audit/pkg/types/constants.go b/audit/pkg/types/constants.go index 10b51a35c..4f2f79d5e 100644 --- a/audit/pkg/types/constants.go +++ b/audit/pkg/types/constants.go @@ -23,6 +23,13 @@ const ( ActionFilePurged = "file_trash_delete" ActionFileRestored = "file_trash_restore" ActionFileVersionRestored = "file_version_restore" + + // Spaces + ActionSpaceCreated = "space_created" + ActionSpaceRenamed = "space_renamed" + ActionSpaceDisabled = "space_disabled" + ActionSpaceEnabled = "space_enabled" + ActionSpaceDeleted = "space_deleted" ) // MessageShareCreated returns the human readable string that describes the action @@ -104,3 +111,28 @@ func MessageFileRestored(item, path string) string { func MessageFileVersionRestored(item string, version string) string { return fmt.Sprintf("File '%s' was restored in version '%s'", item, version) } + +// MessageSpaceCreated returns the human readable string that describes the action +func MessageSpaceCreated(spaceID string, name string) string { + return fmt.Sprintf("Space '%s' with name '%s' was created", spaceID, name) +} + +// MessageSpaceRenamed returns the human readable string that describes the action +func MessageSpaceRenamed(spaceID string, name string) string { + return fmt.Sprintf("Space '%s' was renamed to '%s'", spaceID, name) +} + +// MessageSpaceDisabled returns the human readable string that describes the action +func MessageSpaceDisabled(spaceID string) string { + return fmt.Sprintf("Space '%s' was disabled", spaceID) +} + +// MessageSpaceEnabled returns the human readable string that describes the action +func MessageSpaceEnabled(spaceID string) string { + return fmt.Sprintf("Space '%s' was (re-) enabled", spaceID) +} + +// MessageSpaceDeleted returns the human readable string that describes the action +func MessageSpaceDeleted(spaceID string) string { + return fmt.Sprintf("Space '%s' was deleted", spaceID) +} diff --git a/audit/pkg/types/conversion.go b/audit/pkg/types/conversion.go index 29dde2525..f03732daf 100644 --- a/audit/pkg/types/conversion.go +++ b/audit/pkg/types/conversion.go @@ -310,6 +310,65 @@ func FileVersionRestored(ev events.FileVersionRestored) AuditEventFileVersionRes } } +// SpacesAuditEvent creates an AuditEventSpaces from the given values +func SpacesAuditEvent(base AuditEvent, spaceID string) AuditEventSpaces { + return AuditEventSpaces{ + AuditEvent: base, + SpaceID: spaceID, + } +} + +// SpaceCreated converts a SpaceCreated event to an AuditEventSpaceCreated +func SpaceCreated(ev events.SpaceCreated) AuditEventSpaceCreated { + sid := ev.ID.GetOpaqueId() + iid, _, owner := extractFileDetails(&provider.Reference{ResourceId: ev.Root}, ev.Owner) + base := BasicAuditEvent("", formatTime(ev.MTime), MessageSpaceCreated(sid, ev.Name), ActionSpaceCreated) + return AuditEventSpaceCreated{ + AuditEventSpaces: SpacesAuditEvent(base, sid), + Owner: owner, + RootItem: iid, + Name: ev.Name, + Type: ev.Type, + } +} + +// SpaceRenamed converts a SpaceRenamed event to an AuditEventSpaceRenamed +func SpaceRenamed(ev events.SpaceRenamed) AuditEventSpaceRenamed { + sid := ev.ID.GetOpaqueId() + base := BasicAuditEvent("", "", MessageSpaceRenamed(sid, ev.Name), ActionSpaceRenamed) + return AuditEventSpaceRenamed{ + AuditEventSpaces: SpacesAuditEvent(base, sid), + NewName: ev.Name, + } +} + +// SpaceDisabled converts a SpaceDisabled event to an AuditEventSpaceDisabled +func SpaceDisabled(ev events.SpaceDisabled) AuditEventSpaceDisabled { + sid := ev.ID.GetOpaqueId() + base := BasicAuditEvent("", "", MessageSpaceDisabled(sid), ActionSpaceDisabled) + return AuditEventSpaceDisabled{ + AuditEventSpaces: SpacesAuditEvent(base, sid), + } +} + +// SpaceEnabled converts a SpaceEnabled event to an AuditEventSpaceEnabled +func SpaceEnabled(ev events.SpaceEnabled) AuditEventSpaceEnabled { + sid := ev.ID.GetOpaqueId() + base := BasicAuditEvent("", "", MessageSpaceEnabled(sid), ActionSpaceEnabled) + return AuditEventSpaceEnabled{ + AuditEventSpaces: SpacesAuditEvent(base, sid), + } +} + +// SpaceDeleted converts a SpaceDeleted event to an AuditEventSpaceDeleted +func SpaceDeleted(ev events.SpaceDeleted) AuditEventSpaceDeleted { + sid := ev.ID.GetOpaqueId() + base := BasicAuditEvent("", "", MessageSpaceDeleted(sid), ActionSpaceDeleted) + return AuditEventSpaceDeleted{ + AuditEventSpaces: SpacesAuditEvent(base, sid), + } +} + func extractGrantee(uid *user.UserId, gid *group.GroupId) (string, string) { switch { case uid != nil && uid.OpaqueId != "": diff --git a/audit/pkg/types/events.go b/audit/pkg/types/events.go index 85cb3c99c..743044a04 100644 --- a/audit/pkg/types/events.go +++ b/audit/pkg/types/events.go @@ -23,5 +23,10 @@ func RegisteredEvents() []events.Unmarshaller { events.ItemPurged{}, events.ItemRestored{}, events.FileVersionRestored{}, + events.SpaceCreated{}, + events.SpaceRenamed{}, + events.SpaceEnabled{}, + events.SpaceDisabled{}, + events.SpaceDeleted{}, } } diff --git a/audit/pkg/types/types.go b/audit/pkg/types/types.go index 1b1728f02..d4227a196 100644 --- a/audit/pkg/types/types.go +++ b/audit/pkg/types/types.go @@ -154,3 +154,46 @@ type AuditEventFileVersionRestored struct { type AuditEventFileVersionDeleted struct { AuditEventFiles } + +/* + Spaces +*/ + +// AuditEventSpaces is the basic audit event for spaces +type AuditEventSpaces struct { + AuditEvent + + SpaceID string +} + +// AuditEventSpaceCreated is the event logged when a space is created +type AuditEventSpaceCreated struct { + AuditEventSpaces + + Owner string + RootItem string + Name string + Type string +} + +// AuditEventSpaceRenamed is the event logged when a space is renamed +type AuditEventSpaceRenamed struct { + AuditEventSpaces + + NewName string +} + +// AuditEventSpaceDisabled is the event logged when a space is disabled +type AuditEventSpaceDisabled struct { + AuditEventSpaces +} + +// AuditEventSpaceEnabled is the event logged when a space is (re-)enabled +type AuditEventSpaceEnabled struct { + AuditEventSpaces +} + +// AuditEventSpaceDeleted is the event logged when a space is deleted +type AuditEventSpaceDeleted struct { + AuditEventSpaces +} diff --git a/go.mod b/go.mod index 5378d6c93..ab979443c 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/blevesearch/bleve/v2 v2.3.1 github.com/coreos/go-oidc/v3 v3.1.0 github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19 - github.com/cs3org/reva/v2 v2.0.0-20220317153101-5a93e519610c + github.com/cs3org/reva/v2 v2.0.0-20220321093112-25cedab9f739 github.com/disintegration/imaging v1.6.2 github.com/glauth/glauth/v2 v2.0.0-20211021011345-ef3151c28733 github.com/go-chi/chi/v5 v5.0.7 diff --git a/go.sum b/go.sum index f2cea32d5..7ad343f8e 100644 --- a/go.sum +++ b/go.sum @@ -341,8 +341,8 @@ github.com/crewjam/saml v0.4.6/go.mod h1:ZBOXnNPFzB3CgOkRm7Nd6IVdkG+l/wF+0ZXLqD9 github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4= github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19 h1:1jqPH58jCxvbaJ9WLIJ7W2/m622bWS6ChptzljSG6IQ= github.com/cs3org/go-cs3apis v0.0.0-20220126114148-64c025ccdd19/go.mod h1:UXha4TguuB52H14EMoSsCqDj7k8a/t7g4gVP+bgY5LY= -github.com/cs3org/reva/v2 v2.0.0-20220317153101-5a93e519610c h1:tTAuVwgbDNPyeqNJPjMrT1xZ4jZYGSJ2AWqDkvSpXuA= -github.com/cs3org/reva/v2 v2.0.0-20220317153101-5a93e519610c/go.mod h1:XNtK1HEClNzmz5vyQa2DUw4KH3oqBjQoEsV1LhAGlV0= +github.com/cs3org/reva/v2 v2.0.0-20220321093112-25cedab9f739 h1:GD8ZoMqRKclM0dP5hjSMXals9vRWHPH2hOeBruCuQlg= +github.com/cs3org/reva/v2 v2.0.0-20220321093112-25cedab9f739/go.mod h1:XNtK1HEClNzmz5vyQa2DUw4KH3oqBjQoEsV1LhAGlV0= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8 h1:Z9lwXumT5ACSmJ7WGnFl+OMLLjpz5uR2fyz7dC255FI= github.com/cubewise-code/go-mime v0.0.0-20200519001935-8c5762b177d8/go.mod h1:4abs/jPXcmJzYoYGF91JF9Uq9s/KL5n1jvFDix8KcqY= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=