package api_test import ( "encoding/json" "net/http" "os" "strings" "testing" "atlas9.dev/c/core/assert" "atlas9.dev/c/demo/api" ) // publicPaths is the test's own copy of the public-route allowlist. It must // agree with the routes registered on the public mux in boot/server.go; // registering an endpoint public without listing it here fails the sweep // below, which is the point. var publicPaths = map[string]bool{ api.Path_Health: true, api.Path_Account_Register: true, api.Path_Account_Verify: true, api.Path_Account_RequestPasswordReset: true, api.Path_Account_ResendVerification: true, api.Path_Account_ResetPassword: true, api.Path_Identity_Login: true, api.Path_Identity_Logout: true, api.Path_Sso_Check: true, api.Path_Sso_Login: true, api.Path_Sso_GetCallback: true, api.Path_Sso_PostCallback: true, } // Every endpoint requires an authenticated principal unless it is on the // public allowlist. Sweeps all POST routes from the generated OpenAPI spec // anonymously and expects 401, so a handler that forgets its guard check // still can't run anonymously by accident. func TestAnonymous_EndpointsRequireAuth(t *testing.T) { s := startServer(t) s.logout(t) data, err := os.ReadFile("generated/openapi.json") assert.Ok(t, err) var spec struct { Paths map[string]map[string]json.RawMessage } assert.Ok(t, json.Unmarshal(data, &spec)) if len(spec.Paths) < 50 { t.Fatalf("suspiciously few paths in openapi.json: %d", len(spec.Paths)) } for path, ops := range spec.Paths { if _, ok := ops["post"]; !ok { continue // GETs are pages/redirects with their own handling } if strings.Contains(path, "{") { continue // parameterized SSO callbacks; public anyway } if publicPaths["POST "+path] { continue } res := s.call(t, path, struct{}{}, nil) if res.StatusCode != http.StatusUnauthorized { t.Errorf("POST %s: anonymous request got %d, want 401", path, res.StatusCode) } } }