validate comment size and fields

This commit is contained in:
Umputun
2018-05-06 18:48:13 -05:00
parent f924cf76df
commit e8a59ed238
4 changed files with 63 additions and 2 deletions
+17
View File
@@ -138,6 +138,12 @@ func (s *Rest) createCommentCtrl(w http.ResponseWriter, r *http.Request) {
comment.PrepareUntrusted() // clean all fields user not suppoed to set
comment.User = user
comment.User.IP = strings.Split(r.RemoteAddr, ":")[0]
if comment.Validate() != nil {
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "invalid comment")
return
}
comment.Text = string(blackfriday.Run([]byte(comment.Text), blackfriday.WithExtensions(mdExt)))
log.Printf("[DEBUG] create comment %+v", comment)
@@ -165,6 +171,17 @@ func (s *Rest) previewCommentCtrl(w http.ResponseWriter, r *http.Request) {
return
}
user, err := rest.GetUserInfo(r)
if err != nil { // this not suppose to happen (handled by Auth), just dbl-check
rest.SendErrorJSON(w, r, http.StatusUnauthorized, err, "can't get user info")
return
}
comment.User = user
if err := comment.Validate(); err != nil {
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "invalid comment")
return
}
comment.Text = string(blackfriday.Run([]byte(comment.Text), blackfriday.WithExtensions(mdExt)))
comment.Sanitize()
render.HTML(w, r, comment.Text)
+2 -2
View File
@@ -63,7 +63,7 @@ func TestServer_Preview(t *testing.T) {
defer cleanup(srv)
r := strings.NewReader(`{"text": "test 123", "locator":{"url": "https://radio-t.com/blah1", "site": "radio-t"}}`)
resp, err := http.Post(fmt.Sprintf("http://127.0.0.1:%d/api/v1/preview", port), "application/json", r)
resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/preview", port), "application/json", r)
assert.Equal(t, http.StatusOK, resp.StatusCode)
b, err := ioutil.ReadAll(resp.Body)
assert.Nil(t, err)
@@ -90,7 +90,7 @@ BKT
j = strings.Replace(j, "\n", "\\n", -1)
t.Log(j)
r := strings.NewReader(j)
resp, err := http.Post(fmt.Sprintf("http://127.0.0.1:%d/api/v1/preview", port), "application/json", r)
resp, err := http.Post(fmt.Sprintf("http://dev:password@127.0.0.1:%d/api/v1/preview", port), "application/json", r)
assert.Equal(t, http.StatusOK, resp.StatusCode)
b, err := ioutil.ReadAll(resp.Body)
assert.Nil(t, err)
+18
View File
@@ -3,6 +3,7 @@ package store
import (
"crypto/hmac"
"crypto/sha1"
"errors"
"fmt"
"html/template"
"log"
@@ -62,6 +63,9 @@ type BlockedUser struct {
Timestamp time.Time `json:"time"`
}
// MaxCommentSize defines max size of comment's text
const MaxCommentSize = 2048
// PrepareUntrusted preprocess comment received from untrusted source by clearing all
// autogen fields and reset everything users not supposed to provide
func (c *Comment) PrepareUntrusted() {
@@ -95,6 +99,20 @@ func (c *Comment) Sanitize() {
// c.Text = strings.Replace(c.Text, "\t", "", -1)
}
// Validate comment
func (c *Comment) Validate() error {
if c.Text == "" {
return errors.New("empty comment text")
}
if len(c.Text) > MaxCommentSize {
return errors.New("comment text exceeded max allowed size")
}
if c.User.ID == "" || c.User.Name == "" {
return errors.New("empty user info")
}
return nil
}
// hashIP replace sensitive fields with hashes
func (u *User) hashIP(secret string) {
+26
View File
@@ -4,6 +4,7 @@ import (
"testing"
"time"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
@@ -32,6 +33,31 @@ func TestComment_Sanitize(t *testing.T) {
}
}
func TestComment_Validate(t *testing.T) {
longText := ""
for i := 0; i < 4000; i++ {
longText += "X"
}
tbl := []struct {
inp Comment
err error
}{
{inp: Comment{}, err: errors.New("empty comment text")},
{inp: Comment{Text: "something blah", User: User{ID: "myid", Name: "name"}}, err: nil},
{inp: Comment{Text: "something blah", User: User{ID: "myid"}}, err: errors.New("empty user info")},
{inp: Comment{Text: longText, User: User{ID: "myid", Name: "name"}}, err: errors.New("comment text exceeded max allowed size")},
}
for n, tt := range tbl {
e := tt.inp.Validate()
if tt.err == nil {
assert.Nil(t, e, "check #%d", n)
continue
}
assert.EqualError(t, tt.err, e.Error(), "check #%d", n)
}
}
func TestComment_PrepareUntrusted(t *testing.T) {
comment := Comment{
Text: `blah`,