@@ -2,9 +2,8 @@ package sessions
22
33import (
44 "encoding/json"
5+ "errors"
56 "fmt"
6− "strconv"
7− "strings"
87 "time"
98
109 "github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
@@ -126,84 +125,27 @@ func (s *SessionState) EncodeSessionState(c *encryption.Cipher) (string, error)
126125 return string(b), err
127126}
128127
129−// legacyDecodeSessionStatePlain decodes older plain session state string
130−func legacyDecodeSessionStatePlain(v string) (*SessionState, error) {
131− chunks := strings.Split(v, " ")
132− if len(chunks) != 2 {
133− return nil, fmt.Errorf("invalid session state (legacy: expected 2 chunks for user/email got %d)", len(chunks))
134− }
135−
136− user := strings.TrimPrefix(chunks[1], "user:")
137− email := strings.TrimPrefix(chunks[0], "email:")
138−
139− return &SessionState{User: user, Email: email}, nil
140−}
141−
142−// legacyDecodeSessionState attempts to decode the session state string
143−// generated by v3.1.0 or older
144−func legacyDecodeSessionState(v string, c *encryption.Cipher) (*SessionState, error) {
145− chunks := strings.Split(v, "|")
146−
147− if c == nil {
148− if len(chunks) != 1 {
149− return nil, fmt.Errorf("invalid session state (legacy: expected 1 chunk for plain got %d)", len(chunks))
150− }
151− return legacyDecodeSessionStatePlain(chunks[0])
152− }
153−
154− if len(chunks) != 4 && len(chunks) != 5 {
155− return nil, fmt.Errorf("invalid session state (legacy: expected 4 or 5 chunks for full got %d)", len(chunks))
156− }
157−
158− i := 0
159− ss, err := legacyDecodeSessionStatePlain(chunks[i])
160− if err != nil {
161− return nil, err
162− }
163−
164− i++
165− ss.AccessToken = chunks[i]
166−
167− if len(chunks) == 5 {
168− // SessionState with IDToken in v3.1.0
169− i++
170− ss.IDToken = chunks[i]
171− }
172−
173− i++
174− ts, err := strconv.Atoi(chunks[i])
175− if err != nil {
176− return nil, fmt.Errorf("invalid session state (legacy: wrong expiration time: %s)", err)
177− }
178− ss.ExpiresOn = time.Unix(int64(ts), 0)
179−
180− i++
181− ss.RefreshToken = chunks[i]
182−
183− return ss, nil
184−}
185−
186128// DecodeSessionState decodes the session cookie string into a SessionState
187129func DecodeSessionState(v string, c *encryption.Cipher) (*SessionState, error) {
188130 var ssj SessionStateJSON
189131 var ss *SessionState
190132 err := json.Unmarshal([]byte(v), &ssj)
191− if err == nil && ssj.SessionState != nil {
192− // Extract SessionState and CreatedAt,ExpiresOn value from SessionStateJSON
193− ss = ssj.SessionState
194− if ssj.CreatedAt != nil {
195− ss.CreatedAt = *ssj.CreatedAt
196− }
197− if ssj.ExpiresOn != nil {
198− ss.ExpiresOn = *ssj.ExpiresOn
199− }
200− } else {
201− // Try to decode a legacy string when json.Unmarshal failed
202− ss, err = legacyDecodeSessionState(v, c)
203− if err != nil {
204− return nil, err
205− }
133+ if err != nil {
134+ return nil, fmt.Errorf("error unmarshalling session: %w", err)
135+ }
136+ if ssj.SessionState == nil {
137+ return nil, errors.New("expected session state to not be nil")
206138 }
139+
140+ // Extract SessionState and CreatedAt,ExpiresOn value from SessionStateJSON
141+ ss = ssj.SessionState
142+ if ssj.CreatedAt != nil {
143+ ss.CreatedAt = *ssj.CreatedAt
144+ }
145+ if ssj.ExpiresOn != nil {
146+ ss.ExpiresOn = *ssj.ExpiresOn
147+ }
148+
207149 if c == nil {
208150 // Load only Email and User when cipher is unavailable
209151 ss = &SessionState{