1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-11-29 22:48:19 +02:00

Drop support for pre v3.1 cookies (#535)

Co-authored-by: Henry Jenkins <henry@henryjenkins.name>
This commit is contained in:
Joel Speed
2020-05-10 10:09:53 +01:00
committed by GitHub
parent 24cdfa68b6
commit de280824de
3 changed files with 20 additions and 119 deletions

View File

@@ -2,9 +2,8 @@ package sessions
import (
"encoding/json"
"errors"
"fmt"
"strconv"
"strings"
"time"
"github.com/oauth2-proxy/oauth2-proxy/pkg/encryption"
@@ -126,84 +125,27 @@ func (s *SessionState) EncodeSessionState(c *encryption.Cipher) (string, error)
return string(b), err
}
// legacyDecodeSessionStatePlain decodes older plain session state string
func legacyDecodeSessionStatePlain(v string) (*SessionState, error) {
chunks := strings.Split(v, " ")
if len(chunks) != 2 {
return nil, fmt.Errorf("invalid session state (legacy: expected 2 chunks for user/email got %d)", len(chunks))
}
user := strings.TrimPrefix(chunks[1], "user:")
email := strings.TrimPrefix(chunks[0], "email:")
return &SessionState{User: user, Email: email}, nil
}
// legacyDecodeSessionState attempts to decode the session state string
// generated by v3.1.0 or older
func legacyDecodeSessionState(v string, c *encryption.Cipher) (*SessionState, error) {
chunks := strings.Split(v, "|")
if c == nil {
if len(chunks) != 1 {
return nil, fmt.Errorf("invalid session state (legacy: expected 1 chunk for plain got %d)", len(chunks))
}
return legacyDecodeSessionStatePlain(chunks[0])
}
if len(chunks) != 4 && len(chunks) != 5 {
return nil, fmt.Errorf("invalid session state (legacy: expected 4 or 5 chunks for full got %d)", len(chunks))
}
i := 0
ss, err := legacyDecodeSessionStatePlain(chunks[i])
if err != nil {
return nil, err
}
i++
ss.AccessToken = chunks[i]
if len(chunks) == 5 {
// SessionState with IDToken in v3.1.0
i++
ss.IDToken = chunks[i]
}
i++
ts, err := strconv.Atoi(chunks[i])
if err != nil {
return nil, fmt.Errorf("invalid session state (legacy: wrong expiration time: %s)", err)
}
ss.ExpiresOn = time.Unix(int64(ts), 0)
i++
ss.RefreshToken = chunks[i]
return ss, nil
}
// DecodeSessionState decodes the session cookie string into a SessionState
func DecodeSessionState(v string, c *encryption.Cipher) (*SessionState, error) {
var ssj SessionStateJSON
var ss *SessionState
err := json.Unmarshal([]byte(v), &ssj)
if err == nil && ssj.SessionState != nil {
// Extract SessionState and CreatedAt,ExpiresOn value from SessionStateJSON
ss = ssj.SessionState
if ssj.CreatedAt != nil {
ss.CreatedAt = *ssj.CreatedAt
}
if ssj.ExpiresOn != nil {
ss.ExpiresOn = *ssj.ExpiresOn
}
} else {
// Try to decode a legacy string when json.Unmarshal failed
ss, err = legacyDecodeSessionState(v, c)
if err != nil {
return nil, err
}
if err != nil {
return nil, fmt.Errorf("error unmarshalling session: %w", err)
}
if ssj.SessionState == nil {
return nil, errors.New("expected session state to not be nil")
}
// Extract SessionState and CreatedAt,ExpiresOn value from SessionStateJSON
ss = ssj.SessionState
if ssj.CreatedAt != nil {
ss.CreatedAt = *ssj.CreatedAt
}
if ssj.ExpiresOn != nil {
ss.ExpiresOn = *ssj.ExpiresOn
}
if c == nil {
// Load only Email and User when cipher is unavailable
ss = &SessionState{