Files
computer-playbook/roles/web-app-seaweedfs/files/playwright/test-biber-persona.js
kevinveenbirkenbachandClaude Opus 4.8 0039602379 feat(seaweedfs): extract browser frontend into a gated service
SeaweedFS is a server-side S3 backend for its consumers; only the
filer/master admin UIs are browser-facing. Split them into a `frontend`
service that stays off on onion nodes ('svc-net-tor' in group_names):

- frontend disabled: no nginx proxy container, no filer/master vhosts,
  no oauth2 SSO sidecar; the S3 API vhost is unaffected
- stale filer/master vhosts from earlier frontend-enabled deploys are
  removed so the site-wide CSP health probe stops hitting dead domains
- csp_skip_domains additionally skips canonicals a disabled service
  declares via services.<name>.domains (defense in depth)
- UI personas (admin/biber/guest/storage-buckets) gate on the
  FRONTEND_SERVICE_ENABLED flag; tor variants dropped (backend role)

Verified on the onion node: 4/4 UI specs skip, S3 API reachable, CSP
health check green, matrix S3 media consumer unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-12 10:56:13 +02:00

31 lines
1.3 KiB
JavaScript

const { test } = require("@playwright/test");
const { gotoOnion } = require("./personas");
exports.register = function (shared) {
const { env, keycloakLogin, isAuthChain, expect } = shared;
async function assertDenied(page, targetUrl) {
const response = await gotoOnion(page, targetUrl, { waitUntil: "domcontentloaded" });
if (isAuthChain(page.url())) {
await keycloakLogin(page, env.biberUsername, env.biberPassword);
}
await page.waitForLoadState("networkidle").catch(() => {});
const status = response ? response.status() : 0;
const body = (await page.locator("body").innerText().catch(() => "")) || "";
const onAppHost = page.url().includes(new URL(targetUrl).host) && !isAuthChain(page.url());
const forbidden = status === 403 || /forbidden|not a member|unauthorized|access denied/i.test(body);
expect(
forbidden || !onAppHost,
`biber (non-admin) must be denied at ${targetUrl}`
).toBe(true);
}
test("biber: denied on Filer and Master (admin-only)", async ({ page }) => {
test.skip(!env.frontendEnabled, "frontend disabled (headless backend node)");
test.skip(!env.ssoEnabled, "SSO disabled");
await assertDenied(page, env.filerUrl);
await page.context().clearCookies();
await assertDenied(page, env.masterUrl);
});
};