1
0
forked from baron/baron-sso
Files
baron-sso/orgfront/tests/devfront-security.spec.ts

123 lines
3.4 KiB
TypeScript

import { expect, test } from "@playwright/test";
import {
type Consent,
installDevApiMock,
makeClient,
seedAuth,
} from "./helpers/devfront-fixtures";
test.describe("DevFront security and isolation", () => {
test.beforeEach(async ({ page }) => {
page.on("dialog", async (dialog) => {
await dialog.accept();
});
await seedAuth(page);
});
test("tenant isolation: forbidden client shows blocked error", async ({
page,
}) => {
const state = {
clients: [makeClient("tenant-a-client", { name: "Tenant A app" })],
consents: [] as Consent[],
auditLogsByCursor: undefined,
};
await installDevApiMock(page, state);
await page.goto("/clients/tenant-b-client");
await expect(
page.getByText(
/Error loading (app|client)|앱 정보를 불러오지 못했습니다|클라이언트 정보를 불러오지 못했습니다/i,
),
).toBeVisible();
});
test("RBAC: user without manage_all permission should not see private apps", async ({
page,
}) => {
const state = {
clients: [
makeClient("pkce-client", {
name: "PKCE only app",
type: "pkce",
}),
],
consents: [] as Consent[],
auditLogsByCursor: undefined,
};
await installDevApiMock(page, state);
await page.goto("/clients");
await expect(page.getByText("PKCE only app")).toBeVisible();
await expect(page.getByText("Server side App")).not.toBeVisible();
});
test("tenant_member user is blocked at AuthGuard", async ({ page }) => {
await seedAuth(page, "tenant_member");
await page.goto("/clients");
await expect(
page.getByText(/DevFront는 관리자 전용 화면입니다|administrator access/i),
).toBeVisible();
await expect(page).toHaveURL(/\/clients$/);
});
test("rp_admin receives 403 on clients list and sees ForbiddenMessage", async ({
page,
}) => {
await seedAuth(page, "rp_admin");
const state = {
clients: [] as ReturnType<typeof makeClient>[],
consents: [] as Consent[],
auditLogsByCursor: undefined,
};
await installDevApiMock(page, state);
await page.route("**/api/v1/dev/clients", async (route) => {
if (route.request().method() === "GET") {
return route.fulfill({
status: 403,
contentType: "application/json",
body: '{"error": "forbidden"}',
});
}
return route.fallback();
});
await page.goto("/clients");
await expect(
page.getByText(/RP 관리자는|RP administrators can only access/i),
).toBeVisible();
});
test("tenant_admin receives 403 on audit logs and sees ForbiddenMessage", async ({
page,
}) => {
await seedAuth(page, "tenant_admin");
const state = {
clients: [] as ReturnType<typeof makeClient>[],
consents: [] as Consent[],
auditLogsByCursor: undefined,
};
await installDevApiMock(page, state);
await page.route("**/api/v1/dev/audit-logs*", async (route) => {
if (route.request().method() === "GET") {
return route.fulfill({
status: 403,
contentType: "application/json",
body: '{"error": "forbidden"}',
});
}
return route.fallback();
});
await page.goto("/audit-logs");
await expect(
page.getByText(/테넌트 관리자 권한|Tenant administrator permissions/i),
).toBeVisible();
});
});