mirror of
https://github.com/nikdoof/pocket-id.git
synced 2025-12-14 07:12:19 +00:00
feat: map allowed groups to OIDC clients (#202)
This commit is contained in:
@@ -40,7 +40,7 @@ test('Update account details fails with already taken username', async ({ page }
|
||||
test('Add passkey to an account', async ({ page }) => {
|
||||
await page.goto('/settings/account');
|
||||
|
||||
await (await passkeyUtil.init(page)).addPasskey('new');
|
||||
await (await passkeyUtil.init(page)).addPasskey('timNew');
|
||||
|
||||
await page.click('button:text("Add Passkey")');
|
||||
|
||||
|
||||
@@ -24,6 +24,8 @@ test('Update general configuration', async ({ page }) => {
|
||||
test('Update email configuration', async ({ page }) => {
|
||||
await page.goto('/settings/admin/application-configuration');
|
||||
|
||||
await page.getByRole('button', { name: 'Expand card' }).nth(1).click();
|
||||
|
||||
await page.getByLabel('SMTP Host').fill('smtp.gmail.com');
|
||||
await page.getByLabel('SMTP Port').fill('587');
|
||||
await page.getByLabel('SMTP User').fill('test@gmail.com');
|
||||
@@ -47,14 +49,53 @@ test('Update email configuration', async ({ page }) => {
|
||||
await expect(page.getByLabel('Email One Time Access')).toBeChecked();
|
||||
});
|
||||
|
||||
test('Update LDAP configuration', async ({ page }) => {
|
||||
await page.goto('/settings/admin/application-configuration');
|
||||
|
||||
await page.getByRole('button', { name: 'Expand card' }).nth(2).click();
|
||||
|
||||
await page.getByLabel('LDAP URL').fill('ldap://localhost:389');
|
||||
await page.getByLabel('LDAP Bind DN').fill('cn=admin,dc=example,dc=com');
|
||||
await page.getByLabel('LDAP Bind Password').fill('password');
|
||||
await page.getByLabel('LDAP Base DN').fill('dc=example,dc=com');
|
||||
await page.getByLabel('User Unique Identifier Attribute').fill('uuid');
|
||||
await page.getByLabel('Username Attribute').fill('uid');
|
||||
await page.getByLabel('User Mail Attribute').fill('mail');
|
||||
await page.getByLabel('User First Name Attribute').fill('givenName');
|
||||
await page.getByLabel('User Last Name Attribute').fill('sn');
|
||||
await page.getByLabel('Group Unique Identifier Attribute').fill('uuid');
|
||||
await page.getByLabel('Group Name Attribute').fill('cn');
|
||||
await page.getByLabel('Admin Group Name').fill('admin');
|
||||
|
||||
await page.getByRole('button', { name: 'Enable' }).click();
|
||||
|
||||
await expect(page.getByRole('status')).toHaveText('LDAP configuration updated successfully');
|
||||
|
||||
await page.reload();
|
||||
|
||||
await expect(page.getByRole('button', { name: 'Disable' })).toBeVisible();
|
||||
await expect(page.getByLabel('LDAP URL')).toHaveValue('ldap://localhost:389');
|
||||
await expect(page.getByLabel('LDAP Bind DN')).toHaveValue('cn=admin,dc=example,dc=com');
|
||||
await expect(page.getByLabel('LDAP Bind Password')).toHaveValue('password');
|
||||
await expect(page.getByLabel('LDAP Base DN')).toHaveValue('dc=example,dc=com');
|
||||
await expect(page.getByLabel('User Unique Identifier Attribute')).toHaveValue('uuid');
|
||||
await expect(page.getByLabel('Username Attribute')).toHaveValue('uid');
|
||||
await expect(page.getByLabel('User Mail Attribute')).toHaveValue('mail');
|
||||
await expect(page.getByLabel('User First Name Attribute')).toHaveValue('givenName');
|
||||
await expect(page.getByLabel('User Last Name Attribute')).toHaveValue('sn');
|
||||
await expect(page.getByLabel('Admin Group Name')).toHaveValue('admin');
|
||||
});
|
||||
|
||||
test('Update application images', async ({ page }) => {
|
||||
await page.goto('/settings/admin/application-configuration');
|
||||
|
||||
await page.getByRole('button', { name: 'Expand card' }).nth(3).click();
|
||||
|
||||
await page.getByLabel('Favicon').setInputFiles('tests/assets/w3-schools-favicon.ico');
|
||||
await page.getByLabel('Light Mode Logo').setInputFiles('tests/assets/pingvin-share-logo.png');
|
||||
await page.getByLabel('Dark Mode Logo').setInputFiles('tests/assets/nextcloud-logo.png');
|
||||
await page.getByLabel('Background Image').setInputFiles('tests/assets/clouds.jpg');
|
||||
await page.getByRole('button', { name: 'Save' }).nth(2).click();
|
||||
await page.getByRole('button', { name: 'Save' }).nth(1).click();
|
||||
|
||||
await expect(page.getByRole('status')).toHaveText('Images updated successfully');
|
||||
|
||||
|
||||
@@ -75,6 +75,24 @@ test('Authorize new client while not signed in', async ({ page }) => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Authorize new client fails with user group not allowed', async ({ page }) => {
|
||||
const oidcClient = oidcClients.immich;
|
||||
const urlParams = createUrlParams(oidcClient);
|
||||
await page.context().clearCookies();
|
||||
await page.goto(`/authorize?${urlParams.toString()}`);
|
||||
|
||||
await (await passkeyUtil.init(page)).addPasskey('craig');
|
||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
||||
|
||||
await expect(page.getByTestId('scopes').getByRole('heading', { name: 'Email' })).toBeVisible();
|
||||
await expect(page.getByTestId('scopes').getByRole('heading', { name: 'Profile' })).toBeVisible();
|
||||
|
||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
||||
|
||||
await expect(page.getByRole('paragraph').first()).toHaveText("You're not allowed to access this service.");
|
||||
});
|
||||
|
||||
|
||||
function createUrlParams(oidcClient: { id: string; callbackUrl: string }) {
|
||||
return new URLSearchParams({
|
||||
client_id: oidcClient.id,
|
||||
|
||||
@@ -77,6 +77,8 @@ test('Delete user group', async ({ page }) => {
|
||||
test('Update user group custom claims', async ({ page }) => {
|
||||
await page.goto(`/settings/admin/user-groups/${userGroups.designers.id}`);
|
||||
|
||||
await page.getByRole('button', { name: 'Expand card' }).click();
|
||||
|
||||
// Add two custom claims
|
||||
await page.getByRole('button', { name: 'Add custom claim' }).click();
|
||||
|
||||
|
||||
@@ -142,6 +142,8 @@ test('Update user fails with already taken username', async ({ page }) => {
|
||||
test('Update user custom claims', async ({ page }) => {
|
||||
await page.goto(`/settings/admin/users/${users.craig.id}`);
|
||||
|
||||
await page.getByRole('button', { name: 'Expand card' }).click();
|
||||
|
||||
// Add two custom claims
|
||||
await page.getByRole('button', { name: 'Add custom claim' }).click();
|
||||
|
||||
|
||||
@@ -2,18 +2,21 @@ import type { CDPSession, Page } from '@playwright/test';
|
||||
|
||||
// The existing passkeys are already stored in the database
|
||||
const passkeys = {
|
||||
existing1: {
|
||||
credentialId: 'test-credential-1',
|
||||
tim: {
|
||||
credentialId: 'test-credential-tim',
|
||||
userHandle: 'f4b89dc2-62fb-46bf-9f5f-c34f4eafe93e',
|
||||
privateKey:
|
||||
'MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg3rNKkGApsEA1TpGiphKh6axTq3Vh6wBghLLea/YkIp+hRANCAATBw6jkpXXr0pHrtAQetxiR5cTcILG/YGDCdKrhVhNDHIu12YrF6B7Frwl3AUqEpdrYEwj3Fo3XkGgvrBIJEUmG'
|
||||
},
|
||||
existing2: {
|
||||
credentialId: 'test-credential-2',
|
||||
craig: {
|
||||
credentialId: 'test-credential-craig',
|
||||
userHandle: '1cd19686-f9a6-43f4-a41f-14a0bf5b4036',
|
||||
privateKey:
|
||||
'MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg3rNKkGApsEA1TpGiphKh6axTq3Vh6wBghLLea/YkIp+hRANCAATBw6jkpXXr0pHrtAQetxiR5cTcILG/YGDCdKrhVhNDHIu12YrF6B7Frwl3AUqEpdrYEwj3Fo3XkGgvrBIJEUmG'
|
||||
'MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgL1UaeWG1KYpN+HcxQvXEJysiQjT9Fn7Zif3i5cY+s+yhRANCAASPioDQ+tnODwKjULbufJRvOunwTCOvt46UYjYt+vOZsvmc+FlEB0neERqqscxKckGF8yq1AYrANiloshAUAouH'
|
||||
},
|
||||
new: {
|
||||
credentialId: 'new-test-credential',
|
||||
timNew: {
|
||||
credentialId: 'new-test-credential-tim',
|
||||
userHandle: 'f4b89dc2-62fb-46bf-9f5f-c34f4eafe93e',
|
||||
privateKey:
|
||||
'MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgFl2lIlRyc2G7O9D8WWrw2N8D7NTlhgWcKFY7jYxrfcmhRANCAASmvbCFrXshUvW7avTIysV9UymbhmUwGb7AonUMQPgqK2Jur7PWp9V0AIe5YMuXYH1oxsqY5CoAbdY2YsPmhYoX'
|
||||
}
|
||||
@@ -48,9 +51,9 @@ async function addVirtualAuthenticator(client: CDPSession): Promise<string> {
|
||||
async function addPasskey(
|
||||
authenticatorId: string,
|
||||
client: CDPSession,
|
||||
passkeyName?: keyof typeof passkeys
|
||||
passkeyName: keyof typeof passkeys = 'tim'
|
||||
): Promise<void> {
|
||||
const passkey = passkeys[passkeyName ?? 'existing1'];
|
||||
const passkey = passkeys[passkeyName];
|
||||
await client.send('WebAuthn.addCredential', {
|
||||
authenticatorId,
|
||||
credential: {
|
||||
@@ -58,9 +61,8 @@ async function addPasskey(
|
||||
isResidentCredential: true,
|
||||
rpId: 'localhost',
|
||||
privateKey: passkey.privateKey,
|
||||
userHandle: btoa('f4b89dc2-62fb-46bf-9f5f-c34f4eafe93e'),
|
||||
userHandle: btoa(passkey.userHandle),
|
||||
signCount: Math.round((new Date().getTime() - 1704444610871) / 1000 / 2)
|
||||
// signCount: 2,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user