forked from peterskeide/bones
-
Notifications
You must be signed in to change notification settings - Fork 0
/
session.go
130 lines (101 loc) · 2.84 KB
/
session.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package sessions
import (
"bones/web/handlers"
"encoding/hex"
"github.com/gorilla/securecookie"
"github.com/gorilla/sessions"
"log"
"net/http"
"os"
)
var sessionStore sessions.Store
const (
flashErrorsKey = "_flash_errors"
flashNoticesKey = "_flash_notices"
)
// Initialize the session store with authentication
// and encryption keys.
//
// Keys are read from the environment variables
// SESSION_AUTH_KEY and SESSION_ENCRYPTION_KEY
// If not set, temporary keys will be used.
//
// Using temporary keys will invalidate all sessions
// when the server restarts.
func Enable() {
auth_key := []byte(os.Getenv("SESSION_AUTH_KEY"))
if len(auth_key) == 0 {
log.Println("Using temporary authentication key for session")
auth_key = securecookie.GenerateRandomKey(64)
}
encryption_key := []byte(os.Getenv("SESSION_ENCRYPTION_KEY"))
if len(encryption_key) == 0 {
log.Println("Using temporary encryption key for session")
encryption_key = securecookie.GenerateRandomKey(32)
}
sessionStore = sessions.NewCookieStore(auth_key, encryption_key)
}
type CookieSessionStore struct{}
func (store CookieSessionStore) Session(res http.ResponseWriter, req *http.Request) handlers.Session {
session, _ := sessionStore.Get(req, "bones_session")
return &CookieSession{session, res, req}
}
type CookieSession struct {
session *sessions.Session
responseWriter http.ResponseWriter
request *http.Request
}
func (s *CookieSession) AddFlashError(msg string) {
s.session.AddFlash(msg, flashErrorsKey)
}
func (s *CookieSession) FlashErrors() []string {
return s.flashMessages(flashErrorsKey)
}
func (s *CookieSession) flashMessages(key string) []string {
flashes := s.session.Flashes(key)
length := len(flashes)
messages := make([]string, length, length)
for i, msg := range flashes {
messages[i] = msg.(string)
}
return messages
}
func (s *CookieSession) AddFlashNotice(msg string) {
s.session.AddFlash(msg, flashNoticesKey)
}
func (s *CookieSession) FlashNotices() []string {
return s.flashMessages(flashNoticesKey)
}
func (s *CookieSession) UserId() int {
value := s.session.Values["userId"]
if id, ok := value.(int); ok {
return id
}
return -1
}
func (s *CookieSession) SetUserId(id int) {
s.session.Values["userId"] = id
}
// Returns existing CsrfToken from cookie or
// creates and saves a new token.
// Will panic if it is unable to return a token.
func (s *CookieSession) CsrfToken() string {
token, ok := s.session.Values["CsrfToken"].(string)
if !ok {
randomKey := securecookie.GenerateRandomKey(32)
token = hex.EncodeToString(randomKey)
s.session.Values["CsrfToken"] = token
err := s.Save()
if err != nil {
panic(err)
}
}
return token
}
func (s *CookieSession) Clear() error {
s.session.Values = nil
return s.Save()
}
func (s *CookieSession) Save() error {
return s.session.Save(s.request, s.responseWriter)
}