-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathsession.go
138 lines (118 loc) · 3.18 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
131
132
133
134
135
136
137
138
//go:generate mockgen -package main -destination=session_mock_test.go -source=session.go
package main
import (
"net/http"
"net/http/cookiejar"
"sync"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/session"
"github.com/rs/zerolog"
)
type SessionManager interface {
NewSession(c *fiber.Ctx, lureURL string) (*proxySession, error)
GetSession(c *fiber.Ctx) (*proxySession, error)
GetOrCreateSession(c *fiber.Ctx, lureURL string) (*proxySession, error)
DeleteSession(sessionID string)
}
func NewSessionManager(log *zerolog.Logger, store *session.Store, sessionCookieName string) SessionManager {
return &sessionManager{
log: log,
sessions: make(map[string]*proxySession),
store: store,
cookieName: sessionCookieName,
}
}
type sessionManager struct {
log *zerolog.Logger
// mu locks the remaining fields.
mu sync.RWMutex
// sessions maps sessionId to session object
sessions map[string]*proxySession
// Store interface to store the session data
store *session.Store
// Name of authentication cookie
cookieName string
}
func (m *sessionManager) NewSession(c *fiber.Ctx, lureURL string) (*proxySession, error) {
m.log.Info().Str("lureURL", lureURL).Str("host", c.Hostname()).Msg("create new session")
sess, err := m.store.Get(c)
if err != nil {
return nil, err
}
cookie, _ := cookiejar.New(nil)
newSess := &proxySession{cookieJar: cookie, lureURL: lureURL}
m.mu.Lock()
m.sessions[sess.ID()] = newSess
m.mu.Unlock()
resultSess := *newSess
resultSess.Session = sess
return &resultSess, nil
}
func (m *sessionManager) GetSession(c *fiber.Ctx) (result *proxySession, err error) {
id := c.Cookies(m.cookieName)
if len(id) == 0 {
return
}
m.mu.RLock()
proxySess := m.sessions[id]
m.mu.RUnlock()
if proxySess == nil {
return
}
sess, err := m.store.Get(c)
if err != nil {
return nil, err
}
if sess.ID() != id {
return
}
resultSess := *proxySess
resultSess.Session = sess
return &resultSess, nil
}
func (m *sessionManager) GetOrCreateSession(c *fiber.Ctx, lureURL string) (*proxySession, error) {
proxySess, err := m.GetSession(c)
if err != nil || proxySess != nil {
return proxySess, err
}
return m.NewSession(c, lureURL)
}
func (m *sessionManager) DeleteSession(sessionID string) {
m.mu.Lock()
defer m.mu.Unlock()
delete(m.sessions, sessionID)
}
type proxySession struct {
*session.Session
lureURL string
cookieJar http.CookieJar
}
func (s *proxySession) CookieJar() http.CookieJar {
return s.cookieJar
}
func (s *proxySession) LureURL() string {
return s.lureURL
}
type SessionDeleter interface {
DeleteSession(sessionID string)
}
func NewSessionStorage(delegate fiber.Storage, deleteCallbacks ...SessionDeleter) SessionStorage {
return &sessionStorage{delegate, deleteCallbacks}
}
type SessionStorage interface {
fiber.Storage
AddSessionDeleter(sd SessionDeleter)
}
type sessionStorage struct {
fiber.Storage
deleteCallbacks []SessionDeleter
}
func (s *sessionStorage) Delete(key string) error {
for _, callback := range s.deleteCallbacks {
callback.DeleteSession(key)
}
return s.Storage.Delete(key)
}
func (s *sessionStorage) AddSessionDeleter(sd SessionDeleter) {
s.deleteCallbacks = append(s.deleteCallbacks, sd)
}