Files
wonderwall/pkg/session/session_id.go
Trong Huu Nguyen 1f5635239a refactor: split out openid client, config and provider
There's a bunch of changes here, but in essence:

- split out openid configuration
- separate openid configuration between client/rp and provider
- consolidate client and provider related code in separate packages

These changes allow for simplification of the Handler, as well as a
bunch of test/mock code as the configuration is now instantiated
seperately from the client/provider code.
2022-07-05 13:09:00 +02:00

65 lines
1.5 KiB
Go

package session
import (
"crypto/rand"
"encoding/base64"
"fmt"
"io"
"net/url"
"github.com/nais/wonderwall/pkg/jwt"
"github.com/nais/wonderwall/pkg/openid/config"
)
const (
SessionStateParamKey = "session_state"
)
func NewSessionID(cfg *config.Provider, idToken *jwt.IDToken, params url.Values) (string, error) {
// 1. check for 'sid' claim in id_token
sessionID, err := idToken.GetSidClaim()
if err == nil {
return sessionID, nil
}
// 1a. error if sid claim is required according to openid config
if err != nil && cfg.SidClaimRequired() {
return "", err
}
// 2. check for session_state in callback params
sessionID, err = getSessionStateFrom(params)
if err == nil {
return sessionID, nil
}
// 2a. error if session_state is required according to openid config
if err != nil && cfg.SessionStateRequired() {
return "", err
}
// 3. generate ID if all else fails
sessionID, err = generateSessionID()
if err != nil {
return "", err
}
return sessionID, nil
}
func getSessionStateFrom(params url.Values) (string, error) {
sessionState := params.Get(SessionStateParamKey)
if len(sessionState) == 0 {
return "", fmt.Errorf("missing required '%s' in params", SessionStateParamKey)
}
return sessionState, nil
}
func generateSessionID() (string, error) {
rawID := make([]byte, 64)
_, err := io.ReadFull(rand.Reader, rawID)
if err != nil {
return "", fmt.Errorf("generating session ID: %w", err)
}
return base64.RawURLEncoding.EncodeToString(rawID), nil
}