github.com/cs3org/reva/v2@v2.27.7/pkg/siteacc/email/email.go (about) 1 // Copyright 2018-2020 CERN 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package email 20 21 import ( 22 "bytes" 23 "strings" 24 "text/template" 25 26 "github.com/cs3org/reva/v2/pkg/siteacc/config" 27 "github.com/cs3org/reva/v2/pkg/siteacc/data" 28 "github.com/cs3org/reva/v2/pkg/smtpclient" 29 "github.com/pkg/errors" 30 ) 31 32 type emailData struct { 33 Account *data.Account 34 35 AccountsAddress string 36 GOCDBAddress string 37 38 Params map[string]string 39 } 40 41 // SendFunction is the definition of email send functions. 42 type SendFunction = func(*data.Account, []string, map[string]string, config.Configuration) error 43 44 func getEmailData(account *data.Account, conf config.Configuration, params map[string]string) *emailData { 45 return &emailData{ 46 Account: account, 47 AccountsAddress: conf.Webserver.URL, 48 GOCDBAddress: conf.GOCDB.URL, 49 Params: params, 50 } 51 } 52 53 // SendAccountCreated sends an email about account creation. 54 func SendAccountCreated(account *data.Account, recipients []string, params map[string]string, conf config.Configuration) error { 55 return send(recipients, "ScienceMesh: Site Administrator Account created", accountCreatedTemplate, getEmailData(account, conf, params), conf.Email.SMTP) 56 } 57 58 // SendSiteAccessGranted sends an email about granted Site access. 59 func SendSiteAccessGranted(account *data.Account, recipients []string, params map[string]string, conf config.Configuration) error { 60 return send(recipients, "ScienceMesh: Site access granted", siteAccessGrantedTemplate, getEmailData(account, conf, params), conf.Email.SMTP) 61 } 62 63 // SendGOCDBAccessGranted sends an email about granted GOCDB access. 64 func SendGOCDBAccessGranted(account *data.Account, recipients []string, params map[string]string, conf config.Configuration) error { 65 return send(recipients, "ScienceMesh: GOCDB access granted", gocdbAccessGrantedTemplate, getEmailData(account, conf, params), conf.Email.SMTP) 66 } 67 68 // SendPasswordReset sends an email containing the user's new password. 69 func SendPasswordReset(account *data.Account, recipients []string, params map[string]string, conf config.Configuration) error { 70 return send(recipients, "ScienceMesh: Password reset", passwordResetTemplate, getEmailData(account, conf, params), conf.Email.SMTP) 71 } 72 73 // SendContactForm sends a generic contact form to the ScienceMesh admins. 74 func SendContactForm(account *data.Account, recipients []string, params map[string]string, conf config.Configuration) error { 75 return send(recipients, "ScienceMesh: Contact form", contactFormTemplate, getEmailData(account, conf, params), conf.Email.SMTP) 76 } 77 78 // SendAlertNotification sends an alert via email. 79 func SendAlertNotification(account *data.Account, recipients []string, params map[string]string, conf config.Configuration) error { 80 subject := params["Summary"] 81 tpl := alertFiringNotificationTemplate 82 if strings.EqualFold(params["Status"], "resolved") { 83 tpl = alertResolvedNotificationTemplate 84 subject += " [RESOLVED]" 85 } 86 return send(recipients, "ScienceMesh Alert: "+subject, tpl, getEmailData(account, conf, params), conf.Email.SMTP) 87 } 88 89 func send(recipients []string, subject string, bodyTemplate string, data interface{}, smtp *smtpclient.SMTPCredentials) error { 90 // Do not fail if no SMTP client or recipient is given 91 if smtp == nil { 92 return nil 93 } 94 95 tpl := template.New("email") 96 prepareEmailTemplate(tpl) 97 98 if _, err := tpl.Parse(bodyTemplate); err != nil { 99 return errors.Wrap(err, "error while parsing email template") 100 } 101 102 var body bytes.Buffer 103 if err := tpl.Execute(&body, data); err != nil { 104 return errors.Wrap(err, "error while executing email template") 105 } 106 107 for _, recipient := range recipients { 108 if len(recipient) == 0 { 109 continue 110 } 111 112 // Send the mail w/o blocking the main thread 113 go func(recipient string) { 114 _ = smtp.SendMail(recipient, subject, body.String()) 115 }(recipient) 116 } 117 118 return nil 119 } 120 121 func prepareEmailTemplate(tpl *template.Template) { 122 // Add some custom helper functions to the template 123 tpl.Funcs(template.FuncMap{ 124 "indent": func(n int, s string) string { 125 lines := make([]string, 0, 10) 126 for _, line := range strings.Split(s, "\n") { 127 line = strings.TrimSpace(line) 128 line = strings.Repeat(" ", n) + line 129 lines = append(lines, line) 130 } 131 return strings.Join(lines, "\n") 132 }, 133 }) 134 }