mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 10:59:59 +00:00
Tor: use the shared tor block (bond 0.5, enabled when svc-net-tor is in the node's groups, tor pinned on in both variants) so a node serves one network, onion on a Tor node and clearnet otherwise. SPOT and sizing: WAZUH_INDEXER_URL replaces four hand-built copies of the indexer URL, and the indexer heap is half of mem_limit instead of a hardcoded 1g (unchanged for the current 2g limit). Fixes: bcrypt_hash rejects secrets over 72 bytes; the Keycloak group-removal helper uses the same resolver as the add helper and checks every response (the realm is no longer URL-encoded, matching the add helper), and a failed cleanup fails an otherwise passing test; the swarm certs generator removes a stale container before each attempt; vm.max_map_count is set before the early handler flush; securityadmin failed_when now needs rc 0 and the success marker. The regenerated role README also picks up generator drift (mailu to stalwart).
127 lines
4.4 KiB
JavaScript
127 lines
4.4 KiB
JavaScript
const { expect } = require("@playwright/test");
|
|
const { decodeDotenvQuotedValue, normalizeBaseUrl, gotoOnion } = require("./personas");
|
|
const { resolveTimeout } = require("./timeouts");
|
|
const keycloakAdmin = require("./personas/utils/keycloak");
|
|
|
|
const env = {
|
|
appBaseUrl: normalizeBaseUrl(process.env.APP_BASE_URL || ""),
|
|
keycloakBaseUrl: normalizeBaseUrl(process.env.KEYCLOAK_BASE_URL || ""),
|
|
realmName: decodeDotenvQuotedValue(process.env.KEYCLOAK_REALM_NAME),
|
|
superAdminUsername: decodeDotenvQuotedValue(process.env.SUPER_ADMIN_USERNAME),
|
|
superAdminPassword: decodeDotenvQuotedValue(process.env.SUPER_ADMIN_PASSWORD),
|
|
adminUsername: decodeDotenvQuotedValue(process.env.ADMIN_USERNAME),
|
|
adminPassword: decodeDotenvQuotedValue(process.env.ADMIN_PASSWORD),
|
|
biberUsername: decodeDotenvQuotedValue(process.env.BIBER_USERNAME),
|
|
biberPassword: decodeDotenvQuotedValue(process.env.BIBER_PASSWORD),
|
|
keycloakAdminRealm: decodeDotenvQuotedValue(process.env.KEYCLOAK_ADMIN_REALM),
|
|
keycloakAdminCliClientId: decodeDotenvQuotedValue(process.env.KEYCLOAK_ADMIN_CLI_CLIENT_ID),
|
|
rbacGroupPathPrefix: decodeDotenvQuotedValue(process.env.RBAC_GROUP_PATH_PREFIX),
|
|
};
|
|
|
|
function attachDiagnostics(page) {
|
|
const consoleErrors = [];
|
|
const pageErrors = [];
|
|
const cspRelated = [];
|
|
page.on("console", (message) => {
|
|
if (message.type() === "error") consoleErrors.push(message.text());
|
|
if (/content security policy|csp/i.test(message.text())) {
|
|
cspRelated.push({ source: "console", text: message.text() });
|
|
}
|
|
});
|
|
page.on("pageerror", (error) => {
|
|
const text = String(error);
|
|
pageErrors.push(text);
|
|
if (/content security policy|csp/i.test(text)) {
|
|
cspRelated.push({ source: "pageerror", text });
|
|
}
|
|
});
|
|
return { consoleErrors, pageErrors, cspRelated };
|
|
}
|
|
|
|
async function wazuhLoginViaOidc(page, appBaseUrl, username, password) {
|
|
await gotoOnion(page, `${appBaseUrl}/`, { waitUntil: "domcontentloaded" });
|
|
|
|
if (!page.url().includes("openid-connect/auth")) {
|
|
const strictLink = page
|
|
.getByRole("link", { name: /^\s*(log\s*in|sign\s*in|login|sso)\s*$/i })
|
|
.or(page.getByRole("button", { name: /^\s*(log\s*in|sign\s*in|login|sso)\s*$/i }))
|
|
.first();
|
|
const looseLink = page
|
|
.getByRole("link", { name: /log\s*in|sign\s*in|sso/i })
|
|
.or(page.getByRole("button", { name: /log\s*in|sign\s*in|sso/i }))
|
|
.first();
|
|
await keycloakAdmin.clickOidcLoginLink(page, strictLink, looseLink);
|
|
}
|
|
|
|
if (page.url().includes("openid-connect/auth")) {
|
|
await keycloakAdmin.performKeycloakLoginForm(page, username, password);
|
|
}
|
|
|
|
await expect
|
|
.poll(() => page.url(), {
|
|
timeout: resolveTimeout(60_000),
|
|
message: `Expected redirect back to ${appBaseUrl} after OIDC login`,
|
|
})
|
|
.toContain(new URL(appBaseUrl).host);
|
|
await expect
|
|
.poll(async () => (await page.context().cookies()).length, {
|
|
timeout: resolveTimeout(30_000),
|
|
message:
|
|
`Expected a real session cookie after OIDC login to ${appBaseUrl} ` +
|
|
`(got 0 - the URL matched but no session was actually established)`,
|
|
})
|
|
.toBeGreaterThan(0);
|
|
}
|
|
|
|
async function withBiberInGroup(browser, groupPath, fn) {
|
|
const adminOpts = { adminRealm: env.keycloakAdminRealm, adminClientId: env.keycloakAdminCliClientId };
|
|
const adminCtx = await browser.newContext({ ignoreHTTPSErrors: true });
|
|
let biberAdded = false;
|
|
let bodyFailed = false;
|
|
try {
|
|
biberAdded = await keycloakAdmin.keycloakAdminAddUserToGroup(
|
|
adminCtx.request,
|
|
env.keycloakBaseUrl,
|
|
env.realmName,
|
|
groupPath,
|
|
env.biberUsername,
|
|
env.superAdminUsername,
|
|
env.superAdminPassword,
|
|
adminOpts,
|
|
);
|
|
return await fn();
|
|
} catch (err) {
|
|
bodyFailed = true;
|
|
throw err;
|
|
} finally {
|
|
try {
|
|
if (biberAdded) {
|
|
await keycloakAdmin
|
|
.keycloakRemoveUserFromGroupViaRest(
|
|
adminCtx.request,
|
|
env.keycloakBaseUrl,
|
|
env.realmName,
|
|
env.superAdminUsername,
|
|
env.superAdminPassword,
|
|
groupPath,
|
|
env.biberUsername,
|
|
adminOpts,
|
|
)
|
|
.catch((err) => {
|
|
if (!bodyFailed) throw err;
|
|
console.warn(`Cleanup removal of biber from ${groupPath} failed: ${err}`);
|
|
});
|
|
}
|
|
} finally {
|
|
await adminCtx.close().catch(() => {});
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
env,
|
|
attachDiagnostics,
|
|
wazuhLoginViaOidc,
|
|
withBiberInGroup,
|
|
};
|