mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-06 20:29:54 -06:00
notify about other events
Signed-off-by: jkoberg <jkoberg@owncloud.com>
This commit is contained in:
@@ -2,7 +2,6 @@ package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"text/template"
|
||||
"time"
|
||||
@@ -11,10 +10,13 @@ import (
|
||||
storageprovider "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"
|
||||
ehmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/eventhistory/v0"
|
||||
)
|
||||
|
||||
var (
|
||||
_resourceTypeSpace = "storagespace"
|
||||
_resourceTypeShare = "share"
|
||||
)
|
||||
|
||||
// OC10Notification is the oc10 style representation of an event
|
||||
@@ -33,55 +35,57 @@ type OC10Notification struct {
|
||||
MessageDetails map[string]interface{} `json:"messageRichParameters"`
|
||||
}
|
||||
|
||||
// SpaceDisabled converts a SpaceDisabled event to an OC10Notification
|
||||
func (ul *UserlogService) SpaceDisabled(ctx context.Context, eventid string, ev events.SpaceDisabled) (OC10Notification, error) {
|
||||
user, err := ul.getUser(ctx, ev.Executant)
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
// ConvertEvent converts an eventhistory event to an OC10Notification
|
||||
func (ul *UserlogService) ConvertEvent(event *ehmsg.Event) (OC10Notification, error) {
|
||||
etype, ok := ul.registeredEvents[event.Type]
|
||||
if !ok {
|
||||
// this should not happen
|
||||
return OC10Notification{}, errors.New("eventtype not registered")
|
||||
}
|
||||
|
||||
space, err := ul.getSpace(ul.impersonate(user.GetId()), ev.ID.GetOpaqueId())
|
||||
einterface, err := etype.Unmarshal(event.Event)
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
// this shouldn't happen either
|
||||
return OC10Notification{}, errors.New("cant unmarshal event")
|
||||
}
|
||||
|
||||
subj, subjraw, msg, msgraw, err := ul.composeMessage(SpaceDisabled, map[string]string{
|
||||
"username": user.GetDisplayName(),
|
||||
"spacename": space.GetName(),
|
||||
})
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
switch ev := einterface.(type) {
|
||||
default:
|
||||
return OC10Notification{}, errors.New("unknown event type")
|
||||
// space related
|
||||
case events.SpaceDisabled:
|
||||
return ul.spaceMessage(event.Id, SpaceDisabled, ev.Executant, ev.ID.GetOpaqueId())
|
||||
case events.SpaceDeleted:
|
||||
return ul.spaceMessage(event.Id, SpaceDeleted, ev.Executant, ev.ID.GetOpaqueId())
|
||||
case events.SpaceShared:
|
||||
return ul.spaceMessage(event.Id, SpaceShared, ev.Executant, ev.ID.GetOpaqueId())
|
||||
case events.SpaceUnshared:
|
||||
return ul.spaceMessage(event.Id, SpaceUnshared, ev.Executant, ev.ID.GetOpaqueId())
|
||||
case events.SpaceMembershipExpired:
|
||||
return ul.spaceMessage(event.Id, SpaceMembershipExpired, ev.SpaceOwner, ev.SpaceID.GetOpaqueId())
|
||||
|
||||
// share related
|
||||
case events.ShareCreated:
|
||||
return ul.shareMessage(event.Id, ShareCreated, ev.Executant, ev.ItemID)
|
||||
case events.ShareExpired:
|
||||
return ul.shareMessage(event.Id, ShareExpired, ev.ShareOwner, ev.ItemID)
|
||||
case events.ShareRemoved:
|
||||
return ul.shareMessage(event.Id, ShareRemoved, ev.Executant, nil)
|
||||
}
|
||||
|
||||
return OC10Notification{
|
||||
EventID: eventid,
|
||||
Service: ul.cfg.Service.Name,
|
||||
UserName: user.GetUsername(),
|
||||
Timestamp: time.Now().Format(time.RFC3339Nano),
|
||||
ResourceID: ev.ID.GetOpaqueId(),
|
||||
ResourceType: _resourceTypeSpace,
|
||||
Subject: subj,
|
||||
SubjectRaw: subjraw,
|
||||
Message: msg,
|
||||
MessageRaw: msgraw,
|
||||
MessageDetails: ul.getDetails(user, space, nil),
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
// SpaceShared converts a SpaceShared event to an OC10Notification
|
||||
func (ul *UserlogService) SpaceShared(ctx context.Context, eventid string, ev events.SpaceShared) (OC10Notification, error) {
|
||||
user, err := ul.getUser(ctx, ev.Executant)
|
||||
func (ul *UserlogService) spaceMessage(eventid string, eventname string, executant *user.UserId, spaceid string) (OC10Notification, error) {
|
||||
ctx, user, err := utils.Impersonate(executant, ul.gwClient, ul.cfg.MachineAuthAPIKey)
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
}
|
||||
|
||||
space, err := ul.getSpace(ul.impersonate(user.GetId()), ev.ID.GetOpaqueId())
|
||||
space, err := ul.getSpace(ctx, spaceid)
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
}
|
||||
|
||||
subj, subjraw, msg, msgraw, err := ul.composeMessage(SpaceShared, map[string]string{
|
||||
subj, subjraw, msg, msgraw, err := ul.composeMessage(eventname, map[string]string{
|
||||
"username": user.GetDisplayName(),
|
||||
"spacename": space.GetName(),
|
||||
})
|
||||
@@ -94,7 +98,7 @@ func (ul *UserlogService) SpaceShared(ctx context.Context, eventid string, ev ev
|
||||
Service: ul.cfg.Service.Name,
|
||||
UserName: user.GetUsername(),
|
||||
Timestamp: time.Now().Format(time.RFC3339Nano),
|
||||
ResourceID: ev.ID.GetOpaqueId(),
|
||||
ResourceID: spaceid,
|
||||
ResourceType: _resourceTypeSpace,
|
||||
Subject: subj,
|
||||
SubjectRaw: subjraw,
|
||||
@@ -102,7 +106,40 @@ func (ul *UserlogService) SpaceShared(ctx context.Context, eventid string, ev ev
|
||||
MessageRaw: msgraw,
|
||||
MessageDetails: ul.getDetails(user, space, nil),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ul *UserlogService) shareMessage(eventid string, eventname string, executant *user.UserId, resourceid *storageprovider.ResourceId) (OC10Notification, error) {
|
||||
ctx, user, err := utils.Impersonate(executant, ul.gwClient, ul.cfg.MachineAuthAPIKey)
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
}
|
||||
|
||||
info, err := ul.getResource(ctx, resourceid)
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
}
|
||||
|
||||
subj, subjraw, msg, msgraw, err := ul.composeMessage(eventname, map[string]string{
|
||||
"username": user.GetDisplayName(),
|
||||
"resourcename": info.GetName(),
|
||||
})
|
||||
if err != nil {
|
||||
return OC10Notification{}, err
|
||||
}
|
||||
|
||||
return OC10Notification{
|
||||
EventID: eventid,
|
||||
Service: ul.cfg.Service.Name,
|
||||
UserName: user.GetUsername(),
|
||||
Timestamp: time.Now().Format(time.RFC3339Nano),
|
||||
ResourceID: storagespace.FormatResourceID(*info.GetId()),
|
||||
ResourceType: _resourceTypeShare,
|
||||
Subject: subj,
|
||||
SubjectRaw: subjraw,
|
||||
Message: msg,
|
||||
MessageRaw: msgraw,
|
||||
MessageDetails: ul.getDetails(user, nil, info),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ul *UserlogService) composeMessage(eventname string, vars map[string]string) (string, string, string, string, error) {
|
||||
@@ -114,17 +151,17 @@ func (ul *UserlogService) composeMessage(eventname string, vars map[string]strin
|
||||
subject := ul.executeTemplate(tpl.Subject, vars)
|
||||
|
||||
subjectraw := ul.executeTemplate(tpl.Subject, map[string]string{
|
||||
"username": "{user}",
|
||||
"spacename": "{space}",
|
||||
"resource": "{resource}",
|
||||
"username": "{user}",
|
||||
"spacename": "{space}",
|
||||
"resourcename": "{resource}",
|
||||
})
|
||||
|
||||
message := ul.executeTemplate(tpl.Message, vars)
|
||||
|
||||
messageraw := ul.executeTemplate(tpl.Message, map[string]string{
|
||||
"username": "{user}",
|
||||
"spacename": "{space}",
|
||||
"resource": "{resource}",
|
||||
"username": "{user}",
|
||||
"spacename": "{space}",
|
||||
"resourcename": "{resource}",
|
||||
})
|
||||
|
||||
return subject, subjectraw, message, messageraw, nil
|
||||
|
||||
@@ -1,17 +1,10 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
storageprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||
revactx "github.com/cs3org/reva/v2/pkg/ctx"
|
||||
"github.com/cs3org/reva/v2/pkg/events"
|
||||
ehmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/eventhistory/v0"
|
||||
)
|
||||
|
||||
// ServeHTTP fulfills Handler interface
|
||||
@@ -37,7 +30,7 @@ func (ul *UserlogService) HandleGetEvents(w http.ResponseWriter, r *http.Request
|
||||
|
||||
resp := GetEventResponseOC10{}
|
||||
for _, e := range evs {
|
||||
noti, err := ul.convertEvent(r.Context(), e)
|
||||
noti, err := ul.ConvertEvent(e)
|
||||
if err != nil {
|
||||
ul.log.Error().Err(err).Str("eventid", e.Id).Str("eventtype", e.Type).Msg("failed to convert event")
|
||||
continue
|
||||
@@ -76,59 +69,6 @@ func (ul *UserlogService) HandleDeleteEvents(w http.ResponseWriter, r *http.Requ
|
||||
w.WriteHeader(http.StatusOK)
|
||||
}
|
||||
|
||||
func (ul *UserlogService) convertEvent(ctx context.Context, event *ehmsg.Event) (OC10Notification, error) {
|
||||
etype, ok := ul.registeredEvents[event.Type]
|
||||
if !ok {
|
||||
// this should not happen
|
||||
return OC10Notification{}, errors.New("eventtype not registered")
|
||||
}
|
||||
|
||||
einterface, err := etype.Unmarshal(event.Event)
|
||||
if err != nil {
|
||||
// this shouldn't happen either
|
||||
return OC10Notification{}, errors.New("cant unmarshal event")
|
||||
}
|
||||
|
||||
noti := OC10Notification{
|
||||
EventID: event.Id,
|
||||
Service: "userlog",
|
||||
Timestamp: time.Now().Format(time.RFC3339Nano),
|
||||
}
|
||||
|
||||
// TODO: strange bug with getting space -> fix postponed to make master panic-free
|
||||
var space storageprovider.StorageSpace
|
||||
|
||||
switch ev := einterface.(type) {
|
||||
// space related
|
||||
case events.SpaceDisabled:
|
||||
return ul.SpaceDisabled(ctx, event.Id, ev)
|
||||
case events.SpaceDeleted:
|
||||
noti.Subject = "Space deleted"
|
||||
noti.Message = fmt.Sprintf("Space '%s' was deleted", space.Name)
|
||||
case events.SpaceShared:
|
||||
return ul.SpaceShared(ctx, event.Id, ev)
|
||||
case events.SpaceUnshared:
|
||||
noti.Subject = "Space unshared"
|
||||
noti.Message = fmt.Sprintf("Space '%s' was unshared", space.Name)
|
||||
case events.SpaceMembershipExpired:
|
||||
noti.Subject = "Space membership expired"
|
||||
noti.Message = fmt.Sprintf("A spacemembership for space '%s' has expired", space.Name)
|
||||
|
||||
// share related
|
||||
case events.ShareCreated:
|
||||
noti.Subject = "Share received"
|
||||
noti.Message = fmt.Sprintf("A file was shared in space %s", space.Name)
|
||||
case events.ShareExpired:
|
||||
noti.Subject = "Share expired"
|
||||
noti.Message = fmt.Sprintf("A share has expired in space %s", space.Name)
|
||||
case events.ShareRemoved:
|
||||
noti.Subject = "Share removed"
|
||||
noti.Message = "share was removed"
|
||||
}
|
||||
|
||||
return noti, nil
|
||||
}
|
||||
|
||||
// GetEventResponseOC10 is the response from GET events endpoint in oc10 style
|
||||
type GetEventResponseOC10 struct {
|
||||
OCS struct {
|
||||
|
||||
@@ -395,6 +395,19 @@ func (ul *UserlogService) getGroup(ctx context.Context, groupid string) (*group.
|
||||
return r.GetGroup(), nil
|
||||
}
|
||||
|
||||
func (ul *UserlogService) getResource(ctx context.Context, resourceid *storageprovider.ResourceId) (*storageprovider.ResourceInfo, error) {
|
||||
res, err := ul.gwClient.Stat(ctx, &storageprovider.StatRequest{Ref: &storageprovider.Reference{ResourceId: resourceid}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if res.GetStatus().GetCode() != rpc.Code_CODE_OK {
|
||||
return nil, fmt.Errorf("Unexpected status code while getting space: %v", res.GetStatus().GetCode())
|
||||
}
|
||||
|
||||
return res.GetInfo(), nil
|
||||
}
|
||||
|
||||
func listStorageSpaceRequest(spaceID string) *storageprovider.ListStorageSpacesRequest {
|
||||
return &storageprovider.ListStorageSpacesRequest{
|
||||
Filters: []*storageprovider.ListStorageSpacesRequest_Filter{
|
||||
|
||||
@@ -4,13 +4,51 @@ import "text/template"
|
||||
|
||||
// the available templates
|
||||
var (
|
||||
SpaceShared = "space-shared"
|
||||
SpaceSharedSubject = "Space shared"
|
||||
SpaceSharedMessage = "{{ .username }} shared Space {{ .spacename }} with you"
|
||||
|
||||
SpaceUnshared = "space-unshared"
|
||||
SpaceUnsharedSubject = "Removed from Space"
|
||||
SpaceUnsharedMessage = "{{ .username }} removed you from Space {{ .spacename }}"
|
||||
|
||||
SpaceDisabled = "space-disabled"
|
||||
SpaceDisabledSubject = "Space disabled"
|
||||
SpaceDisabledMessage = "{{ .username }} disabled Space {{ .spacename }}"
|
||||
|
||||
SpaceShared = "space-shared"
|
||||
SpaceSharedSubject = "Space shared"
|
||||
SpaceSharedMessage = "{{ .username }} shared Space {{ .spacename }} with you"
|
||||
SpaceDeleted = "space-deleted"
|
||||
SpaceDeletedSubject = "Space deleted"
|
||||
SpaceDeletedMessage = "{{ .username }} deleted Space {{ .spacename }}"
|
||||
|
||||
SpaceMembershipExpired = "space-membership-expired"
|
||||
SpaceMembershipExpiredSubject = "Membership expired"
|
||||
SpaceMembershipExpiredMessage = "Access to Space {{ .spacename }} lost"
|
||||
|
||||
ShareCreated = "item-shared"
|
||||
ShareCreatedSubject = "Resource shared"
|
||||
ShareCreatedMessage = "{{ .username }} shared {{ .itemname }} with you"
|
||||
|
||||
ShareRemoved = "item-unshared"
|
||||
ShareRemovedSubject = "Resource unshared"
|
||||
ShareRemovedMessage = "{{ .username }} unshared {{ .itemname }} with you"
|
||||
|
||||
ShareExpired = "share-expired"
|
||||
ShareExpiredSubject = "Share expired"
|
||||
ShareExpiredMessage = "Access to {{ .resourcename }} expired"
|
||||
)
|
||||
|
||||
// rendered templates
|
||||
var (
|
||||
_templates = map[string]NotificationTemplate{
|
||||
SpaceShared: notiTmpl(SpaceSharedSubject, SpaceSharedMessage),
|
||||
SpaceUnshared: notiTmpl(SpaceUnsharedSubject, SpaceUnsharedMessage),
|
||||
SpaceDisabled: notiTmpl(SpaceDisabledSubject, SpaceDisabledMessage),
|
||||
SpaceDeleted: notiTmpl(SpaceDeletedSubject, SpaceDeletedMessage),
|
||||
SpaceMembershipExpired: notiTmpl(SpaceMembershipExpiredSubject, SpaceMembershipExpiredMessage),
|
||||
ShareCreated: notiTmpl(ShareCreatedSubject, ShareCreatedMessage),
|
||||
ShareRemoved: notiTmpl(ShareRemovedSubject, ShareRemovedMessage),
|
||||
ShareExpired: notiTmpl(ShareExpiredSubject, ShareExpiredMessage),
|
||||
}
|
||||
)
|
||||
|
||||
// NotificationTemplate is the data structure for the notifications
|
||||
@@ -19,16 +57,9 @@ type NotificationTemplate struct {
|
||||
Message *template.Template
|
||||
}
|
||||
|
||||
// rendered templates
|
||||
var (
|
||||
_templates = map[string]NotificationTemplate{
|
||||
SpaceDisabled: {
|
||||
Subject: template.Must(template.New("").Parse(SpaceDisabledSubject)),
|
||||
Message: template.Must(template.New("").Parse(SpaceDisabledMessage)),
|
||||
},
|
||||
SpaceShared: {
|
||||
Subject: template.Must(template.New("").Parse(SpaceSharedSubject)),
|
||||
Message: template.Must(template.New("").Parse(SpaceSharedMessage)),
|
||||
},
|
||||
func notiTmpl(subjectname string, messagename string) NotificationTemplate {
|
||||
return NotificationTemplate{
|
||||
Subject: template.Must(template.New("").Parse(subjectname)),
|
||||
Message: template.Must(template.New("").Parse(messagename)),
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user