浏览代码

EventManager: add content type option for email config

Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
Nicola Murino 2 年之前
父节点
当前提交
bbaca578cd

+ 1 - 1
internal/common/eventmanager.go

@@ -1484,7 +1484,7 @@ func executeEmailRuleAction(c dataprovider.EventActionEmailConfig, params *Event
 		}
 		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",
 		time.Since(startTime), err)
 	if err != nil {

+ 10 - 6
internal/common/protocol_test.go

@@ -6016,9 +6016,10 @@ func TestEventRuleRenameEvent(t *testing.T) {
 		Type: dataprovider.ActionTypeEmail,
 		Options: dataprovider.BaseEventActionOptions{
 			EmailConfig: dataprovider.EventActionEmailConfig{
-				Recipients: []string{"test@example.com"},
-				Subject:    `"{{Event}}" from "{{Name}}"`,
-				Body:       `Fs path {{FsPath}}, Target path "{{VirtualTargetDirPath}}/{{TargetName}}", size: {{FileSize}}`,
+				Recipients:  []string{"test@example.com"},
+				Subject:     `"{{Event}}" from "{{Name}}"`,
+				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.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, "Content-Type: text/html")
 		assert.Contains(t, email.Data, fmt.Sprintf("Target path %q", path.Join("/subdir", testFileName)))
 	}
 
@@ -6378,9 +6380,10 @@ func TestEventRuleCertificate(t *testing.T) {
 		Type: dataprovider.ActionTypeEmail,
 		Options: dataprovider.BaseEventActionOptions{
 			EmailConfig: dataprovider.EventActionEmailConfig{
-				Recipients: []string{"test@example.com"},
-				Subject:    `"{{Event}} {{StatusString}}"`,
-				Body:       "Domain: {{Name}} Timestamp: {{Timestamp}} {{ErrorString}}",
+				Recipients:  []string{"test@example.com"},
+				Subject:     `"{{Event}} {{StatusString}}"`,
+				ContentType: 0,
+				Body:        "Domain: {{Name}} Timestamp: {{Timestamp}} {{ErrorString}}",
 			},
 		},
 	}
@@ -6446,6 +6449,7 @@ func TestEventRuleCertificate(t *testing.T) {
 	assert.Len(t, email.To, 1)
 	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, "Content-Type: text/plain")
 	assert.Contains(t, email.Data, `Domain: example.com Timestamp`)
 
 	lastReceivedEmail.reset()

+ 5 - 0
internal/dataprovider/eventrule.go

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

+ 7 - 3
internal/httpd/httpd_test.go

@@ -1858,9 +1858,10 @@ func TestActionRuleRelations(t *testing.T) {
 		Type: dataprovider.ActionTypeEmail,
 		Options: dataprovider.BaseEventActionOptions{
 			EmailConfig: dataprovider.EventActionEmailConfig{
-				Recipients: []string{"test@example.net"},
-				Subject:    "test subject",
-				Body:       "test body",
+				Recipients:  []string{"test@example.net"},
+				ContentType: 1,
+				Subject:     "test subject",
+				Body:        "test body",
 			},
 		},
 	}
@@ -21820,12 +21821,14 @@ func TestWebEventAction(t *testing.T) {
 	action.Options.EmailConfig = dataprovider.EventActionEmailConfig{
 		Recipients:  []string{"address1@example.com", "address2@example.com"},
 		Subject:     "subject",
+		ContentType: 1,
 		Body:        "body",
 		Attachments: []string{"/file1.txt", "/file2.txt"},
 	}
 	form.Set("type", fmt.Sprintf("%d", action.Type))
 	form.Set("email_recipients", "address1@example.com,  address2@example.com")
 	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_attachments", "file1.txt, file2.txt")
 	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.Options.EmailConfig.Recipients, actionGet.Options.EmailConfig.Recipients)
 	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.Attachments, actionGet.Options.EmailConfig.Attachments)
 	assert.Equal(t, dataprovider.EventActionHTTPConfig{}, actionGet.Options.HTTPConfig)

+ 5 - 0
internal/httpd/webadmin.go

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

+ 3 - 0
internal/httpdtest/httpdtest.go

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

+ 9 - 0
openapi/openapi.yaml

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

+ 10 - 0
templates/webadmin/eventaction.html

@@ -474,6 +474,16 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
                 </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">
                 <label for="idEmailBody" class="col-sm-2 col-form-label">Email body</label>
                 <div class="col-sm-10">