Skip to content

Commit 554c408

Browse files
committed
Handled user without profile
1 parent 281bf17 commit 554c408

File tree

4 files changed

+68
-5
lines changed

4 files changed

+68
-5
lines changed

src/hooks.server.js

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,14 @@ export async function handle({ event, resolve }) {
7979
}
8080

8181
// Authentication guard
82-
if (!isPublicPage && userInfo === null) {
83-
logger.debug('Authentication required - No auth cookie found - Redirecting to login');
84-
redirect(302, '/auth/login?invalidate=true');
82+
if (!isPublicPage) {
83+
if (userInfo === null) {
84+
logger.debug('Authentication required - No auth cookie found - Redirecting to login');
85+
redirect(302, '/auth/login?invalidate=true');
86+
} else if (userInfo.profile_id === null) {
87+
logger.debug('User without profile - Redirecting to home');
88+
redirect(302, '/');
89+
}
8590
}
8691

8792
// Admin area check

src/routes/+page.svelte

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
import { formatMarkdown } from '$lib/common/component_utilities';
66
import { onMount } from 'svelte';
77
8-
let userLoggedIn = $derived(!!page.data.userInfo);
8+
/** @type {import('fractal-components/types/api').User|undefined} */
9+
let userInfo = $derived(page.data.userInfo);
910
let news = $derived(page.data.news);
1011
1112
let mounted = $state(false);
@@ -22,6 +23,12 @@
2223
</script>
2324

2425
<div class="container mt-3">
26+
{#if userInfo && userInfo.profile_id === null}
27+
<div class="alert alert-warning">
28+
This user is not authorized to use this Fractal instance - please contact {env.PUBLIC_FRACTAL_ADMIN_SUPPORT_EMAIL}.
29+
</div>
30+
{/if}
31+
2532
{#if temporaryMessage}
2633
<div class="alert alert-info">
2734
{temporaryMessage}
@@ -49,7 +56,7 @@
4956
</p>
5057

5158
<div class="col mb-3">
52-
{#if !userLoggedIn}
59+
{#if !userInfo}
5360
<a href="/auth/login" class="btn btn-primary">Login</a>
5461
{/if}
5562
<a href="/v2/projects" class="btn btn-primary">Projects</a>
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { expect, test } from '@playwright/test';
2+
import { login, logout, waitPageLoading } from '../utils.js';
3+
4+
// Reset storage state for this file to avoid being authenticated
5+
test.use({ storageState: { cookies: [], origins: [] } });
6+
7+
test('User without profile', async ({ page }) => {
8+
const randomValue = Math.random().toString(36).substring(7);
9+
const randomEmail = `${randomValue}@example.com`;
10+
11+
await test.step('Login as admin and create test user', async () => {
12+
await login(page, '[email protected]', '1234');
13+
await page.goto('/v2/admin/users/register');
14+
await waitPageLoading(page);
15+
await page.getByRole('textbox', { name: 'E-mail' }).fill(randomEmail);
16+
await page.getByRole('textbox', { name: 'Password', exact: true }).fill('1234');
17+
await page.getByRole('textbox', { name: 'Confirm password' }).fill('1234');
18+
await page.getByRole('textbox', { name: 'Project dir' }).fill('/tmp');
19+
20+
// Unset the profile
21+
await page
22+
.getByRole('combobox', { name: 'Select resource' })
23+
.selectOption('Select resource...');
24+
await expect(page.getByRole('combobox', { name: 'Select profile' })).toBeDisabled();
25+
await expect(page.getByRole('combobox', { name: 'Select profile' })).toHaveValue('');
26+
27+
await page.getByRole('button', { name: 'Save' }).first().click();
28+
await page.waitForURL(/\/v2\/admin\/users\/\d+\/edit/);
29+
});
30+
31+
await test.step('Login as test user', async () => {
32+
await logout(page, '[email protected]');
33+
34+
await page.goto('/auth/login');
35+
await waitPageLoading(page);
36+
await page.getByRole('button', { name: 'Log in with username & password' }).click();
37+
await page.getByLabel('Email address').fill(randomEmail);
38+
await page.getByLabel('Password').fill('1234');
39+
await page.getByRole('button', { name: 'Log in', exact: true }).click();
40+
41+
await page.waitForURL('/');
42+
43+
await expect(
44+
page.getByText(/This user is not authorized to use this Fractal instance/)
45+
).toBeVisible();
46+
47+
await logout(page, randomEmail);
48+
});
49+
});

tests/v2/viewer_paths.spec.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ test('Viewer paths', async ({ page }) => {
1717
await page.getByRole('textbox', { name: 'Password', exact: true }).fill('1234');
1818
await page.getByRole('textbox', { name: 'Confirm password' }).fill('1234');
1919
await page.getByRole('textbox', { name: 'Project dir' }).fill('/tmp');
20+
await page.getByRole('combobox', { name: 'Select resource' }).selectOption('Local resource');
21+
await page.getByRole('combobox', { name: 'Select profile' }).selectOption('Local profile');
2022
await page.getByRole('button', { name: 'Save' }).first().click();
2123
await page.waitForURL(/\/v2\/admin\/users\/\d+\/edit/);
2224
});

0 commit comments

Comments
 (0)