Merge pull request #10104 from 2403905/issue-10011

Added the ShareUpdate activity in the space context.
This commit is contained in:
Roman Perekhod
2024-09-23 11:19:10 +02:00
committed by GitHub
13 changed files with 93 additions and 43 deletions

View File

@@ -0,0 +1,6 @@
Bugfix: Added ShareUpdate activity
Added the ShareUpdate activity in the space context.
https://github.com/owncloud/ocis/pull/10104
https://github.com/owncloud/ocis/issues/10011

2
go.mod
View File

@@ -15,7 +15,7 @@ require (
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/coreos/go-oidc/v3 v3.11.0
github.com/cs3org/go-cs3apis v0.0.0-20240724121416-062c4e3046cb
github.com/cs3org/reva/v2 v2.24.2-0.20240918135034-5a494dc2ebf7
github.com/cs3org/reva/v2 v2.24.2-0.20240919151635-556263192484
github.com/dhowden/tag v0.0.0-20230630033851-978a0926ee25
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
github.com/egirna/icap-client v0.1.1

4
go.sum
View File

@@ -255,8 +255,8 @@ github.com/crewjam/saml v0.4.14 h1:g9FBNx62osKusnFzs3QTN5L9CVA/Egfgm+stJShzw/c=
github.com/crewjam/saml v0.4.14/go.mod h1:UVSZCf18jJkk6GpWNVqcyQJMD5HsRugBPf4I1nl2mME=
github.com/cs3org/go-cs3apis v0.0.0-20240724121416-062c4e3046cb h1:KmYZDReplv/yfwc1LNYpDcVhVujC3Pasv6WjXx1haSU=
github.com/cs3org/go-cs3apis v0.0.0-20240724121416-062c4e3046cb/go.mod h1:yyP8PRo0EZou3nSH7H4qjlzQwaydPeIRNgX50npQHpE=
github.com/cs3org/reva/v2 v2.24.2-0.20240918135034-5a494dc2ebf7 h1:htjWHMNWh1YLOArxMtjV9zvj9Uu214iyYOHn8wi/10Q=
github.com/cs3org/reva/v2 v2.24.2-0.20240918135034-5a494dc2ebf7/go.mod h1:p7CHBXcg6sSqB+0JMNDfC1S7TSh9FghXkw1kTV3KcJI=
github.com/cs3org/reva/v2 v2.24.2-0.20240919151635-556263192484 h1:MeHzCFCh5WttP2hz7UTCHgV6WQXrucQXSyQs5+aIrcY=
github.com/cs3org/reva/v2 v2.24.2-0.20240919151635-556263192484/go.mod h1:p7CHBXcg6sSqB+0JMNDfC1S7TSh9FghXkw1kTV3KcJI=
github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=

View File

@@ -35,6 +35,7 @@ var _registeredEvents = []events.Unmarshaller{
events.ItemPurged{},
events.ItemMoved{},
events.ShareCreated{},
events.ShareUpdated{},
events.ShareRemoved{},
events.LinkCreated{},
events.LinkUpdated{},

View File

@@ -115,6 +115,9 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h
vars map[string]interface{}
)
loc := l10n.MustGetUserLocale(r.Context(), activeUser.GetId().GetOpaqueId(), r.Header.Get(l10n.HeaderAcceptLanguage), s.valService)
t := l10n.NewTranslatorFromCommonConfig(s.cfg.DefaultLanguage, _domain, s.cfg.TranslationPath, _localeFS, _localeSubPath)
switch ev := s.unwrapEvent(e).(type) {
case nil:
// error already logged in unwrapEvent
@@ -152,6 +155,13 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h
message = MessageShareCreated
ts = utils.TSToTime(ev.CTime)
vars, err = s.GetVars(ctx, WithResource(toRef(ev.ItemID), false), WithUser(ev.Executant, ""), WithSharee(ev.GranteeUserID, ev.GranteeGroupID))
case events.ShareUpdated:
if ev.Sharer != nil && ev.ItemID != nil && ev.Sharer.GetOpaqueId() == ev.ItemID.GetSpaceId() {
continue
}
message = MessageShareUpdated
ts = utils.TSToTime(ev.MTime)
vars, err = s.GetVars(ctx, WithResource(toRef(ev.ItemID), false), WithUser(ev.Executant, ""), WithTranslation(&t, loc, "field", ev.UpdateMask))
case events.ShareRemoved:
message = MessageShareDeleted
ts = ev.Timestamp
@@ -165,11 +175,12 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h
continue
}
message = MessageLinkUpdated
ts = utils.TSToTime(ev.CTime)
ts = utils.TSToTime(ev.MTime)
vars, err = s.GetVars(ctx,
WithResource(toRef(ev.ItemID), false),
WithUser(ev.Executant, ""),
WithLinkFieldUpdated(&ev))
WithTranslation(&t, loc, "field", []string{ev.FieldUpdated}),
WithVar("token", ev.ItemID.GetOpaqueId(), ev.Token))
case events.LinkRemoved:
message = MessageLinkDeleted
ts = utils.TSToTime(ev.Timestamp)
@@ -189,9 +200,6 @@ func (s *ActivitylogService) HandleGetItemActivities(w http.ResponseWriter, r *h
continue
}
loc := l10n.MustGetUserLocale(r.Context(), activeUser.GetId().GetOpaqueId(), r.Header.Get(l10n.HeaderAcceptLanguage), s.valService)
t := l10n.NewTranslatorFromCommonConfig(s.cfg.DefaultLanguage, _domain, s.cfg.TranslationPath, _localeFS, _localeSubPath)
resp.Activities = append(resp.Activities, NewActivity(t.Translate(message, loc), ts, e.GetId(), vars))
}

View File

@@ -3,8 +3,8 @@ package service
import (
"context"
"fmt"
"github.com/cs3org/reva/v2/pkg/events"
"path/filepath"
"strings"
"time"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
@@ -27,12 +27,29 @@ var (
MessageResourceMoved = l10n.Template("{user} moved {resource} to {folder}")
MessageResourceRenamed = l10n.Template("{user} renamed {oldResource} to {resource}")
MessageShareCreated = l10n.Template("{user} shared {resource} with {sharee}")
MessageShareUpdated = l10n.Template("{user} updated {field} for the {resource}")
MessageShareDeleted = l10n.Template("{user} removed {sharee} from {resource}")
MessageLinkCreated = l10n.Template("{user} shared {resource} via link")
MessageLinkUpdated = l10n.Template("{user} updated {field} for a link {token} on {resource}")
MessageLinkDeleted = l10n.Template("{user} removed link to {resource}")
MessageSpaceShared = l10n.Template("{user} added {sharee} as member of {space}")
MessageSpaceUnshared = l10n.Template("{user} removed {sharee} from {space}")
StrSomeField = l10n.Template(_someField)
StrPermission = l10n.Template(_permission)
StrPassword = l10n.Template(_password)
StrExpirationDate = l10n.Template(_expirationDate)
StrDisplayName = l10n.Template(_displayName)
StrDescription = l10n.Template(_description)
)
const (
_someField = "some field"
_permission = "permission"
_password = "password"
_expirationDate = "expiration date"
_displayName = "display name"
_description = "description"
)
// GetActivitiesResponse is the response on GET activities requests
@@ -228,29 +245,29 @@ func WithSpace(spaceid *provider.StorageSpaceId) ActivityOption {
}
}
// WithLinkFieldUpdated sets the field and token variables for an activity
func WithLinkFieldUpdated(e *events.LinkUpdated) ActivityOption {
// WithTranslation sets a variable that translation is needed for
func WithTranslation(t *l10n.Translator, locale string, key string, values []string) ActivityOption {
return func(_ context.Context, _ gateway.GatewayAPIClient, vars map[string]interface{}) error {
f := "some field"
switch e.FieldUpdated {
case "TYPE_PERMISSIONS":
f = "permission"
case "TYPE_PASSWORD":
f = "password"
case "TYPE_EXPIRATION":
f = "expiration date"
case "TYPE_DISPLAYNAME":
f = "display name"
case "TYPE_DESCRIPTION":
f = "description"
f := t.Translate(StrSomeField, locale)
if len(values) > 0 {
for i := range values {
values[i] = t.Translate(mapField(values[i]), locale)
}
f = strings.Join(values, ", ")
}
vars["field"] = Resource{
ID: e.ItemID.GetOpaqueId(),
vars[key] = Resource{
Name: f,
}
vars["token"] = Resource{
ID: e.ItemID.GetOpaqueId(),
Name: e.Token,
return nil
}
}
// WithVar sets a variable for an activity
func WithVar(key, id, name string) ActivityOption {
return func(_ context.Context, _ gateway.GatewayAPIClient, vars map[string]interface{}) error {
vars[key] = Resource{
ID: id,
Name: name,
}
return nil
}
@@ -284,3 +301,19 @@ func (s *ActivitylogService) GetVars(ctx context.Context, opts ...ActivityOption
return vars, nil
}
func mapField(val string) string {
switch val {
case "TYPE_PERMISSIONS", "permission":
return _permission
case "TYPE_PASSWORD", "password":
return _password
case "TYPE_EXPIRATION", "expiration":
return _expirationDate
case "TYPE_DISPLAYNAME":
return _displayName
case "TYPE_DESCRIPTION":
return _description
}
return _someField
}

View File

@@ -110,13 +110,17 @@ func (a *ActivitylogService) Run() {
err = a.AddActivity(ev.Ref, e.ID, utils.TSToTime(ev.Timestamp))
case events.ShareCreated:
err = a.AddActivity(toRef(ev.ItemID), e.ID, utils.TSToTime(ev.CTime))
case events.ShareUpdated:
if ev.Sharer != nil && ev.ItemID != nil && ev.Sharer.GetOpaqueId() != ev.ItemID.GetSpaceId() {
err = a.AddActivity(toRef(ev.ItemID), e.ID, utils.TSToTime(ev.MTime))
}
case events.ShareRemoved:
err = a.AddActivity(toRef(ev.ItemID), e.ID, ev.Timestamp)
case events.LinkCreated:
err = a.AddActivity(toRef(ev.ItemID), e.ID, utils.TSToTime(ev.CTime))
case events.LinkUpdated:
if ev.Sharer != nil && ev.ItemID != nil && ev.Sharer.GetOpaqueId() != ev.ItemID.GetSpaceId() {
err = a.AddActivity(toRef(ev.ItemID), e.ID, utils.TSToTime(ev.CTime))
err = a.AddActivity(toRef(ev.ItemID), e.ID, utils.TSToTime(ev.MTime))
}
case events.LinkRemoved:
err = a.AddActivity(toRef(ev.ItemID), e.ID, utils.TSToTime(ev.Timestamp))

View File

@@ -123,7 +123,7 @@ var testCases = []struct {
Sharer: userID("sharing-userid"),
ItemID: resourceID("provider-1", "storage-1", "itemid-1"),
Permissions: linkPermissions("stat"),
CTime: timestamp(10e8),
MTime: timestamp(10e8),
DisplayName: "link",
Expiration: timestamp(10e8 + 10e5),
PasswordProtected: true,

View File

@@ -115,7 +115,7 @@ func ShareUpdated(ev events.ShareUpdated) AuditEventShareUpdated {
func LinkUpdated(ev events.LinkUpdated) AuditEventShareUpdated {
uid := ev.Sharer.OpaqueId
with, typ := "", _linktype
base := BasicAuditEvent(uid, formatTime(ev.CTime), MessageLinkUpdated(uid, ev.ShareID.OpaqueId, ev.FieldUpdated), updateType(ev.FieldUpdated))
base := BasicAuditEvent(uid, formatTime(ev.MTime), MessageLinkUpdated(uid, ev.ShareID.GetOpaqueId(), ev.FieldUpdated), updateType(ev.FieldUpdated))
return AuditEventShareUpdated{
AuditEventSharing: SharingAuditEvent(ev.ShareID.GetOpaqueId(), ev.ItemID.OpaqueId, uid, base),
ShareOwner: uid,

View File

@@ -78,12 +78,6 @@ func ShareRemoved(r *collaboration.RemoveShareResponse, req *collaboration.Remov
// ShareUpdated converts the response to an event
func ShareUpdated(r *collaboration.UpdateShareResponse, req *collaboration.UpdateShareRequest, executant *user.UserId) events.ShareUpdated {
updated := ""
if req.Field.GetPermissions() != nil {
updated = "permissions"
} else if req.Field.GetDisplayName() != "" {
updated = "displayname"
}
return events.ShareUpdated{
Executant: executant,
ShareID: r.Share.Id,
@@ -93,7 +87,7 @@ func ShareUpdated(r *collaboration.UpdateShareResponse, req *collaboration.Updat
GranteeGroupID: r.Share.GetGrantee().GetGroupId(),
Sharer: r.Share.Creator,
MTime: r.Share.Mtime,
Updated: updated,
UpdateMask: req.GetUpdateMask().GetPaths(),
}
}
@@ -139,7 +133,7 @@ func LinkUpdated(r *link.UpdatePublicShareResponse, req *link.UpdatePublicShareR
DisplayName: r.Share.DisplayName,
Expiration: r.Share.Expiration,
PasswordProtected: r.Share.PasswordProtected,
CTime: r.Share.Ctime,
MTime: r.Share.Mtime,
Token: r.Share.Token,
FieldUpdated: link.UpdatePublicShareRequest_Update_Type_name[int32(req.Update.GetType())],
}

View File

@@ -84,8 +84,9 @@ type ShareUpdated struct {
Sharer *user.UserId
MTime *types.Timestamp
// indicates what was updated - one of "displayname", "permissions"
Updated string
Updated string // Deprecated
// indicates what was updated
UpdateMask []string
}
// Unmarshal to fulfill umarshaller interface
@@ -165,7 +166,7 @@ type LinkUpdated struct {
DisplayName string
Expiration *types.Timestamp
PasswordProtected bool
CTime *types.Timestamp
MTime *types.Timestamp
Token string
FieldUpdated string

View File

@@ -146,6 +146,9 @@ func TSToUnixNano(ts *types.Timestamp) uint64 {
// TSToTime converts a protobuf Timestamp to Go's time.Time.
func TSToTime(ts *types.Timestamp) time.Time {
if ts == nil {
return time.Time{}
}
return time.Unix(int64(ts.Seconds), int64(ts.Nanos))
}

2
vendor/modules.txt vendored
View File

@@ -367,7 +367,7 @@ github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1
github.com/cs3org/go-cs3apis/cs3/storage/registry/v1beta1
github.com/cs3org/go-cs3apis/cs3/tx/v1beta1
github.com/cs3org/go-cs3apis/cs3/types/v1beta1
# github.com/cs3org/reva/v2 v2.24.2-0.20240918135034-5a494dc2ebf7
# github.com/cs3org/reva/v2 v2.24.2-0.20240919151635-556263192484
## explicit; go 1.21
github.com/cs3org/reva/v2/cmd/revad/internal/grace
github.com/cs3org/reva/v2/cmd/revad/runtime