Space events audit logging (#3346)

* space created event

Signed-off-by: jkoberg <jkoberg@owncloud.com>

* space renamed event

Signed-off-by: jkoberg <jkoberg@owncloud.com>

* disable, enable & delete events

Signed-off-by: jkoberg <jkoberg@owncloud.com>

* use edge reva

Signed-off-by: jkoberg <jkoberg@owncloud.com>
This commit is contained in:
kobergj
2022-03-21 11:01:08 +01:00
committed by GitHub
parent ed417ea1c9
commit 7bc6596924
8 changed files with 240 additions and 3 deletions
+10
View File
@@ -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
+88
View File
@@ -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,
+32
View File
@@ -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)
}
+59
View File
@@ -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 != "":
+5
View File
@@ -23,5 +23,10 @@ func RegisteredEvents() []events.Unmarshaller {
events.ItemPurged{},
events.ItemRestored{},
events.FileVersionRestored{},
events.SpaceCreated{},
events.SpaceRenamed{},
events.SpaceEnabled{},
events.SpaceDisabled{},
events.SpaceDeleted{},
}
}
+43
View File
@@ -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
}