-
Notifications
You must be signed in to change notification settings - Fork 41
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
Validate the user invitation HTML templates #4835
Conversation
0594a87
to
062e537
Compare
// getEmailSubject returns the subject for the email based on the message payload | ||
func getEmailSubject(project string) string { | ||
return fmt.Sprintf("You have been invited to join the %s organization in Minder", project) | ||
} | ||
|
||
// isValidField checks if the string is empty or contains HTML or JavaScript injection | ||
func isValidField(str string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is also covered by html/template -- do we need both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to add it because html/template was not erroring if it finds html in the template input, instead it escapes it and so we end up with things like <script>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment that we want to detect and error, rather than escape?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment 👍
Pull Request Test Coverage Report for Build 11603399089Details
💛 - Coveralls |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, just got a chance to review this on computer rather than on phone, and I've got a few more comments.
// getEmailSubject returns the subject for the email based on the message payload | ||
func getEmailSubject(project string) string { | ||
return fmt.Sprintf("You have been invited to join the %s organization in Minder", project) | ||
} | ||
|
||
// isValidField checks if the string is empty or contains HTML or JavaScript injection | ||
func isValidField(str string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add a comment that we want to detect and error, rather than escape?
} | ||
|
||
// Check for JavaScript content separately | ||
escapedJS := template.JSEscaper(str) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like JSEscapeString
should be simpler / faster here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean that any potential JS code would have been wrapped into HTML tags and so this is rather obsolete/redundant or it's something else?
internal/invites/service.go
Outdated
|
||
// isEmail is used to validate if the email is a valid email address according to RFC 5322 | ||
func isEmail(emailString string) bool { | ||
_, err := mail.ParseAddress(emailString) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we be using only the address
part for the rest of the function? I'm not sure we've thought about "Joe Bob <[email protected]>"
and "Oh gosh, I really dislike you <[email protected]>"
in the rest of our code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(If so, we could just return string
or ""
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can, but do we want to support such kind of inputs? For now at least I assume it's much cleaner to fail if the input is not strictly an email.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point is that mail.ParseAddress
will accept "An unpleasant joke from recent politics <[email protected]>"
, and the Name
field will be set to "An unpleasant joke from recent politics"
.
(And I was suggesting we should return just the parsed.Address
part of the ParseAddress
result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://github.com/bufbuild/protovalidate-go/blob/1446f1e1d576e67382edcb4863f76414e2eb2256/celext/lib.go#L426 for fairly-complete email address validation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(And, I'm okay removing this bit of code in favor of #4840 )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to remove it in favour of the validation checks we'll introduce 👍
b9869c6
to
91f14ac
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few nits (which you can ignore) aligning with what I think of as idiomatic go, and one bit on isEmail
that we probably do want to fix.
internal/email/email.go
Outdated
err = data.Validate() | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
err = data.Validate() | |
if err != nil { | |
if err := data.Validate(); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applied 👍
return nil, err | ||
} | ||
// Create the HTML and text bodies | ||
strBodyHTML, err := data.GetEmailBodyHTML(ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, these are really nice as methods on the data struct!
internal/email/email_test.go
Outdated
|
||
tests := []struct { | ||
input bodyData | ||
expectedErr bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you need expectedErr
separately from expectedErrMsg != ""
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks 👍 Removed the obsolete bool for expected error 👍
internal/invites/service.go
Outdated
|
||
// isEmail is used to validate if the email is a valid email address according to RFC 5322 | ||
func isEmail(emailString string) bool { | ||
_, err := mail.ParseAddress(emailString) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My point is that mail.ParseAddress
will accept "An unpleasant joke from recent politics <[email protected]>"
, and the Name
field will be set to "An unpleasant joke from recent politics"
.
(And I was suggesting we should return just the parsed.Address
part of the ParseAddress
result.
Signed-off-by: Radoslav Dimitrov <[email protected]>
Signed-off-by: Radoslav Dimitrov <[email protected]>
Signed-off-by: Radoslav Dimitrov <[email protected]>
Signed-off-by: Radoslav Dimitrov <[email protected]>
Signed-off-by: Radoslav Dimitrov <[email protected]>
Signed-off-by: Radoslav Dimitrov <[email protected]>
Signed-off-by: Radoslav Dimitrov <[email protected]>
91f14ac
to
2e3ae2f
Compare
…idation Signed-off-by: Radoslav Dimitrov <[email protected]>
2e3ae2f
to
1b26070
Compare
Summary
The following PR:
Change Type
Mark the type of change your PR introduces:
Testing
Outline how the changes were tested, including steps to reproduce and any relevant configurations.
Attach screenshots if helpful.
Review Checklist: