Skip to content

Commit

Permalink
Share events for audit logging (#2627)
Browse files Browse the repository at this point in the history
* share removed event

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

* update share event

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

* link created event

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

* link updated event

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

* link removed event

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

* update received share event

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

* link accessed and access failed events

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

* add changelog

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

* permissions for sharecreated

Signed-off-by: jkoberg <jkoberg@owncloud.com>
  • Loading branch information
kobergj committed Mar 14, 2022
1 parent b086491 commit 8e5b22a
Show file tree
Hide file tree
Showing 5 changed files with 317 additions and 7 deletions.
6 changes: 6 additions & 0 deletions changelog/unreleased/sharing-events.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Enhancement: Add events for sharing action

Includes lifecycle events for shares and public links doesn't include federated sharing events for now
see full list of events in `pkg/events/types.go`

https://github.com/cs3org/reva/pull/2627
112 changes: 109 additions & 3 deletions internal/grpc/interceptors/eventsmiddleware/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,124 @@ package eventsmiddleware

import (
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
"github.com/cs3org/reva/v2/pkg/events"
)

// ShareCreated converts response to event
// ShareCreated converts the response to an event
func ShareCreated(r *collaboration.CreateShareResponse) events.ShareCreated {
e := events.ShareCreated{
return events.ShareCreated{
Sharer: r.Share.Creator,
GranteeUserID: r.Share.GetGrantee().GetUserId(),
GranteeGroupID: r.Share.GetGrantee().GetGroupId(),
ItemID: r.Share.ResourceId,
CTime: r.Share.Ctime,
Permissions: r.Share.Permissions,
}
}

// ShareRemoved converts the response to an event
func ShareRemoved(r *collaboration.RemoveShareResponse, req *collaboration.RemoveShareRequest) events.ShareRemoved {
return events.ShareRemoved{
ShareID: req.Ref.GetId(),
ShareKey: req.Ref.GetKey(),
}
}

// ShareUpdated converts the response to an event
func ShareUpdated(r *collaboration.UpdateShareResponse, req *collaboration.UpdateShareRequest) events.ShareUpdated {
updated := ""
if req.Field.GetPermissions() != nil {
updated = "permissions"
} else if req.Field.GetDisplayName() != "" {
updated = "displayname"
}
return events.ShareUpdated{
ShareID: r.Share.Id,
ItemID: r.Share.ResourceId,
Permissions: r.Share.Permissions,
GranteeUserID: r.Share.GetGrantee().GetUserId(),
GranteeGroupID: r.Share.GetGrantee().GetGroupId(),
Sharer: r.Share.Creator,
MTime: r.Share.Mtime,
Updated: updated,
}
}

// ReceivedShareUpdated converts the response to an event
func ReceivedShareUpdated(r *collaboration.UpdateReceivedShareResponse) events.ReceivedShareUpdated {
return events.ReceivedShareUpdated{
ShareID: r.Share.Share.Id,
ItemID: r.Share.Share.ResourceId,
Permissions: r.Share.Share.Permissions,
GranteeUserID: r.Share.Share.GetGrantee().GetUserId(),
GranteeGroupID: r.Share.Share.GetGrantee().GetGroupId(),
Sharer: r.Share.Share.Creator,
MTime: r.Share.Share.Mtime,
State: collaboration.ShareState_name[int32(r.Share.State)],
}
}

// LinkCreated converts the response to an event
func LinkCreated(r *link.CreatePublicShareResponse) events.LinkCreated {
return events.LinkCreated{
ShareID: r.Share.Id,
Sharer: r.Share.Creator,
ItemID: r.Share.ResourceId,
Permissions: r.Share.Permissions,
DisplayName: r.Share.DisplayName,
Expiration: r.Share.Expiration,
PasswordProtected: r.Share.PasswordProtected,
CTime: r.Share.Ctime,
Token: r.Share.Token,
}
}

// LinkUpdated converts the response to an event
func LinkUpdated(r *link.UpdatePublicShareResponse, req *link.UpdatePublicShareRequest) events.LinkUpdated {
return events.LinkUpdated{
ShareID: r.Share.Id,
Sharer: r.Share.Creator,
ItemID: r.Share.ResourceId,
Permissions: r.Share.Permissions,
DisplayName: r.Share.DisplayName,
Expiration: r.Share.Expiration,
PasswordProtected: r.Share.PasswordProtected,
CTime: r.Share.Ctime,
Token: r.Share.Token,
FieldUpdated: link.UpdatePublicShareRequest_Update_Type_name[int32(req.Update.GetType())],
}
}

return e
// LinkAccessed converts the response to an event
func LinkAccessed(r *link.GetPublicShareByTokenResponse) events.LinkAccessed {
return events.LinkAccessed{
ShareID: r.Share.Id,
Sharer: r.Share.Creator,
ItemID: r.Share.ResourceId,
Permissions: r.Share.Permissions,
DisplayName: r.Share.DisplayName,
Expiration: r.Share.Expiration,
PasswordProtected: r.Share.PasswordProtected,
CTime: r.Share.Ctime,
Token: r.Share.Token,
}
}

// LinkAccessFailed converts the response to an event
func LinkAccessFailed(r *link.GetPublicShareByTokenResponse, req *link.GetPublicShareByTokenRequest) events.LinkAccessFailed {
return events.LinkAccessFailed{
ShareID: r.Share.Id,
Token: r.Share.Token,
Status: r.Status.Code,
Message: r.Status.Message,
}
}

// LinkRemoved converts the response to an event
func LinkRemoved(r *link.RemovePublicShareResponse, req *link.RemovePublicShareRequest) events.LinkRemoved {
return events.LinkRemoved{
ShareID: req.Ref.GetId(),
ShareToken: req.Ref.GetToken(),
}
}
43 changes: 42 additions & 1 deletion internal/grpc/interceptors/eventsmiddleware/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import (

"github.com/asim/go-micro/plugins/events/nats/v4"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
v1beta12 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
link "github.com/cs3org/go-cs3apis/cs3/sharing/link/v1beta1"
"github.com/cs3org/reva/v2/pkg/events"
"github.com/cs3org/reva/v2/pkg/events/server"
"github.com/cs3org/reva/v2/pkg/rgrpc"
Expand Down Expand Up @@ -59,9 +61,39 @@ func NewUnary(m map[string]interface{}) (grpc.UnaryServerInterceptor, int, error
var ev interface{}
switch v := res.(type) {
case *collaboration.CreateShareResponse:
if v.Status.Code == rpc.Code_CODE_OK {
if isSuccess(v) {
ev = ShareCreated(v)
}
case *collaboration.RemoveShareResponse:
if isSuccess(v) {
ev = ShareRemoved(v, req.(*collaboration.RemoveShareRequest))
}
case *collaboration.UpdateShareResponse:
if isSuccess(v) {
ev = ShareUpdated(v, req.(*collaboration.UpdateShareRequest))
}
case *collaboration.UpdateReceivedShareResponse:
if isSuccess(v) {
ev = ReceivedShareUpdated(v)
}
case *link.CreatePublicShareResponse:
if isSuccess(v) {
ev = LinkCreated(v)
}
case *link.UpdatePublicShareResponse:
if isSuccess(v) {
ev = LinkUpdated(v, req.(*link.UpdatePublicShareRequest))
}
case *link.RemovePublicShareResponse:
if isSuccess(v) {
ev = LinkRemoved(v, req.(*link.RemovePublicShareRequest))
}
case *link.GetPublicShareByTokenResponse:
if isSuccess(v) {
ev = LinkAccessed(v)
} else {
ev = LinkAccessFailed(v, req.(*link.GetPublicShareByTokenRequest))
}
}

if ev != nil {
Expand All @@ -85,6 +117,15 @@ func NewStream() grpc.StreamServerInterceptor {
return interceptor
}

// common interface to all responses
type su interface {
GetStatus() *v1beta12.Status
}

func isSuccess(res su) bool {
return res.GetStatus().Code == rpc.Code_CODE_OK
}

func publisherFromConfig(m map[string]interface{}) (events.Publisher, error) {
typ := m["type"].(string)
switch typ {
Expand Down
11 changes: 9 additions & 2 deletions pkg/events/example/consumer/consumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,15 @@ func Example(c events.Consumer) {

// Step 2 - which events does the consumer listen too?
evs := []events.Unmarshaller{
// for example created shares
events.ShareCreated{},
events.ShareUpdated{},
events.ShareRemoved{},
events.ReceivedShareUpdated{},
events.LinkCreated{},
events.LinkUpdated{},
events.LinkRemoved{},
events.LinkAccessed{},
events.LinkAccessFailed{},
}

// Step 3 - create event channel
Expand All @@ -53,7 +60,7 @@ func Example(c events.Consumer) {
case events.ShareCreated:
fmt.Printf("%s) Share created: %+v\n", group, v)
default:
fmt.Printf("%s) Unregistered event: %+v\n", group, v)
fmt.Printf("%s) %T: %+v\n", group, v, v)
}
}

Expand Down
Loading

0 comments on commit 8e5b22a

Please sign in to comment.