From fd507f1d127b4a9a43d9c5ff469d64e1b676cddd Mon Sep 17 00:00:00 2001 From: Shivam Kalra Date: Tue, 19 Sep 2023 00:46:32 +0530 Subject: [PATCH] test: e2e oidc (#11129) Co-authored-by: Syed Ali Shahbaz <52925846+alishaz-polymath@users.noreply.github.com> --- .env.example | 15 ++++ apps/web/playwright/fixtures/users.ts | 4 +- apps/web/playwright/oidc.e2e.ts | 71 +++++++++++++++++++ .../ee/sso/components/ConnectionInfo.tsx | 6 +- .../ee/sso/components/OIDCConnection.tsx | 7 +- turbo.json | 7 ++ 6 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 apps/web/playwright/oidc.e2e.ts diff --git a/.env.example b/.env.example index d71aef5501..3ab772cabb 100644 --- a/.env.example +++ b/.env.example @@ -229,3 +229,18 @@ AUTH_BEARER_TOKEN_VERCEL= # Used for E2E tests on Apple Calendar E2E_TEST_APPLE_CALENDAR_EMAIL="" E2E_TEST_APPLE_CALENDAR_PASSWORD="" + +# - OIDC E2E TEST ******************************************************************************************* + +# Ensure this ADMIN EMAIL is present in the SAML_ADMINS list +E2E_TEST_SAML_ADMIN_EMAIL= +E2E_TEST_SAML_ADMIN_PASSWORD= + +E2E_TEST_OIDC_CLIENT_ID= +E2E_TEST_OIDC_CLIENT_SECRET= +E2E_TEST_OIDC_PROVIDER_DOMAIN= + +E2E_TEST_OIDC_USER_EMAIL= +E2E_TEST_OIDC_USER_PASSWORD= + +# *********************************************************************************************************** \ No newline at end of file diff --git a/apps/web/playwright/fixtures/users.ts b/apps/web/playwright/fixtures/users.ts index 3dc815cec6..58adf7c1dd 100644 --- a/apps/web/playwright/fixtures/users.ts +++ b/apps/web/playwright/fixtures/users.ts @@ -438,7 +438,7 @@ const createUserFixture = (user: UserWithIncludes, page: Page) => { type SupportedTestEventTypes = PrismaType.EventTypeCreateInput & { _bookings?: PrismaType.BookingCreateInput[]; }; -type CustomUserOptsKeys = "username" | "password" | "completedOnboarding" | "locale" | "name"; +type CustomUserOptsKeys = "username" | "password" | "completedOnboarding" | "locale" | "name" | "email"; type CustomUserOpts = Partial> & { timeZone?: TimeZoneEnum; eventTypes?: SupportedTestEventTypes[]; @@ -457,7 +457,7 @@ const createUser = (workerInfo: WorkerInfo, opts?: CustomUserOpts | null): Prism return { username: uname, name: opts?.name, - email: `${uname}@example.com`, + email: opts?.email ?? `${uname}@example.com`, password: hashPassword(uname), emailVerified: new Date(), completedOnboarding: opts?.completedOnboarding ?? true, diff --git a/apps/web/playwright/oidc.e2e.ts b/apps/web/playwright/oidc.e2e.ts new file mode 100644 index 0000000000..0917ec22cc --- /dev/null +++ b/apps/web/playwright/oidc.e2e.ts @@ -0,0 +1,71 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import { test } from "./lib/fixtures"; + +const SAML_DATABASE_URL = process.env.SAML_DATABASE_URL!; +const SAML_ADMINS = process.env.SAML_ADMINS!; +const SAML_ADMIN_EMAIL = process.env.E2E_TEST_SAML_ADMIN_EMAIL!; +const SAML_ADMIN_PASSWORD = process.env.E2E_TEST_SAML_ADMIN_PASSWORD!; +const OIDC_CLIENT_ID = process.env.E2E_TEST_OIDC_CLIENT_ID!; +const OIDC_CLIENT_SECRET = process.env.E2E_TEST_OIDC_CLIENT_SECRET!; +const OIDC_PROVIDER_DOMAIN = process.env.E2E_TEST_OIDC_PROVIDER_DOMAIN!; +const OIDC_USER_EMAIL = process.env.E2E_TEST_OIDC_USER_EMAIL!; +const OIDC_USER_PASSWORD = process.env.E2E_TEST_OIDC_USER_PASSWORD!; + +const SHOULD_SKIP_TESTS = + !SAML_DATABASE_URL || + !SAML_ADMINS || + !SAML_ADMIN_EMAIL || + !SAML_ADMIN_PASSWORD || + !OIDC_CLIENT_ID || + !OIDC_CLIENT_SECRET || + !OIDC_PROVIDER_DOMAIN || + !OIDC_USER_EMAIL || + !OIDC_USER_PASSWORD; + +test.afterEach(({ users }) => users.deleteAll()); +// TODO: Cleanup the OIDC connection after the tests with fixtures +test.describe("OIDC", () => { + // eslint-disable-next-line playwright/no-skipped-test + test.skip(SHOULD_SKIP_TESTS, "Skipping due to missing the testing variables"); + test("Setup with SAML admin and login", async ({ page, users }) => { + // Add the admin user provided in the environment variables to the db + const samlAdminUser = await users.create({ email: SAML_ADMIN_EMAIL, password: SAML_ADMIN_PASSWORD }); + await samlAdminUser.apiLogin(); + await test.step("Connect with OIDC Provider", async () => { + await page.goto("/settings/security/sso"); + await page.click('[data-testid="sso-oidc-configure"]'); + await page.fill('[data-testid="sso-oidc-client-id"]', OIDC_CLIENT_ID); + await page.fill('[data-testid="sso-oidc-client-secret"]', OIDC_CLIENT_SECRET); + await page.fill( + '[data-testid="sso-oidc-well-known-url"]', + `https://${OIDC_PROVIDER_DOMAIN}/.well-known/openid-configuration` + ); + await page.click('[data-testid="sso-oidc-save"]'); + await page.waitForSelector('[data-testid="toast-success"]'); + }); + // Logout the SAML Admin + await samlAdminUser.logout(); + await test.step("Login using the OIDC provider", async () => { + // Login a user using the OIDC provider. + // The credentials are handled by the provider, so we don't need to create a user in the db. + await page.goto("/auth/login"); + await page.click('[data-testid="saml"]'); + // Redirected outide of the app, the user would be redirected to the OIDC provider. + await page.waitForURL(/https:\/\/[^/]+\/oauth2\/v1\/authorize\?.*/); + await page.getByRole("textbox", { name: "Username" }).fill(OIDC_USER_EMAIL); + await page.getByRole("textbox", { name: "Password" }).fill(OIDC_USER_PASSWORD); + await page.getByRole("button", { name: "Sign in" }).click(); + // The user is redirected back to the app. + await page.waitForURL("getting-started", { waitUntil: "load" }); + }); + // Logout the user. + await page.goto("/auth/logout"); + await test.step("Disconnect OIDC Provider", async () => { + samlAdminUser.apiLogin(); + await page.goto("/settings/security/sso", { waitUntil: "load" }); + await page.getByTestId("delete-oidc-sso-connection").click(); + await page.getByRole("button", { name: "Yes, delete OIDC configuration" }).click(); + await page.waitForSelector('[data-testid="toast-success"]'); + }); + }); +}); diff --git a/packages/features/ee/sso/components/ConnectionInfo.tsx b/packages/features/ee/sso/components/ConnectionInfo.tsx index c2a3a85fb2..3ec6f30c59 100644 --- a/packages/features/ee/sso/components/ConnectionInfo.tsx +++ b/packages/features/ee/sso/components/ConnectionInfo.tsx @@ -57,7 +57,11 @@ export default function ConnectionInfo({
- +
{!connection && (
-
@@ -100,6 +100,7 @@ const CreateConnectionDialog = ({ { form.setValue("clientId", e?.target.value); @@ -116,6 +117,7 @@ const CreateConnectionDialog = ({ { form.setValue("clientSecret", e?.target.value); @@ -132,6 +134,7 @@ const CreateConnectionDialog = ({ { form.setValue("wellKnownUrl", e?.target.value); @@ -152,7 +155,7 @@ const CreateConnectionDialog = ({ tabIndex={-1}> {t("cancel")} - diff --git a/turbo.json b/turbo.json index 9bed5b8a1b..3a6325f844 100644 --- a/turbo.json +++ b/turbo.json @@ -211,6 +211,13 @@ "E2E_TEST_APPLE_CALENDAR_EMAIL", "E2E_TEST_APPLE_CALENDAR_PASSWORD", "E2E_TEST_MAILHOG_ENABLED", + "E2E_TEST_OIDC_CLIENT_ID", + "E2E_TEST_OIDC_CLIENT_SECRET", + "E2E_TEST_OIDC_PROVIDER_DOMAIN", + "E2E_TEST_OIDC_USER_EMAIL", + "E2E_TEST_OIDC_USER_PASSWORD", + "E2E_TEST_SAML_ADMIN_EMAIL", + "E2E_TEST_SAML_ADMIN_PASSWORD", "EMAIL_FROM", "EMAIL_SERVER_HOST", "EMAIL_SERVER_PASSWORD",