Help us shape the future of Go! Take the 2026 Go Developer Survey

fakeprovider

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Oct 30, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package fakeprovider holds in-process fakes of the identity providers the library talks to (an OIDC issuer with the Keycloak admin API, and GitHub) for unit and end-to-end tests. It is test support: excluded from coverage and never imported by library code. Its servers are safe for concurrent use.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type GitHubEndpoint

type GitHubEndpoint string

GitHubEndpoint names an endpoint of the fake GitHub for FailWith and Calls.

const (
	GitHubEndpointAuthorize GitHubEndpoint = "authorize" // GET /login/oauth/authorize
	GitHubEndpointToken     GitHubEndpoint = "token"     // POST /login/oauth/access_token
	GitHubEndpointUser      GitHubEndpoint = "user"      // GET /user
	GitHubEndpointTeams     GitHubEndpoint = "teams"     // GET /user/teams
	GitHubEndpointRevoke    GitHubEndpoint = "revoke"    // DELETE /applications/{client_id}/token
)

The endpoints of the fake GitHub.

type GitHubOptions

type GitHubOptions struct {
	ClientID     string       // default "github-client-id"
	ClientSecret string       // default "github-client-secret"
	User         GitHubUser   // default {ID: 1, Login: "octocat", Name: "The Octocat", Email: "octocat@example.com"}
	Teams        []GitHubTeam // the user's teams; SetTeams replaces them
}

GitHubOptions configure StartGitHub. The zero value is usable.

type GitHubServer

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

GitHubServer is a fake GitHub on http://127.0.0.1:<port>: the OAuth endpoints (authorize auto-approves, the token endpoint checks the client credentials, PKCE S256 and that redirect_uri is the one the code was issued for) and the REST API parts the github provider uses. It is safe for concurrent use.

func StartGitHub

func StartGitHub(tb testing.TB, options GitHubOptions) *GitHubServer

StartGitHub starts a fake GitHub and closes it when the test ends.

func (*GitHubServer) APIURL

func (s *GitHubServer) APIURL() string

APIURL returns the github.Options.APIURL to use: URL() (the API sits at the root, as on api.github.com).

func (*GitHubServer) AuthorizeURL

func (s *GitHubServer) AuthorizeURL() string

AuthorizeURL returns the github.Options.AuthorizeURL to use: URL() + "/login/oauth/authorize".

func (*GitHubServer) Calls

func (s *GitHubServer) Calls(endpoint GitHubEndpoint) int

Calls returns how many requests endpoint received, failed ones included.

func (*GitHubServer) ClientID

func (s *GitHubServer) ClientID() string

ClientID returns the OAuth app's client ID (GitHubOptions.ClientID or its default).

func (*GitHubServer) ClientSecret

func (s *GitHubServer) ClientSecret() string

ClientSecret returns the OAuth app's client secret (GitHubOptions.ClientSecret or its default).

func (*GitHubServer) FailWith

func (s *GitHubServer) FailWith(endpoint GitHubEndpoint, status int)

FailWith makes endpoint answer status with a GitHub-style JSON error until called again with status 0. The authorize endpoint instead redirects back with error=access_denied (the user declined).

func (*GitHubServer) RevokedTokens

func (s *GitHubServer) RevokedTokens() []string

RevokedTokens returns the access tokens revoked through DELETE /applications/{client_id}/token, in order.

func (*GitHubServer) SetTeams

func (s *GitHubServer) SetTeams(teams []GitHubTeam)

SetTeams replaces the user's teams, e.g. to remove the user from an allowed team.

func (*GitHubServer) TokenURL

func (s *GitHubServer) TokenURL() string

TokenURL returns the github.Options.TokenURL to use: URL() + "/login/oauth/access_token".

func (*GitHubServer) URL

func (s *GitHubServer) URL() string

URL returns the base URL, http://127.0.0.1:<port>.

type GitHubTeam

type GitHubTeam struct {
	Organization string
	Slug         string
}

GitHubTeam is one team of the user as GET /user/teams returns it: organization login and team slug, in the case GitHub reports them.

type GitHubUser

type GitHubUser struct {
	ID        int64
	Login     string
	Name      string
	Email     string
	AvatarURL string
}

GitHubUser is the user the fake GitHub authenticates (GET /user).

type OIDCHandler

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

OIDCHandler is the fake issuer as an http.Handler. It serves, below the IssuerURL path: /.well-known/openid-configuration, /jwks, /authorize (auto-approves User: redirects to redirect_uri with code and state; a request without state, nonce or S256 code challenge gets error=invalid_request, an unknown client_id or unregistered redirect_uri a 400 page), /token (client secret, single-use code, redirect_uri and PKCE S256 checked; ID token with the authorize nonce and a JWT access token, RS256) and /end_session (records id_token_hint, redirects to a registered post_logout_redirect_uri with state, else a plain page). It is safe for concurrent use.

func NewOIDCHandler

func NewOIDCHandler(options *OIDCOptions) (*OIDCHandler, error)

NewOIDCHandler returns a fake issuer with a fresh RSA signing key. It keeps a copy of options: changing them afterwards has no effect.

func (*OIDCHandler) IDTokenHints

func (h *OIDCHandler) IDTokenHints() []string

IDTokenHints returns the id_token_hint values /end_session received, oldest first.

func (*OIDCHandler) IssuerURL

func (h *OIDCHandler) IssuerURL() string

IssuerURL returns the issuer as configured: the iss claim and the discovery issuer.

func (*OIDCHandler) KeycloakClientLookups

func (h *OIDCHandler) KeycloakClientLookups() int

KeycloakClientLookups returns how many client lookups (GET /clients?clientId=) the Admin API answered.

func (*OIDCHandler) KeycloakTokenRequests

func (h *OIDCHandler) KeycloakTokenRequests() int

KeycloakTokenRequests returns how many requests reached the Keycloak token endpoint.

func (*OIDCHandler) RevokeKeycloakTokens

func (h *OIDCHandler) RevokeKeycloakTokens()

RevokeKeycloakTokens invalidates every admin token issued so far, as Keycloak does before their expiry (key rotation, a logout of the service account): the Admin API answers 401 to them.

func (*OIDCHandler) ServeHTTP

func (h *OIDCHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request)

ServeHTTP serves the issuer's endpoints.

type OIDCOptions

type OIDCOptions struct {
	IssuerURL              string   // required by NewOIDCHandler, set by StartOIDC: the iss claim; endpoints are served below its path
	ClientID               string   // required
	ClientSecret           string   // required; accepted by HTTP Basic and in the form
	RedirectURIs           []string // registered redirect URIs; empty accepts any
	PostLogoutRedirectURIs []string // registered post-logout redirect URIs; empty accepts any
	User                   OIDCUser

	OmitEndSessionEndpoint bool // discovery without end_session_endpoint
	OmitIDToken            bool // token response without id_token
	OpaqueAccessToken      bool // a random access token instead of a JWT, as Google issues
	WrongNonce             bool // the ID token carries another nonce than the authorize request
	BadSignature           bool // ID and access token signatures do not verify
	ExpiredIDToken         bool // the ID token expired a minute ago

	TokenAnswer http.Handler // when set, answers every /token request in place of the fake: an IdP's error or broken answers
	JWKSAnswer  http.Handler // when set, answers every /jwks request in place of the fake: a key set outage or a broken key set

	KeycloakRealm               string // when set, also serves the Keycloak token endpoint and Admin API of this realm (keycloak.go)
	KeycloakAuthenticationRealm string // realm whose token endpoint issues admin tokens; default KeycloakRealm
	KeycloakClientID            string // service account client for the client credentials grant
	KeycloakClientSecret        string
	KeycloakUsername            string // admin user for the password grant
	KeycloakPassword            string
}

OIDCOptions configures the fake issuer. Faults (the bool fields after User) make every token response broken in one specific way; TokenAnswer and JWKSAnswer replace the token endpoint and the key set altogether.

type OIDCServer

type OIDCServer struct {
	*OIDCHandler
	// contains filtered or unexported fields
}

OIDCServer is a fake issuer on an httptest server.

func StartOIDC

func StartOIDC(tb testing.TB, options OIDCOptions) *OIDCServer

StartOIDC serves a fake issuer on a loopback httptest server until the test ends. It sets IssuerURL to the server URL, or to <server URL>/realms/<KeycloakRealm> when a Keycloak realm is configured (the Keycloak layout). Construction errors fail the test.

func (*OIDCServer) URL

func (s *OIDCServer) URL() string

URL returns the server's base URL: the Keycloak URL when a Keycloak realm is configured.

type OIDCUser

type OIDCUser struct {
	Subject           string              // ID token sub and Keycloak user ID; default "fake-user"
	PreferredUsername string              // preferred_username claim
	Name              string              // name claim
	Email             string              // email claim
	EmailVerified     bool                // email_verified claim
	Picture           string              // picture claim
	SessionID         string              // sid claim of the ID token; omitted when empty
	RealmRoles        []string            // access token realm_access.roles; Keycloak composite realm roles
	ClientRoles       []string            // access token resource_access.<ClientID>.roles; Keycloak composite roles of client ClientID
	Groups            []string            // access token groups; Keycloak group paths
	Attributes        map[string][]string // Keycloak user attributes
}

OIDCUser is the one user the fake issuer logs in. With a Keycloak realm the Admin API answers with the same roles and groups the access token carries.

Jump to

Keyboard shortcuts

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