mirror of https://github.com/boxyhq/jackson.git
165 lines
8.5 KiB
TypeScript
165 lines
8.5 KiB
TypeScript
import { expect, test } from '@playwright/test';
|
|
|
|
// SAML SSO
|
|
const TEST_SAML_SSO_CONNECTION_NAME = 'pw_admin_portal_saml_sso';
|
|
const MOCKSAML_ORIGIN = process.env.MOCKSAML_ORIGIN || 'https://mocksaml.com';
|
|
const MOCKSAML_METADATA_URL = `${MOCKSAML_ORIGIN}/api/saml/metadata`;
|
|
const MOCKSAML_SIGNIN_BUTTON_NAME = 'Sign In';
|
|
// OIDC SSO
|
|
const TEST_OIDC_SSO_CONNECTION_NAME = 'pw_admin_portal_oidc_sso';
|
|
const MOCKLAB_DISCOVERY_ENDPOINT = 'https://oauth.wiremockapi.cloud/.well-known/openid-configuration';
|
|
const MOCKLAB_ISSUER = 'https://oauth.wiremockapi.cloud';
|
|
const MOCKLAB_AUTHORIZATION_ENDPOINT = 'https://oauth.wiremockapi.cloud/oauth/authorize';
|
|
const MOCKLAB_TOKEN_ENDPOINT = 'https://oauth.wiremockapi.cloud/oauth/token';
|
|
const MOCKLAB_USERINFO_ENDPOINT = 'https://oauth.wiremockapi.cloud/userinfo';
|
|
const MOCKLAB_JWKS_URI = 'https://oauth.wiremockapi.cloud/.well-known/jwks.json';
|
|
const MOCKLAB_ORIGIN = 'https://oauth.wiremockapi.cloud';
|
|
const MOCKLAB_CLIENT_ID = 'mocklab_oauth2';
|
|
const MOCKLAB_CLIENT_SECRET = 'mocklab_secret';
|
|
const MOCKLAB_SIGNIN_BUTTON_NAME = 'Login';
|
|
|
|
test.describe('Admin Portal SSO - SAML', () => {
|
|
test('should be able to add SSO connection to mocksaml', async ({ page }) => {
|
|
await page.goto('/admin/settings');
|
|
// Find the new connection button and click on it
|
|
await page.getByTestId('create-connection').click();
|
|
// Fill the name for the connection
|
|
const nameInput = page.getByLabel('Connection name (Optional)');
|
|
await nameInput.fill(TEST_SAML_SSO_CONNECTION_NAME);
|
|
// Enter the metadata url for mocksaml in the form
|
|
const metadataUrlInput = page.getByLabel('Metadata URL');
|
|
await metadataUrlInput.fill(MOCKSAML_METADATA_URL);
|
|
// submit the form
|
|
await page.getByRole('button', { name: /save/i }).click();
|
|
// check if the added connection appears in the connection list
|
|
await expect(page.getByText(TEST_SAML_SSO_CONNECTION_NAME)).toBeVisible();
|
|
});
|
|
|
|
test('should be able to login with mocksaml via SP initiated SSO', async ({ page, baseURL }) => {
|
|
const userAvatarLocator = page.getByTestId('user-avatar');
|
|
// Logout from the magic link authentication
|
|
await page.goto('/');
|
|
await userAvatarLocator.click();
|
|
await page.getByTestId('logout').click();
|
|
// Click on login with sso button
|
|
await page.getByTestId('sso-login-button').click();
|
|
// Perform sign in at mocksaml
|
|
await page.waitForURL((url) => url.origin === MOCKSAML_ORIGIN);
|
|
await page.getByPlaceholder('jackson').fill('bob');
|
|
await page.getByRole('button', { name: MOCKSAML_SIGNIN_BUTTON_NAME }).click();
|
|
// Wait for browser to redirect back to admin portal
|
|
await page.waitForURL((url) => url.origin === baseURL);
|
|
// assert login state
|
|
await expect(userAvatarLocator).toBeVisible();
|
|
});
|
|
|
|
test('should be able to login with mocksaml via IdP initiated SSO', async ({ page, baseURL }) => {
|
|
const userAvatarLocator = page.getByTestId('user-avatar');
|
|
// Logout from the magic link authentication
|
|
await page.goto('/');
|
|
await userAvatarLocator.click();
|
|
await page.getByTestId('logout').click();
|
|
await expect(page.getByTestId('sso-login-button')).toBeVisible();
|
|
// Go directly to mocksaml hosting
|
|
await page.goto(MOCKSAML_ORIGIN);
|
|
await page.getByRole('link', { name: 'Test IdP Login' }).click();
|
|
await page.getByPlaceholder('https://sso.eu.boxyhq.com/api/oauth/saml').fill(`${baseURL}/api/oauth/saml`);
|
|
await page.getByRole('textbox', { name: 'Please provide a mock email address' }).fill('bob');
|
|
await page.getByRole('button', { name: MOCKSAML_SIGNIN_BUTTON_NAME }).click();
|
|
// Wait for browser to redirect to admin portal
|
|
await page.waitForURL((url) => url.origin === baseURL);
|
|
// assert login state
|
|
await expect(userAvatarLocator).toBeVisible();
|
|
});
|
|
|
|
test('delete the SAML SSO connection', async ({ page }) => {
|
|
await page.goto('/admin/settings');
|
|
// select the row of the connection list table, then locate the edit button
|
|
const editButton = page.getByText(TEST_SAML_SSO_CONNECTION_NAME).locator('..').getByLabel('Edit');
|
|
await editButton.click();
|
|
// click the delete and confirm deletion
|
|
await page.getByRole('button', { name: 'Delete' }).click();
|
|
await page.getByRole('button', { name: 'Confirm' }).click();
|
|
// check that the SSO connection is deleted from the connection list
|
|
await expect(page.getByText(TEST_SAML_SSO_CONNECTION_NAME)).not.toBeVisible();
|
|
});
|
|
});
|
|
|
|
test.describe('Admin Portal SSO - OIDC', () => {
|
|
const oidcMetadataMode = ['discoveryUrl', 'metadata'];
|
|
for (const mode of oidcMetadataMode) {
|
|
test.describe(`SSO connection via ${mode}`, () => {
|
|
test('should be able to add OIDC SSO connection to mocklab', async ({ page }) => {
|
|
await page.goto('/admin/settings');
|
|
// Find the new connection button and click on it
|
|
await page.getByTestId('create-connection').click();
|
|
// Toggle connection type to OIDC
|
|
await page.getByLabel('OIDC').check();
|
|
// Fill the name for the connection
|
|
const nameInput = page.getByLabel('Connection name (Optional)');
|
|
await nameInput.fill(TEST_OIDC_SSO_CONNECTION_NAME);
|
|
if (mode === 'discoveryUrl') {
|
|
// Enter the OIDC discovery url for mocklab in the form
|
|
const discoveryUrlInput = page.getByLabel('Well-known URL of OpenID Provider');
|
|
await discoveryUrlInput.fill(MOCKLAB_DISCOVERY_ENDPOINT);
|
|
} else {
|
|
// Enter the OIDC issuer value for mocklab in the form
|
|
const issuerInput = page.getByLabel('issuer');
|
|
await issuerInput.fill(MOCKLAB_ISSUER);
|
|
// Enter the OIDC authorization_endpoint value for mocklab in the form
|
|
const authzEndpointInput = page.getByLabel('Authorization Endpoint');
|
|
await authzEndpointInput.fill(MOCKLAB_AUTHORIZATION_ENDPOINT);
|
|
// Enter the OIDC token_endpoint value for mocklab in the form
|
|
const tokenEndpointInput = page.getByLabel('Token endpoint');
|
|
await tokenEndpointInput.fill(MOCKLAB_TOKEN_ENDPOINT);
|
|
// Enter the OIDC userinfo_endpoint value for mocklab in the form
|
|
const userInfoEndpointInput = page.getByLabel('UserInfo endpoint');
|
|
await userInfoEndpointInput.fill(MOCKLAB_USERINFO_ENDPOINT);
|
|
// Enter the OIDC jwks_uri value for mocklab in the form
|
|
const jwksUriInput = page.getByLabel('JWKS URI');
|
|
await jwksUriInput.fill(MOCKLAB_JWKS_URI);
|
|
}
|
|
// Enter the OIDC client credentials for mocklab in the form
|
|
const clientIdInput = page.getByLabel('Client ID');
|
|
await clientIdInput.fill(MOCKLAB_CLIENT_ID);
|
|
const clientSecretInput = page.getByLabel('Client Secret');
|
|
await clientSecretInput.fill(MOCKLAB_CLIENT_SECRET);
|
|
// submit the form
|
|
await page.getByRole('button', { name: /save/i }).click();
|
|
// check if the added connection appears in the connection list
|
|
await expect(page.getByText(TEST_OIDC_SSO_CONNECTION_NAME)).toBeVisible();
|
|
});
|
|
|
|
test('should be able to login with mocklab', async ({ page, baseURL }) => {
|
|
const userAvatarLocator = page.getByTestId('user-avatar');
|
|
// Logout from the magic link authentication
|
|
await page.goto('/');
|
|
await userAvatarLocator.click();
|
|
await page.getByTestId('logout').click();
|
|
// Click on login with sso button
|
|
await page.getByTestId('sso-login-button').click();
|
|
// Perform sign in at mocksaml
|
|
await page.waitForURL((url) => url.origin === MOCKLAB_ORIGIN);
|
|
await page.getByPlaceholder('yours@example.com').fill('bob@oidc.com');
|
|
await page.getByRole('button', { name: MOCKLAB_SIGNIN_BUTTON_NAME }).click();
|
|
// Wait for browser to redirect back to admin portal
|
|
await page.waitForURL((url) => url.origin === baseURL);
|
|
// assert login state
|
|
await expect(userAvatarLocator).toBeVisible();
|
|
});
|
|
|
|
test('delete the OIDC SSO connection', async ({ page }) => {
|
|
await page.goto('/admin/settings');
|
|
// select the row of the connection list table, then locate the edit button
|
|
const editButton = page.getByText(TEST_OIDC_SSO_CONNECTION_NAME).locator('..').getByLabel('Edit');
|
|
await editButton.click();
|
|
// click the delete and confirm deletion
|
|
await page.getByRole('button', { name: 'Delete' }).click();
|
|
await page.getByRole('button', { name: 'Confirm' }).click();
|
|
// check that the SSO connection is deleted from the connection list
|
|
await expect(page.getByText(TEST_OIDC_SSO_CONNECTION_NAME)).not.toBeVisible();
|
|
});
|
|
});
|
|
}
|
|
});
|