This repository has been archived by the owner on Apr 10, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsession.go
125 lines (111 loc) · 2.95 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
package session
import (
"context"
"crypto/rand"
"encoding/base64"
"io"
)
// Based on https://github.com/gorilla/sessions/blob/master/sessions.go
// Default flashes key.
const flashesKey = "_flash"
// NewSession creates a new session instance
func NewSession(length int) *Session {
return &Session{
ID: generateRandomKey(length),
Values: make(map[string]interface{}),
}
}
// Session stores the values and optional configuration for a session.
type Session struct {
// The ID of the session, generated by stores. It should not be used for
// user data.
ID []byte
// Values contains the user-data for the session.
Values map[string]interface{}
// Session changed and should be saved
store Store
}
// Base64ID version of ID bytes
func (s *Session) Base64ID() string {
return EncodeSessionID(s.ID)
}
// Get will return the value or nil
func (s *Session) Get(key string) interface{} {
if v, ok := s.Values[key]; ok {
return v
}
return nil
}
// Set will update or create a new key value
func (s *Session) Set(key string, value interface{}) {
// if v, ok := s.Values[key]; ok {
// if v != value {
// s.changed = true
// }
// } else {
// s.changed = true
// }
s.Values[key] = value
}
// Save a session
func (s *Session) Save(ctx context.Context) error {
return s.store.Save(ctx, s)
}
// 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.
func (s *Session) Flashes(vars ...string) []interface{} {
var flashes []interface{}
key := flashesKey
if len(vars) > 0 {
key = vars[0]
}
if v, ok := s.Values[key]; ok {
// Drop the flashes and return it.
delete(s.Values, key)
s.changed = true
flashes = v.([]interface{})
}
return flashes
}
// 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.
func (s *Session) AddFlash(value interface{}, vars ...string) {
key := flashesKey
if len(vars) > 0 {
key = vars[0]
}
var flashes []interface{}
if v, ok := s.Values[key]; ok {
flashes = v.([]interface{})
}
s.Values[key] = append(flashes, value)
s.changed = true
}
// EncodeSessionID in base64 string for cookie
func EncodeSessionID(s []byte) string {
return base64.URLEncoding.EncodeToString(s)
}
// DecodeSessionID in base64 from cookie
func DecodeSessionID(s string) []byte {
b, err := base64.URLEncoding.DecodeString(s)
if err == nil {
return b
}
return nil
}
// GenerateRandomKey creates a random key with the given length in bytes.
// On failure, returns nil.
//
// Callers should explicitly check for the possibility of a nil return, treat
// it as a failure of the system random number generator, and not continue.
func generateRandomKey(length int) []byte {
k := make([]byte, length)
if _, err := io.ReadFull(rand.Reader, k); err != nil {
return nil
}
return k
}