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

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

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,

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)
}

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 != "":

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{},
}
}

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
}

2
go.mod
View File

@@ -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

4
go.sum
View File

@@ -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=