fix cookie -- not working
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
@@ -99,7 +100,7 @@ func (c *nativeCodec) Encode(session *SessionContext) (string, error) {
|
||||
|
||||
plaintext := session.Plaintext
|
||||
if plaintext == "" {
|
||||
plaintext = serializeValues(session.Values, session.OrderedKeys)
|
||||
plaintext = serializeCookieValues(session.Values, session.OrderedKeys, c.cfg.CookieIV)
|
||||
}
|
||||
return c.encryptInternal(plaintext)
|
||||
}
|
||||
@@ -321,6 +322,67 @@ func serializeValues(values map[string]string, orderedKeys []string) string {
|
||||
return strings.Join(pairs, fieldSeparator)
|
||||
}
|
||||
|
||||
func serializeCookieValues(values map[string]string, orderedKeys []string, cookieIV string) string {
|
||||
if len(values) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
keys := orderedValueKeys(values, orderedKeys, "checksum")
|
||||
if len(keys) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
var builder strings.Builder
|
||||
for _, key := range keys {
|
||||
builder.WriteString(key)
|
||||
builder.WriteString(pairSeparator)
|
||||
builder.WriteString(values[key])
|
||||
builder.WriteString(fieldSeparator)
|
||||
}
|
||||
|
||||
checksum := crc32.ChecksumIEEE([]byte(cookieIV + builder.String()))
|
||||
builder.WriteString("checksum")
|
||||
builder.WriteString(pairSeparator)
|
||||
builder.WriteString(fmt.Sprintf("%d", checksum))
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
func orderedValueKeys(values map[string]string, orderedKeys []string, excluded ...string) []string {
|
||||
if len(values) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
excludeSet := make(map[string]struct{}, len(excluded))
|
||||
for _, key := range excluded {
|
||||
excludeSet[key] = struct{}{}
|
||||
}
|
||||
|
||||
keys := make([]string, 0, len(values))
|
||||
seen := map[string]struct{}{}
|
||||
for _, key := range orderedKeys {
|
||||
if _, skip := excludeSet[key]; skip {
|
||||
continue
|
||||
}
|
||||
if _, ok := values[key]; ok {
|
||||
keys = append(keys, key)
|
||||
seen[key] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
extra := make([]string, 0)
|
||||
for key := range values {
|
||||
if _, skip := excludeSet[key]; skip {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[key]; !ok {
|
||||
extra = append(extra, key)
|
||||
}
|
||||
}
|
||||
sort.Strings(extra)
|
||||
keys = append(keys, extra...)
|
||||
return keys
|
||||
}
|
||||
|
||||
func int64Ptr(value string) *int64 {
|
||||
if value == "" {
|
||||
return nil
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
package cookie
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
testCookieKey = "def000008bf3d70e7012b7493c382d561e193218d0c74ab162fb0ea8029ce20e926531b4bcf0aaec9381152e6c161f198e06918b2d1aad67cc7cf40819a51ee328c63830"
|
||||
@@ -66,3 +71,44 @@ func TestNativeCodecRoundTrip(t *testing.T) {
|
||||
t.Fatalf("plaintext mismatch after roundtrip\n got: %s\nwant: %s", redecoded.Plaintext, decoded.Plaintext)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNativeCodecEncodeRecomputesPrestashopChecksum(t *testing.T) {
|
||||
codec, err := NewCodec(Config{
|
||||
CookieName: "PrestaShop-test",
|
||||
CookieKey: testCookieKey,
|
||||
CookieIV: "vfRFMV42",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("NewCodec() error = %v", err)
|
||||
}
|
||||
|
||||
decoded, err := codec.Decode(testCookie)
|
||||
if err != nil {
|
||||
t.Fatalf("Decode() error = %v", err)
|
||||
}
|
||||
|
||||
decoded.Values["iso_code_country"] = "PL"
|
||||
decoded.Values["id_currency"] = "6"
|
||||
decoded.Values["checksum"] = "stale"
|
||||
decoded.Plaintext = ""
|
||||
|
||||
encoded, err := codec.Encode(decoded)
|
||||
if err != nil {
|
||||
t.Fatalf("Encode() error = %v", err)
|
||||
}
|
||||
|
||||
redecoded, err := codec.Decode(encoded)
|
||||
if err != nil {
|
||||
t.Fatalf("Decode(encoded) error = %v", err)
|
||||
}
|
||||
|
||||
pairs := strings.Split(redecoded.Plaintext, fieldSeparator)
|
||||
if len(pairs) < 2 {
|
||||
t.Fatalf("plaintext too short: %q", redecoded.Plaintext)
|
||||
}
|
||||
body := strings.Join(pairs[:len(pairs)-1], fieldSeparator) + fieldSeparator
|
||||
wantChecksum := fmt.Sprintf("%d", crc32.ChecksumIEEE([]byte("vfRFMV42"+body)))
|
||||
if got := redecoded.Values["checksum"]; got != wantChecksum {
|
||||
t.Fatalf("checksum = %q, want %q", got, wantChecksum)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user