hard body limit, encode disqus imported ID
This commit is contained in:
@@ -129,7 +129,7 @@ func (d *Disqus) convert(r io.Reader, siteID string) (ch chan store.Comment) {
|
||||
ID: comment.UID,
|
||||
Locator: store.Locator{URL: postsMap[comment.Tid.Val], SiteID: siteID},
|
||||
User: store.User{
|
||||
ID: "disqus_" + comment.AuthorUserName,
|
||||
ID: "disqus_" + store.EncodeID(comment.AuthorUserName),
|
||||
Name: comment.AuthorName,
|
||||
IP: comment.IP,
|
||||
},
|
||||
|
||||
@@ -32,7 +32,7 @@ func TestDisqus_Import(t *testing.T) {
|
||||
assert.Equal(t, "", c.ParentID)
|
||||
assert.Equal(t, store.Locator{SiteID: "test", URL: "http://radio-t.umputun.com/2011/03/229_8880.html"}, c.Locator)
|
||||
assert.Equal(t, "Dmitry Noname", c.User.Name)
|
||||
assert.Equal(t, "disqus_google-74b9e7568ef6860e93862c5d77590123", c.User.ID)
|
||||
assert.Equal(t, "disqus_8799342cdf328253e03313958ffc6a433659d7ff", c.User.ID)
|
||||
assert.Equal(t, "89.89.89.139", c.User.IP)
|
||||
|
||||
posts, err := dataStore.List("test", 0, 0)
|
||||
@@ -63,7 +63,7 @@ func TestDisqus_Convert(t *testing.T) {
|
||||
Text: `<p>The quick brown fox jumps over the lazy dog.</p><p><a href="https://https://radio-t.com" rel="nofollow noopener" title="radio-t">some link</a></p>`,
|
||||
User: store.User{
|
||||
Name: "Alexander Blah",
|
||||
ID: "disqus_facebook-1787732238",
|
||||
ID: "disqus_328c8b68974aef73785f6b38c3d3fedfdf941434",
|
||||
IP: "178.178.178.178",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ type Rest struct {
|
||||
amdminService admin
|
||||
}
|
||||
|
||||
const hardBodyLimit = 1024 * 64 // limit size of body
|
||||
|
||||
var mdExt = blackfriday.NoIntraEmphasis | blackfriday.Tables | blackfriday.FencedCode |
|
||||
blackfriday.Strikethrough | blackfriday.SpaceHeadings | blackfriday.HardLineBreak |
|
||||
blackfriday.BackslashLineBreak
|
||||
@@ -124,7 +126,7 @@ func (s *Rest) Run(port int) {
|
||||
func (s *Rest) createCommentCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
comment := store.Comment{}
|
||||
if err := render.DecodeJSON(r.Body, &comment); err != nil {
|
||||
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &comment); err != nil {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't bind comment")
|
||||
return
|
||||
}
|
||||
@@ -166,7 +168,7 @@ func (s *Rest) createCommentCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
func (s *Rest) previewCommentCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
comment := store.Comment{}
|
||||
if err := render.DecodeJSON(r.Body, &comment); err != nil {
|
||||
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &comment); err != nil {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't bind comment")
|
||||
return
|
||||
}
|
||||
@@ -195,7 +197,7 @@ func (s *Rest) updateCommentCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
Summary string
|
||||
}{}
|
||||
|
||||
if err := render.DecodeJSON(r.Body, &edit); err != nil {
|
||||
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &edit); err != nil {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't bind comment")
|
||||
return
|
||||
}
|
||||
@@ -397,7 +399,7 @@ func (s *Rest) countCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
func (s *Rest) countMultiCtrl(w http.ResponseWriter, r *http.Request) {
|
||||
siteID := r.URL.Query().Get("site")
|
||||
posts := []string{}
|
||||
if err := render.DecodeJSON(r.Body, &posts); err != nil {
|
||||
if err := render.DecodeJSON(http.MaxBytesReader(w, r.Body, hardBodyLimit), &posts); err != nil {
|
||||
rest.SendErrorJSON(w, r, http.StatusBadRequest, err, "can't get list of posts from request")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func (p *AvatarProxy) Put(u store.User) (avatarURL string, err error) {
|
||||
}()
|
||||
|
||||
// get ID and location of locally cached avatar
|
||||
encID := rest.EncodeID(u.ID)
|
||||
encID := store.EncodeID(u.ID)
|
||||
location := p.location(encID) // location adds partion to path
|
||||
|
||||
if _, err = os.Stat(location); os.IsNotExist(err) {
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"golang.org/x/oauth2/github"
|
||||
"golang.org/x/oauth2/google"
|
||||
|
||||
"github.com/umputun/remark/app/rest"
|
||||
"github.com/umputun/remark/app/store"
|
||||
)
|
||||
|
||||
@@ -25,7 +24,7 @@ func NewGoogle(p Params) Provider {
|
||||
MapUser: func(data userData, _ []byte) store.User {
|
||||
userInfo := store.User{
|
||||
// encode email with provider name to avoid collision if same id returned by other provider
|
||||
ID: "google_" + rest.EncodeID(data.value("email")),
|
||||
ID: "google_" + store.EncodeID(data.value("email")),
|
||||
Name: data.value("name"),
|
||||
Picture: data.value("picture"),
|
||||
}
|
||||
@@ -48,7 +47,7 @@ func NewGithub(p Params) Provider {
|
||||
Store: p.SessionStore,
|
||||
MapUser: func(data userData, _ []byte) store.User {
|
||||
userInfo := store.User{
|
||||
ID: "github_" + rest.EncodeID(data.value("login")),
|
||||
ID: "github_" + store.EncodeID(data.value("login")),
|
||||
Name: data.value("name"),
|
||||
Picture: data.value("avatar_url"),
|
||||
}
|
||||
@@ -83,7 +82,7 @@ func NewFacebook(p Params) Provider {
|
||||
Store: p.SessionStore,
|
||||
MapUser: func(data userData, bdata []byte) store.User {
|
||||
userInfo := store.User{
|
||||
ID: "facebook_" + rest.EncodeID(data.value("id")),
|
||||
ID: "facebook_" + store.EncodeID(data.value("id")),
|
||||
Name: data.value("name"),
|
||||
}
|
||||
if userInfo.Name == "" {
|
||||
@@ -113,7 +112,7 @@ func NewDisqus(p Params) Provider {
|
||||
Store: p.SessionStore,
|
||||
MapUser: func(data userData, _ []byte) store.User {
|
||||
userInfo := store.User{
|
||||
ID: "disqus_" + rest.EncodeID(data.value("login")),
|
||||
ID: "disqus_" + store.EncodeID(data.value("login")),
|
||||
Name: data.value("name"),
|
||||
Picture: data.value("avatar_url"),
|
||||
}
|
||||
|
||||
@@ -2,11 +2,7 @@ package rest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha1"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/crc64"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/umputun/remark/app/store"
|
||||
@@ -35,14 +31,3 @@ func SetUserInfo(r *http.Request, user store.User) *http.Request {
|
||||
ctx = context.WithValue(ctx, contextKey("user"), user)
|
||||
return r.WithContext(ctx)
|
||||
}
|
||||
|
||||
// EncodeID hashes user id to sha1
|
||||
func EncodeID(id string) string {
|
||||
h := sha1.New()
|
||||
if _, err := h.Write([]byte(id)); err != nil {
|
||||
// fail back to crc64
|
||||
log.Printf("[WARN] can't hash id %s, %s", id, err)
|
||||
return fmt.Sprintf("%x", crc64.Checksum([]byte(id), crc64.MakeTable(crc64.ECMA)))
|
||||
}
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
@@ -8,21 +8,6 @@ import (
|
||||
"github.com/umputun/remark/app/store"
|
||||
)
|
||||
|
||||
func TestEncodeID(t *testing.T) {
|
||||
tbl := []struct {
|
||||
id string
|
||||
hash string
|
||||
}{
|
||||
{"myid", "6e34471f84557e1713012d64a7477c71bfdac631"},
|
||||
{"", "da39a3ee5e6b4b0d3255bfef95601890afd80709"},
|
||||
{"blah blah", "135a1e01bae742c4a576b20fd41a683f6483ca43"},
|
||||
}
|
||||
|
||||
for i, tt := range tbl {
|
||||
assert.Equal(t, tt.hash, EncodeID(tt.id), "case #%d", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetUserInfo(t *testing.T) {
|
||||
r, err := http.NewRequest("GET", "http://blah.com", nil)
|
||||
assert.Nil(t, err)
|
||||
|
||||
+14
-1
@@ -4,6 +4,7 @@ import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"hash/crc64"
|
||||
"html/template"
|
||||
"log"
|
||||
"strconv"
|
||||
@@ -95,7 +96,7 @@ func (c *Comment) Sanitize() {
|
||||
// c.Text = strings.Replace(c.Text, "\t", "", -1)
|
||||
}
|
||||
|
||||
// hashIP replace sensitive fields with hashes
|
||||
// hashIP replace sensitive fields with hmac
|
||||
func (u *User) hashIP(secret string) {
|
||||
|
||||
hashVal := func(val string) string {
|
||||
@@ -112,3 +113,15 @@ func (u *User) hashIP(secret string) {
|
||||
|
||||
u.IP = hashVal(u.IP)
|
||||
}
|
||||
|
||||
// EncodeID hashes id to sha1. The function intentionally left outside of User struct because in some cases
|
||||
// we need hashing for parts of id, in some others hasing for non-User values.
|
||||
func EncodeID(id string) string {
|
||||
h := sha1.New()
|
||||
if _, err := h.Write([]byte(id)); err != nil {
|
||||
// fail back to crc64
|
||||
log.Printf("[WARN] can't hash id %s, %s", id, err)
|
||||
return fmt.Sprintf("%x", crc64.Checksum([]byte(id), crc64.MakeTable(crc64.ECMA)))
|
||||
}
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
@@ -58,3 +58,18 @@ func TestComment_PrepareUntrusted(t *testing.T) {
|
||||
assert.Equal(t, User{ID: "username"}, comment.User)
|
||||
|
||||
}
|
||||
|
||||
func TestComment_EncodeID(t *testing.T) {
|
||||
tbl := []struct {
|
||||
id string
|
||||
hash string
|
||||
}{
|
||||
{"myid", "6e34471f84557e1713012d64a7477c71bfdac631"},
|
||||
{"", "da39a3ee5e6b4b0d3255bfef95601890afd80709"},
|
||||
{"blah blah", "135a1e01bae742c4a576b20fd41a683f6483ca43"},
|
||||
}
|
||||
|
||||
for i, tt := range tbl {
|
||||
assert.Equal(t, tt.hash, EncodeID(tt.id), "case #%d", i)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user