authtest

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package authtest installs an authenticated request context without a server, a database, or a ceremony.

It exists because most application tests treat authentication as a precondition rather than as the subject: they need to say which account a request belongs to and then test what the handler does. Running a WebAuthn ceremony to reach that point proves nothing about the handler and costs a port, a database, and an authenticator.

A test may call a bare handler or ServeHTTP against the real middleware chain; the installed value survives both, because the session middleware leaves the context untouched on its unauthenticated path. The same test reads identically under every auth.mode, since this is exactly the value the resolve middleware would have installed.

Why this is not a bypass

The carrier is a context value, which no remote client can set: net/http creates a fresh context for an incoming request, so nothing that arrives over a connection can reach it. A header would be the opposite, which is why plugin/auth reads none.

The package must never appear in an application binary. It cannot forge an identity anywhere it is absent, and pw build rejects it in a dependency graph.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Anonymous

func Anonymous(ctx context.Context) context.Context

Anonymous returns ctx in the explicitly unauthenticated state, so a test can prove the deny path rather than relying on a value simply being absent.

func Authenticate

func Authenticate(client *http.Client, serverURL string, identity Identity) error

Authenticate installs a real session for the identity into the jar of an existing client, which a test uses when it built the client itself.

func NewAnonymousRequest

func NewAnonymousRequest(method, target string, body io.Reader) *http.Request

NewAnonymousRequest returns an httptest request in the explicitly unauthenticated state.

func NewClient

func NewClient(serverURL string, identity Identity) (*http.Client, error)

NewClient returns an HTTP client whose jar holds a real login session for the identity, against a server started by testutil.TestRun.

This is the rung above NewRequest: the request travels over a real connection, carries a real session cookie, and passes through every framework middleware including the guard. The session is created by the same session manager a completed login uses, so its rotation, lifetime, and cookie attributes are the production ones.

No ceremony runs. A test that means to prove that authentication itself works must drive the real endpoints with contrib/passkey/passkeytest or a development identity provider instead; this seam assumes authentication works and tests what happens after it.

func NewContext

func NewContext(ctx context.Context, identity Identity) context.Context

NewContext returns ctx carrying an authenticated request, exactly as the session middleware would have installed it. auth.User, auth.Session, pw.Authenticated, and pw.RequestAuthentication all read it.

func NewRequest

func NewRequest(method, target string, body io.Reader, identity Identity) *http.Request

NewRequest returns an httptest request that already carries the identity. It is the usual entry point: build the request, hand it to a handler, assert on what the handler did.

func SessionCookies

func SessionCookies(identity Identity) ([]*http.Cookie, error)

SessionCookies creates a real session and returns the cookies a browser would have received, for a test that manages its own jar or drives a handler directly.

Types

type Identity

type Identity struct {
	// AccountID is the stable application identifier. It also becomes the
	// authentication subject, matching what plugin/auth records.
	AccountID   string
	DisplayName string
	Email       string
	// Issuer, Subject, KeyClaim, and Key describe an external identity. They
	// are what an OIDC login records and are empty for a passkey session.
	Issuer   string
	Subject  string
	KeyClaim string
	Key      string
	// Method defaults to auth.MethodOIDC. Use auth.MethodPasskey to model an
	// account that logged in with a credential.
	Method string
	// AuthenticatedAt defaults to now, so a handler gated on recent
	// authentication passes unless the test wants it not to.
	AuthenticatedAt time.Time
	// ExpiresAt defaults to an hour out.
	ExpiresAt time.Time
	// Scope carries optional tenant, role, or permission values for an
	// application authorization check.
	Scope []string
}

Identity is what a test says the request is. Only AccountID is required.

Jump to

Keyboard shortcuts

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