mirror of
https://github.com/cubixle/tuukoti-framework.git
synced 2026-04-24 21:24:42 +01:00
working on flash messages
This commit is contained in:
109
cookies/cookies.go
Normal file
109
cookies/cookies.go
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package cookies
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gorilla/securecookie"
|
||||||
|
)
|
||||||
|
|
||||||
|
const flashCookieName = "tuukoti_flash"
|
||||||
|
|
||||||
|
type Cookies struct {
|
||||||
|
secureCookies *securecookie.SecureCookie
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(sc *securecookie.SecureCookie) *Cookies {
|
||||||
|
return &Cookies{secureCookies: sc}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Cookies) Create(name string, val string) (*http.Cookie, error) {
|
||||||
|
encodedValue, err := c.secureCookies.Encode(name, val)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
cookie := &http.Cookie{
|
||||||
|
Name: name,
|
||||||
|
Value: encodedValue,
|
||||||
|
Expires: time.Now().Add(3 * (24 * time.Hour)),
|
||||||
|
HttpOnly: true,
|
||||||
|
Path: "/",
|
||||||
|
}
|
||||||
|
|
||||||
|
return cookie, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadCookie will decode the secure cookie value into `out`.
|
||||||
|
func (c *Cookies) Read(req *http.Request, name string, out interface{}) error {
|
||||||
|
cookie, err := req.Cookie(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.secureCookies.Decode(name, cookie.Value, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFlashCookie will set a flash cookie with the data you give it a map[string]string{}.
|
||||||
|
func SetFlash(w http.ResponseWriter, val map[string]string) error {
|
||||||
|
b, err := json.Marshal(val)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
co := &http.Cookie{
|
||||||
|
Name: flashCookieName,
|
||||||
|
Value: encode(b),
|
||||||
|
Path: "/",
|
||||||
|
HttpOnly: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
http.SetCookie(w, co)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFlash will return any flash data as a map[string]string{}.
|
||||||
|
// It also sets the flash cookies value back to nothing so the flash only exists once.
|
||||||
|
func GetFlash(w http.ResponseWriter, req *http.Request) (map[string]string, error) {
|
||||||
|
co, err := req.Cookie(flashCookieName)
|
||||||
|
if err != nil {
|
||||||
|
switch err {
|
||||||
|
case http.ErrNoCookie:
|
||||||
|
return nil, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
value, err := decode(co.Value)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
out := map[string]string{}
|
||||||
|
if err := json.Unmarshal(value, &out); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
http.SetCookie(w, &http.Cookie{
|
||||||
|
Name: flashCookieName,
|
||||||
|
Value: "",
|
||||||
|
MaxAge: -1,
|
||||||
|
Expires: time.Unix(1, 0),
|
||||||
|
Path: "/",
|
||||||
|
HttpOnly: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encode(src []byte) string {
|
||||||
|
return base64.URLEncoding.EncodeToString(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
func decode(src string) ([]byte, error) {
|
||||||
|
return base64.URLEncoding.DecodeString(src)
|
||||||
|
}
|
||||||
56
cookies/cookies_test.go
Normal file
56
cookies/cookies_test.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package cookies_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/gorilla/securecookie"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"github.com/tuukoti/framework/cookies"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCookieReadAndGet(t *testing.T) {
|
||||||
|
secureCookie := securecookie.New([]byte("very-secret"), []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"))
|
||||||
|
c := cookies.New(secureCookie)
|
||||||
|
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
|
cookie, err := c.Create("testing", "test")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
http.SetCookie(w, cookie)
|
||||||
|
|
||||||
|
req := &http.Request{
|
||||||
|
Header: http.Header{},
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Cookie", w.Header().Get("Set-Cookie"))
|
||||||
|
|
||||||
|
out := ""
|
||||||
|
|
||||||
|
err = c.Read(req, "testing", &out)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, "test", out)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetGetFlash(t *testing.T) {
|
||||||
|
w := httptest.NewRecorder()
|
||||||
|
|
||||||
|
d := map[string]string{
|
||||||
|
"test": "testing",
|
||||||
|
}
|
||||||
|
|
||||||
|
err := cookies.SetFlash(w, d)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
req := &http.Request{
|
||||||
|
Header: http.Header{},
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Cookie", w.Header().Get("Set-Cookie"))
|
||||||
|
|
||||||
|
data, err := cookies.GetFlash(w, req)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, d, data)
|
||||||
|
}
|
||||||
4
go.mod
4
go.mod
@@ -3,14 +3,18 @@ module github.com/tuukoti/framework
|
|||||||
go 1.18
|
go 1.18
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/gorilla/securecookie v1.1.1
|
||||||
github.com/labstack/echo/v4 v4.7.2
|
github.com/labstack/echo/v4 v4.7.2
|
||||||
|
github.com/stretchr/testify v1.7.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/labstack/gommon v0.3.1 // indirect
|
github.com/labstack/gommon v0.3.1 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.11 // indirect
|
github.com/mattn/go-colorable v0.1.11 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.14 // indirect
|
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasttemplate v1.2.1 // indirect
|
github.com/valyala/fasttemplate v1.2.1 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
|
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -1,6 +1,8 @@
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||||
|
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||||
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
|
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
|
||||||
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||||
|
|||||||
Reference in New Issue
Block a user