mirror of
https://github.com/owncloud/ocis.git
synced 2025-04-18 23:44:07 +03:00
fix: ocm share notifications
eventsmiddleware OCMCoreShareCreated intercepted in ocis wip: ocm share removed event feat: userlog, ocm share handling feat: formatted user notifications feat: changelog feat: resolve username of the sharer fix: revert event field name change feat: event config for reva omcore fix: remove config for request interception fix: getOCMUser fix: config cleanup feat: bump reva version fix: go vendor fix: remove unused
This commit is contained in:
parent
64abd624a9
commit
ba7987ff5b
6
changelog/unreleased/fix-ocm-share-notifications.md
Normal file
6
changelog/unreleased/fix-ocm-share-notifications.md
Normal file
@ -0,0 +1,6 @@
|
||||
Bugfix: OCM Share Notifications
|
||||
|
||||
Fix no OCM sharing notifications, now share and unshare notifications are created
|
||||
|
||||
https://github.com/owncloud/ocis/pull/11162
|
||||
https://github.com/owncloud/ocis/issues/11042
|
2
go.mod
2
go.mod
@ -67,7 +67,7 @@ require (
|
||||
github.com/open-policy-agent/opa v0.70.0
|
||||
github.com/orcaman/concurrent-map v1.0.0
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20250217093259-fa3804be6c27
|
||||
github.com/owncloud/reva/v2 v2.0.0-20250313103212-d8b4c329554a
|
||||
github.com/owncloud/reva/v2 v2.0.0-20250331084351-00f64db78848
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/xattr v0.4.10
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
|
4
go.sum
4
go.sum
@ -881,8 +881,8 @@ github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CF
|
||||
github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA=
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20250217093259-fa3804be6c27 h1:ID8s5lGBntmrlI6TbDAjTzRyHucn3bVM2wlW+HBplv4=
|
||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20250217093259-fa3804be6c27/go.mod h1:+gT+x62AS9u2Farh9wE2uYmgdvTg0MQgsSI62D+xoRg=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20250313103212-d8b4c329554a h1:90QCmxi6n/GkcYbm+zw7Y4HrLcLzqN/ipFfNCOLw3TA=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20250313103212-d8b4c329554a/go.mod h1:1QUFTq8Q2tjzwY3g+Y1dHIO4tPYqTovV6ScacW3sTPs=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20250331084351-00f64db78848 h1:eWOevrc619bmhJwV9tzT3Ak1oFU9Nx9gufLFiCETN9Q=
|
||||
github.com/owncloud/reva/v2 v2.0.0-20250331084351-00f64db78848/go.mod h1:1QUFTq8Q2tjzwY3g+Y1dHIO4tPYqTovV6ScacW3sTPs=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
|
||||
github.com/pablodz/inotifywaitgo v0.0.7 h1:1ii49dGBnRn0t1Sz7RGZS6/NberPEDQprwKHN49Bv6U=
|
||||
|
@ -168,6 +168,14 @@ func OCMConfigFromStruct(cfg *config.Config, logger log.Logger) map[string]inter
|
||||
"file": cfg.OCMCore.Drivers.JSON.File,
|
||||
},
|
||||
},
|
||||
"events": map[string]interface{}{
|
||||
"natsaddress": cfg.Events.Endpoint,
|
||||
"natsclusterid": cfg.Events.Cluster,
|
||||
"tlsinsecure": cfg.Events.TLSInsecure,
|
||||
"tlsrootcacertificate": cfg.Events.TLSRootCACertificate,
|
||||
"authusername": cfg.Events.AuthUsername,
|
||||
"authpassword": cfg.Events.AuthPassword,
|
||||
},
|
||||
},
|
||||
"storageprovider": map[string]interface{}{
|
||||
"driver": "ocmreceived",
|
||||
|
@ -43,6 +43,8 @@ var _registeredEvents = []events.Unmarshaller{
|
||||
events.ShareCreated{},
|
||||
events.ShareRemoved{},
|
||||
events.ShareExpired{},
|
||||
events.OCMCoreShareCreated{},
|
||||
events.OCMCoreShareDelete{},
|
||||
}
|
||||
|
||||
// Server is the entrypoint for the server command.
|
||||
|
@ -12,6 +12,9 @@ import (
|
||||
|
||||
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
||||
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
invitepb "github.com/cs3org/go-cs3apis/cs3/ocm/invite/v1beta1"
|
||||
typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
|
||||
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
|
||||
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
"github.com/owncloud/ocis/v2/ocis-pkg/l10n"
|
||||
@ -28,7 +31,6 @@ var (
|
||||
_resourceTypeResource = "resource"
|
||||
_resourceTypeSpace = "storagespace"
|
||||
_resourceTypeShare = "share"
|
||||
_resourceTypeGlobal = "global"
|
||||
|
||||
_domain = "userlog"
|
||||
)
|
||||
@ -115,6 +117,10 @@ func (c *Converter) ConvertEvent(eventid string, event interface{}) (OC10Notific
|
||||
return c.shareMessage(eventid, ShareExpired, ev.ShareOwner, ev.ItemID, ev.ShareID, ev.ExpiredAt)
|
||||
case events.ShareRemoved:
|
||||
return c.shareMessage(eventid, ShareRemoved, ev.Executant, ev.ItemID, ev.ShareID, ev.Timestamp)
|
||||
case events.OCMCoreShareCreated:
|
||||
return c.omcShareCreatedMessage(ev, eventid)
|
||||
case events.OCMCoreShareDelete:
|
||||
return c.omcShareDeleteMessage(ev, eventid)
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,6 +239,95 @@ func (c *Converter) shareMessage(eventid string, nt NotificationTemplate, execut
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Converter) omcShareCreatedMessage(ev events.OCMCoreShareCreated, eventid string) (OC10Notification, error) {
|
||||
sharerUser, err := c.getOCMUser(ev.Sharer, ev.GranteeUserID)
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
}
|
||||
|
||||
shareid := &collaboration.ShareId{OpaqueId: ev.ShareID}
|
||||
subj, subjraw, msg, msgraw, err := composeMessage(ShareCreated, c.locale, c.defaultLanguage, c.translationPath, map[string]interface{}{
|
||||
"username": sharerUser.GetDisplayName(),
|
||||
"resourcename": ev.ResourceName,
|
||||
})
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
}
|
||||
|
||||
return OC10Notification{
|
||||
EventID: eventid,
|
||||
Service: c.serviceName,
|
||||
UserName: sharerUser.GetDisplayName(),
|
||||
Timestamp: utils.TSToTime(ev.CTime).Format(time.RFC3339Nano),
|
||||
ResourceID: ev.ItemID,
|
||||
ResourceType: _resourceTypeShare,
|
||||
Subject: subj,
|
||||
SubjectRaw: subjraw,
|
||||
Message: msg,
|
||||
MessageRaw: msgraw,
|
||||
MessageDetails: generateDetails(sharerUser, nil, nil, shareid),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Converter) omcShareDeleteMessage(ev events.OCMCoreShareDelete, eventid string) (OC10Notification, error) {
|
||||
sharerUser, err := c.getOCMUser(ev.Sharer, ev.Grantee)
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
}
|
||||
|
||||
shareid := &collaboration.ShareId{OpaqueId: ev.ShareID}
|
||||
subj, subjraw, msg, msgraw, err := composeMessage(ShareRemoved, c.locale, c.defaultLanguage, c.translationPath, map[string]interface{}{
|
||||
"username": sharerUser.GetDisplayName(),
|
||||
"resourcename": ev.ResourceName,
|
||||
})
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
}
|
||||
|
||||
return OC10Notification{
|
||||
EventID: eventid,
|
||||
Service: c.serviceName,
|
||||
UserName: sharerUser.GetDisplayName(),
|
||||
Timestamp: utils.TSToTime(ev.CTime).Format(time.RFC3339Nano),
|
||||
ResourceID: ev.ShareID,
|
||||
ResourceType: _resourceTypeShare,
|
||||
Subject: subj,
|
||||
SubjectRaw: subjraw,
|
||||
Message: msg,
|
||||
MessageRaw: msgraw,
|
||||
MessageDetails: generateDetails(sharerUser, nil, nil, shareid),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *Converter) getOCMUser(sharer *user.UserId, grantee *user.UserId) (*user.User, error) {
|
||||
gwc, err := c.gatewaySelector.Next()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Context c.serviceAccountContext will cause the user to be not found.
|
||||
// GetAcceptedUser() calls getUserFilter() that gets the user from the context
|
||||
// and use it as 'initiator' parameter in the GetRemoteUser() call.
|
||||
// The 'initiator' should be ev.Grantee.
|
||||
granteeJson, _ := json.Marshal(grantee)
|
||||
rspSharer, err := gwc.GetAcceptedUser(context.Background(), &invitepb.GetAcceptedUserRequest{
|
||||
RemoteUserId: sharer,
|
||||
Opaque: &typespb.Opaque{
|
||||
Map: map[string]*typespb.OpaqueEntry{
|
||||
"user-filter": {
|
||||
Decoder: "json",
|
||||
Value: granteeJson,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rspSharer.GetRemoteUser(), nil
|
||||
}
|
||||
|
||||
func (c *Converter) virusMessage(eventid string, nt NotificationTemplate, executant *user.User, rid *storageprovider.ResourceId, filename string, virus string, ts time.Time) (OC10Notification, error) {
|
||||
subj, subjraw, msg, msgraw, err := composeMessage(nt, c.locale, c.defaultLanguage, c.translationPath, map[string]interface{}{
|
||||
"resourcename": filename,
|
||||
|
@ -183,8 +183,16 @@ func (ul *UserlogService) processEvent(event events.Event) {
|
||||
users, err = utils.ResolveID(ctx, e.GranteeUserID, e.GranteeGroupID, gwc)
|
||||
case events.ShareExpired:
|
||||
users, err = utils.ResolveID(ctx, e.GranteeUserID, e.GranteeGroupID, gwc)
|
||||
}
|
||||
|
||||
// ocmcore share related
|
||||
case events.OCMCoreShareCreated:
|
||||
executant = e.Sharer
|
||||
users = append(users, e.GranteeUserID.GetOpaqueId())
|
||||
case events.OCMCoreShareDelete:
|
||||
fmt.Println("### userlog processEvent OCMCoreShareDelete", e.Sharer, e.Grantee)
|
||||
executant = e.Sharer
|
||||
users = append(users, e.Grantee.GetOpaqueId())
|
||||
}
|
||||
if err != nil {
|
||||
// TODO: Find out why this errors on ci pipeline
|
||||
ul.log.Debug().Err(err).Interface("event", event).Msg("error gathering members for event")
|
||||
|
90
vendor/github.com/owncloud/reva/v2/internal/grpc/services/ocmcore/ocmcore.go
generated
vendored
90
vendor/github.com/owncloud/reva/v2/internal/grpc/services/ocmcore/ocmcore.go
generated
vendored
@ -28,8 +28,10 @@ import (
|
||||
ocmcore "github.com/cs3org/go-cs3apis/cs3/ocm/core/v1beta1"
|
||||
ocm "github.com/cs3org/go-cs3apis/cs3/sharing/ocm/v1beta1"
|
||||
providerpb "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||
"github.com/owncloud/reva/v2/pkg/errtypes"
|
||||
"github.com/owncloud/reva/v2/pkg/events"
|
||||
"github.com/owncloud/reva/v2/pkg/events/stream"
|
||||
"github.com/owncloud/reva/v2/pkg/ocm/share"
|
||||
"github.com/owncloud/reva/v2/pkg/ocm/share/repository/registry"
|
||||
ocmuser "github.com/owncloud/reva/v2/pkg/ocm/user"
|
||||
@ -46,14 +48,28 @@ func init() {
|
||||
rgrpc.Register("ocmcore", New)
|
||||
}
|
||||
|
||||
// EventOptions are the configurable options for events
|
||||
type EventOptions struct {
|
||||
Endpoint string `mapstructure:"natsaddress"`
|
||||
Cluster string `mapstructure:"natsclusterid"`
|
||||
TLSInsecure bool `mapstructure:"tlsinsecure"`
|
||||
TLSRootCACertificate string `mapstructure:"tlsrootcacertificate"`
|
||||
EnableTLS bool `mapstructure:"enabletls"`
|
||||
AuthUsername string `mapstructure:"authusername"`
|
||||
AuthPassword string `mapstructure:"authpassword"`
|
||||
}
|
||||
|
||||
type config struct {
|
||||
Driver string `mapstructure:"driver"`
|
||||
Drivers map[string]map[string]interface{} `mapstructure:"drivers"`
|
||||
Events EventOptions `mapstructure:"events"`
|
||||
}
|
||||
|
||||
type service struct {
|
||||
conf *config
|
||||
repo share.Repository
|
||||
conf *config
|
||||
repo share.Repository
|
||||
eventStream events.Stream
|
||||
log *zerolog.Logger
|
||||
}
|
||||
|
||||
func (c *config) ApplyDefaults() {
|
||||
@ -74,7 +90,7 @@ func getShareRepository(c *config) (share.Repository, error) {
|
||||
}
|
||||
|
||||
// New creates a new ocm core svc.
|
||||
func New(m map[string]interface{}, ss *grpc.Server, _ *zerolog.Logger) (rgrpc.Service, error) {
|
||||
func New(m map[string]interface{}, ss *grpc.Server, log *zerolog.Logger) (rgrpc.Service, error) {
|
||||
var c config
|
||||
if err := cfg.Decode(m, &c); err != nil {
|
||||
return nil, err
|
||||
@ -88,6 +104,15 @@ func New(m map[string]interface{}, ss *grpc.Server, _ *zerolog.Logger) (rgrpc.Se
|
||||
service := &service{
|
||||
conf: &c,
|
||||
repo: repo,
|
||||
log: log,
|
||||
}
|
||||
|
||||
if c.Events.Endpoint != "" {
|
||||
es, err := stream.NatsFromConfig("ocmcore-handler", false, stream.NatsConfig(c.Events))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
service.eventStream = es
|
||||
}
|
||||
|
||||
return service, nil
|
||||
@ -111,7 +136,7 @@ func (s *service) CreateOCMCoreShare(ctx context.Context, req *ocmcore.CreateOCM
|
||||
return nil, errtypes.NotSupported("share type not supported")
|
||||
}
|
||||
|
||||
now := &typesv1beta1.Timestamp{
|
||||
now := &typespb.Timestamp{
|
||||
Seconds: uint64(time.Now().Unix()),
|
||||
}
|
||||
|
||||
@ -141,6 +166,30 @@ func (s *service) CreateOCMCoreShare(ctx context.Context, req *ocmcore.CreateOCM
|
||||
}, nil
|
||||
}
|
||||
|
||||
var permissions *providerpb.ResourcePermissions
|
||||
for _, p := range req.GetProtocols() {
|
||||
if p.GetWebdavOptions() != nil {
|
||||
permissions = p.GetWebdavOptions().GetPermissions().GetPermissions()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if s.eventStream != nil {
|
||||
if err := events.Publish(ctx, s.eventStream, events.OCMCoreShareCreated{
|
||||
ShareID: share.Id.OpaqueId,
|
||||
Executant: share.Creator,
|
||||
Sharer: share.Creator,
|
||||
GranteeUserID: share.Grantee.GetUserId(),
|
||||
ItemID: share.RemoteShareId,
|
||||
ResourceName: share.Name,
|
||||
CTime: share.Ctime,
|
||||
Permissions: permissions,
|
||||
}); err != nil {
|
||||
s.log.Error().Err(err).
|
||||
Msg("failed to publish the ocmcore share created event")
|
||||
}
|
||||
}
|
||||
|
||||
return &ocmcore.CreateOCMCoreShareResponse{
|
||||
Status: status.NewOK(ctx),
|
||||
Id: share.Id.OpaqueId,
|
||||
@ -185,18 +234,43 @@ func (s *service) DeleteOCMCoreShare(ctx context.Context, req *ocmcore.DeleteOCM
|
||||
return nil, errtypes.UserRequired("missing remote user id in a metadata")
|
||||
}
|
||||
|
||||
user := &userpb.User{Id: ocmuser.RemoteID(&userpb.UserId{OpaqueId: grantee})}
|
||||
|
||||
err := s.repo.DeleteReceivedShare(ctx, user, &ocm.ShareReference{
|
||||
share, err := s.repo.GetReceivedShare(ctx, &userpb.User{Id: ocmuser.RemoteID(&userpb.UserId{OpaqueId: grantee})}, &ocm.ShareReference{
|
||||
Spec: &ocm.ShareReference_Id{
|
||||
Id: &ocm.ShareId{
|
||||
OpaqueId: req.GetId(),
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errtypes.InternalError("unable to get share details")
|
||||
}
|
||||
|
||||
granteeUser := &userpb.User{Id: ocmuser.RemoteID(&userpb.UserId{OpaqueId: grantee})}
|
||||
err = s.repo.DeleteReceivedShare(ctx, granteeUser, &ocm.ShareReference{
|
||||
Spec: &ocm.ShareReference_Id{
|
||||
Id: &ocm.ShareId{
|
||||
OpaqueId: req.GetId(),
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
res := &ocmcore.DeleteOCMCoreShareResponse{}
|
||||
if err == nil {
|
||||
res.Status = status.NewOK(ctx)
|
||||
|
||||
if s.eventStream != nil {
|
||||
if err := events.Publish(ctx, s.eventStream, events.OCMCoreShareDelete{
|
||||
ShareID: share.Id.OpaqueId,
|
||||
Sharer: share.GetOwner(),
|
||||
Grantee: ocmuser.RemoteID(&userpb.UserId{OpaqueId: grantee}),
|
||||
ResourceName: share.Name,
|
||||
CTime: &typespb.Timestamp{Seconds: uint64(time.Now().Unix())},
|
||||
}); err != nil {
|
||||
s.log.Error().Err(err).
|
||||
Msg("failed to publish the ocmcore share deleted event")
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
var notFound errtypes.NotFound
|
||||
if errors.As(err, ¬Found) {
|
||||
|
16
vendor/github.com/owncloud/reva/v2/pkg/events/ocmcore.go
generated
vendored
16
vendor/github.com/owncloud/reva/v2/pkg/events/ocmcore.go
generated
vendored
@ -44,3 +44,19 @@ func (OCMCoreShareCreated) Unmarshal(v []byte) (interface{}, error) {
|
||||
err := json.Unmarshal(v, &e)
|
||||
return e, err
|
||||
}
|
||||
|
||||
// OCMCoreShareDelete is emitted when an ocm share is requested for delete
|
||||
type OCMCoreShareDelete struct {
|
||||
ShareID string
|
||||
Sharer *user.UserId
|
||||
Grantee *user.UserId
|
||||
ResourceName string
|
||||
CTime *types.Timestamp
|
||||
}
|
||||
|
||||
// Unmarshal to fulfill umarshaller interface
|
||||
func (OCMCoreShareDelete) Unmarshal(v []byte) (interface{}, error) {
|
||||
e := OCMCoreShareDelete{}
|
||||
err := json.Unmarshal(v, &e)
|
||||
return e, err
|
||||
}
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -1219,7 +1219,7 @@ github.com/orcaman/concurrent-map
|
||||
# github.com/owncloud/libre-graph-api-go v1.0.5-0.20250217093259-fa3804be6c27
|
||||
## explicit; go 1.18
|
||||
github.com/owncloud/libre-graph-api-go
|
||||
# github.com/owncloud/reva/v2 v2.0.0-20250313103212-d8b4c329554a
|
||||
# github.com/owncloud/reva/v2 v2.0.0-20250331084351-00f64db78848
|
||||
## explicit; go 1.22.7
|
||||
github.com/owncloud/reva/v2/cmd/revad/internal/grace
|
||||
github.com/owncloud/reva/v2/cmd/revad/runtime
|
||||
|
Loading…
x
Reference in New Issue
Block a user