From bfa4b8abbebdfcaec1b32d282b7e47c8065f88b2 Mon Sep 17 00:00:00 2001 From: jkoberg Date: Thu, 10 Mar 2022 16:20:06 +0100 Subject: [PATCH] link accessed and access failed events Signed-off-by: jkoberg --- .../eventsmiddleware/conversion.go | 25 +++++++++++ .../interceptors/eventsmiddleware/events.go | 17 ++++++++ pkg/events/example/consumer/consumer.go | 1 + pkg/events/types.go | 41 +++++++++++++++++-- 4 files changed, 80 insertions(+), 4 deletions(-) diff --git a/internal/grpc/interceptors/eventsmiddleware/conversion.go b/internal/grpc/interceptors/eventsmiddleware/conversion.go index 08735cee125..b4f63343af3 100644 --- a/internal/grpc/interceptors/eventsmiddleware/conversion.go +++ b/internal/grpc/interceptors/eventsmiddleware/conversion.go @@ -108,6 +108,31 @@ func LinkUpdated(r *link.UpdatePublicShareResponse, req *link.UpdatePublicShareR } } +// 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{ diff --git a/internal/grpc/interceptors/eventsmiddleware/events.go b/internal/grpc/interceptors/eventsmiddleware/events.go index f302a59b871..1e79fe14bf7 100644 --- a/internal/grpc/interceptors/eventsmiddleware/events.go +++ b/internal/grpc/interceptors/eventsmiddleware/events.go @@ -88,6 +88,23 @@ func NewUnary(m map[string]interface{}) (grpc.UnaryServerInterceptor, int, error if isSuccess(v) { ev = LinkRemoved(v, req.(*link.RemovePublicShareRequest)) } + case *link.GetPublicShareByTokenResponse: + switch v.Status.Code { + case rpc.Code_CODE_OK: + ev = LinkAccessed(v) + case rpc.Code_CODE_NOT_FOUND: + // in this case the URL from the link is misspelled. Do we want to track this? + case rpc.Code_CODE_PERMISSION_DENIED: + // clients are currently checking for password protection by sending a request without password + // so logging this would spam the event bus unneccessarily + // as soon as clients have a better way to make this check we can remove this case + if v.Status.Message == "wrong password" { + ev = LinkAccessFailed(v, req.(*link.GetPublicShareByTokenRequest)) + } + default: + ev = LinkAccessFailed(v, req.(*link.GetPublicShareByTokenRequest)) + + } } if ev != nil { diff --git a/pkg/events/example/consumer/consumer.go b/pkg/events/example/consumer/consumer.go index 615687b42e0..c0a1278acb5 100644 --- a/pkg/events/example/consumer/consumer.go +++ b/pkg/events/example/consumer/consumer.go @@ -41,6 +41,7 @@ func Example(c events.Consumer) { events.LinkCreated{}, events.LinkUpdated{}, events.LinkRemoved{}, + events.LinkAccessed{}, } // Step 3 - create event channel diff --git a/pkg/events/types.go b/pkg/events/types.go index fd2b5a9a172..bd47a29b0bc 100644 --- a/pkg/events/types.go +++ b/pkg/events/types.go @@ -23,6 +23,7 @@ import ( group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1" user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + rpc "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" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" @@ -112,10 +113,7 @@ type LinkCreated struct { Expiration *types.Timestamp PasswordProtected bool CTime *types.Timestamp - - // TODO: are we sure we want to send the token via event-bus? Imho this is a major security issue: - // Eveybody who has access to the event bus can access the file - Token string + Token string } // Unmarshal to fulfill umarshaller interface @@ -147,6 +145,41 @@ func (LinkUpdated) Unmarshal(v []byte) (interface{}, error) { return e, err } +// LinkAccessed is emitted when a public link is accessed successfully (by token) +type LinkAccessed struct { + ShareID *link.PublicShareId + Sharer *user.UserId + ItemID *provider.ResourceId + Permissions *link.PublicSharePermissions + DisplayName string + Expiration *types.Timestamp + PasswordProtected bool + CTime *types.Timestamp + Token string +} + +// Unmarshal to fulfill umarshaller interface +func (LinkAccessed) Unmarshal(v []byte) (interface{}, error) { + e := LinkAccessed{} + err := json.Unmarshal(v, &e) + return e, err +} + +// LinkAccessFailed is emitted when an access to a public link has resulted in an error (by token) +type LinkAccessFailed struct { + ShareID *link.PublicShareId + Token string + Status rpc.Code + Message string +} + +// Unmarshal to fulfill umarshaller interface +func (LinkAccessFailed) Unmarshal(v []byte) (interface{}, error) { + e := LinkAccessFailed{} + err := json.Unmarshal(v, &e) + return e, err +} + // LinkRemoved is emitted when a share is removed type LinkRemoved struct { // split protobuf Ref