go-skeletor/vendor/github.com/martini-contrib/sessions/sessions.go

167 lines
4.1 KiB
Go
Raw Normal View History

2021-11-02 11:25:21 +01:00
// Package sessions contains middleware for easy session management in Martini.
//
// package main
//
// import (
// "github.com/go-martini/martini"
// "github.com/martini-contrib/sessions"
// )
//
// func main() {
// m := martini.Classic()
//
// store := sessions.NewCookieStore([]byte("secret123"))
// m.Use(sessions.Sessions("my_session", store))
//
// m.Get("/", func(session sessions.Session) string {
// session.Set("hello", "world")
// })
// }
package sessions
import (
"github.com/go-martini/martini"
"github.com/gorilla/context"
"github.com/gorilla/sessions"
"log"
"net/http"
)
const (
errorFormat = "[sessions] ERROR! %s\n"
)
// Store is an interface for custom session stores.
type Store interface {
sessions.Store
}
// Options stores configuration for a session or session store.
//
// Fields are a subset of http.Cookie fields.
type Options struct {
Path string
Domain string
// MaxAge=0 means no 'Max-Age' attribute specified.
// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'.
// MaxAge>0 means Max-Age attribute present and given in seconds.
MaxAge int
Secure bool
HttpOnly bool
}
// Session stores the values and optional configuration for a session.
type Session interface {
// Get returns the session value associated to the given key.
Get(key interface{}) interface{}
// Set sets the session value associated to the given key.
Set(key interface{}, val interface{})
// Delete removes the session value associated to the given key.
Delete(key interface{})
// Clear deletes all values in the session.
Clear()
// AddFlash adds a flash message to the session.
// A single variadic argument is accepted, and it is optional: it defines the flash key.
// If not defined "_flash" is used by default.
AddFlash(value interface{}, vars ...string)
// Flashes returns a slice of flash messages from the session.
// A single variadic argument is accepted, and it is optional: it defines the flash key.
// If not defined "_flash" is used by default.
Flashes(vars ...string) []interface{}
// Options sets confuguration for a session.
Options(Options)
}
// Sessions is a Middleware that maps a session.Session service into the Martini handler chain.
// Sessions can use a number of storage solutions with the given store.
func Sessions(name string, store Store) martini.Handler {
return func(res http.ResponseWriter, r *http.Request, c martini.Context, l *log.Logger) {
// Map to the Session interface
s := &session{name, r, l, store, nil, false}
c.MapTo(s, (*Session)(nil))
// Use before hook to save out the session
rw := res.(martini.ResponseWriter)
rw.Before(func(martini.ResponseWriter) {
if s.Written() {
check(s.Session().Save(r, res), l)
}
})
// clear the context, we don't need to use
// gorilla context and we don't want memory leaks
defer context.Clear(r)
c.Next()
}
}
type session struct {
name string
request *http.Request
logger *log.Logger
store Store
session *sessions.Session
written bool
}
func (s *session) Get(key interface{}) interface{} {
return s.Session().Values[key]
}
func (s *session) Set(key interface{}, val interface{}) {
s.Session().Values[key] = val
s.written = true
}
func (s *session) Delete(key interface{}) {
delete(s.Session().Values, key)
s.written = true
}
func (s *session) Clear() {
for key := range s.Session().Values {
s.Delete(key)
}
}
func (s *session) AddFlash(value interface{}, vars ...string) {
s.Session().AddFlash(value, vars...)
s.written = true
}
func (s *session) Flashes(vars ...string) []interface{} {
s.written = true
return s.Session().Flashes(vars...)
}
func (s *session) Options(options Options) {
s.Session().Options = &sessions.Options{
Path: options.Path,
Domain: options.Domain,
MaxAge: options.MaxAge,
Secure: options.Secure,
HttpOnly: options.HttpOnly,
}
}
func (s *session) Session() *sessions.Session {
if s.session == nil {
var err error
s.session, err = s.store.Get(s.request, s.name)
check(err, s.logger)
}
return s.session
}
func (s *session) Written() bool {
return s.written
}
func check(err error, l *log.Logger) {
if err != nil {
l.Printf(errorFormat, err)
}
}