oidc

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 10, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrPKCEMethodNotSupported = errors.New("code_challenge_method must be S256")
	ErrPKCEVerifierMismatch   = errors.New("invalid code_verifier")
)
View Source
var (
	ErrClientNotFound        = errors.New("client not found")
	ErrClientExists          = errors.New("client already exists")
	ErrInvalidClientSecret   = errors.New("invalid client secret")
	ErrClientInactive        = errors.New("client is inactive")
	ErrUnsupportedGrantType  = errors.New("client does not allow grant type")
	ErrConsentNotFound       = errors.New("consent not found")
	ErrAuthCodeNotFound      = errors.New("authorization code not found")
	ErrAuthCodeExpired       = errors.New("authorization code expired")
	ErrAuthCodeConsumed      = errors.New("authorization code already consumed")
	ErrRefreshTokenNotFound  = errors.New("refresh token not found")
	ErrRefreshTokenExpired   = errors.New("refresh token expired")
	ErrRefreshTokenRevoked   = errors.New("refresh token revoked")
	ErrRefreshTokenReplay    = errors.New("refresh token replay detected")
	ErrInvalidRedirectURI    = errors.New("invalid redirect uri")
	ErrInvalidRequestedScope = errors.New("invalid scope")
)
View Source
var ErrInvalidToken = errors.New("invalid token")
View Source
var ErrPrivateKeyInvalid = errors.New("private key is invalid")

Functions

func ClientAllowsGrantType

func ClientAllowsGrantType(client OIDCClient, grantType string) bool

func IsClientActive

func IsClientActive(client OIDCClient) bool

func MustAuthorizeURL

func MustAuthorizeURL(basePath string, client OIDCClient, redirectURI string) string

func ValidateRedirectURI

func ValidateRedirectURI(client OIDCClient, uri string) error

func ValidateScopes

func ValidateScopes(client OIDCClient, requested []string) error

Types

type AccessTokenClaims

type AccessTokenClaims struct {
	Issuer    string
	Audience  string
	Subject   string
	Scope     []string
	IssuedAt  time.Time
	ExpiresAt time.Time
	TokenUse  string
}

type AdminClientHandler

type AdminClientHandler struct {
	// contains filtered or unexported fields
}

func NewAdminClientHandler

func NewAdminClientHandler(store Store) *AdminClientHandler

func (*AdminClientHandler) HandleCreate

func (h *AdminClientHandler) HandleCreate(ctx HTTPContext)

func (*AdminClientHandler) HandleDelete

func (h *AdminClientHandler) HandleDelete(ctx HTTPContext, clientID string)

func (*AdminClientHandler) HandleGet

func (h *AdminClientHandler) HandleGet(ctx HTTPContext, clientID string)

func (*AdminClientHandler) HandleList

func (h *AdminClientHandler) HandleList(ctx HTTPContext)

func (*AdminClientHandler) HandleUpdate

func (h *AdminClientHandler) HandleUpdate(ctx HTTPContext, clientID string)

type AuthCodeRecord

type AuthCodeRecord struct {
	CodeHash       string
	ClientID       string
	UserID         string
	RedirectURI    string
	Scope          []string
	CodeChallenge  string
	CodeMethod     string
	Nonce          string
	ExpiresAt      time.Time
	ConsumedAt     *time.Time
	CreatedAt      time.Time
	OriginalState  string
	SessionBinding string
}

type AuthorizeHandler

type AuthorizeHandler struct {
	// contains filtered or unexported fields
}

func NewAuthorizeHandler

func NewAuthorizeHandler(store Store, config Config, resolve UserResolver) *AuthorizeHandler

func (*AuthorizeHandler) Handle

func (h *AuthorizeHandler) Handle(ctx HTTPContext)

type Config

type Config struct {
	Issuer               string
	BasePath             string
	AccessTokenTTL       time.Duration
	IDTokenTTL           time.Duration
	RefreshTokenTTL      time.Duration
	AuthorizationCodeTTL time.Duration
	PrivateKeyPEM        string
	DefaultScopes        []string
}

func DefaultConfig

func DefaultConfig() Config

func ParseConfig

func ParseConfig(data []byte, current Config) (Config, error)

func (Config) Normalize

func (c Config) Normalize() Config

func (Config) ToPluginConfigFields

func (c Config) ToPluginConfigFields() []answerplugin.ConfigField

func (Config) WithFallbackIssuer

func (c Config) WithFallbackIssuer(siteURL string) Config

type ConsentRecord

type ConsentRecord struct {
	ClientID   string
	UserID     string
	Scope      []string
	GrantedAt  time.Time
	UpdatedAt  time.Time
	RevokedAt  *time.Time
	FirstParty bool
}

type GinContext

type GinContext struct {
	// contains filtered or unexported fields
}

func (*GinContext) BindJSON

func (g *GinContext) BindJSON(value any) error

func (*GinContext) Header

func (g *GinContext) Header(key string) string

func (*GinContext) JSON

func (g *GinContext) JSON(status int, value any)

func (*GinContext) PostForm

func (g *GinContext) PostForm(key string) string

func (*GinContext) Query

func (g *GinContext) Query(key string) string

func (*GinContext) Redirect

func (g *GinContext) Redirect(status int, location string)

func (*GinContext) Status

func (g *GinContext) Status(status int)

type HTTPContext

type HTTPContext interface {
	Query(string) string
	PostForm(string) string
	Header(string) string
	JSON(int, any)
	Redirect(int, string)
	Status(int)
	BindJSON(any) error
}

func WrapGinContext

func WrapGinContext(ctx *gin.Context) HTTPContext

type IDTokenClaims

type IDTokenClaims struct {
	Issuer    string
	Audience  string
	Subject   string
	Nonce     string
	IssuedAt  time.Time
	ExpiresAt time.Time
	AuthTime  time.Time
}

type InMemoryStore

type InMemoryStore struct {
	// contains filtered or unexported fields
}

func NewInMemoryStore

func NewInMemoryStore() *InMemoryStore

func (*InMemoryStore) ConsumeAuthCode

func (s *InMemoryStore) ConsumeAuthCode(rawCode string, now time.Time) (AuthCodeRecord, error)

func (*InMemoryStore) CreateClient

func (s *InMemoryStore) CreateClient(client OIDCClient, rawSecret string) (OIDCClient, string, error)

func (*InMemoryStore) DeleteClient

func (s *InMemoryStore) DeleteClient(id string) error

func (*InMemoryStore) GetClient

func (s *InMemoryStore) GetClient(id string) (OIDCClient, error)

func (*InMemoryStore) GetConsent

func (s *InMemoryStore) GetConsent(clientID, userID string) (ConsentRecord, error)

func (*InMemoryStore) GetRefreshToken

func (s *InMemoryStore) GetRefreshToken(rawToken string, now time.Time) (RefreshTokenRecord, error)

func (*InMemoryStore) ListClients

func (s *InMemoryStore) ListClients() []OIDCClient

func (*InMemoryStore) RevokeRefreshToken

func (s *InMemoryStore) RevokeRefreshToken(rawToken string, now time.Time) error

func (*InMemoryStore) RotateRefreshToken

func (s *InMemoryStore) RotateRefreshToken(oldRawToken string, newRecord RefreshTokenRecord, now time.Time) error

func (*InMemoryStore) SaveAuthCode

func (s *InMemoryStore) SaveAuthCode(record AuthCodeRecord) error

func (*InMemoryStore) SaveConsent

func (s *InMemoryStore) SaveConsent(record ConsentRecord) error

func (*InMemoryStore) SaveRefreshToken

func (s *InMemoryStore) SaveRefreshToken(record RefreshTokenRecord) error

func (*InMemoryStore) UpdateClient

func (s *InMemoryStore) UpdateClient(client OIDCClient) (OIDCClient, error)

func (*InMemoryStore) ValidateClientSecret

func (s *InMemoryStore) ValidateClientSecret(clientID, rawSecret string) (OIDCClient, error)

type JSONWebKey

type JSONWebKey struct {
	Kty string `json:"kty"`
	Use string `json:"use"`
	Kid string `json:"kid"`
	Alg string `json:"alg"`
	N   string `json:"n"`
	E   string `json:"e"`
}

type JSONWebKeySet

type JSONWebKeySet struct {
	Keys []JSONWebKey `json:"keys"`
}

type KVStore

type KVStore struct {
	// contains filtered or unexported fields
}

func NewKVStore

func NewKVStore(operator *answerplugin.KVOperator) *KVStore

func (*KVStore) ConsumeAuthCode

func (s *KVStore) ConsumeAuthCode(rawCode string, now time.Time) (AuthCodeRecord, error)

func (*KVStore) CreateClient

func (s *KVStore) CreateClient(client OIDCClient, rawSecret string) (OIDCClient, string, error)

func (*KVStore) DeleteClient

func (s *KVStore) DeleteClient(id string) error

func (*KVStore) GetClient

func (s *KVStore) GetClient(id string) (OIDCClient, error)

func (*KVStore) GetConsent

func (s *KVStore) GetConsent(clientID, userID string) (ConsentRecord, error)

func (*KVStore) GetRefreshToken

func (s *KVStore) GetRefreshToken(rawToken string, now time.Time) (RefreshTokenRecord, error)

func (*KVStore) ListClients

func (s *KVStore) ListClients() []OIDCClient

func (*KVStore) RevokeRefreshToken

func (s *KVStore) RevokeRefreshToken(rawToken string, now time.Time) error

func (*KVStore) RotateRefreshToken

func (s *KVStore) RotateRefreshToken(oldRawToken string, newRecord RefreshTokenRecord, now time.Time) error

func (*KVStore) SaveAuthCode

func (s *KVStore) SaveAuthCode(record AuthCodeRecord) error

func (*KVStore) SaveConsent

func (s *KVStore) SaveConsent(record ConsentRecord) error

func (*KVStore) SaveRefreshToken

func (s *KVStore) SaveRefreshToken(record RefreshTokenRecord) error

func (*KVStore) UpdateClient

func (s *KVStore) UpdateClient(client OIDCClient) (OIDCClient, error)

func (*KVStore) ValidateClientSecret

func (s *KVStore) ValidateClientSecret(clientID, rawSecret string) (OIDCClient, error)

type KeyService

type KeyService struct {
	// contains filtered or unexported fields
}

func NewKeyService

func NewKeyService(privateKeyPEM string) (*KeyService, error)

func (*KeyService) JWKS

func (k *KeyService) JWKS() JSONWebKeySet

func (*KeyService) KID

func (k *KeyService) KID() string

func (*KeyService) PrivateKey

func (k *KeyService) PrivateKey() *rsa.PrivateKey

func (*KeyService) PublicKey

func (k *KeyService) PublicKey() *rsa.PublicKey

type MetadataHandler

type MetadataHandler struct {
	// contains filtered or unexported fields
}

func NewMetadataHandler

func NewMetadataHandler(config Config, keyService *KeyService) *MetadataHandler

func (*MetadataHandler) HandleDiscovery

func (h *MetadataHandler) HandleDiscovery(ctx HTTPContext)

func (*MetadataHandler) HandleJWKS

func (h *MetadataHandler) HandleJWKS(ctx HTTPContext)

type OAuthError

type OAuthError struct {
	Error            string `json:"error"`
	ErrorDescription string `json:"error_description,omitempty"`
	TraceID          string `json:"trace_id,omitempty"`
}

type OIDCClient

type OIDCClient struct {
	ID                      string    `json:"id"`
	Name                    string    `json:"name"`
	SecretHash              string    `json:"-"`
	RedirectURIs            []string  `json:"redirect_uris"`
	Scopes                  []string  `json:"scopes"`
	GrantTypes              []string  `json:"grant_types"`
	TokenEndpointAuthMethod string    `json:"token_endpoint_auth_method"`
	FirstParty              bool      `json:"first_party"`
	Status                  string    `json:"status"`
	CreatedAt               time.Time `json:"created_at"`
	UpdatedAt               time.Time `json:"updated_at"`
}

type PluginInfo

type PluginInfo struct {
	Name        string `json:"name"`
	Slug        string `json:"slug"`
	Description string `json:"description"`
	Version     string `json:"version"`
}

type RefreshTokenRecord

type RefreshTokenRecord struct {
	TokenHash   string
	ClientID    string
	UserID      string
	Scope       []string
	ExpiresAt   time.Time
	RevokedAt   *time.Time
	CreatedAt   time.Time
	RotatedFrom string
}

type RevokeHandler

type RevokeHandler struct {
	// contains filtered or unexported fields
}

func NewRevokeHandler

func NewRevokeHandler(store Store) *RevokeHandler

func (*RevokeHandler) Handle

func (h *RevokeHandler) Handle(ctx HTTPContext)

type Store

type Store interface {
	CreateClient(client OIDCClient, rawSecret string) (OIDCClient, string, error)
	GetClient(id string) (OIDCClient, error)
	ListClients() []OIDCClient
	UpdateClient(client OIDCClient) (OIDCClient, error)
	DeleteClient(id string) error
	ValidateClientSecret(clientID, rawSecret string) (OIDCClient, error)

	SaveAuthCode(record AuthCodeRecord) error
	ConsumeAuthCode(rawCode string, now time.Time) (AuthCodeRecord, error)

	SaveRefreshToken(record RefreshTokenRecord) error
	GetRefreshToken(rawToken string, now time.Time) (RefreshTokenRecord, error)
	RevokeRefreshToken(rawToken string, now time.Time) error
	RotateRefreshToken(oldRawToken string, newRecord RefreshTokenRecord, now time.Time) error

	SaveConsent(record ConsentRecord) error
	GetConsent(clientID, userID string) (ConsentRecord, error)
}

type TokenClaims

type TokenClaims map[string]any

type TokenHandler

type TokenHandler struct {
	// contains filtered or unexported fields
}

func NewTokenHandler

func NewTokenHandler(store Store, tokenService *TokenService) *TokenHandler

func (*TokenHandler) Handle

func (h *TokenHandler) Handle(ctx HTTPContext)

type TokenResponse

type TokenResponse struct {
	AccessToken  string `json:"access_token"`
	TokenType    string `json:"token_type"`
	ExpiresIn    int64  `json:"expires_in"`
	RefreshToken string `json:"refresh_token,omitempty"`
	IDToken      string `json:"id_token,omitempty"`
	Scope        string `json:"scope,omitempty"`
}

type TokenService

type TokenService struct {
	// contains filtered or unexported fields
}

func NewTokenService

func NewTokenService(config Config, keyService *KeyService) *TokenService

func (*TokenService) IssueAccessToken

func (s *TokenService) IssueAccessToken(claims AccessTokenClaims) (string, int64, error)

func (*TokenService) IssueIDToken

func (s *TokenService) IssueIDToken(claims IDTokenClaims) (string, int64, error)

func (*TokenService) NewRefreshToken

func (s *TokenService) NewRefreshToken() (raw string, hash string, expiresAt time.Time, err error)

func (*TokenService) ParseAndValidateAccessToken

func (s *TokenService) ParseAndValidateAccessToken(raw string) (TokenClaims, error)

type UserInfoHandler

type UserInfoHandler struct {
	// contains filtered or unexported fields
}

func NewUserInfoHandler

func NewUserInfoHandler(tokenService *TokenService, resolveUser UserInfoResolver) *UserInfoHandler

func (*UserInfoHandler) Handle

func (h *UserInfoHandler) Handle(ctx HTTPContext)

type UserInfoResolver

type UserInfoResolver func(userID string) (UserProfile, error)

type UserProfile

type UserProfile struct {
	ID       string `json:"id"`
	Username string `json:"username"`
	Email    string `json:"email"`
	Name     string `json:"name"`
}

func ExtractAnswerUserFromContext

func ExtractAnswerUserFromContext(ctx *gin.Context) (UserProfile, bool)

func ExtractAnswerUserFromHTTPContext

func ExtractAnswerUserFromHTTPContext(ctx HTTPContext) (UserProfile, bool)

type UserResolver

type UserResolver func(ctx HTTPContext) (UserProfile, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL