validate comment size and fields
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -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`,
|
||||
|
||||
Reference in New Issue
Block a user