Skip to content

Commit

Permalink
implement user and group audit events
Browse files Browse the repository at this point in the history
  • Loading branch information
David Christofas committed Apr 8, 2022
1 parent 21e37fc commit b4f025c
Show file tree
Hide file tree
Showing 19 changed files with 345 additions and 15 deletions.
14 changes: 14 additions & 0 deletions audit/pkg/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,20 @@ func StartAuditLogger(ctx context.Context, ch <-chan interface{}, log log.Logger
auditEvent = types.SpaceEnabled(ev)
case events.SpaceDeleted:
auditEvent = types.SpaceDeleted(ev)
case events.UserCreated:
auditEvent = types.UserCreated(ev)
case events.UserDeleted:
auditEvent = types.UserDeleted(ev)
case events.UserFeatureChanged:
auditEvent = types.UserFeatureChanged(ev)
case events.GroupCreated:
auditEvent = types.GroupCreated(ev)
case events.GroupDeleted:
auditEvent = types.GroupDeleted(ev)
case events.GroupMemberAdded:
auditEvent = types.GroupMemberAdded(ev)
case events.GroupMemberRemoved:
auditEvent = types.GroupMemberRemoved(ev)
default:
log.Error().Interface("event", ev).Msg(fmt.Sprintf("can't handle event of type '%T'", ev))
continue
Expand Down
64 changes: 63 additions & 1 deletion audit/pkg/types/constants.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package types

import "fmt"
import (
"fmt"
"strings"

"github.com/cs3org/reva/v2/pkg/events"
)

// short identifiers for audit actions
const (
Expand Down Expand Up @@ -30,6 +35,17 @@ const (
ActionSpaceDisabled = "space_disabled"
ActionSpaceEnabled = "space_enabled"
ActionSpaceDeleted = "space_deleted"

// Users
ActionUserCreated = "user_created"
ActionUserDeleted = "user_deleted"
ActionUserFeatureChanged = "user_feature_changed"

// Groups
ActionGroupCreated = "group_created"
ActionGroupDeleted = "group_deleted"
ActionGroupMemberAdded = "group_member_added"
ActionGroupMemberRemoved = "group_member_removed"
)

// MessageShareCreated returns the human readable string that describes the action
Expand Down Expand Up @@ -136,3 +152,49 @@ func MessageSpaceEnabled(spaceID string) string {
func MessageSpaceDeleted(spaceID string) string {
return fmt.Sprintf("Space '%s' was deleted", spaceID)
}

// MessageUserCreated returns the human readable string that describes the action
func MessageUserCreated(userID string) string {
return fmt.Sprintf("User '%s' was created", userID)
}

// MessageUserDeleted returns the human readable string that describes the action
func MessageUserDeleted(userID string) string {
return fmt.Sprintf("User '%s' was deleted", userID)
}

// MessageUserFeatureChanged returns the human readable string that describes the action
func MessageUserFeatureChanged(userID string, features []events.UserFeature) string {
// Result is: "User %username%'s feature changed: %featurename%=%featurevalue% %featurename%=%featurevalue%"
var sb strings.Builder
sb.WriteString("User ")
sb.WriteString(userID)
sb.WriteString("'s feature changed: ")
for _, f := range features {
sb.WriteString(f.Name)
sb.WriteRune('=')
sb.WriteString(f.Value)
sb.WriteRune(' ')
}
return sb.String()
}

// MessageGroupCreated returns the human readable string that describes the action
func MessageGroupCreated(groupID string) string {
return fmt.Sprintf("Group '%s' was created", groupID)
}

// MessageGroupDeleted returns the human readable string that describes the action
func MessageGroupDeleted(groupID string) string {
return fmt.Sprintf("Group '%s' was deleted", groupID)
}

// MessageGroupMemberAdded returns the human readable string that describes the action
func MessageGroupMemberAdded(userID, groupID string) string {
return fmt.Sprintf("User '%s' was added to group '%s'", userID, groupID)
}

// MessageGroupMemberRemoved returns the human readable string that describes the action
func MessageGroupMemberRemoved(userID, groupID string) string {
return fmt.Sprintf("User '%s' was removed from group '%s'", userID, groupID)
}
69 changes: 69 additions & 0 deletions audit/pkg/types/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,75 @@ func SpaceDeleted(ev events.SpaceDeleted) AuditEventSpaceDeleted {
}
}

// UserCreated converts a UserCreated event to an AuditEventUserCreated
func UserCreated(ev events.UserCreated) AuditEventUserCreated {
base := BasicAuditEvent("", "", MessageUserCreated(ev.UserID), ActionUserCreated)
return AuditEventUserCreated{
AuditEvent: base,
UserID: ev.UserID,
}
}

// UserDeleted converts a UserCreated event to an AuditEventUserDeleted
func UserDeleted(ev events.UserDeleted) AuditEventUserDeleted {
base := BasicAuditEvent("", "", MessageUserDeleted(ev.UserID), ActionUserDeleted)
return AuditEventUserDeleted{
AuditEvent: base,
UserID: ev.UserID,
}
}

// UserFeatureChanged converts a UserFeatureChanged event to an AuditEventUserFeatureChanged
func UserFeatureChanged(ev events.UserFeatureChanged) AuditEventUserFeatureChanged {
msg := MessageUserFeatureChanged(ev.UserID, ev.Features)
base := BasicAuditEvent("", "", msg, ActionUserFeatureChanged)
return AuditEventUserFeatureChanged{
AuditEvent: base,
UserID: ev.UserID,
Features: ev.Features,
}
}

// GroupCreated converts a GroupCreated event to an AuditEventGroupCreated
func GroupCreated(ev events.GroupCreated) AuditEventGroupCreated {
base := BasicAuditEvent("", "", MessageGroupCreated(ev.GroupID), ActionGroupCreated)
return AuditEventGroupCreated{
AuditEvent: base,
GroupID: ev.GroupID,
}
}

// GroupDeleted converts a GroupDeleted event to an AuditEventGroupDeleted
func GroupDeleted(ev events.GroupDeleted) AuditEventGroupDeleted {
base := BasicAuditEvent("", "", MessageGroupDeleted(ev.GroupID), ActionGroupDeleted)
return AuditEventGroupDeleted{
AuditEvent: base,
GroupID: ev.GroupID,
}
}

// GroupMemberAdded converts a GroupMemberAdded event to an AuditEventGroupMemberAdded
func GroupMemberAdded(ev events.GroupMemberAdded) AuditEventGroupMemberAdded {
msg := MessageGroupMemberAdded(ev.GroupID, ev.UserID)
base := BasicAuditEvent("", "", msg, ActionGroupMemberAdded)
return AuditEventGroupMemberAdded{
AuditEvent: base,
GroupID: ev.GroupID,
UserID: ev.UserID,
}
}

// GroupMemberRemoved converts a GroupMemberRemoved event to an AuditEventGroupMemberRemove
func GroupMemberRemoved(ev events.GroupMemberRemoved) AuditEventGroupMemberRemoved {
msg := MessageGroupMemberRemoved(ev.GroupID, ev.UserID)
base := BasicAuditEvent("", "", msg, ActionGroupMemberRemoved)
return AuditEventGroupMemberRemoved{
AuditEvent: base,
GroupID: ev.GroupID,
UserID: ev.UserID,
}
}

func extractGrantee(uid *user.UserId, gid *group.GroupId) (string, string) {
switch {
case uid != nil && uid.OpaqueId != "":
Expand Down
7 changes: 7 additions & 0 deletions audit/pkg/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,12 @@ func RegisteredEvents() []events.Unmarshaller {
events.SpaceEnabled{},
events.SpaceDisabled{},
events.SpaceDeleted{},
events.UserCreated{},
events.UserDeleted{},
events.UserFeatureChanged{},
events.GroupCreated{},
events.GroupDeleted{},
events.GroupMemberAdded{},
events.GroupMemberRemoved{},
}
}
47 changes: 47 additions & 0 deletions audit/pkg/types/types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package types

import "github.com/cs3org/reva/v2/pkg/events"

// AuditEvent is the basic audit event
type AuditEvent struct {
RemoteAddr string // the remote client IP
Expand Down Expand Up @@ -197,3 +199,48 @@ type AuditEventSpaceEnabled struct {
type AuditEventSpaceDeleted struct {
AuditEventSpaces
}

// AuditEventUserCreated is the event logged when a user is created
type AuditEventUserCreated struct {
AuditEvent
UserID string
}

// AuditEventUserDeleted is the event logged when a user is deleted
type AuditEventUserDeleted struct {
AuditEvent
UserID string
}

// AuditEventUserFeatureChanged is the event logged when a user feature is changed
type AuditEventUserFeatureChanged struct {
AuditEvent
UserID string
Features []events.UserFeature
}

// AuditEventGroupCreated is the event logged when a group is created
type AuditEventGroupCreated struct {
AuditEvent
GroupID string
}

// AuditEventGroupDeleted is the event logged when a group is deleted
type AuditEventGroupDeleted struct {
AuditEvent
GroupID string
}

// AuditEventGroupMemberAdded is the event logged when a group member is added
type AuditEventGroupMemberAdded struct {
AuditEvent
GroupID string
UserID string
}

// AuditEventGroupMemberRemoved is the event logged when a group member is removed
type AuditEventGroupMemberRemoved struct {
AuditEvent
GroupID string
UserID string
}
12 changes: 12 additions & 0 deletions changelog/unreleased/user-group-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Enhancement: Implement audit events for user and groups

Added audit events for users and groups. This will log:
* User creation
* User deletion
* User property change (currently only email)
* Group creation
* Group deletion
* Group member add
* Group member remove

https://github.com/owncloud/ocis/pull/3467
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/blevesearch/bleve/v2 v2.3.2
github.com/coreos/go-oidc/v3 v3.1.0
github.com/cs3org/go-cs3apis v0.0.0-20220328105952-297bef33e13f
github.com/cs3org/reva/v2 v2.0.0-20220407085842-3cb849aed454
github.com/cs3org/reva/v2 v2.0.0-20220408135504-b09ab7f30b90
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
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBW
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
github.com/c0rby/reva/v2 v2.0.0-20220408131604-1da5e0195e73 h1:SUnn2hey8h3iGFVzAlGvQSnvmHy+kO2qOEYTyp+4GDU=
github.com/c0rby/reva/v2 v2.0.0-20220408131604-1da5e0195e73/go.mod h1:rE2wCGoiGiUuQ3zj6aD7sZ+BhboLyNsNQ3z3auunWm4=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
Expand Down Expand Up @@ -335,8 +337,8 @@ github.com/crewjam/httperr v0.2.0/go.mod h1:Jlz+Sg/XqBQhyMjdDiC+GNNRzZTD7x39Gu3p
github.com/crewjam/saml v0.4.6 h1:XCUFPkQSJLvzyl4cW9OvpWUbRf0gE7VUpU8ZnilbeM4=
github.com/crewjam/saml v0.4.6/go.mod h1:ZBOXnNPFzB3CgOkRm7Nd6IVdkG+l/wF+0ZXLqD96t1A=
github.com/cs3org/cato v0.0.0-20200828125504-e418fc54dd5e/go.mod h1:XJEZ3/EQuI3BXTp/6DUzFr850vlxq11I6satRtz0YQ4=
github.com/cs3org/reva/v2 v2.0.0-20220407085842-3cb849aed454 h1:25NWQyxjSg7FikhUm1BMxE7Ca9gZXQeOfzNsGY4iyoQ=
github.com/cs3org/reva/v2 v2.0.0-20220407085842-3cb849aed454/go.mod h1:rE2wCGoiGiUuQ3zj6aD7sZ+BhboLyNsNQ3z3auunWm4=
github.com/cs3org/reva/v2 v2.0.0-20220408135504-b09ab7f30b90 h1:tzlLpQrZ797P8+FqNl0TBcH6aQB7KfCf+4qvUGZSpTo=
github.com/cs3org/reva/v2 v2.0.0-20220408135504-b09ab7f30b90/go.mod h1:rE2wCGoiGiUuQ3zj6aD7sZ+BhboLyNsNQ3z3auunWm4=
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=
Expand Down
2 changes: 2 additions & 0 deletions graph/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ include ../.make/generate.mk
ci-go-generate: $(MOCKERY) # CI runs ci-node-generate automatically before this target
$(MOCKERY) --dir pkg/service/v0 --case underscore --name GatewayClient
$(MOCKERY) --dir pkg/service/v0 --case underscore --name HTTPClient
$(MOCKERY) --dir pkg/service/v0 --case underscore --name Publisher


.PHONY: ci-node-generate
ci-node-generate:
Expand Down
34 changes: 34 additions & 0 deletions graph/mocks/publisher.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions graph/pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Config struct {

Spaces Spaces `yaml:"spaces"`
Identity Identity `yaml:"identity"`
Events Events `yaml:"events"`

Context context.Context `yaml:"-"`
}
Expand Down Expand Up @@ -62,3 +63,9 @@ type Identity struct {
Backend string `yaml:"backend" env:"GRAPH_IDENTITY_BACKEND"`
LDAP LDAP `yaml:"ldap"`
}

// Events combines the configuration options for the event bus.
type Events struct {
Endpoint string `yaml:"events_endpoint" env:"GRAPH_EVENTS_ENDPOINT" desc:"the address of the streaming service"`
Cluster string `yaml:"events_cluster" env:"GRAPH_EVENTS_CLUSTER" desc:"the clusterID of the streaming service. Mandatory when using nats"`
}
4 changes: 4 additions & 0 deletions graph/pkg/config/defaults/defaultconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ func DefaultConfig() *config.Config {
GroupIDAttribute: "owncloudUUID",
},
},
Events: config.Events{
Endpoint: "127.0.0.1:9233",
Cluster: "ocis-cluster",
},
}
}

Expand Down
Loading

0 comments on commit b4f025c

Please sign in to comment.