forked from bitly/oauth2_proxy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsession_state.go
136 lines (117 loc) · 2.83 KB
/
session_state.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
package providers
import (
"fmt"
"strconv"
"strings"
"time"
"github.com/bitly/oauth2_proxy/cookie"
)
type SessionState struct {
AccessToken string
IdToken string
ExpiresOn time.Time
RefreshToken string
Email string
User string
}
func (s *SessionState) IsExpired() bool {
if !s.ExpiresOn.IsZero() && s.ExpiresOn.Before(time.Now()) {
return true
}
return false
}
func (s *SessionState) String() string {
o := fmt.Sprintf("Session{%s", s.accountInfo())
if s.AccessToken != "" {
o += " token:true"
}
if s.IdToken != "" {
o += " id_token:true"
}
if !s.ExpiresOn.IsZero() {
o += fmt.Sprintf(" expires:%s", s.ExpiresOn)
}
if s.RefreshToken != "" {
o += " refresh_token:true"
}
return o + "}"
}
func (s *SessionState) EncodeSessionState(c *cookie.Cipher) (string, error) {
if c == nil || s.AccessToken == "" {
return s.accountInfo(), nil
}
return s.EncryptedString(c)
}
func (s *SessionState) accountInfo() string {
return fmt.Sprintf("email:%s user:%s", s.Email, s.User)
}
func (s *SessionState) EncryptedString(c *cookie.Cipher) (string, error) {
var err error
if c == nil {
panic("error. missing cipher")
}
a := s.AccessToken
if a != "" {
if a, err = c.Encrypt(a); err != nil {
return "", err
}
}
i := s.IdToken
if i != "" {
fmt.Printf("Encrytping ID Token")
if i, err = c.Encrypt(i); err != nil {
return "", err
}
}
r := s.RefreshToken
if r != "" {
if r, err = c.Encrypt(r); err != nil {
return "", err
}
}
return fmt.Sprintf("%s|%s|%s|%d|%s", s.accountInfo(), a, i, s.ExpiresOn.Unix(), r), nil
}
func decodeSessionStatePlain(v string) (s *SessionState, err error) {
chunks := strings.Split(v, " ")
if len(chunks) != 2 {
return nil, fmt.Errorf("could not decode session state: expected 2 chunks got %d", len(chunks))
}
email := strings.TrimPrefix(chunks[0], "email:")
user := strings.TrimPrefix(chunks[1], "user:")
if user == "" {
user = strings.Split(email, "@")[0]
}
return &SessionState{User: user, Email: email}, nil
}
func DecodeSessionState(v string, c *cookie.Cipher) (s *SessionState, err error) {
if c == nil {
return decodeSessionStatePlain(v)
}
chunks := strings.Split(v, "|")
if len(chunks) != 5 {
err = fmt.Errorf("invalid number of fields (got %d expected 5)", len(chunks))
return
}
sessionState, err := decodeSessionStatePlain(chunks[0])
if err != nil {
return nil, err
}
if chunks[1] != "" {
if sessionState.AccessToken, err = c.Decrypt(chunks[1]); err != nil {
return nil, err
}
}
if chunks[2] != "" {
if sessionState.IdToken, err = c.Decrypt(chunks[2]); err != nil {
return nil, err
}
}
ts, _ := strconv.Atoi(chunks[3])
sessionState.ExpiresOn = time.Unix(int64(ts), 0)
if chunks[4] != "" {
if sessionState.RefreshToken, err = c.Decrypt(chunks[4]); err != nil {
return nil, err
}
}
return sessionState, nil
}