enhancement(notifications): process ocm invites and sent out a mail notification

This commit is contained in:
Florian Schade
2024-09-03 18:18:14 +02:00
parent 194921eb0c
commit 5ceb081262
4 changed files with 107 additions and 10 deletions

View File

@@ -25,7 +25,7 @@ var (
imgDir = filepath.Join("templates", "html", "img")
)
// RenderEmailTemplate renders the email template for a new share
// RenderEmailTemplate is responsible to prepare a message which than can be used to notify the user via email.
func RenderEmailTemplate(mt MessageTemplate, locale, defaultLocale string, emailTemplatePath string, translationPath string, vars map[string]string) (*channels.Message, error) {
textMt, err := NewTextTemplate(mt, locale, defaultLocale, translationPath, vars)
if err != nil {

View File

@@ -72,18 +72,39 @@ You might still have access through your other groups or direct membership.`),
Even though this membership has expired you still might have access through other shares and/or space memberships`),
}
ScienceMeshInviteTokenGenerated = MessageTemplate{
textTemplate: "templates/text/email.text.tmpl",
htmlTemplate: "templates/html/email.html.tmpl",
// ScienceMeshInviteTokenGenerated email template, Subject field (resolves directly)
Subject: l10n.Template(`ScienceMesh: {InitiatorName} wants to collaborate with you`),
// ScienceMeshInviteTokenGenerated email template, resolves via {{ .Greeting }}
Greeting: l10n.Template(`Hi,`),
// ScienceMeshInviteTokenGenerated email template, resolves via {{ .MessageBody }}
MessageBody: l10n.Template(`{ShareSharer} ({ShareSharerMail}) wants to start sharing OCM resources with you.
{{if .ShareLink }}To accept the invite, please visit the following URL:
{ShareLink}
Alternatively, you can{{else}}
Please{{end}} visit your mesh provider and use the following details:
Token: {Token}
ProviderDomain: {ProviderDomain}`),
}
)
// holds the information to turn the raw template into a parseable go template
var _placeholders = map[string]string{
"{ShareSharer}": "{{ .ShareSharer }}",
"{ShareFolder}": "{{ .ShareFolder }}",
"{ShareGrantee}": "{{ .ShareGrantee }}",
"{ShareLink}": "{{ .ShareLink }}",
"{SpaceName}": "{{ .SpaceName }}",
"{SpaceGrantee}": "{{ .SpaceGrantee }}",
"{SpaceSharer}": "{{ .SpaceSharer }}",
"{ExpiredAt}": "{{ .ExpiredAt }}",
"{ShareSharer}": "{{ .ShareSharer }}",
"{ShareFolder}": "{{ .ShareFolder }}",
"{ShareGrantee}": "{{ .ShareGrantee }}",
"{ShareLink}": "{{ .ShareLink }}",
"{SpaceName}": "{{ .SpaceName }}",
"{SpaceGrantee}": "{{ .SpaceGrantee }}",
"{SpaceSharer}": "{{ .SpaceSharer }}",
"{ExpiredAt}": "{{ .ExpiredAt }}",
"{ShareSharerMail}": "{{ .ShareSharerMail }}",
"{ProviderDomain}": "{{ .ProviderDomain }}",
"{Token}": "{{ .Token }}",
}
// MessageTemplate is the data structure for the email

View File

@@ -1,9 +1,77 @@
package service
import (
"context"
"github.com/cs3org/reva/v2/pkg/events"
"github.com/cs3org/reva/v2/pkg/utils"
"github.com/owncloud/ocis/v2/services/notifications/pkg/channels"
"github.com/owncloud/ocis/v2/services/notifications/pkg/email"
)
func (s eventsNotifier) handleScienceMeshInviteTokenGenerated(e events.ScienceMeshInviteTokenGenerated) {
// fixMe: add implementation
logger := s.logger.With().
Str("event", "ScienceMeshInviteTokenGenerated").
Logger()
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
logger.Error().Err(err).Msg("could not select next gateway client")
return
}
ctx, err := utils.GetServiceUserContextWithContext(context.Background(), gatewayClient, s.serviceAccountID, s.serviceAccountSecret)
if err != nil {
logger.Error().Err(err).Msg("Could not impersonate service user")
return
}
owner, err := utils.GetUserWithContext(ctx, e.Sharer, gatewayClient)
if err != nil {
logger.Error().Err(err).Msg("unable to get user")
return
}
msgENV := map[string]string{
"ShareSharer": owner.GetDisplayName(),
"ShareSharerMail": owner.GetMail(),
"ShareLink": e.InviteLink,
"Token": e.Token,
"ProviderDomain": owner.GetId().GetIdp(),
"RecipientMail": e.RecipientMail,
}
// validate the message, we only need recipient mail at the moment,
// event that is optional when the event got triggered...
// this means if we get a validation error, we can't send the message and skip it
{
validationEnv := make(map[string]interface{}, len(msgENV))
for k, v := range msgENV {
validationEnv[k] = v
}
if errs := validate.ValidateMap(validationEnv,
map[string]interface{}{
"RecipientMail": "required,email", // only recipient mail is required to send the message
}); len(errs) > 0 {
return // no mail, no message
}
}
msg, err := email.RenderEmailTemplate(
email.ScienceMeshInviteTokenGenerated,
s.defaultLanguage, // fixMe: the recipient is unknown, should it be the defaultLocale?,
s.defaultLanguage, // fixMe: the defaultLocale is not set by default, shouldn't it be?,
s.emailTemplatePath,
s.translationPath,
msgENV,
)
if err != nil {
s.logger.Error().Err(err).Msg("building the message has failed")
return
}
msg.Sender = owner.GetDisplayName()
msg.Recipient = []string{e.RecipientMail}
s.send(ctx, []*channels.Message{msg})
}

View File

@@ -16,6 +16,7 @@ import (
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"github.com/go-playground/validator/v10"
"go-micro.dev/v4/metadata"
"google.golang.org/protobuf/types/known/fieldmaskpb"
@@ -30,6 +31,13 @@ import (
"github.com/owncloud/ocis/v2/services/settings/pkg/store/defaults"
)
// validate is the package level validator instance
var validate *validator.Validate
func init() {
validate = validator.New()
}
// Service should be named `Runner`
type Service interface {
Run() error