Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add validation of attachment values in flow definitions #1277

Merged
merged 1 commit into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions flows/actions/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ func (a *baseAction) evaluateMessage(run flows.Run, languages []i18n.Language, a
for _, a := range translatedAttachments {
evaluatedAttachment, _ := run.EvaluateTemplate(a, logEvent)
evaluatedAttachment = strings.TrimSpace(evaluatedAttachment)
if evaluatedAttachment == "" {
logEvent(events.NewErrorf("attachment text evaluated to empty string, skipping"))
if !utils.IsValidAttachment(evaluatedAttachment) {
logEvent(events.NewErrorf("attachment evaluated to invalid value, skipping"))
continue
}
if len(evaluatedAttachment) > flows.MaxAttachmentLength {
Expand All @@ -103,7 +103,7 @@ func (a *baseAction) evaluateMessage(run flows.Run, languages []i18n.Language, a
for _, qr := range translatedQuickReplies {
evaluatedQuickReply, _ := run.EvaluateTemplate(qr, logEvent)
if evaluatedQuickReply == "" {
logEvent(events.NewErrorf("quick reply text evaluated to empty string, skipping"))
logEvent(events.NewErrorf("quick reply evaluated to empty string, skipping"))
continue
}
evaluatedQuickReplies = append(evaluatedQuickReplies, stringsx.TruncateEllipsis(evaluatedQuickReply, flows.MaxQuickReplyLength))
Expand Down Expand Up @@ -261,9 +261,9 @@ func (a *otherContactsAction) resolveRecipients(run flows.Run, logEvent flows.Ev

// utility struct for actions which create a message
type createMsgAction struct {
Text string `json:"text" validate:"required" engine:"localized,evaluated"`
Attachments []string `json:"attachments,omitempty" engine:"localized,evaluated"`
QuickReplies []string `json:"quick_replies,omitempty" engine:"localized,evaluated"`
Text string `json:"text" validate:"required" engine:"localized,evaluated"`
Attachments []string `json:"attachments,omitempty" validate:"dive,attachment" engine:"localized,evaluated"`
QuickReplies []string `json:"quick_replies,omitempty" engine:"localized,evaluated"`
}

// helper function for actions that have a set of group references that must be resolved to actual groups
Expand Down
12 changes: 6 additions & 6 deletions flows/actions/testdata/send_broadcast.json
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@
],
"text": "Hi there!",
"attachments": [
"http://example.com/red.jpg"
"image:http://example.com/red.jpg"
],
"quick_replies": [
"Yes",
Expand All @@ -265,7 +265,7 @@
"Hola!"
],
"attachments": [
"http://example.com/rojo.jpg"
"image:http://example.com/rojo.jpg"
],
"quick_replies": [
"Si",
Expand All @@ -283,7 +283,7 @@
"eng": {
"text": "Hi there!",
"attachments": [
"http://example.com/red.jpg"
"image:http://example.com/red.jpg"
],
"quick_replies": [
"Yes",
Expand All @@ -293,7 +293,7 @@
"spa": {
"text": "Hola!",
"attachments": [
"http://example.com/rojo.jpg"
"image:http://example.com/rojo.jpg"
],
"quick_replies": [
"Si",
Expand All @@ -310,8 +310,8 @@
"templates": [
"Hi there!",
"Hola!",
"http://example.com/red.jpg",
"http://example.com/rojo.jpg",
"image:http://example.com/red.jpg",
"image:http://example.com/rojo.jpg",
"Yes",
"No",
"Si",
Expand Down
32 changes: 16 additions & 16 deletions flows/actions/testdata/send_msg.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"text": "",
"attachments": [
"http://example.com/red.jpg"
"image:http://example.com/red.jpg"
]
},
"read_error": "field 'text' is required"
Expand All @@ -28,8 +28,8 @@
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"text": "Hi there @(1 / 0)",
"attachments": [
"http://example.com/red.jpg@(1 / 0)",
"@(xxxxx)"
"image:http://example.com/red.jpg@(1 / 0)",
"image:@(xxxxx)"
],
"quick_replies": [
"Red@(1 / 0)",
Expand Down Expand Up @@ -60,7 +60,7 @@
"type": "error",
"created_on": "2018-10-18T14:20:30.000123456Z",
"step_uuid": "59d74b86-3e2f-4a93-aece-b05d2fdcde0c",
"text": "attachment text evaluated to empty string, skipping"
"text": "attachment evaluated to invalid value, skipping"
},
{
"type": "error",
Expand All @@ -78,7 +78,7 @@
"type": "error",
"created_on": "2018-10-18T14:20:30.000123456Z",
"step_uuid": "59d74b86-3e2f-4a93-aece-b05d2fdcde0c",
"text": "quick reply text evaluated to empty string, skipping"
"text": "quick reply evaluated to empty string, skipping"
},
{
"type": "msg_created",
Expand All @@ -93,7 +93,7 @@
},
"text": "Hi there ",
"attachments": [
"http://example.com/red.jpg"
"image:http://example.com/red.jpg"
],
"quick_replies": [
"Red",
Expand All @@ -111,7 +111,7 @@
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"text": "Hi there",
"attachments": [
"@(\" \")"
"image:@(\" \")"
],
"quick_replies": [
"@(\"\")"
Expand All @@ -122,13 +122,13 @@
"type": "error",
"created_on": "2018-10-18T14:20:30.000123456Z",
"step_uuid": "59d74b86-3e2f-4a93-aece-b05d2fdcde0c",
"text": "attachment text evaluated to empty string, skipping"
"text": "attachment evaluated to invalid value, skipping"
},
{
"type": "error",
"created_on": "2018-10-18T14:20:30.000123456Z",
"step_uuid": "59d74b86-3e2f-4a93-aece-b05d2fdcde0c",
"text": "quick reply text evaluated to empty string, skipping"
"text": "quick reply evaluated to empty string, skipping"
},
{
"type": "msg_created",
Expand All @@ -154,7 +154,7 @@
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"text": "Hi there",
"attachments": [
"@(json(run) & json(run) & json(run))",
"image:@(json(run) & json(run) & json(run))",
"image/jpeg:http://exacmple.com/test.jpg"
]
},
Expand Down Expand Up @@ -710,7 +710,7 @@
"uuid": "ad154980-7bf7-4ab8-8728-545fd6378912",
"text": "Hi there!",
"attachments": [
"http://example.com/red.jpg"
"image:http://example.com/red.jpg"
],
"quick_replies": [
"Yes",
Expand All @@ -724,7 +724,7 @@
"Hola!"
],
"attachments": [
"http://example.com/rojo.jpg"
"image:http://example.com/rojo.jpg"
],
"quick_replies": [
"Si",
Expand All @@ -747,7 +747,7 @@
},
"text": "Hola!",
"attachments": [
"http://example.com/rojo.jpg"
"image:http://example.com/rojo.jpg"
],
"quick_replies": [
"Si",
Expand All @@ -760,16 +760,16 @@
"templates": [
"Hi there!",
"Hola!",
"http://example.com/red.jpg",
"http://example.com/rojo.jpg",
"image:http://example.com/red.jpg",
"image:http://example.com/rojo.jpg",
"Yes",
"No",
"Si",
"No"
],
"localizables": [
"Hi there!",
"http://example.com/red.jpg",
"image:http://example.com/red.jpg",
"Yes",
"No"
],
Expand Down
14 changes: 7 additions & 7 deletions flows/urn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ import (
"github.com/stretchr/testify/require"
)

type testStruct struct {
ValidURN string `json:"valid_urn" validate:"urn"`
InvalidURN string `json:"invalid_urn" validate:"urn"`
ValidScheme string `json:"valid_scheme" validate:"urnscheme"`
InvalidScheme string `json:"invalid_scheme" validate:"urnscheme"`
}

func TestURNValidation(t *testing.T) {
type testStruct struct {
ValidURN string `json:"valid_urn" validate:"urn"`
InvalidURN string `json:"invalid_urn" validate:"urn"`
ValidScheme string `json:"valid_scheme" validate:"urnscheme"`
InvalidScheme string `json:"invalid_scheme" validate:"urnscheme"`
}

obj := testStruct{
ValidURN: "tel:+123456789",
InvalidURN: "xyz",
Expand Down
13 changes: 13 additions & 0 deletions utils/attachment.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,21 @@ package utils
import (
"regexp"
"strings"

"github.com/go-playground/validator/v10"
)

func init() {
RegisterValidatorTag("attachment",
func(fl validator.FieldLevel) bool {
return IsValidAttachment(fl.Field().String())
},
func(validator.FieldError) string {
return "is not a valid attachment"
},
)
}

// Attachment is a media attachment on a message in the format <content-type>:<url>. Content type may be a full
// media type or may omit the subtype when it is unknown.
//
Expand Down
14 changes: 14 additions & 0 deletions utils/attachment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,17 @@ func TestAttachment(t *testing.T) {
assertParse("HTTPS://test.jpg", "", "HTTPS://test.jpg", false)
assertParse(":http://test.jpg", "", ":http://test.jpg", false)
}

func TestAttachmentValidation(t *testing.T) {
type testStruct struct {
Valid string `json:"valid" validate:"attachment"`
Invalid string `json:"invalid" validate:"attachment"`
}

obj := testStruct{
Valid: "image:http://test.jpg",
Invalid: "xyz",
}
err := utils.Validate(obj)
assert.EqualError(t, err, "field 'invalid' is not a valid attachment")
}
Loading