From 949c5d08484f61a72a2debf5bf709eb126d3cdaf Mon Sep 17 00:00:00 2001 From: Florian Schade Date: Tue, 18 Jun 2024 12:13:13 +0200 Subject: [PATCH] enhancement(activitylog): enhance activitylog graph endpoint - make use of libregraph artifacts - add a basic activity kql ast parser --- services/activitylog/pkg/service/http.go | 36 ++++++++++++++-- services/activitylog/pkg/service/response.go | 42 ++++++------------- services/activitylog/pkg/service/service.go | 7 ++-- .../pkg/config/defaults/defaultconfig.go | 9 +--- 4 files changed, 50 insertions(+), 44 deletions(-) diff --git a/services/activitylog/pkg/service/http.go b/services/activitylog/pkg/service/http.go index 6cf8ba551d..f574bfea85 100644 --- a/services/activitylog/pkg/service/http.go +++ b/services/activitylog/pkg/service/http.go @@ -5,6 +5,7 @@ import ( "encoding/json" "net/http" "net/url" + "strings" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" revactx "github.com/cs3org/reva/v2/pkg/ctx" @@ -12,10 +13,14 @@ import ( "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/cs3org/reva/v2/pkg/utils" "github.com/go-chi/chi/v5" + libregraph "github.com/owncloud/libre-graph-api-go" + "github.com/owncloud/ocis/v2/ocis-pkg/l10n" ehmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/eventhistory/v0" ehsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/eventhistory/v0" "github.com/owncloud/ocis/v2/services/graph/pkg/errorcode" + "github.com/owncloud/ocis/v2/services/search/pkg/query/ast" + "github.com/owncloud/ocis/v2/services/search/pkg/query/kql" ) var ( @@ -42,8 +47,33 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h return } - // TODO: Compare driveid with itemid to avoid bad requests - rid, err := parseIDParam(r, "item-id") + qraw := r.URL.Query().Get("kql") + if qraw == "" { + w.WriteHeader(http.StatusBadRequest) + } + + qBuilder := kql.Builder{} + qast, err := qBuilder.Build(qraw) + if err != nil { + w.WriteHeader(http.StatusBadRequest) + } + + var itemID string + + for _, n := range qast.Nodes { + v, ok := n.(*ast.StringNode) + if !ok { + continue + } + + if strings.ToLower(v.Key) != "itemid" { + continue + } + + itemID = v.Value + } + + rid, err := storagespace.ParseID(itemID) if err != nil { s.log.Info().Err(err).Msg("invalid resource id") w.WriteHeader(http.StatusBadRequest) @@ -80,7 +110,7 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h message string res Resource act Actor - ts Times + ts libregraph.ActivityTimes ) switch ev := s.unwrapEvent(e).(type) { diff --git a/services/activitylog/pkg/service/response.go b/services/activitylog/pkg/service/response.go index ce185cc206..9186d1d3e8 100644 --- a/services/activitylog/pkg/service/response.go +++ b/services/activitylog/pkg/service/response.go @@ -7,6 +7,8 @@ import ( provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/cs3org/reva/v2/pkg/utils" + libregraph "github.com/owncloud/libre-graph-api-go" + "github.com/owncloud/ocis/v2/ocis-pkg/l10n" ) @@ -29,14 +31,7 @@ var ( // GetActivitiesResponse is the response on GET activities requests type GetActivitiesResponse struct { - Activities []Activity `json:"value"` -} - -// Activity represents an activity as it is returned to the client -type Activity struct { - ID string `json:"id"` - Times Times `json:"times"` - Template Template `json:"template"` + Activities []libregraph.Activity `json:"value"` } // Resource represents an item such as a file or folder @@ -51,23 +46,12 @@ type Actor struct { DisplayName string `json:"displayName"` } -// Times represents the timestamps of the Activity -type Times struct { - RecordedTime time.Time `json:"recordedTime"` -} - -// Template contains activity details -type Template struct { - Message string `json:"message"` - Variables map[string]interface{} `json:"variables"` -} - // NewActivity creates a new activity -func NewActivity(message string, res Resource, user Actor, ts Times, eventID string) Activity { - return Activity{ - ID: eventID, +func NewActivity(message string, res Resource, user Actor, ts libregraph.ActivityTimes, eventID string) libregraph.Activity { + return libregraph.Activity{ + Id: eventID, Times: ts, - Template: Template{ + Template: libregraph.ActivityTemplate{ Message: message, Variables: map[string]interface{}{ "resource": res, @@ -78,26 +62,26 @@ func NewActivity(message string, res Resource, user Actor, ts Times, eventID str } // ResponseData returns the relevant response data for the activity -func (s *ActivitylogService) ResponseData(ref *provider.Reference, uid *user.UserId, username string, ts time.Time) (Resource, Actor, Times, error) { +func (s *ActivitylogService) ResponseData(ref *provider.Reference, uid *user.UserId, username string, ts time.Time) (Resource, Actor, libregraph.ActivityTimes, error) { gwc, err := s.gws.Next() if err != nil { - return Resource{}, Actor{}, Times{}, err + return Resource{}, Actor{}, libregraph.ActivityTimes{}, err } ctx, err := utils.GetServiceUserContext(s.cfg.ServiceAccount.ServiceAccountID, gwc, s.cfg.ServiceAccount.ServiceAccountSecret) if err != nil { - return Resource{}, Actor{}, Times{}, err + return Resource{}, Actor{}, libregraph.ActivityTimes{}, err } info, err := utils.GetResource(ctx, ref, gwc) if err != nil { - return Resource{}, Actor{}, Times{}, err + return Resource{}, Actor{}, libregraph.ActivityTimes{}, err } if username == "" { u, err := utils.GetUser(uid, gwc) if err != nil { - return Resource{}, Actor{}, Times{}, err + return Resource{}, Actor{}, libregraph.ActivityTimes{}, err } username = u.GetUsername() } @@ -108,7 +92,7 @@ func (s *ActivitylogService) ResponseData(ref *provider.Reference, uid *user.Use }, Actor{ ID: uid.GetOpaqueId(), DisplayName: username, - }, Times{ + }, libregraph.ActivityTimes{ RecordedTime: ts, }, nil diff --git a/services/activitylog/pkg/service/service.go b/services/activitylog/pkg/service/service.go index 9cfbb7ff28..0362474059 100644 --- a/services/activitylog/pkg/service/service.go +++ b/services/activitylog/pkg/service/service.go @@ -15,11 +15,12 @@ import ( "github.com/cs3org/reva/v2/pkg/storagespace" "github.com/cs3org/reva/v2/pkg/utils" "github.com/go-chi/chi/v5" + microstore "go-micro.dev/v4/store" + "github.com/owncloud/ocis/v2/ocis-pkg/log" ehsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/eventhistory/v0" settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0" "github.com/owncloud/ocis/v2/services/activitylog/pkg/config" - microstore "go-micro.dev/v4/store" ) // RawActivity represents an activity as it is stored in the activitylog store @@ -75,9 +76,7 @@ func New(opts ...Option) (*ActivitylogService, error) { registeredEvents: make(map[string]events.Unmarshaller), } - s.mux.Route("/graph/v1.0/drives/{drive-id}", func(r chi.Router) { - r.Get("/items/{item-id}/activities", s.HandleGetItemActivities) - }) + s.mux.Get("/graph/v1beta1/extensions/org.libregraph/activities", s.HandleGetItemActivities) for _, e := range o.RegisteredEvents { typ := reflect.TypeOf(e) diff --git a/services/proxy/pkg/config/defaults/defaultconfig.go b/services/proxy/pkg/config/defaults/defaultconfig.go index e73fe14e9b..af2093522b 100644 --- a/services/proxy/pkg/config/defaults/defaultconfig.go +++ b/services/proxy/pkg/config/defaults/defaultconfig.go @@ -236,15 +236,8 @@ func DefaultPolicies() []config.Policy { Endpoint: "/app/", // /app or /apps? ocdav only handles /apps Service: "com.owncloud.web.frontend", }, - // reroute activities endpoint to activitylog service - // { - // Type: config.RegexRoute, - // Endpoint: "/graph/v1.0/drives/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/items/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/activities", - // Service: "com.owncloud.web.activitylog", - // }, { - Type: config.RegexRoute, - Endpoint: "/graph/v1.0/drives/[^/]+/items/[^/]+/activities", + Endpoint: "/graph/v1beta1/extensions/org.libregraph/activities", Service: "com.owncloud.web.activitylog", }, {