EventManager: add content type option for email config

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
Nicola Murino 2023-05-17 19:28:13 +02:00
parent da30389989
commit bbaca578cd
No known key found for this signature in database
GPG key ID: 935D2952DEC4EECF
8 changed files with 50 additions and 10 deletions

View file

@ -1484,7 +1484,7 @@ func executeEmailRuleAction(c dataprovider.EventActionEmailConfig, params *Event
} }
files = append(files, res...) files = append(files, res...)
} }
err := smtp.SendEmail(recipients, subject, body, smtp.EmailContentTypeTextPlain, files...) err := smtp.SendEmail(recipients, subject, body, smtp.EmailContentType(c.ContentType), files...)
eventManagerLog(logger.LevelDebug, "executed email notification action, elapsed: %s, error: %v", eventManagerLog(logger.LevelDebug, "executed email notification action, elapsed: %s, error: %v",
time.Since(startTime), err) time.Since(startTime), err)
if err != nil { if err != nil {

View file

@ -6018,7 +6018,8 @@ func TestEventRuleRenameEvent(t *testing.T) {
EmailConfig: dataprovider.EventActionEmailConfig{ EmailConfig: dataprovider.EventActionEmailConfig{
Recipients: []string{"test@example.com"}, Recipients: []string{"test@example.com"},
Subject: `"{{Event}}" from "{{Name}}"`, Subject: `"{{Event}}" from "{{Name}}"`,
Body: `Fs path {{FsPath}}, Target path "{{VirtualTargetDirPath}}/{{TargetName}}", size: {{FileSize}}`, ContentType: 1,
Body: `<p>Fs path {{FsPath}}, Target path "{{VirtualTargetDirPath}}/{{TargetName}}", size: {{FileSize}}</p>`,
}, },
}, },
} }
@ -6065,6 +6066,7 @@ func TestEventRuleRenameEvent(t *testing.T) {
assert.Len(t, email.To, 1) assert.Len(t, email.To, 1)
assert.True(t, util.Contains(email.To, "test@example.com")) assert.True(t, util.Contains(email.To, "test@example.com"))
assert.Contains(t, email.Data, fmt.Sprintf(`Subject: "rename" from "%s"`, user.Username)) assert.Contains(t, email.Data, fmt.Sprintf(`Subject: "rename" from "%s"`, user.Username))
assert.Contains(t, email.Data, "Content-Type: text/html")
assert.Contains(t, email.Data, fmt.Sprintf("Target path %q", path.Join("/subdir", testFileName))) assert.Contains(t, email.Data, fmt.Sprintf("Target path %q", path.Join("/subdir", testFileName)))
} }
@ -6380,6 +6382,7 @@ func TestEventRuleCertificate(t *testing.T) {
EmailConfig: dataprovider.EventActionEmailConfig{ EmailConfig: dataprovider.EventActionEmailConfig{
Recipients: []string{"test@example.com"}, Recipients: []string{"test@example.com"},
Subject: `"{{Event}} {{StatusString}}"`, Subject: `"{{Event}} {{StatusString}}"`,
ContentType: 0,
Body: "Domain: {{Name}} Timestamp: {{Timestamp}} {{ErrorString}}", Body: "Domain: {{Name}} Timestamp: {{Timestamp}} {{ErrorString}}",
}, },
}, },
@ -6446,6 +6449,7 @@ func TestEventRuleCertificate(t *testing.T) {
assert.Len(t, email.To, 1) assert.Len(t, email.To, 1)
assert.True(t, util.Contains(email.To, "test@example.com")) assert.True(t, util.Contains(email.To, "test@example.com"))
assert.Contains(t, email.Data, fmt.Sprintf(`Subject: "%s OK"`, renewalEvent)) assert.Contains(t, email.Data, fmt.Sprintf(`Subject: "%s OK"`, renewalEvent))
assert.Contains(t, email.Data, "Content-Type: text/plain")
assert.Contains(t, email.Data, `Domain: example.com Timestamp`) assert.Contains(t, email.Data, `Domain: example.com Timestamp`)
lastReceivedEmail.reset() lastReceivedEmail.reset()

View file

@ -477,6 +477,7 @@ type EventActionEmailConfig struct {
Subject string `json:"subject,omitempty"` Subject string `json:"subject,omitempty"`
Body string `json:"body,omitempty"` Body string `json:"body,omitempty"`
Attachments []string `json:"attachments,omitempty"` Attachments []string `json:"attachments,omitempty"`
ContentType int `json:"content_type,omitempty"`
} }
// GetRecipientsAsString returns the list of recipients as comma separated string // GetRecipientsAsString returns the list of recipients as comma separated string
@ -514,6 +515,9 @@ func (c *EventActionEmailConfig) validate() error {
if c.Body == "" { if c.Body == "" {
return util.NewValidationError("email body is required") return util.NewValidationError("email body is required")
} }
if c.ContentType < 0 || c.ContentType > 1 {
return util.NewValidationError("invalid email content type")
}
for idx, val := range c.Attachments { for idx, val := range c.Attachments {
val = strings.TrimSpace(val) val = strings.TrimSpace(val)
if val == "" { if val == "" {
@ -938,6 +942,7 @@ func (o *BaseEventActionOptions) getACopy() BaseEventActionOptions {
EmailConfig: EventActionEmailConfig{ EmailConfig: EventActionEmailConfig{
Recipients: emailRecipients, Recipients: emailRecipients,
Subject: o.EmailConfig.Subject, Subject: o.EmailConfig.Subject,
ContentType: o.EmailConfig.ContentType,
Body: o.EmailConfig.Body, Body: o.EmailConfig.Body,
Attachments: emailAttachments, Attachments: emailAttachments,
}, },

View file

@ -1859,6 +1859,7 @@ func TestActionRuleRelations(t *testing.T) {
Options: dataprovider.BaseEventActionOptions{ Options: dataprovider.BaseEventActionOptions{
EmailConfig: dataprovider.EventActionEmailConfig{ EmailConfig: dataprovider.EventActionEmailConfig{
Recipients: []string{"test@example.net"}, Recipients: []string{"test@example.net"},
ContentType: 1,
Subject: "test subject", Subject: "test subject",
Body: "test body", Body: "test body",
}, },
@ -21820,12 +21821,14 @@ func TestWebEventAction(t *testing.T) {
action.Options.EmailConfig = dataprovider.EventActionEmailConfig{ action.Options.EmailConfig = dataprovider.EventActionEmailConfig{
Recipients: []string{"address1@example.com", "address2@example.com"}, Recipients: []string{"address1@example.com", "address2@example.com"},
Subject: "subject", Subject: "subject",
ContentType: 1,
Body: "body", Body: "body",
Attachments: []string{"/file1.txt", "/file2.txt"}, Attachments: []string{"/file1.txt", "/file2.txt"},
} }
form.Set("type", fmt.Sprintf("%d", action.Type)) form.Set("type", fmt.Sprintf("%d", action.Type))
form.Set("email_recipients", "address1@example.com, address2@example.com") form.Set("email_recipients", "address1@example.com, address2@example.com")
form.Set("email_subject", action.Options.EmailConfig.Subject) form.Set("email_subject", action.Options.EmailConfig.Subject)
form.Set("email_content_type", fmt.Sprintf("%d", action.Options.EmailConfig.ContentType))
form.Set("email_body", action.Options.EmailConfig.Body) form.Set("email_body", action.Options.EmailConfig.Body)
form.Set("email_attachments", "file1.txt, file2.txt") form.Set("email_attachments", "file1.txt, file2.txt")
req, err = http.NewRequest(http.MethodPost, path.Join(webAdminEventActionPath, action.Name), req, err = http.NewRequest(http.MethodPost, path.Join(webAdminEventActionPath, action.Name),
@ -21841,6 +21844,7 @@ func TestWebEventAction(t *testing.T) {
assert.Equal(t, action.Type, actionGet.Type) assert.Equal(t, action.Type, actionGet.Type)
assert.Equal(t, action.Options.EmailConfig.Recipients, actionGet.Options.EmailConfig.Recipients) assert.Equal(t, action.Options.EmailConfig.Recipients, actionGet.Options.EmailConfig.Recipients)
assert.Equal(t, action.Options.EmailConfig.Subject, actionGet.Options.EmailConfig.Subject) assert.Equal(t, action.Options.EmailConfig.Subject, actionGet.Options.EmailConfig.Subject)
assert.Equal(t, action.Options.EmailConfig.ContentType, actionGet.Options.EmailConfig.ContentType)
assert.Equal(t, action.Options.EmailConfig.Body, actionGet.Options.EmailConfig.Body) assert.Equal(t, action.Options.EmailConfig.Body, actionGet.Options.EmailConfig.Body)
assert.Equal(t, action.Options.EmailConfig.Attachments, actionGet.Options.EmailConfig.Attachments) assert.Equal(t, action.Options.EmailConfig.Attachments, actionGet.Options.EmailConfig.Attachments)
assert.Equal(t, dataprovider.EventActionHTTPConfig{}, actionGet.Options.HTTPConfig) assert.Equal(t, dataprovider.EventActionHTTPConfig{}, actionGet.Options.HTTPConfig)

View file

@ -2301,6 +2301,10 @@ func getEventActionOptionsFromPostFields(r *http.Request) (dataprovider.BaseEven
if r.Form.Get("idp_mode") == "1" { if r.Form.Get("idp_mode") == "1" {
idpMode = 1 idpMode = 1
} }
emailContentType := 0
if r.Form.Get("email_content_type") == "1" {
emailContentType = 1
}
options := dataprovider.BaseEventActionOptions{ options := dataprovider.BaseEventActionOptions{
HTTPConfig: dataprovider.EventActionHTTPConfig{ HTTPConfig: dataprovider.EventActionHTTPConfig{
Endpoint: r.Form.Get("http_endpoint"), Endpoint: r.Form.Get("http_endpoint"),
@ -2323,6 +2327,7 @@ func getEventActionOptionsFromPostFields(r *http.Request) (dataprovider.BaseEven
EmailConfig: dataprovider.EventActionEmailConfig{ EmailConfig: dataprovider.EventActionEmailConfig{
Recipients: getSliceFromDelimitedValues(r.Form.Get("email_recipients"), ","), Recipients: getSliceFromDelimitedValues(r.Form.Get("email_recipients"), ","),
Subject: r.Form.Get("email_subject"), Subject: r.Form.Get("email_subject"),
ContentType: emailContentType,
Body: r.Form.Get("email_body"), Body: r.Form.Get("email_body"),
Attachments: emailAttachments, Attachments: emailAttachments,
}, },

View file

@ -2662,6 +2662,9 @@ func compareEventActionEmailConfigFields(expected, actual dataprovider.EventActi
if expected.Subject != actual.Subject { if expected.Subject != actual.Subject {
return errors.New("email subject mismatch") return errors.New("email subject mismatch")
} }
if expected.ContentType != actual.ContentType {
return errors.New("email content type mismatch")
}
if expected.Body != actual.Body { if expected.Body != actual.Body {
return errors.New("email body mismatch") return errors.New("email body mismatch")
} }

View file

@ -7092,6 +7092,15 @@ components:
type: string type: string
body: body:
type: string type: string
content_type:
type: integer
enum:
- 0
- 1
description: |
Content type:
* `0` text/plain
* `1` text/html
attachments: attachments:
type: array type: array
items: items:

View file

@ -474,6 +474,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
</div> </div>
</div> </div>
<div class="form-group row action-type action-smtp">
<label for="idEmailContentType" class="col-sm-2 col-form-label">Email content type</label>
<div class="col-sm-10">
<select class="form-control selectpicker" id="idEmailContentType" name="email_content_type">
<option value="0" {{ if eq .Action.Options.EmailConfig.ContentType 0 }}selected{{end}}>Text/plain</option>
<option value="1" {{ if eq .Action.Options.EmailConfig.ContentType 1 }}selected{{end}}>Text/html</option>
</select>
</div>
</div>
<div class="form-group row action-type action-smtp"> <div class="form-group row action-type action-smtp">
<label for="idEmailBody" class="col-sm-2 col-form-label">Email body</label> <label for="idEmailBody" class="col-sm-2 col-form-label">Email body</label>
<div class="col-sm-10"> <div class="col-sm-10">