hash ip with hmac
This commit is contained in:
+1
-1
@@ -93,7 +93,7 @@ func main() {
|
||||
log.Printf("[WARN] running in dev mode")
|
||||
}
|
||||
|
||||
dataService := store.Service{Interface: dataStore, EditDuration: 5 * time.Minute}
|
||||
dataService := store.Service{Interface: dataStore, EditDuration: 5 * time.Minute, Secret: opts.ServerCommand.StoreKey}
|
||||
sessionStore := func() sessions.Store {
|
||||
sess := sessions.NewFilesystemStore(opts.ServerCommand.SessionStore, []byte(opts.ServerCommand.StoreKey))
|
||||
sess.Options.HttpOnly = true
|
||||
|
||||
@@ -97,7 +97,7 @@ func TestServer_CreateAndGet(t *testing.T) {
|
||||
assert.Equal(t, "<p><strong>test</strong> <em>123</em> http://radio-t.com</p>", comment.Text)
|
||||
assert.Equal(t, store.User{Name: "developer one", ID: "dev",
|
||||
Picture: "/api/v1/avatar/remark.image",
|
||||
Profile: "https://remark42.com", Admin: true, Blocked: false, IP: "4b84b15bff6ee5796152495a230e45e3d7e947d9"},
|
||||
Profile: "https://remark42.com", Admin: true, Blocked: false, IP: "ae12fe3b5f129b5cc4cdd2b136b7b7947c4d2741"},
|
||||
comment.User)
|
||||
t.Logf("%+v", comment)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"hash/crc64"
|
||||
"html/template"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -98,16 +99,16 @@ func (c *Comment) sanitize() {
|
||||
}
|
||||
|
||||
// hashIP replace sensitive fields with hashes
|
||||
func (u *User) hashIP() {
|
||||
func (u *User) hashIP(secret string) {
|
||||
|
||||
hashVal := func(val string) string {
|
||||
if _, err := strconv.ParseUint(val, 16, 64); err == nil || val == "" {
|
||||
return val // already hashed
|
||||
}
|
||||
h := sha1.New()
|
||||
key := []byte(secret)
|
||||
h := hmac.New(sha1.New, key)
|
||||
if _, err := h.Write([]byte(val)); err != nil {
|
||||
// fail back to crc64
|
||||
return fmt.Sprintf("%x", crc64.Checksum([]byte(val), crc64.MakeTable(crc64.ECMA)))
|
||||
log.Printf("[WARN] can't hash ip, %s", err)
|
||||
}
|
||||
return fmt.Sprintf("%x", h.Sum(nil))
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
type Service struct {
|
||||
Interface
|
||||
EditDuration time.Duration
|
||||
Secret string
|
||||
}
|
||||
|
||||
// Create prepares comment and forward to Interface.Create
|
||||
@@ -27,8 +28,8 @@ func (s *Service) Create(comment Comment) (commentID string, err error) {
|
||||
comment.Votes = make(map[string]bool)
|
||||
}
|
||||
|
||||
comment.sanitize() // clear potentially dangerous js from all parts of comment
|
||||
comment.User.hashIP() // replace ip by hash
|
||||
comment.sanitize() // clear potentially dangerous js from all parts of comment
|
||||
comment.User.hashIP(s.Secret) // replace ip by hash
|
||||
|
||||
return s.Interface.Create(comment)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,52 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestService_CreateFromEmpty(t *testing.T) {
|
||||
defer os.Remove(testDb)
|
||||
b := Service{Interface: prep(t), Secret: "secret 123"}
|
||||
comment := Comment{
|
||||
Text: "text",
|
||||
User: User{IP: "192.168.1.1", ID: "user"},
|
||||
Locator: Locator{URL: "https://radio-t.com", SiteID: "radio-t"},
|
||||
}
|
||||
id, err := b.Create(comment)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, id != "", id)
|
||||
|
||||
res, err := b.Get(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, id)
|
||||
assert.NoError(t, err)
|
||||
t.Logf("%+v", res)
|
||||
assert.Equal(t, "text", res.Text)
|
||||
assert.True(t, time.Since(res.Timestamp).Seconds() < 1)
|
||||
assert.Equal(t, "user", res.User.ID)
|
||||
assert.Equal(t, "9f41a4b2dca0c826f1aa2c69246347758a43eac1", res.User.IP)
|
||||
assert.Equal(t, map[string]bool{}, res.Votes)
|
||||
}
|
||||
|
||||
func TestService_CreateFromPartial(t *testing.T) {
|
||||
defer os.Remove(testDb)
|
||||
b := Service{Interface: prep(t), Secret: "secret 123"}
|
||||
comment := Comment{
|
||||
Text: "text",
|
||||
Timestamp: time.Date(2018, 3, 25, 16, 34, 33, 0, time.UTC),
|
||||
Votes: map[string]bool{"u1": true, "u2": false},
|
||||
User: User{IP: "192.168.1.1", ID: "user"},
|
||||
Locator: Locator{URL: "https://radio-t.com", SiteID: "radio-t"},
|
||||
}
|
||||
id, err := b.Create(comment)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, id != "", id)
|
||||
|
||||
res, err := b.Get(Locator{URL: "https://radio-t.com", SiteID: "radio-t"}, id)
|
||||
assert.NoError(t, err)
|
||||
t.Logf("%+v", res)
|
||||
assert.Equal(t, "text", res.Text)
|
||||
assert.Equal(t, comment.Timestamp, res.Timestamp)
|
||||
assert.Equal(t, "user", res.User.ID)
|
||||
assert.Equal(t, "9f41a4b2dca0c826f1aa2c69246347758a43eac1", res.User.IP)
|
||||
assert.Equal(t, comment.Votes, res.Votes)
|
||||
}
|
||||
|
||||
func TestService_Vote(t *testing.T) {
|
||||
defer os.Remove(testDb)
|
||||
b := Service{Interface: prep(t)}
|
||||
|
||||
Reference in New Issue
Block a user