From 1fb31178b620a1e4659ed57ea64980d6606af184 Mon Sep 17 00:00:00 2001 From: jkoberg Date: Wed, 12 Jun 2024 15:19:09 +0200 Subject: [PATCH] feat(activitylog): adjust response format Signed-off-by: jkoberg --- services/activitylog/pkg/service/http.go | 30 +++++--- services/activitylog/pkg/service/response.go | 75 +++++++++++++++----- services/eventhistory/pkg/service/service.go | 4 ++ 3 files changed, 80 insertions(+), 29 deletions(-) diff --git a/services/activitylog/pkg/service/http.go b/services/activitylog/pkg/service/http.go index 5636ec2432..81548b3ff9 100644 --- a/services/activitylog/pkg/service/http.go +++ b/services/activitylog/pkg/service/http.go @@ -2,13 +2,13 @@ package service import ( "encoding/json" - "fmt" "net/http" "net/url" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/cs3org/reva/v2/pkg/events" "github.com/cs3org/reva/v2/pkg/storagespace" + "github.com/cs3org/reva/v2/pkg/utils" "github.com/go-chi/chi/v5" ehmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/eventhistory/v0" ehsvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/eventhistory/v0" @@ -43,8 +43,6 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h ids = append(ids, a.EventID) } - fmt.Println("IDS:", ids) - evRes, err := s.evHistory.GetEvents(r.Context(), &ehsvc.GetEventsRequest{Ids: ids}) if err != nil { s.log.Error().Err(err).Msg("error getting events") @@ -52,25 +50,35 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h return } - // TODO: compare returned events with initial list and remove missing ones - - fmt.Println("EVENTS:", evRes.GetEvents()) - var acts []Activity for _, e := range evRes.GetEvents() { + // TODO: compare returned events with initial list and remove missing ones + // FIXME: Should all users get all events? If not we can filter here + var ( + message string + res Resource + act Actor + ts Times + ) + switch ev := s.unwrapEvent(e).(type) { case nil: // error already logged in unwrapEvent continue case events.UploadReady: - act := UploadReady(e.Id, ev) - acts = append(acts, act) + message = "{user} created {resource}" + res, act, ts, err = s.ResponseData(ev.FileRef, ev.ExecutingUser.GetId(), ev.ExecutingUser.GetDisplayName(), utils.TSToTime(ev.Timestamp)) } - } - fmt.Println("ACTIVITIES:", acts) + if err != nil { + s.log.Error().Err(err).Msg("error getting response data") + continue + } + + acts = append(acts, NewActivity(message, res, act, ts.RecordedTime, e.GetId())) + } b, err := json.Marshal(acts) if err != nil { diff --git a/services/activitylog/pkg/service/response.go b/services/activitylog/pkg/service/response.go index f09d6cfff1..9b24564ee4 100644 --- a/services/activitylog/pkg/service/response.go +++ b/services/activitylog/pkg/service/response.go @@ -3,8 +3,10 @@ package service import ( "time" - "github.com/cs3org/reva/v2/pkg/events" + user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1" + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" "github.com/cs3org/reva/v2/pkg/storagespace" + "github.com/cs3org/reva/v2/pkg/utils" ) // GetActivitiesResponse is the response on GET activities requests @@ -14,15 +16,14 @@ type GetActivitiesResponse struct { // Activity represents an activity as it is returned to the client type Activity struct { - ID string `json:"id"` + ID string `json:"id"` + DriveItem Resource `json:"driveItem"` + Actor Actor `json:"actor"` + Times Times `json:"times"` + Template Template `json:"template"` - // TODO: Implement these - Action interface{} `json:"action"` - DriveItem Resource `json:"driveItem"` - Actor Actor `json:"actor"` - Times Times `json:"times"` - - Template Template `json:"template"` + // TODO: Implement + Action interface{} `json:"action"` } // Resource represents an item such as a file or folder @@ -48,20 +49,58 @@ type Template struct { Variables map[string]interface{} `json:"variables"` } -// UploadReady converts a UploadReady events to an Activity -func UploadReady(eid string, e events.UploadReady) Activity { - rid, _ := storagespace.FormatReference(e.FileRef) - res := Resource{ - ID: rid, - Name: e.Filename, - } +// NewActivity creates a new activity +func NewActivity(message string, res Resource, user Actor, ts time.Time, eventID string) Activity { return Activity{ - ID: eid, + ID: eventID, + Times: Times{ + RecordedTime: ts, + }, + DriveItem: res, + Actor: user, Template: Template{ - Message: "file created", + Message: message, Variables: map[string]interface{}{ "resource": res, + "user": user, }, }, } } + +// 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) { + gwc, err := s.gws.Next() + if err != nil { + return Resource{}, Actor{}, Times{}, err + } + + ctx, err := utils.GetServiceUserContext(s.cfg.ServiceAccount.ServiceAccountID, gwc, s.cfg.ServiceAccount.ServiceAccountSecret) + if err != nil { + return Resource{}, Actor{}, Times{}, err + } + + info, err := utils.GetResource(ctx, ref, gwc) + if err != nil { + return Resource{}, Actor{}, Times{}, err + } + + if username == "" { + u, err := utils.GetUser(uid, gwc) + if err != nil { + return Resource{}, Actor{}, Times{}, err + } + username = u.GetUsername() + } + + return Resource{ + ID: storagespace.FormatResourceID(*info.Id), + Name: info.Path, + }, Actor{ + ID: uid.GetOpaqueId(), + DisplayName: username, + }, Times{ + RecordedTime: ts, + }, nil + +} diff --git a/services/eventhistory/pkg/service/service.go b/services/eventhistory/pkg/service/service.go index 848fc4d9b4..ba2a492986 100644 --- a/services/eventhistory/pkg/service/service.go +++ b/services/eventhistory/pkg/service/service.go @@ -130,6 +130,10 @@ func (eh *EventHistoryService) getEvent(id string) (*ehmsg.Event, error) { return nil, err } + if len(evs) == 0 { + return nil, store.ErrNotFound + } + var ev StoreEvent if err := json.Unmarshal(evs[0].Value, &ev); err != nil { eh.log.Error().Err(err).Str("eventid", id).Msg("could not unmarshal event")