package auth import ( "context" "encoding/base64" "net/http" "strconv" "testing" "github.com/urpi/go-bananas/internal/config" ) // base64RawURL encodes without padding, matching how cookies are written. func base64RawURL(s string) string { return base64.RawURLEncoding.EncodeToString([]byte(s)) } // base64RawURLBytes encodes raw bytes without padding. func base64RawURLBytes(b []byte) string { return base64.RawURLEncoding.EncodeToString(b) } // itoa renders an int64 for embedding in a JSON test fixture. func itoa(v int64) string { return strconv.FormatInt(v, 10) } // stubResolver is a Resolver that authenticates nobody. It exists so that tests // can construct an Authenticator in OIDC mode without a live provider, which // also documents that New refuses to start in OIDC mode without one. type stubResolver struct{} func (stubResolver) Begin(context.Context, *http.Request, http.ResponseWriter, string) error { return nil } func (stubResolver) Complete(context.Context, *http.Request) (*Login, error) { return nil, ErrNoSession } func (stubResolver) End(context.Context, string) string { return "" } func (stubResolver) Enabled() bool { return true } func (stubResolver) ClearState(http.ResponseWriter) {} func (stubResolver) LogoutURL(string) string { return "https://idp.example/logout" } // newTestAuthenticator builds an Authenticator for a configuration. // // The key store is optional and is passed straight through: with machine // credentials removed it only carries the user table, which most of these tests do // not exercise. func newTestAuthenticator(t *testing.T, cfg config.Config, keys KeyStore) *Authenticator { t.Helper() if cfg.SessionSecret == "" { cfg.SessionSecret = testSecret } // A stub resolver rather than nil: New refuses to construct in OIDC mode // without one, and the point of some of these tests is exactly that an // unauthenticated request is rejected even when a provider is wired up. a, err := New(cfg, stubResolver{}, keys) if err != nil { t.Fatalf("New: %v", err) } return a }