Files
pocket-id/backend/internal/oidc/session.go
2026-06-22 18:42:02 +02:00

149 lines
3.5 KiB
Go

package oidc
import (
"encoding/json"
"time"
"github.com/google/uuid"
"github.com/ory/fosite"
fositeoauth2 "github.com/ory/fosite/handler/oauth2"
"github.com/ory/fosite/handler/openid"
fositejwt "github.com/ory/fosite/token/jwt"
)
var _ openid.Session = (*Session)(nil)
var _ fositeoauth2.JWTSessionContainer = (*Session)(nil)
type Session struct {
Claims *fositejwt.IDTokenClaims `json:"id_token_claims"`
Headers *fositejwt.Headers `json:"headers"`
JWTClaims *fositejwt.JWTClaims `json:"jwt_claims,omitempty"`
JWTHeader *fositejwt.Headers `json:"jwt_header,omitempty"`
ExpiresAt map[fosite.TokenType]time.Time `json:"expires_at,omitempty"`
Subject string `json:"subject"`
AuthenticationMethod string `json:"authentication_method,omitempty"`
}
func NewEmptySession() *Session {
return &Session{
Claims: &fositejwt.IDTokenClaims{
RequestedAt: time.Now().UTC(),
Extra: map[string]interface{}{},
},
}
}
func NewAuthenticatedSession(subject, authenticationMethod string, authenticationTime, requestedAt time.Time) *Session {
now := time.Now().UTC()
if authenticationTime.IsZero() {
authenticationTime = now
}
if requestedAt.IsZero() {
requestedAt = now
}
session := NewEmptySession()
session.Subject = subject
session.AuthenticationMethod = authenticationMethod
session.Claims.Subject = subject
session.Claims.AuthTime = authenticationTime.UTC()
session.Claims.RequestedAt = requestedAt.UTC()
session.Claims.JTI = uuid.NewString()
return session
}
func (s *Session) SetExpiresAt(key fosite.TokenType, exp time.Time) {
if s.ExpiresAt == nil {
s.ExpiresAt = make(map[fosite.TokenType]time.Time)
}
s.ExpiresAt[key] = exp
}
func (s *Session) GetExpiresAt(key fosite.TokenType) time.Time {
if s.ExpiresAt == nil {
s.ExpiresAt = make(map[fosite.TokenType]time.Time)
}
return s.ExpiresAt[key]
}
func (s *Session) GetUsername() string {
return s.GetSubject()
}
func (s *Session) GetExtraClaims() map[string]interface{} {
if s == nil || s.Claims == nil || s.Claims.Issuer == "" {
return map[string]interface{}{}
}
return map[string]interface{}{
"iss": s.Claims.Issuer,
}
}
func (s *Session) GetSubject() string {
if s == nil {
return ""
}
return s.Subject
}
func (s *Session) Clone() fosite.Session {
if s == nil {
return nil
}
var clone Session
data, err := json.Marshal(s)
if err != nil {
return NewEmptySession()
}
if err = json.Unmarshal(data, &clone); err != nil {
return NewEmptySession()
}
return &clone
}
func (s *Session) IDTokenClaims() *fositejwt.IDTokenClaims {
if s.Claims == nil {
s.Claims = &fositejwt.IDTokenClaims{}
}
if s.Claims.Extra == nil {
s.Claims.Extra = map[string]interface{}{}
}
return s.Claims
}
func (s *Session) IDTokenHeaders() *fositejwt.Headers {
if s.Headers == nil {
s.Headers = &fositejwt.Headers{}
}
if s.Headers.Extra == nil {
s.Headers.Extra = map[string]interface{}{}
}
return s.Headers
}
func (s *Session) GetJWTClaims() fositejwt.JWTClaimsContainer {
if s.JWTClaims == nil {
s.JWTClaims = &fositejwt.JWTClaims{}
}
if s.JWTClaims.Subject == "" {
s.JWTClaims.Subject = s.GetSubject()
}
if s.JWTClaims.Extra == nil {
s.JWTClaims.Extra = map[string]interface{}{}
}
return s.JWTClaims
}
func (s *Session) GetJWTHeader() *fositejwt.Headers {
if s.JWTHeader == nil {
s.JWTHeader = &fositejwt.Headers{}
}
if s.JWTHeader.Extra == nil {
s.JWTHeader.Extra = map[string]interface{}{}
}
return s.JWTHeader
}