added sessions and flash storage

This commit is contained in:
2018-04-07 14:37:07 +01:00
parent 971f157307
commit b8f8c995c1
10 changed files with 263 additions and 39 deletions

124
Gopkg.lock generated
View File

@@ -13,12 +13,6 @@
packages = ["crdb"]
revision = "59c0560478b705bf9bd12f9252224a0fad7c87df"
[[projects]]
name = "github.com/davecgh/go-spew"
packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
version = "v1.1.0"
[[projects]]
name = "github.com/daviddengcn/go-colortext"
packages = ["."]
@@ -63,13 +57,23 @@
[[projects]]
name = "github.com/gobuffalo/plush"
packages = [".","ast","lexer","parser","token"]
packages = [
".",
"ast",
"lexer",
"parser",
"token"
]
revision = "a3df688902c0ccd9fa712ed5a1da6b78e7efab0d"
version = "v3.6.12"
[[projects]]
name = "github.com/gobuffalo/tags"
packages = [".","form","form/bootstrap"]
packages = [
".",
"form",
"form/bootstrap"
]
revision = "ab52126649ee51d858d9525f60bc1618592433b0"
version = "v2.0.0"
@@ -81,7 +85,10 @@
[[projects]]
name = "github.com/gobuffalo/validate"
packages = [".","validators"]
packages = [
".",
"validators"
]
revision = "42d8db6e06e617cdedcc7a849d6690a2cb5a8d28"
version = "v2.0.0"
@@ -92,15 +99,24 @@
version = "v1.1"
[[projects]]
name = "github.com/gorilla/mux"
name = "github.com/gorilla/securecookie"
packages = ["."]
revision = "53c1911da2b537f792e7cafcb446b05ffe33b996"
version = "v1.6.1"
revision = "e59506cc896acb7f7bf732d4fdf5e25f7ccd8983"
version = "v1.1.1"
[[projects]]
name = "github.com/gorilla/sessions"
packages = ["."]
revision = "ca9ada44574153444b00d3fd9c8559e4cc95f896"
version = "v1.1"
[[projects]]
branch = "master"
name = "github.com/jmoiron/sqlx"
packages = [".","reflectx"]
packages = [
".",
"reflectx"
]
revision = "cf35089a197953c69420c8d0cecda90809764b1d"
[[projects]]
@@ -112,13 +128,20 @@
[[projects]]
branch = "master"
name = "github.com/lib/pq"
packages = [".","oid"]
packages = [
".",
"oid"
]
revision = "88edab0803230a3898347e77b474f8c1820a1f20"
[[projects]]
branch = "master"
name = "github.com/markbates/going"
packages = ["defaults","randx","wait"]
packages = [
"defaults",
"randx",
"wait"
]
revision = "0576708c56cea02331f864fe6e157ac7841923e4"
[[projects]]
@@ -129,7 +152,13 @@
[[projects]]
name = "github.com/markbates/pop"
packages = [".","associations","columns","fizz","fizz/translators"]
packages = [
".",
"associations",
"columns",
"fizz",
"fizz/translators"
]
revision = "f230643ae0f8fa01e9444c2fb857ba1f1a78eb1f"
version = "v4.0.0"
@@ -142,7 +171,36 @@
[[projects]]
branch = "master"
name = "github.com/mattn/anko"
packages = ["ast","builtins","builtins/encoding/json","builtins/errors","builtins/flag","builtins/fmt","builtins/github.com/daviddengcn/go-colortext","builtins/io","builtins/io/ioutil","builtins/math","builtins/math/big","builtins/math/rand","builtins/net","builtins/net/http","builtins/net/url","builtins/os","builtins/os/exec","builtins/os/signal","builtins/path","builtins/path/filepath","builtins/regexp","builtins/runtime","builtins/sort","builtins/strconv","builtins/strings","builtins/time","parser","vm"]
packages = [
"ast",
"builtins",
"builtins/encoding/json",
"builtins/errors",
"builtins/flag",
"builtins/fmt",
"builtins/github.com/daviddengcn/go-colortext",
"builtins/io",
"builtins/io/ioutil",
"builtins/math",
"builtins/math/big",
"builtins/math/rand",
"builtins/net",
"builtins/net/http",
"builtins/net/url",
"builtins/os",
"builtins/os/exec",
"builtins/os/signal",
"builtins/path",
"builtins/path/filepath",
"builtins/regexp",
"builtins/runtime",
"builtins/sort",
"builtins/strconv",
"builtins/strings",
"builtins/time",
"parser",
"vm"
]
revision = "d5441ca3f0c7e071a9ede864f9db2cc652690f42"
[[projects]]
@@ -181,12 +239,6 @@
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
[[projects]]
name = "github.com/pmezard/go-difflib"
packages = ["difflib"]
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
version = "v1.0.0"
[[projects]]
name = "github.com/russross/blackfriday"
packages = ["."]
@@ -219,7 +271,12 @@
[[projects]]
branch = "master"
name = "github.com/shurcooL/go"
packages = ["parserutil","printerutil","reflectfind","reflectsource"]
packages = [
"parserutil",
"printerutil",
"reflectfind",
"reflectsource"
]
revision = "364c5ae8518b51f5fda954762864d6f4d5c30c89"
[[projects]]
@@ -276,12 +333,6 @@
packages = ["."]
revision = "bd320f5d308e1a3c4314c678d8227a0d72574ae7"
[[projects]]
name = "github.com/stretchr/testify"
packages = ["assert","require"]
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
version = "v1.2.1"
[[projects]]
branch = "master"
name = "golang.org/x/crypto"
@@ -291,7 +342,11 @@
[[projects]]
branch = "master"
name = "golang.org/x/net"
packages = ["context","html","html/atom"]
packages = [
"context",
"html",
"html/atom"
]
revision = "ae89d30ce0c63142b652837da33d782e2b0a9b25"
[[projects]]
@@ -303,7 +358,10 @@
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = ["unix","windows"]
packages = [
"unix",
"windows"
]
revision = "c28acc882ebcbfbe8ce9f0f14b9ac26ee138dd51"
[[projects]]
@@ -315,6 +373,6 @@
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "686f5e2aed8b743dfbc53e74a1e48185702059972b7a587db36af49ec0eeea8f"
inputs-digest = "a9de62d6e42d4a73e9888b54ce7f31b165f2709ba75b468104413487da78238a"
solver-name = "gps-cdcl"
solver-version = 1

View File

@@ -20,3 +20,7 @@
[[constraint]]
name = "github.com/sirupsen/logrus"
version = "1.0.5"
[[constraint]]
name = "github.com/gorilla/sessions"
version = "1.1.0"

View File

@@ -12,7 +12,7 @@ import (
"github.com/sirupsen/logrus"
)
func newContext(r Route, res http.ResponseWriter, req *http.Request) *DefaultContext {
func (a *App) newContext(r Route, res http.ResponseWriter, req *http.Request) *DefaultContext {
data := make(map[string]interface{})
data["path"] = r.Path
data["env"] = r.Env
@@ -23,6 +23,13 @@ func newContext(r Route, res http.ResponseWriter, req *http.Request) *DefaultCon
params.Set(k, v)
}
sessionStore, _ := a.cfg.SessionStore.Get(req, a.cfg.SessionName)
session := &Session{
Session: sessionStore,
req: req,
res: res,
}
return &DefaultContext{
response: res,
request: req,
@@ -30,6 +37,8 @@ func newContext(r Route, res http.ResponseWriter, req *http.Request) *DefaultCon
data: data,
env: r.Env,
logger: r.Logger,
session: session,
flash: newFlash(session),
}
}
@@ -42,6 +51,8 @@ type DefaultContext struct {
data map[string]interface{}
env string
logger *logrus.Logger
session *Session
flash *Flash
}
// Response returns the original Response for the request.
@@ -125,3 +136,11 @@ func (d *DefaultContext) Env() string {
func (d *DefaultContext) Logger() *logrus.Logger {
return d.logger
}
func (d *DefaultContext) Session() *Session {
return d.session
}
func (d *DefaultContext) Flash() *Flash {
return d.flash
}

View File

@@ -22,6 +22,11 @@ type DefaultRouter struct {
Routes []*Route
StaticRoutes []*StaticRoute
Options *RouterOptions
app *App
}
func (r *DefaultRouter) SetApp(app *App) {
r.app = app
}
func (r *DefaultRouter) GET(path string, h Handler) {
@@ -67,6 +72,7 @@ func (r *DefaultRouter) addRoute(m, p string, h Handler) {
Env: r.Options.Env,
Middleware: r.Options.MiddlewareStack,
Logger: r.Options.Logger,
app: r.app,
})
}

57
flash.go Normal file
View File

@@ -0,0 +1,57 @@
package tuu
import "encoding/json"
// flashKey is the prefix inside the Session.
const flashKey = "_flash_"
//Flash is a struct that helps with the operations over flash messages.
type Flash struct {
data map[string][]string
}
//Delete removes a particular key from the Flash.
func (f Flash) Delete(key string) {
delete(f.data, key)
}
//Clear removes all keys from the Flash.
func (f *Flash) Clear() {
f.data = map[string][]string{}
}
//Set allows to set a list of values into a particular key.
func (f Flash) Set(key string, values []string) {
f.data[key] = values
}
//Add adds a flash value for a flash key, if the key already has values the list for that value grows.
func (f Flash) Add(key, value string) {
if len(f.data[key]) == 0 {
f.data[key] = []string{value}
return
}
f.data[key] = append(f.data[key], value)
}
//Persist the flash inside the session.
func (f Flash) persist(session *Session) {
b, _ := json.Marshal(f.data)
session.Set(flashKey, b)
session.Save()
}
//newFlash creates a new Flash and loads the session data inside its data.
func newFlash(session *Session) *Flash {
result := &Flash{
data: map[string][]string{},
}
if session.Session != nil {
if f := session.Get(flashKey); f != nil {
json.Unmarshal(f.([]byte), &result.data)
}
}
return result
}

16
middleware/session.go Normal file
View File

@@ -0,0 +1,16 @@
package middleware
import (
"github.com/lukerodham/tuu"
)
func SessionSaver(next tuu.Handler) Handler {
return func(c tuu.Context) error {
err := next(c)
if err != nil {
return err
}
return c.Session().Save()
}
}

View File

@@ -14,12 +14,13 @@ type Route struct {
Env string
Middleware MiddlewareStack
Logger *logrus.Logger
app *App
}
func (r *Route) ServeHTTP(res http.ResponseWriter, req *http.Request) {
defer gcontext.Clear(req)
c := newContext(*r, res, req)
c := r.app.newContext(*r, res, req)
err := r.Middleware.handler(r)(c)

View File

@@ -5,6 +5,7 @@ import "net/http"
type Handler func(Context) error
type Router interface {
SetApp(app *App)
GET(path string, h Handler)
POST(path string, h Handler)
Static(path string, root http.FileSystem)

52
session.go Normal file
View File

@@ -0,0 +1,52 @@
package tuu
import (
"net/http"
"github.com/gorilla/sessions"
)
// Session wraps the "github.com/gorilla/sessions" API
// in something a little cleaner and a bit more useable.
type Session struct {
Session *sessions.Session
req *http.Request
res http.ResponseWriter
}
// Save the current session.
func (s *Session) Save() error {
return s.Session.Save(s.req, s.res)
}
// Get a value from the current session.
func (s *Session) Get(name interface{}) interface{} {
return s.Session.Values[name]
}
// GetOnce gets a value from the current session and then deletes it.
func (s *Session) GetOnce(name interface{}) interface{} {
if x, ok := s.Session.Values[name]; ok {
s.Delete(name)
return x
}
return nil
}
// Set a value onto the current session. If a value with that name
// already exists it will be overridden with the new value.
func (s *Session) Set(name, value interface{}) {
s.Session.Values[name] = value
}
// Delete a value from the current session.
func (s *Session) Delete(name interface{}) {
delete(s.Session.Values, name)
}
// Clear the current session
func (s *Session) Clear() {
for k := range s.Session.Values {
s.Delete(k)
}
}

12
tuu.go
View File

@@ -9,16 +9,26 @@ import (
"os/signal"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
)
type Config struct {
IPAddr string
Port string
Env string
SessionName string
SessionStore sessions.Store
}
func New(r Router, cfg Config) *App {
return &App{router: r, cfg: cfg}
cfg.SessionName = "_tuu_session"
// TODO: make session secret actual, secret.
cfg.SessionStore = sessions.NewCookieStore([]byte("secret"))
app := &App{router: r, cfg: cfg}
r.SetApp(app)
return app
}
type App struct {