From 63b592a04d8c25c8db21b983bc19290fbf79221d Mon Sep 17 00:00:00 2001 From: jkoberg Date: Sun, 8 Jan 2023 13:33:48 +0100 Subject: [PATCH] membership expired notification Signed-off-by: jkoberg --- services/notifications/pkg/command/server.go | 2 + .../shares/shareExpired.email.body.tmpl | 2 +- .../spaces/membershipExpired.email.body.tmpl | 18 ++++++++ .../membershipExpired.email.subject.tmpl | 1 + services/notifications/pkg/service/service.go | 34 ++------------- services/notifications/pkg/service/shares.go | 12 +++--- services/notifications/pkg/service/spaces.go | 41 ++++++++++++++++++- 7 files changed, 72 insertions(+), 38 deletions(-) create mode 100644 services/notifications/pkg/email/templates/spaces/membershipExpired.email.body.tmpl create mode 100644 services/notifications/pkg/email/templates/spaces/membershipExpired.email.subject.tmpl diff --git a/services/notifications/pkg/command/server.go b/services/notifications/pkg/command/server.go index 93998f7c0..d5eff8322 100644 --- a/services/notifications/pkg/command/server.go +++ b/services/notifications/pkg/command/server.go @@ -35,8 +35,10 @@ func Server(cfg *config.Config) *cli.Command { // evs defines a list of events to subscribe to evs := []events.Unmarshaller{ events.ShareCreated{}, + events.ShareExpired{}, events.SpaceShared{}, events.SpaceUnshared{}, + events.SpaceMembershipExpired{}, } evtsCfg := cfg.Notifications.Events diff --git a/services/notifications/pkg/email/templates/shares/shareExpired.email.body.tmpl b/services/notifications/pkg/email/templates/shares/shareExpired.email.body.tmpl index e90a2b9bb..736dd0aa9 100644 --- a/services/notifications/pkg/email/templates/shares/shareExpired.email.body.tmpl +++ b/services/notifications/pkg/email/templates/shares/shareExpired.email.body.tmpl @@ -10,7 +10,7 @@ Hallo {{ .ShareGrantee }}, Deine Freigabe zu {{ .ShareFolder }} ist am {{ .ExpiredAt }} abgelaufen. -Obwohl diese Freigabe nicht mehr zur Verfügung steht könntest du immernoch Zugriff über andere Freigaben und/oder space Mitgliedschaften haben. +Obwohl diese Freigabe nicht mehr zur Verfügung steht könntest du immernoch Zugriff über andere Freigaben und/oder Space Mitgliedschaften haben. --- diff --git a/services/notifications/pkg/email/templates/spaces/membershipExpired.email.body.tmpl b/services/notifications/pkg/email/templates/spaces/membershipExpired.email.body.tmpl new file mode 100644 index 000000000..d62218f42 --- /dev/null +++ b/services/notifications/pkg/email/templates/spaces/membershipExpired.email.body.tmpl @@ -0,0 +1,18 @@ +Hello {{ .SpaceGrantee }}, + +Your membership of space {{ .SpaceName }} has expired at {{ .ExpiredAt }} + +Even though this membership has expired you still might have access through other shares and/or space memberships + +---------------------------------------------------------- + +Hallo {{ .SpaceGrantee }}, + +Deine Mitgliedschaft zu dem Space {{ .SpaceName }} ist am {{ .ExpiredAt }} abgelaufen. + +Obwohl diese Mitgliedschaft nicht mehr zur Verfügung steht könntest du immernoch Zugriff über andere Freigaben und/oder Space Mitgliedschaften haben. + + +--- +ownCloud - Store. Share. Work. +https://owncloud.com diff --git a/services/notifications/pkg/email/templates/spaces/membershipExpired.email.subject.tmpl b/services/notifications/pkg/email/templates/spaces/membershipExpired.email.subject.tmpl new file mode 100644 index 000000000..d8c96f39a --- /dev/null +++ b/services/notifications/pkg/email/templates/spaces/membershipExpired.email.subject.tmpl @@ -0,0 +1 @@ +Membership of '{{ .SpaceName }}' expired at {{ .ExpiredAt }} diff --git a/services/notifications/pkg/service/service.go b/services/notifications/pkg/service/service.go index f0f52fe9b..eb0ecd4d1 100644 --- a/services/notifications/pkg/service/service.go +++ b/services/notifications/pkg/service/service.go @@ -16,12 +16,10 @@ import ( rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" - revactx "github.com/cs3org/reva/v2/pkg/ctx" "github.com/cs3org/reva/v2/pkg/events" "github.com/owncloud/ocis/v2/ocis-pkg/log" "github.com/owncloud/ocis/v2/services/notifications/pkg/channels" "github.com/owncloud/ocis/v2/services/notifications/pkg/email" - "google.golang.org/grpc/metadata" "google.golang.org/protobuf/types/known/fieldmaskpb" ) @@ -73,8 +71,12 @@ func (s eventsNotifier) Run() error { s.handleSpaceShared(e) case events.SpaceUnshared: s.handleSpaceUnshared(e) + case events.SpaceMembershipExpired: + s.handleSpaceMembershipExpired(e) case events.ShareCreated: s.handleShareCreated(e) + case events.ShareExpired: + s.handleShareExpired(e) } }() case <-s.signals: @@ -142,34 +144,6 @@ func (s eventsNotifier) getGranteeName(ctx context.Context, u *user.UserId, g *g } -func (s eventsNotifier) impersonate(userID *user.UserId) (context.Context, string, error) { - getUserResponse, err := s.gwClient.GetUser(context.Background(), &user.GetUserRequest{ - UserId: userID, - }) - if err != nil { - return nil, "", err - } - if getUserResponse.Status.Code != rpc.Code_CODE_OK { - return nil, "", fmt.Errorf("error getting user: %s", getUserResponse.Status.Message) - } - - // Get auth context - ownerCtx := revactx.ContextSetUser(context.Background(), getUserResponse.User) - authRes, err := s.gwClient.Authenticate(ownerCtx, &gateway.AuthenticateRequest{ - Type: "machine", - ClientId: "userid:" + userID.OpaqueId, - ClientSecret: s.machineAuthAPIKey, - }) - if err != nil { - return nil, "", err - } - if authRes.GetStatus().GetCode() != rpc.Code_CODE_OK { - return nil, "", fmt.Errorf("error impersonating user: %s", authRes.Status.Message) - } - - return metadata.AppendToOutgoingContext(context.Background(), revactx.TokenHeader, authRes.Token), authRes.GetUser().GetDisplayName(), nil -} - func (s eventsNotifier) getResourceInfo(ctx context.Context, resourceID *providerv1beta1.ResourceId, fieldmask *fieldmaskpb.FieldMask) (*provider.ResourceInfo, error) { // TODO: maybe cache this stat to reduce storage iops md, err := s.gwClient.Stat(ctx, &provider.StatRequest{ diff --git a/services/notifications/pkg/service/shares.go b/services/notifications/pkg/service/shares.go index 8713b507c..0709f3f33 100644 --- a/services/notifications/pkg/service/shares.go +++ b/services/notifications/pkg/service/shares.go @@ -2,6 +2,7 @@ package service import ( "github.com/cs3org/reva/v2/pkg/events" + "github.com/cs3org/reva/v2/pkg/utils" "google.golang.org/protobuf/types/known/fieldmaskpb" ) @@ -11,7 +12,7 @@ func (s eventsNotifier) handleShareCreated(e events.ShareCreated) { Str("itemid", e.ItemID.OpaqueId). Logger() - ownerCtx, sharerDisplayName, err := s.impersonate(e.Sharer) + ownerCtx, owner, err := utils.Impersonate(e.Sharer, s.gwClient, s.machineAuthAPIKey) if err != nil { logger.Error().Err(err).Msg("Could not impersonate sharer") return @@ -39,6 +40,7 @@ func (s eventsNotifier) handleShareCreated(e events.ShareCreated) { return } + sharerDisplayName := owner.GetDisplayName() msg, subj, err := s.render("shares/shareCreated.email.body.tmpl", "shares/shareCreated.email.subject.tmpl", map[string]string{ "ShareGrantee": shareGrantee, "ShareSharer": sharerDisplayName, @@ -62,13 +64,13 @@ func (s eventsNotifier) handleShareExpired(e events.ShareExpired) { Str("itemid", e.ItemID.GetOpaqueId()). Logger() - ownerCtx, sharerDisplayName, err := s.impersonate(e.ShareOwner) + ctx, owner, err := utils.Impersonate(e.ShareOwner, s.gwClient, s.machineAuthAPIKey) if err != nil { logger.Error().Err(err).Msg("Could not impersonate sharer") return } - resourceInfo, err := s.getResourceInfo(ownerCtx, e.ItemID, &fieldmaskpb.FieldMask{Paths: []string{"name"}}) + resourceInfo, err := s.getResourceInfo(ctx, e.ItemID, &fieldmaskpb.FieldMask{Paths: []string{"name"}}) if err != nil { logger.Error(). Err(err). @@ -76,7 +78,7 @@ func (s eventsNotifier) handleShareExpired(e events.ShareExpired) { return } - shareGrantee, err := s.getGranteeName(ownerCtx, e.GranteeUserID, e.GranteeGroupID) + shareGrantee, err := s.getGranteeName(ctx, e.GranteeUserID, e.GranteeGroupID) if err != nil { s.logger.Error().Err(err).Str("event", "ShareCreated").Msg("Could not get grantee name") return @@ -92,7 +94,7 @@ func (s eventsNotifier) handleShareExpired(e events.ShareExpired) { s.logger.Error().Err(err).Str("event", "ShareCreated").Msg("Could not render E-Mail body template for shares") } - if err := s.send(ownerCtx, e.GranteeUserID, e.GranteeGroupID, msg, subj, sharerDisplayName); err != nil { + if err := s.send(ctx, e.GranteeUserID, e.GranteeGroupID, msg, subj, owner.GetDisplayName()); err != nil { s.logger.Error().Err(err).Str("event", "ShareCreated").Msg("failed to send a message") } diff --git a/services/notifications/pkg/service/spaces.go b/services/notifications/pkg/service/spaces.go index 7a7cbb8a4..3c4684967 100644 --- a/services/notifications/pkg/service/spaces.go +++ b/services/notifications/pkg/service/spaces.go @@ -3,6 +3,7 @@ package service import ( "github.com/cs3org/reva/v2/pkg/events" "github.com/cs3org/reva/v2/pkg/storagespace" + "github.com/cs3org/reva/v2/pkg/utils" ) func (s eventsNotifier) handleSpaceShared(e events.SpaceShared) { @@ -11,7 +12,7 @@ func (s eventsNotifier) handleSpaceShared(e events.SpaceShared) { Str("itemid", e.ID.OpaqueId). Logger() - ownerCtx, sharerDisplayName, err := s.impersonate(e.Executant) + ownerCtx, owner, err := utils.Impersonate(e.Executant, s.gwClient, s.machineAuthAPIKey) if err != nil { logger.Error(). Err(err). @@ -52,6 +53,7 @@ func (s eventsNotifier) handleSpaceShared(e events.SpaceShared) { return } + sharerDisplayName := owner.GetDisplayName() msg, subj, err := s.render("spaces/sharedSpace.email.body.tmpl", "spaces/sharedSpace.email.subject.tmpl", map[string]string{ "SpaceGrantee": spaceGrantee, "SpaceSharer": sharerDisplayName, @@ -74,7 +76,7 @@ func (s eventsNotifier) handleSpaceUnshared(e events.SpaceUnshared) { Str("itemid", e.ID.OpaqueId). Logger() - ownerCtx, sharerDisplayName, err := s.impersonate(e.Executant) + ownerCtx, owner, err := utils.Impersonate(e.Executant, s.gwClient, s.machineAuthAPIKey) if err != nil { logger.Error().Err(err).Msg("could not handle space unshared event") return @@ -113,6 +115,7 @@ func (s eventsNotifier) handleSpaceUnshared(e events.SpaceUnshared) { return } + sharerDisplayName := owner.GetDisplayName() msg, subj, err := s.render("spaces/unsharedSpace.email.body.tmpl", "spaces/unsharedSpace.email.subject.tmpl", map[string]string{ "SpaceGrantee": spaceGrantee, "SpaceSharer": sharerDisplayName, @@ -129,3 +132,37 @@ func (s eventsNotifier) handleSpaceUnshared(e events.SpaceUnshared) { logger.Error().Err(err).Msg("failed to send a message") } } + +func (s eventsNotifier) handleSpaceMembershipExpired(e events.SpaceMembershipExpired) { + logger := s.logger.With(). + Str("event", "SpaceMembershipExpired"). + Str("itemid", e.SpaceID). + Logger() + + ctx, owner, err := utils.Impersonate(e.SpaceOwner, s.gwClient, s.machineAuthAPIKey) + if err != nil { + logger.Error().Err(err).Msg("Could not impersonate sharer") + return + } + + shareGrantee, err := s.getGranteeName(ctx, e.GranteeUserID, e.GranteeGroupID) + if err != nil { + s.logger.Error().Err(err).Str("event", "ShareCreated").Msg("Could not get grantee name") + return + } + + msg, subj, err := s.render("spaces/membershipExpired.email.body.tmpl", "spaces/membershipExpired.email.subject.tmpl", map[string]string{ + "SpaceGrantee": shareGrantee, + "SpaceName": e.SpaceName, + "ExpiredAt": e.ExpiredAt.Format("2006-01-02 15:04:05"), + }) + + if err != nil { + s.logger.Error().Err(err).Str("event", "ShareCreated").Msg("Could not render E-Mail body template for shares") + } + + if err := s.send(ctx, e.GranteeUserID, e.GranteeGroupID, msg, subj, owner.GetDisplayName()); err != nil { + s.logger.Error().Err(err).Str("event", "ShareCreated").Msg("failed to send a message") + } + +}