Documentation
¶
Overview ¶
Package authtest runs AuthKit in a host's Go tests: a real Client on a scratch PostgreSQL schema, an Outbox that captures every email and SMS, an identity provider to sign in with (IdP), and helpers for the usual setup (a verified user, a signed-in session, a role, an authenticator app, a device key, a replica, a stale session).
auth, outbox := authtest.New(t, authtest.WithConfig(func(c *authkit.Config) {
c.Roles = myapp.Roles()
}))
alice := authtest.NewUser(t, auth)
authtest.GrantRole(t, auth, iam.RootGroup(), iam.UserSubject(alice.ID), myapp.Admin)
tokens := authtest.SignIn(t, auth, alice)
// call the host's handlers with "Bearer "+tokens.AccessToken, or drive
// auth.Handler() and read codes and links from outbox.
New needs AUTHKIT_TEST_DATABASE_URL, a database where the test may create schemas. Without it the test is skipped, or fails when AUTHKIT_TEST_REQUIRE_DB=1. AUTHKIT_TEST_KEEP_DB=1 keeps each schema.
The package is covered by AuthKit's compatibility contract like the rest of the module (docs/stability.md).
Index ¶
- Constants
- func GrantRole(t testing.TB, auth *authkit.Client, group iam.GroupRef, subject iam.Subject, ...)
- func Replica(t testing.TB, auth *authkit.Client, opts ...Option) *authkit.Client
- func RevokeRole(t testing.TB, auth *authkit.Client, group iam.GroupRef, subject iam.Subject, ...)
- func SignIn(t testing.TB, auth *authkit.Client, u User) iam.TokenSet
- func StaleSession(t testing.TB, auth *authkit.Client, accessToken string) string
- func TOTPCode(t testing.TB, secret string, at time.Time) string
- type DeviceKey
- type IdP
- type Message
- type Option
- type Outbox
- type TOTP
- type User
Constants ¶
const ( Issuer = "https://example.com" Audience = "authtest" )
Issuer and Audience are the token issuer and audience New configures.
const Password = "Authtest-password-1"
Password is the password NewUser gives every account.
Variables ¶
This section is empty.
Functions ¶
func GrantRole ¶ added in v0.147.0
func GrantRole(t testing.TB, auth *authkit.Client, group iam.GroupRef, subject iam.Subject, role iam.Role)
GrantRole gives subject role in group with system authority. A role that requires MFA needs the account's second factor first (EnrollTOTP).
func Replica ¶ added in v0.147.0
Replica builds another Client on auth's database and schema, as another replica of the deployment runs: the Config and Deps auth was built with (its Outbox included, when New built it), then opts. auth may be any Client authkit.New built, a host's own included. A different Token.Issuer makes a sibling deployment sharing the account store; different HTTPConfig serves the same accounts another way. HTTP is copied, so opts may set its fields; replace, never mutate, the maps and slices opts change: the replica shares auth's.
func RevokeRole ¶ added in v0.147.0
func RevokeRole(t testing.TB, auth *authkit.Client, group iam.GroupRef, subject iam.Subject, role iam.Role)
RevokeRole takes role in group from subject with system authority.
func SignIn ¶ added in v0.147.0
SignIn signs u in with its password through auth's HTTP surface and follows the AuthResult to a session: a second factor is answered with u.TOTP (or the account's remembered app, TOTPOf); an enrollment the deployment requires adds an authenticator app with the enrollment token, which SignIn remembers for the account's later sign-ins. It returns the session's tokens.
func StaleSession ¶ added in v0.147.0
StaleSession moves the sign-in of the session behind accessToken a day into the past, as if its user signed in long ago, and returns a new access token for that session: routes that need a recent sign-in then ask it for a step-up. auth may be any Client authkit.New built.
Types ¶
type DeviceKey ¶ added in v0.147.0
type DeviceKey struct {
ID string
Key ed25519.PrivateKey
// AccessToken is the enrollment's sign-in.
AccessToken string
}
DeviceKey is a device key enrolled on an account (see package devicekey).
func EnrollDeviceKey ¶ added in v0.147.0
EnrollDeviceKey enrolls a new Ed25519 device key on u with the devicekey client, reading the emailed code from outbox and answering a second factor with u.TOTP. The Client needs Config.DeviceKeys.Enabled.
type IdP ¶ added in v1.1.0
type IdP struct {
// contains filtered or unexported fields
}
IdP is an OpenID Provider on a local TLS server, for tests of signing in with an identity provider: discovery, JWKS, and the token and userinfo endpoints. A sign-in start redirects the browser to it; SignIn answers the way it would.
func (*IdP) Provider ¶ added in v1.1.0
Provider is an OpenID Connect provider named name for this IdP, trusted to verify email, for Deps.Providers. opts come after the defaults.
func (*IdP) SignIn ¶ added in v1.1.0
SignIn is the query of the IdP's redirect back to AuthKit's callback once user signs in at authURL, the IdP URL a sign-in start redirected to: its state and a code. AuthKit redeems the code for an ID token naming user's Subject, Email (verified when EmailVerified), PreferredUsername and DisplayName.
type Message ¶ added in v0.147.0
type Message = testoutbox.Message
Message is one captured email or SMS: Channel ("email" or "sms"), Kind, To, Language and what it carries (Code, Link and the Link's Token, the verification Purpose, a ContactChange or DeviceKey notice).
type Option ¶ added in v0.147.0
type Option func(*setup)
Option adjusts what New builds.
func WithConfig ¶ added in v0.147.0
WithConfig edits the Config New passes to authkit.New, after its defaults.
type Outbox ¶ added in v0.147.0
type Outbox = testoutbox.Outbox
Outbox captures every email and SMS AuthKit sends, in order, so a test can complete sign-up, verification, reset and sign-in flows. New wires one; for a Client built another way, pass Email() and SMS() as Deps.Email and Deps.SMS. Its methods:
- Last(t, kind, to) Message: the newest message of kind to that address or number ("" = anyone); the test fails when there is none.
- Messages(kind, to) []Message: all of them, oldest first ("" = any).
- Email() authkit.EmailSender, SMS() authkit.SMSSender: the senders.
- SetEmailHealth(err), SetSMSHealth(err): what the senders' CheckHealth returns (nil, the default, is healthy), so a test can take a channel down and bring it back.
For example, out.Last(t, iam.MessageVerification, email).Code.
func New ¶ added in v0.147.0
New migrates AuthKit into a fresh schema, builds a Client on it, and returns the Client with the Outbox wired as its email and SMS senders. The defaults differ from a zero Config only where a test needs them to:
- Token: Issuer and Audience.
- TwoFactor.TOTPSecretKey: random, so authenticator apps can enroll.
- HTTP: served (DirectPeerIP), with every rate limit lifted (RateLimits).
- Deps.KeySource: an RSA key generated once per test binary.
- Schema and River.Schema: the scratch schema, unless set.
The Client is not started: call Start when a test needs River's work, such as Deps.OnEvent or the deletion hooks. Cleanup closes the Client and drops the scratch schema.
type TOTP ¶ added in v0.147.0
type TOTP struct {
Secret string
// contains filtered or unexported fields
}
TOTP is an authenticator app enrolled on an account.
func EnrollTOTP ¶ added in v0.147.0
EnrollTOTP signs u in and adds an authenticator app through auth's HTTP surface, as a user would. SignIn uses it from now on; keeping it as u.TOTP works too.
type User ¶ added in v0.147.0
type User struct {
iam.User
Email string
Password string
// TOTP is the authenticator app SignIn answers a second-factor challenge
// with. Unset, SignIn uses the app EnrollTOTP or an earlier SignIn enrolled
// on the account (TOTPOf).
TOTP *TOTP
}
User is an account and what SignIn needs to sign it in. Email is the account's address as text ("" for none).