mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
Add the global TIMEOUT_FACTOR and a shared timeouts.js helper: resolveTimeout(base) scales by TIMEOUT_FACTOR and, over a .onion target, an extra multiplier, so Tor's per-request latency no longer trips hard-coded timeouts. Migrate every raw timeout in the specs (timeout:/timeout=/setTimeout/waitForTimeout) to resolveTimeout, stage the helper in all three staging paths, and add test_no_raw_timeouts to forbid raw numeric timeouts. Clearnet behaviour is unchanged (factor 1: resolveTimeout(N) === N). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
55 lines
2.3 KiB
JavaScript
55 lines
2.3 KiB
JavaScript
const { test, expect } = require("@playwright/test");
|
|
const { resolveTimeout } = require("./timeouts");
|
|
const { skipUnlessServiceEnabled } = require("./service-gating");
|
|
const { decodeDotenvQuotedValue, normalizeBaseUrl, performKeycloakLoginForm } = require("./personas");
|
|
|
|
const baseUrl = normalizeBaseUrl(process.env.YOURLS_BASE_URL || "");
|
|
const oidcIssuerUrl = normalizeBaseUrl(process.env.OIDC_ISSUER_URL || "");
|
|
const biberUsername = decodeDotenvQuotedValue(process.env.BIBER_USERNAME || "");
|
|
const biberPassword = decodeDotenvQuotedValue(process.env.BIBER_PASSWORD || "");
|
|
|
|
test.use({ ignoreHTTPSErrors: true });
|
|
|
|
// biber is a regular authenticated Keycloak user but is NOT in the
|
|
// administrator group. YOURLS uses oauth2-proxy in ACL blacklist mode for
|
|
// /admin/, so oauth2-proxy must return HTTP 403 after biber completes the
|
|
// Keycloak login flow — the trusted-header bridge never runs for him.
|
|
test("yourls: biber is denied access to /admin/ after sso login", async ({ browser }) => {
|
|
skipUnlessServiceEnabled("sso");
|
|
expect(baseUrl, "YOURLS_BASE_URL must be set").toBeTruthy();
|
|
expect(oidcIssuerUrl, "OIDC_ISSUER_URL must be set").toBeTruthy();
|
|
expect(biberUsername, "BIBER_USERNAME must be set").toBeTruthy();
|
|
expect(biberPassword, "BIBER_PASSWORD must be set").toBeTruthy();
|
|
|
|
const base = baseUrl.replace(/\/$/, "");
|
|
const expectedOidcAuthUrl = `${oidcIssuerUrl}/protocol/openid-connect/auth`;
|
|
const biberContext = await browser.newContext({ ignoreHTTPSErrors: true });
|
|
|
|
try {
|
|
const biberPage = await biberContext.newPage();
|
|
|
|
const callbackResponsePromise = biberPage.waitForResponse(
|
|
(res) => res.url().includes("/oauth2/callback"),
|
|
{ timeout: resolveTimeout(60_000) },
|
|
);
|
|
|
|
await biberPage.goto(`${base}/admin/`);
|
|
await expect
|
|
.poll(() => biberPage.url(), {
|
|
timeout: resolveTimeout(30_000),
|
|
message: `Expected redirect to Keycloak OIDC auth: ${expectedOidcAuthUrl}`,
|
|
})
|
|
.toContain(expectedOidcAuthUrl);
|
|
|
|
await performKeycloakLoginForm(biberPage, biberUsername, biberPassword);
|
|
|
|
const callbackResponse = await callbackResponsePromise;
|
|
expect(
|
|
callbackResponse.status(),
|
|
`Expected oauth2-proxy to deny biber with 403 at /oauth2/callback, got ${callbackResponse.status()}`,
|
|
).toBe(403);
|
|
} finally {
|
|
await biberContext.close().catch(() => {});
|
|
}
|
|
});
|