feat: verify Google federation through the AP4 edge
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { chromium } from "playwright-core";
|
||||
|
||||
const password = process.env.MOCK_GOOGLE_USER_PASSWORD;
|
||||
const adminUsername = process.env.KC_BOOTSTRAP_ADMIN_USERNAME;
|
||||
const adminPassword = process.env.KC_BOOTSTRAP_ADMIN_PASSWORD;
|
||||
assert.ok(password && adminUsername && adminPassword);
|
||||
|
||||
async function verifyBrokeredEmail() {
|
||||
const tokenResponse = await fetch(
|
||||
"http://localhost:8080/realms/master/protocol/openid-connect/token",
|
||||
{
|
||||
method: "POST",
|
||||
body: new URLSearchParams({
|
||||
client_id: "admin-cli",
|
||||
grant_type: "password",
|
||||
username: adminUsername,
|
||||
password: adminPassword,
|
||||
}),
|
||||
},
|
||||
);
|
||||
assert.equal(tokenResponse.status, 200);
|
||||
const token = (await tokenResponse.json()).access_token;
|
||||
const headers = { Authorization: `Bearer ${token}` };
|
||||
const usersResponse = await fetch(
|
||||
"http://localhost:8080/admin/realms/keycloak-patterns/users"
|
||||
+ "?email=broker-new-user%40example.test&exact=true",
|
||||
{ headers },
|
||||
);
|
||||
assert.equal(usersResponse.status, 200);
|
||||
const users = await usersResponse.json();
|
||||
assert.equal(users.length, 1);
|
||||
const userResponse = await fetch(
|
||||
`http://localhost:8080/admin/realms/keycloak-patterns/users/${users[0].id}`,
|
||||
{ headers },
|
||||
);
|
||||
const user = await userResponse.json();
|
||||
assert.equal(user.emailVerified, false);
|
||||
const updateResponse = await fetch(
|
||||
`http://localhost:8080/admin/realms/keycloak-patterns/users/${user.id}`,
|
||||
{
|
||||
method: "PUT",
|
||||
headers: { ...headers, "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ ...user, emailVerified: true }),
|
||||
},
|
||||
);
|
||||
assert.equal(updateResponse.status, 204);
|
||||
}
|
||||
|
||||
const browser = await chromium.launch({
|
||||
executablePath: process.env.CHROME_BIN ?? "/usr/bin/google-chrome",
|
||||
headless: true,
|
||||
args: ["--no-sandbox"],
|
||||
});
|
||||
|
||||
try {
|
||||
const context = await browser.newContext();
|
||||
const page = await context.newPage();
|
||||
const browserRequests = [];
|
||||
page.on("request", (request) => browserRequests.push(request.url()));
|
||||
|
||||
await page.goto("http://localhost:8088/");
|
||||
await page.waitForURL(/localhost:8080/u);
|
||||
await page.locator('a[href*="/broker/mock-google/login"]').click();
|
||||
await page.waitForURL(/\/realms\/mock-google\//u);
|
||||
await page.locator("#username").fill("mock-new-user");
|
||||
await page.locator("#password").fill(password);
|
||||
await page.locator("#kc-login").click();
|
||||
await page.waitForURL(/\/oauth2\/callback/u);
|
||||
assert.match(await page.locator("body").innerText(), /Internal Server Error/u);
|
||||
|
||||
await verifyBrokeredEmail();
|
||||
await page.goto(
|
||||
"http://localhost:8088/oauth2/start"
|
||||
+ "?rd=http%3A%2F%2Flocalhost%3A8088%2F",
|
||||
);
|
||||
await page.waitForURL("http://localhost:8088/");
|
||||
|
||||
const identity = JSON.parse(await page.locator("body").innerText());
|
||||
assert.equal(identity.pattern, "AP4-edge-forward-auth");
|
||||
assert.match(identity.user, /^[0-9a-f-]{36}$/u);
|
||||
assert.equal(identity.email, "broker-new-user@example.test");
|
||||
assert.equal(
|
||||
browserRequests.some((url) =>
|
||||
url.includes("/protocol/openid-connect/token"),
|
||||
),
|
||||
false,
|
||||
);
|
||||
|
||||
const session = (await context.cookies()).find(
|
||||
(cookie) => cookie.name === "AP4_SESSION",
|
||||
);
|
||||
assert.ok(session?.httpOnly);
|
||||
console.log(
|
||||
"AP4 Google federation verified: unverified email rejected, verified identity -> edge session -> trusted headers",
|
||||
);
|
||||
} finally {
|
||||
await browser.close();
|
||||
}
|
||||
Reference in New Issue
Block a user