From 6daa48d9b523e0e9b807f3698b8ce7527b7efa17 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 22 Nov 2024 02:17:54 +0100 Subject: [PATCH 01/43] Make language choice peristent for users --- .../0037_appliedcontrol_priority.py | 22 ---------- ...t_disaster_recovery_objectives_and_more.py | 10 +++++ backend/core/urls.py | 1 + backend/core/views.py | 41 +++++++++++++++---- .../iam/migrations/0010_user_preferences.py | 17 ++++++++ backend/iam/models.py | 1 + backend/iam/views.py | 1 + .../components/SideBar/SideBarFooter.svelte | 6 +++ frontend/src/lib/utils/helpers.ts | 2 +- frontend/src/routes/(app)/+page.server.ts | 2 +- .../(authentication)/login/+page.server.ts | 21 ++++++++-- frontend/src/routes/+layout.svelte | 7 +++- .../routes/api/user-preferences/+server.ts | 36 ++++++++++++++++ 13 files changed, 130 insertions(+), 37 deletions(-) delete mode 100644 backend/core/migrations/0037_appliedcontrol_priority.py create mode 100644 backend/iam/migrations/0010_user_preferences.py create mode 100644 frontend/src/routes/api/user-preferences/+server.ts diff --git a/backend/core/migrations/0037_appliedcontrol_priority.py b/backend/core/migrations/0037_appliedcontrol_priority.py deleted file mode 100644 index 3f8a97035..000000000 --- a/backend/core/migrations/0037_appliedcontrol_priority.py +++ /dev/null @@ -1,22 +0,0 @@ -# Generated by Django 5.1.1 on 2024-11-19 15:31 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - dependencies = [ - ("core", "0036_asset_owner"), - ] - - operations = [ - migrations.AddField( - model_name="appliedcontrol", - name="priority", - field=models.PositiveSmallIntegerField( - blank=True, - choices=[(1, "P1"), (2, "P2"), (3, "P3"), (4, "P4")], - null=True, - verbose_name="Priority", - ), - ), - ] diff --git a/backend/core/migrations/0037_asset_disaster_recovery_objectives_and_more.py b/backend/core/migrations/0037_asset_disaster_recovery_objectives_and_more.py index 52f795352..20657d346 100644 --- a/backend/core/migrations/0037_asset_disaster_recovery_objectives_and_more.py +++ b/backend/core/migrations/0037_asset_disaster_recovery_objectives_and_more.py @@ -96,4 +96,14 @@ class Migration(migrations.Migration): verbose_name="Security objectives", ), ), + migrations.AddField( + model_name="appliedcontrol", + name="priority", + field=models.PositiveSmallIntegerField( + blank=True, + choices=[(1, "P1"), (2, "P2"), (3, "P3"), (4, "P4")], + null=True, + verbose_name="Priority", + ), + ), ] diff --git a/backend/core/urls.py b/backend/core/urls.py index 5c5c5ddec..7d88f694c 100644 --- a/backend/core/urls.py +++ b/backend/core/urls.py @@ -83,6 +83,7 @@ path("iam/", include("iam.urls")), path("serdes/", include("serdes.urls")), path("settings/", include("global_settings.urls")), + path("user-preferences/", UserPreferencesView.as_view(), name="user-preferences"), path("csrf/", get_csrf_token, name="get_csrf_token"), path("build/", get_build, name="get_build"), path("evidences//upload/", UploadAttachmentView.as_view(), name="upload"), diff --git a/backend/core/views.py b/backend/core/views.py index 846345235..49ffb1ad0 100644 --- a/backend/core/views.py +++ b/backend/core/views.py @@ -48,7 +48,6 @@ from rest_framework.renderers import JSONRenderer from rest_framework.request import Request from rest_framework.response import Response -from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_403_FORBIDDEN from rest_framework.utils.serializer_helpers import ReturnDict from rest_framework.views import APIView @@ -268,7 +267,7 @@ def quality_check_detail(self, request, pk): } return Response(res) else: - return Response(status=HTTP_403_FORBIDDEN) + return Response(status=status.HTTP_403_FORBIDDEN) class ThreatViewSet(BaseModelViewSet): @@ -541,7 +540,7 @@ def quality_check_detail(self, request, pk): risk_assessment = self.get_object() return Response(risk_assessment.quality_check()) else: - return Response(status=HTTP_403_FORBIDDEN) + return Response(status=status.HTTP_403_FORBIDDEN) @action(detail=True, methods=["get"], name="Get treatment plan data") def plan(self, request, pk): @@ -574,7 +573,7 @@ def plan(self, request, pk): return Response(risk_assessment) else: - return Response(status=HTTP_403_FORBIDDEN) + return Response(status=status.HTTP_403_FORBIDDEN) @action(detail=True, name="Get treatment plan CSV") def treatment_plan_csv(self, request, pk): @@ -634,7 +633,9 @@ def treatment_plan_csv(self, request, pk): return response else: - return Response({"error": "Permission denied"}, status=HTTP_403_FORBIDDEN) + return Response( + {"error": "Permission denied"}, status=status.HTTP_403_FORBIDDEN + ) @action(detail=True, name="Get risk assessment CSV") def risk_assessment_csv(self, request, pk): @@ -680,7 +681,9 @@ def risk_assessment_csv(self, request, pk): return response else: - return Response({"error": "Permission denied"}, status=HTTP_403_FORBIDDEN) + return Response( + {"error": "Permission denied"}, status=status.HTTP_403_FORBIDDEN + ) @action(detail=True, name="Get risk assessment PDF") def risk_assessment_pdf(self, request, pk): @@ -1193,7 +1196,7 @@ def update(self, request, *args, **kwargs): _data = { "non_field_errors": "The justification can only be edited by the approver" } - return Response(data=_data, status=HTTP_400_BAD_REQUEST) + return Response(data=_data, status=status.HTTP_400_BAD_REQUEST) else: return super().update(request, *args, **kwargs) @@ -1305,7 +1308,7 @@ def update(self, request: Request, *args, **kwargs) -> Response: if str(admin_group.pk) not in new_user_groups: return Response( {"error": "attemptToRemoveOnlyAdminUserGroup"}, - status=HTTP_403_FORBIDDEN, + status=status.HTTP_403_FORBIDDEN, ) return super().update(request, *args, **kwargs) @@ -1317,7 +1320,7 @@ def destroy(self, request, *args, **kwargs): if number_of_admin_users == 1: return Response( {"error": "attemptToDeleteOnlyAdminAccountError"}, - status=HTTP_403_FORBIDDEN, + status=status.HTTP_403_FORBIDDEN, ) return super().destroy(request, *args, **kwargs) @@ -1532,6 +1535,26 @@ def my_assignments(self, request): ) +class UserPreferencesView(APIView): + permission_classes = [permissions.IsAuthenticated] + + def get(self, request) -> Response: + return Response(request.user.preferences, status=status.HTTP_200_OK) + + def patch(self, request) -> Response: + new_language = request.data.get("lang") + if new_language is None or new_language not in ( + lang[0] for lang in settings.LANGUAGES + ): + return Response( + {"error": "This language doesn't exist."}, + status=status.HTTP_400_BAD_REQUEST, + ) + request.user.preferences["lang"] = new_language + request.user.save() + return Response({}, status=status.HTTP_200_OK) + + @cache_page(60 * SHORT_CACHE_TTL) @vary_on_cookie @api_view(["GET"]) diff --git a/backend/iam/migrations/0010_user_preferences.py b/backend/iam/migrations/0010_user_preferences.py new file mode 100644 index 000000000..eed321d6b --- /dev/null +++ b/backend/iam/migrations/0010_user_preferences.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.1 on 2024-11-22 01:05 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("iam", "0009_create_allauth_emailaddress_objects"), + ] + + operations = [ + migrations.AddField( + model_name="user", + name="preferences", + field=models.JSONField(default=dict), + ), + ] diff --git a/backend/iam/models.py b/backend/iam/models.py index 61f4c2404..9a8e5f5bc 100644 --- a/backend/iam/models.py +++ b/backend/iam/models.py @@ -342,6 +342,7 @@ class User(AbstractBaseUser, AbstractBaseModel, FolderMixin): first_name = models.CharField(_("first name"), max_length=150, blank=True) email = models.CharField(max_length=100, unique=True) first_login = models.BooleanField(default=True) + preferences = models.JSONField(default=dict) is_sso = models.BooleanField(default=False) is_third_party = models.BooleanField(default=False) is_active = models.BooleanField( diff --git a/backend/iam/views.py b/backend/iam/views.py index db7f7d5e8..ee057dea4 100644 --- a/backend/iam/views.py +++ b/backend/iam/views.py @@ -61,6 +61,7 @@ def post(self, request) -> Response: class CurrentUserView(views.APIView): + # Is this condition really necessary if we have permission_classes = [permissions.IsAuthenticated] ? permission_classes = [permissions.IsAuthenticated] def get(self, request) -> Response: diff --git a/frontend/src/lib/components/SideBar/SideBarFooter.svelte b/frontend/src/lib/components/SideBar/SideBarFooter.svelte index 222db555d..7f65e4adb 100644 --- a/frontend/src/lib/components/SideBar/SideBarFooter.svelte +++ b/frontend/src/lib/components/SideBar/SideBarFooter.svelte @@ -50,6 +50,12 @@ event.preventDefault(); value = event?.target?.value; setLanguageTag(value); + fetch('/api/user-preferences', { + method: 'PATCH', + body: JSON.stringify({ + lang: value + }) + }); // sessionStorage.setItem('lang', value); setCookie('ciso_lang', value); window.location.reload(); diff --git a/frontend/src/lib/utils/helpers.ts b/frontend/src/lib/utils/helpers.ts index 57a134484..b0d5b91aa 100644 --- a/frontend/src/lib/utils/helpers.ts +++ b/frontend/src/lib/utils/helpers.ts @@ -60,7 +60,7 @@ export function formatScoreValue(value: number, max_score: number, fullDonut = f } export function getSecureRedirect(url: any): string { - const SECURE_REDIRECT_URL_REGEX = /^\/\w+/; + const SECURE_REDIRECT_URL_REGEX = /^\/\w*/; return typeof url === 'string' && SECURE_REDIRECT_URL_REGEX.test(url) ? url : ''; } diff --git a/frontend/src/routes/(app)/+page.server.ts b/frontend/src/routes/(app)/+page.server.ts index d139b4b57..93ebc0f16 100644 --- a/frontend/src/routes/(app)/+page.server.ts +++ b/frontend/src/routes/(app)/+page.server.ts @@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async () => { - redirect(301, '/analytics'); + redirect(301, '/analytics?refresh=1'); }; diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 0c5ab5392..0ea51b837 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -1,7 +1,6 @@ import { getSecureRedirect } from '$lib/utils/helpers'; import { ALLAUTH_API_URL, BASE_API_URL } from '$lib/utils/constants'; -import { csrfToken } from '$lib/utils/csrf'; import { loginSchema } from '$lib/utils/schemas'; import type { LoginRequestBody } from '$lib/utils/types'; import { fail, redirect, type Actions } from '@sveltejs/kit'; @@ -9,7 +8,6 @@ import { setError, superValidate } from 'sveltekit-superforms'; import { zod } from 'sveltekit-superforms/adapters'; import type { PageServerLoad } from './$types'; import { mfaAuthenticateSchema } from './mfa/utils/schemas'; -import { setFlash } from 'sveltekit-flash-message/server'; interface AuthenticationFlow { id: @@ -117,8 +115,25 @@ export const actions: Actions = { secure: true }); + const preferencesRes = await fetch(`${BASE_API_URL}/user-preferences/`); + const preferences = await preferencesRes.json(); + + const currentLang = cookies.get('ciso_lang') || 'en'; + const preferedLang = preferences.lang; + + if (preferedLang && currentLang !== preferedLang) { + cookies.set('ciso_lang', preferedLang, { + httpOnly: false, + sameSite: 'lax', + path: '/', + secure: true + }); + } + const next = url.searchParams.get('next') || '/'; - redirect(302, getSecureRedirect(next)); + const redirectURL = getSecureRedirect(next) + '?refresh=1'; + [0, 0, 0, 0, 0].forEach(() => console.log(redirectURL)); + redirect(302, redirectURL); }, mfaAuthenticate: async (event) => { const formData = await event.request.formData(); diff --git a/frontend/src/routes/+layout.svelte b/frontend/src/routes/+layout.svelte index fc51d8241..51b1a7cc2 100644 --- a/frontend/src/routes/+layout.svelte +++ b/frontend/src/routes/+layout.svelte @@ -2,7 +2,7 @@ // Most of your app wide CSS should be put in this file import '../app.postcss'; import '@fortawesome/fontawesome-free/css/all.min.css'; - import ParaglideSvelte from './ParaglideJsProvider.svelte'; + import { browser } from '$app/environment'; import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floating-ui/dom'; @@ -77,6 +77,11 @@ createModal: { ref: CreateModal }, deleteConfirmModal: { ref: DeleteConfirmModal } }; + + $: if (browser && $page.url.searchParams.has('refresh')) { + $page.url.searchParams.delete('refresh'); + window.location.href = $page.url.href; + } diff --git a/frontend/src/routes/api/user-preferences/+server.ts b/frontend/src/routes/api/user-preferences/+server.ts new file mode 100644 index 000000000..fbbf7ade2 --- /dev/null +++ b/frontend/src/routes/api/user-preferences/+server.ts @@ -0,0 +1,36 @@ +import { BASE_API_URL } from '$lib/utils/constants'; +import type { RequestHandler } from './$types'; + +export const GET: RequestHandler = async ({ fetch, request }) => { + const endpoint = `${BASE_API_URL}/user-preferences/`; + const req = await fetch(endpoint); + const status = await req.status; + const responseData = await req.json(); + + return new Response(JSON.stringify(responseData), { + status: status, + headers: { + 'Content-Type': 'application/json' + } + }); +}; + +export const PATCH: RequestHandler = async ({ fetch, request }) => { + const newPreferences = await request.json(); + const requestInitOptions: RequestInit = { + method: 'PATCH', + body: JSON.stringify(newPreferences) + }; + + const endpoint = `${BASE_API_URL}/user-preferences/`; + const req = await fetch(endpoint, requestInitOptions); + const status = await req.status; + const responseData = await req.text(); + + return new Response(responseData, { + status: status, + headers: { + 'Content-Type': 'application/json' + } + }); +}; From 29aaf5250fd5cf46450eab18a295eb00f975c69b Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 22 Nov 2024 03:13:07 +0100 Subject: [PATCH 02/43] Attempt to fix migration issues Remove useless prints --- ...0010_user_preferences.py => 0009_user_preferences.py} | 9 +++++---- ...ts.py => 0010_create_allauth_emailaddress_objects.py} | 4 +--- 2 files changed, 6 insertions(+), 7 deletions(-) rename backend/iam/migrations/{0010_user_preferences.py => 0009_user_preferences.py} (56%) rename backend/iam/migrations/{0009_create_allauth_emailaddress_objects.py => 0010_create_allauth_emailaddress_objects.py} (93%) diff --git a/backend/iam/migrations/0010_user_preferences.py b/backend/iam/migrations/0009_user_preferences.py similarity index 56% rename from backend/iam/migrations/0010_user_preferences.py rename to backend/iam/migrations/0009_user_preferences.py index eed321d6b..0a668764e 100644 --- a/backend/iam/migrations/0010_user_preferences.py +++ b/backend/iam/migrations/0009_user_preferences.py @@ -1,17 +1,18 @@ -# Generated by Django 5.1.1 on 2024-11-22 01:05 +# Generated by Django 5.1.1 on 2024-11-22 01:25 from django.db import migrations, models class Migration(migrations.Migration): + dependencies = [ - ("iam", "0009_create_allauth_emailaddress_objects"), + ('iam', '0008_user_is_third_party'), ] operations = [ migrations.AddField( - model_name="user", - name="preferences", + model_name='user', + name='preferences', field=models.JSONField(default=dict), ), ] diff --git a/backend/iam/migrations/0009_create_allauth_emailaddress_objects.py b/backend/iam/migrations/0010_create_allauth_emailaddress_objects.py similarity index 93% rename from backend/iam/migrations/0009_create_allauth_emailaddress_objects.py rename to backend/iam/migrations/0010_create_allauth_emailaddress_objects.py index e2d220c2b..d21f71aa6 100644 --- a/backend/iam/migrations/0009_create_allauth_emailaddress_objects.py +++ b/backend/iam/migrations/0010_create_allauth_emailaddress_objects.py @@ -2,7 +2,6 @@ from django.db import migrations - def create_emailaddress_objects(apps, schema_editor): try: from allauth.account.models import EmailAddress @@ -18,10 +17,9 @@ def create_emailaddress_objects(apps, schema_editor): finally: pass - class Migration(migrations.Migration): dependencies = [ - ("iam", "0008_user_is_third_party"), + ("iam", "0009_user_preferences"), ] operations = [ From 26e76694968f59649777d12a135e440a7e6247aa Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 22 Nov 2024 04:01:36 +0100 Subject: [PATCH 03/43] Formatter --- backend/iam/migrations/0009_user_preferences.py | 7 +++---- .../migrations/0010_create_allauth_emailaddress_objects.py | 2 ++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/backend/iam/migrations/0009_user_preferences.py b/backend/iam/migrations/0009_user_preferences.py index 0a668764e..3766b21cc 100644 --- a/backend/iam/migrations/0009_user_preferences.py +++ b/backend/iam/migrations/0009_user_preferences.py @@ -4,15 +4,14 @@ class Migration(migrations.Migration): - dependencies = [ - ('iam', '0008_user_is_third_party'), + ("iam", "0008_user_is_third_party"), ] operations = [ migrations.AddField( - model_name='user', - name='preferences', + model_name="user", + name="preferences", field=models.JSONField(default=dict), ), ] diff --git a/backend/iam/migrations/0010_create_allauth_emailaddress_objects.py b/backend/iam/migrations/0010_create_allauth_emailaddress_objects.py index d21f71aa6..c1a02e9de 100644 --- a/backend/iam/migrations/0010_create_allauth_emailaddress_objects.py +++ b/backend/iam/migrations/0010_create_allauth_emailaddress_objects.py @@ -2,6 +2,7 @@ from django.db import migrations + def create_emailaddress_objects(apps, schema_editor): try: from allauth.account.models import EmailAddress @@ -17,6 +18,7 @@ def create_emailaddress_objects(apps, schema_editor): finally: pass + class Migration(migrations.Migration): dependencies = [ ("iam", "0009_user_preferences"), From 4068c0b7a9fdb6b38952e3ac7d4dd1bfd5bf909b Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 22 Nov 2024 10:44:25 +0100 Subject: [PATCH 04/43] Copy conflicts solution from main branch --- .../0037_appliedcontrol_priority.py | 22 +++++++++++++++++++ ..._disaster_recovery_objectives_and_more.py} | 14 ++---------- 2 files changed, 24 insertions(+), 12 deletions(-) create mode 100644 backend/core/migrations/0037_appliedcontrol_priority.py rename backend/core/migrations/{0037_asset_disaster_recovery_objectives_and_more.py => 0038_asset_disaster_recovery_objectives_and_more.py} (90%) diff --git a/backend/core/migrations/0037_appliedcontrol_priority.py b/backend/core/migrations/0037_appliedcontrol_priority.py new file mode 100644 index 000000000..3f8a97035 --- /dev/null +++ b/backend/core/migrations/0037_appliedcontrol_priority.py @@ -0,0 +1,22 @@ +# Generated by Django 5.1.1 on 2024-11-19 15:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("core", "0036_asset_owner"), + ] + + operations = [ + migrations.AddField( + model_name="appliedcontrol", + name="priority", + field=models.PositiveSmallIntegerField( + blank=True, + choices=[(1, "P1"), (2, "P2"), (3, "P3"), (4, "P4")], + null=True, + verbose_name="Priority", + ), + ), + ] diff --git a/backend/core/migrations/0037_asset_disaster_recovery_objectives_and_more.py b/backend/core/migrations/0038_asset_disaster_recovery_objectives_and_more.py similarity index 90% rename from backend/core/migrations/0037_asset_disaster_recovery_objectives_and_more.py rename to backend/core/migrations/0038_asset_disaster_recovery_objectives_and_more.py index 20657d346..6045b5ff6 100644 --- a/backend/core/migrations/0037_asset_disaster_recovery_objectives_and_more.py +++ b/backend/core/migrations/0038_asset_disaster_recovery_objectives_and_more.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.1 on 2024-11-20 18:29 +# Generated by Django 5.1.1 on 2024-11-22 07:00 import core.validators from django.db import migrations, models @@ -6,7 +6,7 @@ class Migration(migrations.Migration): dependencies = [ - ("core", "0036_asset_owner"), + ("core", "0037_appliedcontrol_priority"), ] operations = [ @@ -96,14 +96,4 @@ class Migration(migrations.Migration): verbose_name="Security objectives", ), ), - migrations.AddField( - model_name="appliedcontrol", - name="priority", - field=models.PositiveSmallIntegerField( - blank=True, - choices=[(1, "P1"), (2, "P2"), (3, "P3"), (4, "P4")], - null=True, - verbose_name="Priority", - ), - ), ] From 3b24a847b4cefd7fb8138c0ee4014bfc58b72326 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 22 Nov 2024 11:22:21 +0100 Subject: [PATCH 05/43] Attempt to fix startup tests Fix javascript keyword argument syntax Fix missing function call Remove debug console.log --- .github/workflows/startup-tests.yml | 4 ++-- .../(authentication)/login/+page.server.ts | 1 - frontend/tests/functional/startup.test.ts | 2 +- frontend/tests/utils/base-page.ts | 23 +++++++++++++++++-- 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/.github/workflows/startup-tests.yml b/.github/workflows/startup-tests.yml index ad27fc444..1b3f47f42 100644 --- a/.github/workflows/startup-tests.yml +++ b/.github/workflows/startup-tests.yml @@ -136,7 +136,7 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) - server_reponse='{"type":"redirect","status":302,"location":""}' + server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' if [[ "$response" == "$server_reponse" ]]; then echo "Success" exit 0 @@ -264,7 +264,7 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) - server_reponse='{"type":"redirect","status":302,"location":""}' + server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' if [[ "$response" == "$server_reponse" ]]; then echo "Success" exit 0 diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 0ea51b837..214967cc9 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -132,7 +132,6 @@ export const actions: Actions = { const next = url.searchParams.get('next') || '/'; const redirectURL = getSecureRedirect(next) + '?refresh=1'; - [0, 0, 0, 0, 0].forEach(() => console.log(redirectURL)); redirect(302, redirectURL); }, mfaAuthenticate: async (event) => { diff --git a/frontend/tests/functional/startup.test.ts b/frontend/tests/functional/startup.test.ts index a56fee59e..26945e1df 100644 --- a/frontend/tests/functional/startup.test.ts +++ b/frontend/tests/functional/startup.test.ts @@ -5,7 +5,7 @@ test('startup tests', async ({ loginPage, analyticsPage, page }) => { await page.goto('/'); await loginPage.hasUrl(1); await loginPage.login(); - await analyticsPage.hasUrl(); + await analyticsPage.hasUrl(false); }); await test.step('proper redirection to the analytics page after login', async () => { diff --git a/frontend/tests/utils/base-page.ts b/frontend/tests/utils/base-page.ts index 0a6505446..3994fa6e0 100644 --- a/frontend/tests/utils/base-page.ts +++ b/frontend/tests/utils/base-page.ts @@ -1,5 +1,15 @@ import { expect, type Locator, type Page } from './test-utils.js'; +/** + * Escape the characters of `string` to safely insert it in a regex. + * + * @param {string} string - The string to escape. + * @returns {string} The escaped string. +*/ +function escapeRegex(string: string): string { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); +} + export abstract class BasePage { readonly url: string; readonly name: string | RegExp; @@ -28,8 +38,17 @@ export abstract class BasePage { await expect.soft(this.pageTitle).toHaveText(title); } - async hasUrl() { - await expect(this.page).toHaveURL(this.url); + /** + * Check whether the browser's URL match the `this.url` value. + * + * @param {boolean} [strict=true] - Determines the URL matching mode. + * If `strict` is `true`, the function checks if `this.url` is strictly equal to the browser's URL. + * Otherwise, it checks if the browser's URL starts with `this.url`. + * @returns {void} + */ + async hasUrl(strict: boolean=true) { + const URLPattern = strict ? this.url : new RegExp(escapeRegex(this.url) + ".*"); + await expect(this.page).toHaveURL(URLPattern); } async hasBreadcrumbPath(paths: (string | RegExp)[], fullPath = true, origin = 'Home') { From acdbba6caf3fc747f1f9eccc34c732826ee16530 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 22 Nov 2024 18:09:54 +0100 Subject: [PATCH 06/43] Formatter --- frontend/tests/utils/base-page.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/frontend/tests/utils/base-page.ts b/frontend/tests/utils/base-page.ts index 3994fa6e0..e50b607b2 100644 --- a/frontend/tests/utils/base-page.ts +++ b/frontend/tests/utils/base-page.ts @@ -5,7 +5,7 @@ import { expect, type Locator, type Page } from './test-utils.js'; * * @param {string} string - The string to escape. * @returns {string} The escaped string. -*/ + */ function escapeRegex(string: string): string { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } @@ -41,13 +41,13 @@ export abstract class BasePage { /** * Check whether the browser's URL match the `this.url` value. * - * @param {boolean} [strict=true] - Determines the URL matching mode. + * @param {boolean} [strict=true] - Determines the URL matching mode. * If `strict` is `true`, the function checks if `this.url` is strictly equal to the browser's URL. * Otherwise, it checks if the browser's URL starts with `this.url`. * @returns {void} - */ - async hasUrl(strict: boolean=true) { - const URLPattern = strict ? this.url : new RegExp(escapeRegex(this.url) + ".*"); + */ + async hasUrl(strict: boolean = true) { + const URLPattern = strict ? this.url : new RegExp(escapeRegex(this.url) + '.*'); await expect(this.page).toHaveURL(URLPattern); } From 18f898be41c1df7e5259e37ab1a02218b6100c92 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Sat, 23 Nov 2024 01:34:47 +0100 Subject: [PATCH 07/43] Attempt to fix startup tests --- enterprise/frontend/src/routes/+layout.svelte | 6 ++++++ frontend/tests/functional/startup.test.ts | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/enterprise/frontend/src/routes/+layout.svelte b/enterprise/frontend/src/routes/+layout.svelte index 80a90947f..56d4c5c56 100644 --- a/enterprise/frontend/src/routes/+layout.svelte +++ b/enterprise/frontend/src/routes/+layout.svelte @@ -3,6 +3,7 @@ import '../app.postcss'; import '@fortawesome/fontawesome-free/css/all.min.css'; import ParaglideSvelte from './ParaglideJsProvider.svelte'; + import { browser } from '$app/environment'; import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floating-ui/dom'; @@ -97,6 +98,11 @@ ? `data:${$faviconB64.mimeType};base64, ${$faviconB64.data}` : favicon; }); + + $: if (browser && $page.url.searchParams.has('refresh')) { + $page.url.searchParams.delete('refresh'); + window.location.href = $page.url.href; + } diff --git a/frontend/tests/functional/startup.test.ts b/frontend/tests/functional/startup.test.ts index 26945e1df..1dc86a631 100644 --- a/frontend/tests/functional/startup.test.ts +++ b/frontend/tests/functional/startup.test.ts @@ -9,7 +9,7 @@ test('startup tests', async ({ loginPage, analyticsPage, page }) => { }); await test.step('proper redirection to the analytics page after login', async () => { - await analyticsPage.hasUrl(); + await analyticsPage.hasUrl(false); await analyticsPage.hasTitle(); }); }); From 168b56c8713792eef160daa512b08f2e7f362d04 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Mon, 25 Nov 2024 12:25:36 +0100 Subject: [PATCH 08/43] Log language error in preferenc modification --- backend/core/views.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/core/views.py b/backend/core/views.py index 49ffb1ad0..8fb553edd 100644 --- a/backend/core/views.py +++ b/backend/core/views.py @@ -1546,6 +1546,9 @@ def patch(self, request) -> Response: if new_language is None or new_language not in ( lang[0] for lang in settings.LANGUAGES ): + logger.error( + f"Error in UserPreferencesView: new_language={new_language} available languages={[lang[0] for lang in settings.LANGUAGES]}" + ) return Response( {"error": "This language doesn't exist."}, status=status.HTTP_400_BAD_REQUEST, From 9f4898172144d45e4aeae5ebde0a4baf3cdb6b45 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Mon, 25 Nov 2024 12:27:44 +0100 Subject: [PATCH 09/43] Remove useless json deserialization --- frontend/src/routes/api/user-preferences/+server.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/routes/api/user-preferences/+server.ts b/frontend/src/routes/api/user-preferences/+server.ts index fbbf7ade2..3c58fdc79 100644 --- a/frontend/src/routes/api/user-preferences/+server.ts +++ b/frontend/src/routes/api/user-preferences/+server.ts @@ -16,10 +16,10 @@ export const GET: RequestHandler = async ({ fetch, request }) => { }; export const PATCH: RequestHandler = async ({ fetch, request }) => { - const newPreferences = await request.json(); + const newPreferences = await request.text(); const requestInitOptions: RequestInit = { method: 'PATCH', - body: JSON.stringify(newPreferences) + body: newPreferences }; const endpoint = `${BASE_API_URL}/user-preferences/`; From bcf7c682583f7edca7b57875d0433ec95080e7a3 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Mon, 25 Nov 2024 16:13:07 +0100 Subject: [PATCH 10/43] Fix wrong language code --- backend/ciso_assistant/settings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/ciso_assistant/settings.py b/backend/ciso_assistant/settings.py index b0e821d19..b48209166 100644 --- a/backend/ciso_assistant/settings.py +++ b/backend/ciso_assistant/settings.py @@ -303,7 +303,7 @@ def set_ciso_assistant_url(_, __, event_dict): ("es", "Spanish"), ("de", "German"), ("it", "Italian"), - ("nd", "Dutch"), + ("nl", "Dutch"), ("pl", "Polish"), ("pt", "Portuguese"), ("ar", "Arabic"), From 8cd2d310e8bc58076aa5a267a93187522bd96d8e Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 03:18:20 +0100 Subject: [PATCH 11/43] Limit functional tests for faster debug --- .github/workflows/functional-tests.yml | 198 ++++++++++++------------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index 1cb1db33b..bd5cc4dd8 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -108,7 +108,7 @@ jobs: run: pnpm run build - name: Run tests with browser ${{ matrix.playwright-browser }} working-directory: ${{ env.frontend-directory }} - run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} + run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} -g "user can set his password" env: CI: true - uses: actions/upload-artifact@v4 @@ -121,104 +121,104 @@ jobs: ${{ env.frontend-directory }}/tests/reports/ retention-days: 5 - enterprise-functional-tests: - runs-on: ubuntu-20.04 + # enterprise-functional-tests: + # runs-on: ubuntu-20.04 - services: - postgres: - image: postgres:14.12 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: postgres - ports: ["5432:5432"] - options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 - mailhog: - image: mailhog/mailhog - ports: ["1025:1025", "8025:8025"] + # services: + # postgres: + # image: postgres:14.12 + # env: + # POSTGRES_USER: postgres + # POSTGRES_PASSWORD: postgres + # POSTGRES_DB: postgres + # ports: ["5432:5432"] + # options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + # mailhog: + # image: mailhog/mailhog + # ports: ["1025:1025", "8025:8025"] - strategy: - max-parallel: 4 - matrix: - python-version: ["3.11"] - playwright-browser: ["chromium"] + # strategy: + # max-parallel: 4 + # matrix: + # python-version: ["3.11"] + # playwright-browser: ["chromium"] - steps: - - uses: actions/checkout@v4 - - name: Set up python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - cache: "pip" - - uses: actions/setup-node@v4 - with: - node-version: lts/* - - name: Install Poetry - uses: snok/install-poetry@v1 - with: - virtualenvs-create: false - installer-parallel: true - - name: Install backend requirements - working-directory: ${{ env.backend-directory }} - run: poetry install - - name: Install enterprise backend - working-directory: ${{ env.enterprise-backend-directory }} - run: poetry install - - name: Build enterprise frontend - working-directory: ${{ env.enterprise-frontend-directory }} - run: make - - name: Install Playwright browser ${{ matrix.playwright-browser }} - working-directory: ${{ env.enterprise-frontend-build-directory }} - run: pnpm exec playwright install --with-deps ${{ matrix.playwright-browser }} - - name: Create frontend environment variables file - working-directory: ${{ env.enterprise-frontend-build-directory }} - run: | - touch .env - echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env - - name: Create backend environment variables file - working-directory: ${{ env.backend-directory }} - run: | - touch .env - echo LOG_LEVEL=DEBUG >> .env - echo LOG_OUTFILE=ciso-assistant.log >> .env - echo DJANGO_DEBUG=True >> .env - echo DJANGO_SUPERUSER_EMAIL=admin@tests.com >> .env - echo DJANGO_SUPERUSER_PASSWORD=1234 >> .env - echo POSTGRES_NAME=postgres >> .env - echo POSTGRES_USER=postgres >> .env - echo POSTGRES_PASSWORD=postgres >> .env - echo DB_HOST=localhost >> .env - echo CISO_ASSISTANT_SUPERUSER_EMAIL='' >> .env - echo CISO_ASSISTANT_URL=http://localhost:4173 >> .env - echo DEFAULT_FROM_EMAIL='ciso-assistant@tests.net' >> .env - echo EMAIL_HOST=localhost >> .env - echo EMAIL_HOST_USER=user@tests.com >> .env - echo EMAIL_HOST_PASSWORD=password >> .env - echo EMAIL_PORT=1025 >> .env - echo DJANGO_SETTINGS_MODULE=enterprise_core.settings >> .env - echo LICENSE_SEATS=999 >> .env - - name: Run migrations - working-directory: ${{ env.backend-directory }} - run: | - export $(grep -v '^#' .env | xargs) - poetry run python manage.py migrate --settings=${{ env.enterprise-backend-settings-module }} - - name: Start test server - working-directory: ${{ env.backend-directory }} - run: | - export $(grep -v '^#' .env | xargs) - poetry run python manage.py createsuperuser --noinput --settings=${{ env.enterprise-backend-settings-module }} - nohup poetry run python manage.py runserver --settings=${{ env.enterprise-backend-settings-module }} & - - name: Run tests with browser ${{ matrix.playwright-browser }} - working-directory: ${{ env.enterprise-frontend-build-directory }} - run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} - env: - CI: true - - uses: actions/upload-artifact@v4 - if: always() - with: - name: enterprise-functional-tests-report-${{ matrix.playwright-browser }} - path: | - ${{ env.backend-directory }}/*.log - ${{ env.enterprise-frontend-build-directory }}/tests/results/ - ${{ env.enterprise-frontend-build-directory }}/tests/reports/ - retention-days: 5 + # steps: + # - uses: actions/checkout@v4 + # - name: Set up python ${{ matrix.python-version }} + # uses: actions/setup-python@v5 + # with: + # python-version: ${{ matrix.python-version }} + # cache: "pip" + # - uses: actions/setup-node@v4 + # with: + # node-version: lts/* + # - name: Install Poetry + # uses: snok/install-poetry@v1 + # with: + # virtualenvs-create: false + # installer-parallel: true + # - name: Install backend requirements + # working-directory: ${{ env.backend-directory }} + # run: poetry install + # - name: Install enterprise backend + # working-directory: ${{ env.enterprise-backend-directory }} + # run: poetry install + # - name: Build enterprise frontend + # working-directory: ${{ env.enterprise-frontend-directory }} + # run: make + # - name: Install Playwright browser ${{ matrix.playwright-browser }} + # working-directory: ${{ env.enterprise-frontend-build-directory }} + # run: pnpm exec playwright install --with-deps ${{ matrix.playwright-browser }} + # - name: Create frontend environment variables file + # working-directory: ${{ env.enterprise-frontend-build-directory }} + # run: | + # touch .env + # echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env + # - name: Create backend environment variables file + # working-directory: ${{ env.backend-directory }} + # run: | + # touch .env + # echo LOG_LEVEL=DEBUG >> .env + # echo LOG_OUTFILE=ciso-assistant.log >> .env + # echo DJANGO_DEBUG=True >> .env + # echo DJANGO_SUPERUSER_EMAIL=admin@tests.com >> .env + # echo DJANGO_SUPERUSER_PASSWORD=1234 >> .env + # echo POSTGRES_NAME=postgres >> .env + # echo POSTGRES_USER=postgres >> .env + # echo POSTGRES_PASSWORD=postgres >> .env + # echo DB_HOST=localhost >> .env + # echo CISO_ASSISTANT_SUPERUSER_EMAIL='' >> .env + # echo CISO_ASSISTANT_URL=http://localhost:4173 >> .env + # echo DEFAULT_FROM_EMAIL='ciso-assistant@tests.net' >> .env + # echo EMAIL_HOST=localhost >> .env + # echo EMAIL_HOST_USER=user@tests.com >> .env + # echo EMAIL_HOST_PASSWORD=password >> .env + # echo EMAIL_PORT=1025 >> .env + # echo DJANGO_SETTINGS_MODULE=enterprise_core.settings >> .env + # echo LICENSE_SEATS=999 >> .env + # - name: Run migrations + # working-directory: ${{ env.backend-directory }} + # run: | + # export $(grep -v '^#' .env | xargs) + # poetry run python manage.py migrate --settings=${{ env.enterprise-backend-settings-module }} + # - name: Start test server + # working-directory: ${{ env.backend-directory }} + # run: | + # export $(grep -v '^#' .env | xargs) + # poetry run python manage.py createsuperuser --noinput --settings=${{ env.enterprise-backend-settings-module }} + # nohup poetry run python manage.py runserver --settings=${{ env.enterprise-backend-settings-module }} & + # - name: Run tests with browser ${{ matrix.playwright-browser }} + # working-directory: ${{ env.enterprise-frontend-build-directory }} + # run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} + # env: + # CI: true + # - uses: actions/upload-artifact@v4 + # if: always() + # with: + # name: enterprise-functional-tests-report-${{ matrix.playwright-browser }} + # path: | + # ${{ env.backend-directory }}/*.log + # ${{ env.enterprise-frontend-build-directory }}/tests/results/ + # ${{ env.enterprise-frontend-build-directory }}/tests/reports/ + # retention-days: 5 From fadda69248e58a0740c2cc164d29f3f0219c660c Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 03:56:00 +0100 Subject: [PATCH 12/43] Sleep before populating database --- frontend/tests/utils/test-utils.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/tests/utils/test-utils.ts b/frontend/tests/utils/test-utils.ts index 2f75a780c..3474d8214 100644 --- a/frontend/tests/utils/test-utils.ts +++ b/frontend/tests/utils/test-utils.ts @@ -275,6 +275,11 @@ export const test = base.extend({ populateDatabase: async ({ pages, loginPage, sideBar, data }, use) => { test.slow(); + const start = new Date(); + await new Promise((resolve) => setTimeout(resolve, 3000)); + const end = new Date(); + const diff = end - start + console.log(`Sleep time = ${diff}`); await loginPage.goto(); await loginPage.login(); for (const [page, pageData] of Object.entries(data)) { From f3dd0f9ca5974431f09854f556e335e4d8218a15 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 04:24:34 +0100 Subject: [PATCH 13/43] Add requestfailed listener --- frontend/tests/functional/user-permissions.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/tests/functional/user-permissions.test.ts b/frontend/tests/functional/user-permissions.test.ts index 412cb716b..7293243c7 100644 --- a/frontend/tests/functional/user-permissions.test.ts +++ b/frontend/tests/functional/user-permissions.test.ts @@ -33,6 +33,10 @@ Object.entries(userGroups).forEach(([userGroup, userGroupData]) => { mailer, page }) => { + console.log("EXPECTED TEST EXECUTED"); + page.on('requestfailed', request => { + console.log(request.url() + ' ' + request.failure().errorText); + }); await usersPage.goto(); await usersPage.editItemButton(vars.user.email).click(); await usersPage.form.fill({ From ea8580b478dce9a6b3ee1722938487a27cc856f9 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 04:37:02 +0100 Subject: [PATCH 14/43] Fix misplaced requestfailed listener --- frontend/tests/functional/user-permissions.test.ts | 4 ---- frontend/tests/utils/test-utils.ts | 9 ++++++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/frontend/tests/functional/user-permissions.test.ts b/frontend/tests/functional/user-permissions.test.ts index 7293243c7..412cb716b 100644 --- a/frontend/tests/functional/user-permissions.test.ts +++ b/frontend/tests/functional/user-permissions.test.ts @@ -33,10 +33,6 @@ Object.entries(userGroups).forEach(([userGroup, userGroupData]) => { mailer, page }) => { - console.log("EXPECTED TEST EXECUTED"); - page.on('requestfailed', request => { - console.log(request.url() + ' ' + request.failure().errorText); - }); await usersPage.goto(); await usersPage.editItemButton(vars.user.email).click(); await usersPage.form.fill({ diff --git a/frontend/tests/utils/test-utils.ts b/frontend/tests/utils/test-utils.ts index 3474d8214..3021598d6 100644 --- a/frontend/tests/utils/test-utils.ts +++ b/frontend/tests/utils/test-utils.ts @@ -273,8 +273,14 @@ export const test = base.extend({ data: { ...testData }, - populateDatabase: async ({ pages, loginPage, sideBar, data }, use) => { + populateDatabase: async ({ pages, loginPage, sideBar, data, browser }, use) => { test.slow(); + + const context = await browser.newContext(); + context.on('requestfailed', request => { + console.log('[REQUEST_FAILED] ' + request.url() + ' ' + request.failure().errorText); + }); + const start = new Date(); await new Promise((resolve) => setTimeout(resolve, 3000)); const end = new Date(); @@ -290,6 +296,7 @@ export const test = base.extend({ 'dependency' in pageData ? pageData.dependency : null ); } + await context.close(); await sideBar.logout(); await use(); } From c097a0e4c24c9296ef0dce5ea570948da329fe65 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 04:49:36 +0100 Subject: [PATCH 15/43] Remove redirect query paramete --- frontend/src/routes/(app)/+page.server.ts | 2 +- frontend/src/routes/(authentication)/login/+page.server.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/routes/(app)/+page.server.ts b/frontend/src/routes/(app)/+page.server.ts index 93ebc0f16..d139b4b57 100644 --- a/frontend/src/routes/(app)/+page.server.ts +++ b/frontend/src/routes/(app)/+page.server.ts @@ -2,5 +2,5 @@ import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async () => { - redirect(301, '/analytics?refresh=1'); + redirect(301, '/analytics'); }; diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 214967cc9..78e646c6f 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -131,7 +131,7 @@ export const actions: Actions = { } const next = url.searchParams.get('next') || '/'; - const redirectURL = getSecureRedirect(next) + '?refresh=1'; + const redirectURL = getSecureRedirect(next) + ''; redirect(302, redirectURL); }, mfaAuthenticate: async (event) => { From 7e6a240a6bbcda45671e63f4612c59f610b658fa Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 05:12:27 +0100 Subject: [PATCH 16/43] Remove redirection query parameter for CI tests --- .github/workflows/functional-tests.yml | 1 + frontend/src/lib/utils/constants.ts | 2 ++ frontend/src/routes/(app)/+page.server.ts | 5 ++++- .../routes/(authentication)/login/+page.server.ts | 4 ++-- frontend/tests/utils/test-utils.ts | 14 +------------- 5 files changed, 10 insertions(+), 16 deletions(-) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index bd5cc4dd8..fda850435 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -70,6 +70,7 @@ jobs: run: | touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env + echo CI_TEST=1 >> .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} diff --git a/frontend/src/lib/utils/constants.ts b/frontend/src/lib/utils/constants.ts index 3a4843a96..6a3d66317 100644 --- a/frontend/src/lib/utils/constants.ts +++ b/frontend/src/lib/utils/constants.ts @@ -6,6 +6,8 @@ export const BASE_API_URL = `${ : 'http://localhost:8000/api' }`; +export const CI_TEST: boolean = Object.hasOwn(env, 'CI_TEST'); + export const ALLAUTH_API_URL = `${BASE_API_URL}/_allauth/app/v1`; export const BACKEND_API_EXPOSED_URL = `${ diff --git a/frontend/src/routes/(app)/+page.server.ts b/frontend/src/routes/(app)/+page.server.ts index d139b4b57..f74b79b59 100644 --- a/frontend/src/routes/(app)/+page.server.ts +++ b/frontend/src/routes/(app)/+page.server.ts @@ -1,6 +1,9 @@ import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; +import { CI_TEST } from '$lib/utils/constants'; + +const redirectURL = CI_TEST ? '/analytics' : '/analytics?refresh=1'; export const load: PageServerLoad = async () => { - redirect(301, '/analytics'); + redirect(301, redirectURL); }; diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 78e646c6f..00606b48d 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -1,6 +1,6 @@ import { getSecureRedirect } from '$lib/utils/helpers'; -import { ALLAUTH_API_URL, BASE_API_URL } from '$lib/utils/constants'; +import { ALLAUTH_API_URL, BASE_API_URL, CI_TEST } from '$lib/utils/constants'; import { loginSchema } from '$lib/utils/schemas'; import type { LoginRequestBody } from '$lib/utils/types'; import { fail, redirect, type Actions } from '@sveltejs/kit'; @@ -131,7 +131,7 @@ export const actions: Actions = { } const next = url.searchParams.get('next') || '/'; - const redirectURL = getSecureRedirect(next) + ''; + const redirectURL = getSecureRedirect(next) + (CI_TEST ? '' : '?refresh=1'); redirect(302, redirectURL); }, mfaAuthenticate: async (event) => { diff --git a/frontend/tests/utils/test-utils.ts b/frontend/tests/utils/test-utils.ts index 3021598d6..2f75a780c 100644 --- a/frontend/tests/utils/test-utils.ts +++ b/frontend/tests/utils/test-utils.ts @@ -273,19 +273,8 @@ export const test = base.extend({ data: { ...testData }, - populateDatabase: async ({ pages, loginPage, sideBar, data, browser }, use) => { + populateDatabase: async ({ pages, loginPage, sideBar, data }, use) => { test.slow(); - - const context = await browser.newContext(); - context.on('requestfailed', request => { - console.log('[REQUEST_FAILED] ' + request.url() + ' ' + request.failure().errorText); - }); - - const start = new Date(); - await new Promise((resolve) => setTimeout(resolve, 3000)); - const end = new Date(); - const diff = end - start - console.log(`Sleep time = ${diff}`); await loginPage.goto(); await loginPage.login(); for (const [page, pageData] of Object.entries(data)) { @@ -296,7 +285,6 @@ export const test = base.extend({ 'dependency' in pageData ? pageData.dependency : null ); } - await context.close(); await sideBar.logout(); await use(); } From f89ed6cb76b6f0f2cf533360e61f397f036a4aa6 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 05:23:59 +0100 Subject: [PATCH 17/43] Add some debug logging --- .github/workflows/functional-tests.yml | 2 ++ frontend/src/routes/(app)/+page.server.ts | 2 ++ frontend/src/routes/(authentication)/login/+page.server.ts | 1 + 3 files changed, 5 insertions(+) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index fda850435..f0762ff74 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -71,6 +71,8 @@ jobs: touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env echo CI_TEST=1 >> .env + echo "WOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOW" + cat .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} diff --git a/frontend/src/routes/(app)/+page.server.ts b/frontend/src/routes/(app)/+page.server.ts index f74b79b59..b180ce9b3 100644 --- a/frontend/src/routes/(app)/+page.server.ts +++ b/frontend/src/routes/(app)/+page.server.ts @@ -3,7 +3,9 @@ import type { PageServerLoad } from './$types'; import { CI_TEST } from '$lib/utils/constants'; const redirectURL = CI_TEST ? '/analytics' : '/analytics?refresh=1'; +console.log(`[NEW_REDIRECT:1] ${CI_TEST}`); export const load: PageServerLoad = async () => { + console.log(`[NEW_REDIRECT:2] ${CI_TEST}`); redirect(301, redirectURL); }; diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 00606b48d..6df6a6dde 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -132,6 +132,7 @@ export const actions: Actions = { const next = url.searchParams.get('next') || '/'; const redirectURL = getSecureRedirect(next) + (CI_TEST ? '' : '?refresh=1'); + console.log(`[NEW_REDIRECT:3] ${redirectURL}`); redirect(302, redirectURL); }, mfaAuthenticate: async (event) => { From f6c62ed46c05245ea99bfd998807d39bfc30a5a8 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 05:41:13 +0100 Subject: [PATCH 18/43] Fix non-working environment variable import --- frontend/src/lib/utils/constants.ts | 2 -- frontend/src/lib/utils/env_constants.ts | 3 +++ frontend/src/routes/(app)/+page.server.ts | 6 +++--- frontend/src/routes/(authentication)/login/+page.server.ts | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 frontend/src/lib/utils/env_constants.ts diff --git a/frontend/src/lib/utils/constants.ts b/frontend/src/lib/utils/constants.ts index 6a3d66317..3a4843a96 100644 --- a/frontend/src/lib/utils/constants.ts +++ b/frontend/src/lib/utils/constants.ts @@ -6,8 +6,6 @@ export const BASE_API_URL = `${ : 'http://localhost:8000/api' }`; -export const CI_TEST: boolean = Object.hasOwn(env, 'CI_TEST'); - export const ALLAUTH_API_URL = `${BASE_API_URL}/_allauth/app/v1`; export const BACKEND_API_EXPOSED_URL = `${ diff --git a/frontend/src/lib/utils/env_constants.ts b/frontend/src/lib/utils/env_constants.ts new file mode 100644 index 000000000..ac876fe77 --- /dev/null +++ b/frontend/src/lib/utils/env_constants.ts @@ -0,0 +1,3 @@ +import * as env from '$env/static/private'; + +export const CI_TEST: boolean = Object.hasOwn(env, 'CI_TEST'); diff --git a/frontend/src/routes/(app)/+page.server.ts b/frontend/src/routes/(app)/+page.server.ts index b180ce9b3..8cd76b570 100644 --- a/frontend/src/routes/(app)/+page.server.ts +++ b/frontend/src/routes/(app)/+page.server.ts @@ -1,11 +1,11 @@ import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; -import { CI_TEST } from '$lib/utils/constants'; +import { CI_TEST } from '$lib/utils/env_constants'; const redirectURL = CI_TEST ? '/analytics' : '/analytics?refresh=1'; -console.log(`[NEW_REDIRECT:1] ${CI_TEST}`); +console.log(`[CI_TEST_VALUE:1] ${CI_TEST}`); export const load: PageServerLoad = async () => { - console.log(`[NEW_REDIRECT:2] ${CI_TEST}`); + console.log(`[CI_TEST_VALUE:2] ${CI_TEST}`); redirect(301, redirectURL); }; diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 6df6a6dde..ff4549dd4 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -1,6 +1,7 @@ import { getSecureRedirect } from '$lib/utils/helpers'; -import { ALLAUTH_API_URL, BASE_API_URL, CI_TEST } from '$lib/utils/constants'; +import { ALLAUTH_API_URL, BASE_API_URL } from '$lib/utils/constants'; +import { CI_TEST } from '$lib/utils/env_constants'; import { loginSchema } from '$lib/utils/schemas'; import type { LoginRequestBody } from '$lib/utils/types'; import { fail, redirect, type Actions } from '@sveltejs/kit'; @@ -132,7 +133,6 @@ export const actions: Actions = { const next = url.searchParams.get('next') || '/'; const redirectURL = getSecureRedirect(next) + (CI_TEST ? '' : '?refresh=1'); - console.log(`[NEW_REDIRECT:3] ${redirectURL}`); redirect(302, redirectURL); }, mfaAuthenticate: async (event) => { From 900f1bb55ae517d164cba8d3e6c3003fb8029736 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 07:04:17 +0100 Subject: [PATCH 19/43] Remove debug logging --- .github/workflows/functional-tests.yml | 2 -- frontend/src/routes/(app)/+page.server.ts | 2 -- 2 files changed, 4 deletions(-) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index f0762ff74..fda850435 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -71,8 +71,6 @@ jobs: touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env echo CI_TEST=1 >> .env - echo "WOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOWOW" - cat .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} diff --git a/frontend/src/routes/(app)/+page.server.ts b/frontend/src/routes/(app)/+page.server.ts index 8cd76b570..914629e00 100644 --- a/frontend/src/routes/(app)/+page.server.ts +++ b/frontend/src/routes/(app)/+page.server.ts @@ -3,9 +3,7 @@ import type { PageServerLoad } from './$types'; import { CI_TEST } from '$lib/utils/env_constants'; const redirectURL = CI_TEST ? '/analytics' : '/analytics?refresh=1'; -console.log(`[CI_TEST_VALUE:1] ${CI_TEST}`); export const load: PageServerLoad = async () => { - console.log(`[CI_TEST_VALUE:2] ${CI_TEST}`); redirect(301, redirectURL); }; From 7e52bd117b6be5c43f786d32ae9869012558b495 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 11:58:32 +0100 Subject: [PATCH 20/43] Precise env_constants utility --- frontend/src/lib/utils/env_constants.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/lib/utils/env_constants.ts b/frontend/src/lib/utils/env_constants.ts index ac876fe77..d9dd784ab 100644 --- a/frontend/src/lib/utils/env_constants.ts +++ b/frontend/src/lib/utils/env_constants.ts @@ -1,3 +1,5 @@ import * as env from '$env/static/private'; +// This file is separate from constant.ts because '$env/static/private' can only be imported on the server-side. + export const CI_TEST: boolean = Object.hasOwn(env, 'CI_TEST'); From abaf58cbf308a37cef12f815a6b6e03658059f71 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 11:59:27 +0100 Subject: [PATCH 21/43] Restablish functional tests --- .github/workflows/functional-tests.yml | 198 ++++++++++++------------- 1 file changed, 99 insertions(+), 99 deletions(-) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index fda850435..cdfc710be 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -109,7 +109,7 @@ jobs: run: pnpm run build - name: Run tests with browser ${{ matrix.playwright-browser }} working-directory: ${{ env.frontend-directory }} - run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} -g "user can set his password" + run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} env: CI: true - uses: actions/upload-artifact@v4 @@ -122,104 +122,104 @@ jobs: ${{ env.frontend-directory }}/tests/reports/ retention-days: 5 - # enterprise-functional-tests: - # runs-on: ubuntu-20.04 + enterprise-functional-tests: + runs-on: ubuntu-20.04 - # services: - # postgres: - # image: postgres:14.12 - # env: - # POSTGRES_USER: postgres - # POSTGRES_PASSWORD: postgres - # POSTGRES_DB: postgres - # ports: ["5432:5432"] - # options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 - # mailhog: - # image: mailhog/mailhog - # ports: ["1025:1025", "8025:8025"] + services: + postgres: + image: postgres:14.12 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: postgres + ports: ["5432:5432"] + options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 + mailhog: + image: mailhog/mailhog + ports: ["1025:1025", "8025:8025"] - # strategy: - # max-parallel: 4 - # matrix: - # python-version: ["3.11"] - # playwright-browser: ["chromium"] + strategy: + max-parallel: 4 + matrix: + python-version: ["3.11"] + playwright-browser: ["chromium"] - # steps: - # - uses: actions/checkout@v4 - # - name: Set up python ${{ matrix.python-version }} - # uses: actions/setup-python@v5 - # with: - # python-version: ${{ matrix.python-version }} - # cache: "pip" - # - uses: actions/setup-node@v4 - # with: - # node-version: lts/* - # - name: Install Poetry - # uses: snok/install-poetry@v1 - # with: - # virtualenvs-create: false - # installer-parallel: true - # - name: Install backend requirements - # working-directory: ${{ env.backend-directory }} - # run: poetry install - # - name: Install enterprise backend - # working-directory: ${{ env.enterprise-backend-directory }} - # run: poetry install - # - name: Build enterprise frontend - # working-directory: ${{ env.enterprise-frontend-directory }} - # run: make - # - name: Install Playwright browser ${{ matrix.playwright-browser }} - # working-directory: ${{ env.enterprise-frontend-build-directory }} - # run: pnpm exec playwright install --with-deps ${{ matrix.playwright-browser }} - # - name: Create frontend environment variables file - # working-directory: ${{ env.enterprise-frontend-build-directory }} - # run: | - # touch .env - # echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env - # - name: Create backend environment variables file - # working-directory: ${{ env.backend-directory }} - # run: | - # touch .env - # echo LOG_LEVEL=DEBUG >> .env - # echo LOG_OUTFILE=ciso-assistant.log >> .env - # echo DJANGO_DEBUG=True >> .env - # echo DJANGO_SUPERUSER_EMAIL=admin@tests.com >> .env - # echo DJANGO_SUPERUSER_PASSWORD=1234 >> .env - # echo POSTGRES_NAME=postgres >> .env - # echo POSTGRES_USER=postgres >> .env - # echo POSTGRES_PASSWORD=postgres >> .env - # echo DB_HOST=localhost >> .env - # echo CISO_ASSISTANT_SUPERUSER_EMAIL='' >> .env - # echo CISO_ASSISTANT_URL=http://localhost:4173 >> .env - # echo DEFAULT_FROM_EMAIL='ciso-assistant@tests.net' >> .env - # echo EMAIL_HOST=localhost >> .env - # echo EMAIL_HOST_USER=user@tests.com >> .env - # echo EMAIL_HOST_PASSWORD=password >> .env - # echo EMAIL_PORT=1025 >> .env - # echo DJANGO_SETTINGS_MODULE=enterprise_core.settings >> .env - # echo LICENSE_SEATS=999 >> .env - # - name: Run migrations - # working-directory: ${{ env.backend-directory }} - # run: | - # export $(grep -v '^#' .env | xargs) - # poetry run python manage.py migrate --settings=${{ env.enterprise-backend-settings-module }} - # - name: Start test server - # working-directory: ${{ env.backend-directory }} - # run: | - # export $(grep -v '^#' .env | xargs) - # poetry run python manage.py createsuperuser --noinput --settings=${{ env.enterprise-backend-settings-module }} - # nohup poetry run python manage.py runserver --settings=${{ env.enterprise-backend-settings-module }} & - # - name: Run tests with browser ${{ matrix.playwright-browser }} - # working-directory: ${{ env.enterprise-frontend-build-directory }} - # run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} - # env: - # CI: true - # - uses: actions/upload-artifact@v4 - # if: always() - # with: - # name: enterprise-functional-tests-report-${{ matrix.playwright-browser }} - # path: | - # ${{ env.backend-directory }}/*.log - # ${{ env.enterprise-frontend-build-directory }}/tests/results/ - # ${{ env.enterprise-frontend-build-directory }}/tests/reports/ - # retention-days: 5 + steps: + - uses: actions/checkout@v4 + - name: Set up python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: "pip" + - uses: actions/setup-node@v4 + with: + node-version: lts/* + - name: Install Poetry + uses: snok/install-poetry@v1 + with: + virtualenvs-create: false + installer-parallel: true + - name: Install backend requirements + working-directory: ${{ env.backend-directory }} + run: poetry install + - name: Install enterprise backend + working-directory: ${{ env.enterprise-backend-directory }} + run: poetry install + - name: Build enterprise frontend + working-directory: ${{ env.enterprise-frontend-directory }} + run: make + - name: Install Playwright browser ${{ matrix.playwright-browser }} + working-directory: ${{ env.enterprise-frontend-build-directory }} + run: pnpm exec playwright install --with-deps ${{ matrix.playwright-browser }} + - name: Create frontend environment variables file + working-directory: ${{ env.enterprise-frontend-build-directory }} + run: | + touch .env + echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env + - name: Create backend environment variables file + working-directory: ${{ env.backend-directory }} + run: | + touch .env + echo LOG_LEVEL=DEBUG >> .env + echo LOG_OUTFILE=ciso-assistant.log >> .env + echo DJANGO_DEBUG=True >> .env + echo DJANGO_SUPERUSER_EMAIL=admin@tests.com >> .env + echo DJANGO_SUPERUSER_PASSWORD=1234 >> .env + echo POSTGRES_NAME=postgres >> .env + echo POSTGRES_USER=postgres >> .env + echo POSTGRES_PASSWORD=postgres >> .env + echo DB_HOST=localhost >> .env + echo CISO_ASSISTANT_SUPERUSER_EMAIL='' >> .env + echo CISO_ASSISTANT_URL=http://localhost:4173 >> .env + echo DEFAULT_FROM_EMAIL='ciso-assistant@tests.net' >> .env + echo EMAIL_HOST=localhost >> .env + echo EMAIL_HOST_USER=user@tests.com >> .env + echo EMAIL_HOST_PASSWORD=password >> .env + echo EMAIL_PORT=1025 >> .env + echo DJANGO_SETTINGS_MODULE=enterprise_core.settings >> .env + echo LICENSE_SEATS=999 >> .env + - name: Run migrations + working-directory: ${{ env.backend-directory }} + run: | + export $(grep -v '^#' .env | xargs) + poetry run python manage.py migrate --settings=${{ env.enterprise-backend-settings-module }} + - name: Start test server + working-directory: ${{ env.backend-directory }} + run: | + export $(grep -v '^#' .env | xargs) + poetry run python manage.py createsuperuser --noinput --settings=${{ env.enterprise-backend-settings-module }} + nohup poetry run python manage.py runserver --settings=${{ env.enterprise-backend-settings-module }} & + - name: Run tests with browser ${{ matrix.playwright-browser }} + working-directory: ${{ env.enterprise-frontend-build-directory }} + run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} + env: + CI: true + - uses: actions/upload-artifact@v4 + if: always() + with: + name: enterprise-functional-tests-report-${{ matrix.playwright-browser }} + path: | + ${{ env.backend-directory }}/*.log + ${{ env.enterprise-frontend-build-directory }}/tests/results/ + ${{ env.enterprise-frontend-build-directory }}/tests/reports/ + retention-days: 5 From 22613b9f65680ef883c76f3ea6df7bfb29dce9ae Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 13:17:24 +0100 Subject: [PATCH 22/43] Also fix enterprise functional tests --- .github/workflows/functional-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index cdfc710be..9a81d0257 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -71,7 +71,6 @@ jobs: touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env echo CI_TEST=1 >> .env - - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} run: | @@ -176,6 +175,7 @@ jobs: run: | touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env + echo CI_TEST=1 >> .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} run: | From 04ddb26048f001e12a1f1c003f3371fd0898fef8 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 13:33:00 +0100 Subject: [PATCH 23/43] Fix startup tests --- .github/workflows/startup-tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/startup-tests.yml b/.github/workflows/startup-tests.yml index 1b3f47f42..5520ab2b8 100644 --- a/.github/workflows/startup-tests.yml +++ b/.github/workflows/startup-tests.yml @@ -136,7 +136,7 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) - server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' + server_reponse='{"type":"redirect","status":302,"location":"/"}' if [[ "$response" == "$server_reponse" ]]; then echo "Success" exit 0 @@ -264,7 +264,7 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) - server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' + server_reponse='{"type":"redirect","status":302,"location":"/"}' if [[ "$response" == "$server_reponse" ]]; then echo "Success" exit 0 From 3fb43d90ad33bb9428fac1fcb686d328a5e8eb91 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 13:46:02 +0100 Subject: [PATCH 24/43] Fix startup tests again --- .github/workflows/startup-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/startup-tests.yml b/.github/workflows/startup-tests.yml index 5520ab2b8..952bbff8d 100644 --- a/.github/workflows/startup-tests.yml +++ b/.github/workflows/startup-tests.yml @@ -63,6 +63,7 @@ jobs: run: | touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env + echo CI_TEST=1 >> .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} run: | @@ -195,6 +196,7 @@ jobs: run: | touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env + echo CI_TEST=1 >> .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} run: | From 9441864835d61c0a207ff05d280252768b7eb3dc Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 14:11:02 +0100 Subject: [PATCH 25/43] Add logging to debug startup tests --- .github/workflows/startup-tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/startup-tests.yml b/.github/workflows/startup-tests.yml index 952bbff8d..15e26e1d8 100644 --- a/.github/workflows/startup-tests.yml +++ b/.github/workflows/startup-tests.yml @@ -137,6 +137,8 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) + echo "SERVER_RESPONSE" + echo $response server_reponse='{"type":"redirect","status":302,"location":"/"}' if [[ "$response" == "$server_reponse" ]]; then echo "Success" @@ -267,6 +269,8 @@ jobs: run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) server_reponse='{"type":"redirect","status":302,"location":"/"}' + echo "SERVER_RESPONSE" + echo $response if [[ "$response" == "$server_reponse" ]]; then echo "Success" exit 0 From c877852fdb7726828b1b78780cfa3edff0060d46 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Fri, 29 Nov 2024 14:46:21 +0100 Subject: [PATCH 26/43] Lazy fix for startup tests --- .github/workflows/startup-tests.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/startup-tests.yml b/.github/workflows/startup-tests.yml index 15e26e1d8..04279ea0f 100644 --- a/.github/workflows/startup-tests.yml +++ b/.github/workflows/startup-tests.yml @@ -137,9 +137,7 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) - echo "SERVER_RESPONSE" - echo $response - server_reponse='{"type":"redirect","status":302,"location":"/"}' + server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' if [[ "$response" == "$server_reponse" ]]; then echo "Success" exit 0 @@ -268,9 +266,7 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) - server_reponse='{"type":"redirect","status":302,"location":"/"}' - echo "SERVER_RESPONSE" - echo $response + server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' if [[ "$response" == "$server_reponse" ]]; then echo "Success" exit 0 From adeca33a9b209ea2b0367192e269b109a1008cf9 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 08:26:25 +0100 Subject: [PATCH 27/43] Improve startup test verbosity Quickfix --- .github/workflows/startup-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/startup-tests.yml b/.github/workflows/startup-tests.yml index 04279ea0f..d95a2ce37 100644 --- a/.github/workflows/startup-tests.yml +++ b/.github/workflows/startup-tests.yml @@ -137,6 +137,7 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) + echo "$response" server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' if [[ "$response" == "$server_reponse" ]]; then echo "Success" @@ -266,6 +267,7 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) + echo "$response" server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' if [[ "$response" == "$server_reponse" ]]; then echo "Success" From a8b25bd4b7170062db6524b6ab3051a236ccd7ba Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 09:04:09 +0100 Subject: [PATCH 28/43] Fix broken getSecureRedirect --- frontend/src/routes/(authentication)/login/+page.server.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index ff4549dd4..8a6f4f45f 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -132,7 +132,9 @@ export const actions: Actions = { } const next = url.searchParams.get('next') || '/'; - const redirectURL = getSecureRedirect(next) + (CI_TEST ? '' : '?refresh=1'); + const secureNext = getSecureRedirect(next); + const refreshQueryParam = (CI_TEST ? '' : '?refresh=1'); + const redirectURL = secureNext ? `${secureNext}${refreshQueryParam}` : `/${refreshQueryParam}`; redirect(302, redirectURL); }, mfaAuthenticate: async (event) => { From eaee0b556616269582ff7121a065fd3260beab92 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 09:05:17 +0100 Subject: [PATCH 29/43] Formatter Quickfix --- frontend/src/lib/utils/helpers.ts | 2 +- frontend/src/routes/(authentication)/login/+page.server.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/lib/utils/helpers.ts b/frontend/src/lib/utils/helpers.ts index b0d5b91aa..57a134484 100644 --- a/frontend/src/lib/utils/helpers.ts +++ b/frontend/src/lib/utils/helpers.ts @@ -60,7 +60,7 @@ export function formatScoreValue(value: number, max_score: number, fullDonut = f } export function getSecureRedirect(url: any): string { - const SECURE_REDIRECT_URL_REGEX = /^\/\w*/; + const SECURE_REDIRECT_URL_REGEX = /^\/\w+/; return typeof url === 'string' && SECURE_REDIRECT_URL_REGEX.test(url) ? url : ''; } diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 8a6f4f45f..31f5013dc 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -133,7 +133,7 @@ export const actions: Actions = { const next = url.searchParams.get('next') || '/'; const secureNext = getSecureRedirect(next); - const refreshQueryParam = (CI_TEST ? '' : '?refresh=1'); + const refreshQueryParam = CI_TEST ? '' : '?refresh=1'; const redirectURL = secureNext ? `${secureNext}${refreshQueryParam}` : `/${refreshQueryParam}`; redirect(302, redirectURL); }, From 818624a4d7489dc2f124d2ea5efb94d3e483054e Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 12:52:35 +0100 Subject: [PATCH 30/43] First fix attempt debug test --- .github/workflows/functional-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index 9a81d0257..db8d9aff8 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -211,7 +211,7 @@ jobs: nohup poetry run python manage.py runserver --settings=${{ env.enterprise-backend-settings-module }} & - name: Run tests with browser ${{ matrix.playwright-browser }} working-directory: ${{ env.enterprise-frontend-build-directory }} - run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} + run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} -g "fuzz" env: CI: true - uses: actions/upload-artifact@v4 From 30cf4670ecfbe8c7f4febbb500cafeccbd8b99c2 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 12:58:36 +0100 Subject: [PATCH 31/43] Fix attempt 2: Setup the .env file before make (debug commit only running the fuzz test) Quickfix --- .github/workflows/functional-tests.yml | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index db8d9aff8..80bfe60b2 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -164,18 +164,21 @@ jobs: - name: Install enterprise backend working-directory: ${{ env.enterprise-backend-directory }} run: poetry install - - name: Build enterprise frontend - working-directory: ${{ env.enterprise-frontend-directory }} - run: make - - name: Install Playwright browser ${{ matrix.playwright-browser }} - working-directory: ${{ env.enterprise-frontend-build-directory }} - run: pnpm exec playwright install --with-deps ${{ matrix.playwright-browser }} + - name: Create the frontend build directory before build + working-directory: ${{ env.enterprise-backend-directory }} + run: mkdir -p ./build/frontend - name: Create frontend environment variables file working-directory: ${{ env.enterprise-frontend-build-directory }} run: | touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env echo CI_TEST=1 >> .env + - name: Build enterprise frontend + working-directory: ${{ env.enterprise-frontend-directory }} + run: make + - name: Install Playwright browser ${{ matrix.playwright-browser }} + working-directory: ${{ env.enterprise-frontend-build-directory }} + run: pnpm exec playwright install --with-deps ${{ matrix.playwright-browser }} - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} run: | From dc904cd246ffb061409b4c7f83942c0194df30ec Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 13:45:52 +0100 Subject: [PATCH 32/43] Fix tests Quickfix Quickfix --- .github/workflows/functional-tests.yml | 17 +++++++---------- .../(authentication)/login/+page.server.ts | 8 ++++++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index 80bfe60b2..9a81d0257 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -164,21 +164,18 @@ jobs: - name: Install enterprise backend working-directory: ${{ env.enterprise-backend-directory }} run: poetry install - - name: Create the frontend build directory before build - working-directory: ${{ env.enterprise-backend-directory }} - run: mkdir -p ./build/frontend - - name: Create frontend environment variables file - working-directory: ${{ env.enterprise-frontend-build-directory }} - run: | - touch .env - echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env - echo CI_TEST=1 >> .env - name: Build enterprise frontend working-directory: ${{ env.enterprise-frontend-directory }} run: make - name: Install Playwright browser ${{ matrix.playwright-browser }} working-directory: ${{ env.enterprise-frontend-build-directory }} run: pnpm exec playwright install --with-deps ${{ matrix.playwright-browser }} + - name: Create frontend environment variables file + working-directory: ${{ env.enterprise-frontend-build-directory }} + run: | + touch .env + echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env + echo CI_TEST=1 >> .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} run: | @@ -214,7 +211,7 @@ jobs: nohup poetry run python manage.py runserver --settings=${{ env.enterprise-backend-settings-module }} & - name: Run tests with browser ${{ matrix.playwright-browser }} working-directory: ${{ env.enterprise-frontend-build-directory }} - run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} -g "fuzz" + run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} env: CI: true - uses: actions/upload-artifact@v4 diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 31f5013dc..a42f9d4e1 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -120,9 +120,9 @@ export const actions: Actions = { const preferences = await preferencesRes.json(); const currentLang = cookies.get('ciso_lang') || 'en'; - const preferedLang = preferences.lang; + const preferedLang = preferences.lang || 'en'; - if (preferedLang && currentLang !== preferedLang) { + if (currentLang !== preferedLang) { cookies.set('ciso_lang', preferedLang, { httpOnly: false, sameSite: 'lax', @@ -134,6 +134,10 @@ export const actions: Actions = { const next = url.searchParams.get('next') || '/'; const secureNext = getSecureRedirect(next); const refreshQueryParam = CI_TEST ? '' : '?refresh=1'; + if (currentLang == preferedLang) { + redirect(302, secureNext); + } + const redirectURL = secureNext ? `${secureNext}${refreshQueryParam}` : `/${refreshQueryParam}`; redirect(302, redirectURL); }, From 0920bb51b49dea4b31952027554460d517ce0400 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 14:25:30 +0100 Subject: [PATCH 33/43] Slightly improve startup test verbosity --- .github/workflows/startup-tests.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/startup-tests.yml b/.github/workflows/startup-tests.yml index d95a2ce37..5c9df478c 100644 --- a/.github/workflows/startup-tests.yml +++ b/.github/workflows/startup-tests.yml @@ -137,8 +137,9 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) - echo "$response" server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' + echo "[SERVER_RESPONSE] $response" + echo "[EXPECTED_RESPONSE] $server_reponse" if [[ "$response" == "$server_reponse" ]]; then echo "Success" exit 0 @@ -267,8 +268,9 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) - echo "$response" server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' + echo "[SERVER_RESPONSE] $response" + echo "[EXPECTED_RESPONSE] $server_reponse" if [[ "$response" == "$server_reponse" ]]; then echo "Success" exit 0 From 4a540273a587b5fdadfa56074bc33fa3a5731889 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 14:25:51 +0100 Subject: [PATCH 34/43] Attempt to fix codefactor complexity test --- .../(authentication)/login/+page.server.ts | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index a42f9d4e1..83b4235c8 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -73,29 +73,27 @@ export const actions: Actions = { }); return fail(res.status, { form }); } - if (res.status === 401) { + if (res.status === 401 && res.data) { // User is not authenticated - if (res.data) { - const flows: AuthenticationFlow[] = res.data.flows; - if (flows.length > 0) { - const mfaFlow = flows.find((flow) => flow.id === 'mfa_authenticate'); - const sessionToken = res.meta.session_token; - if (sessionToken) { - cookies.set('allauth_session_token', sessionToken, { - httpOnly: true, - sameSite: 'lax', - path: '/', - secure: true - }); - } - - if (mfaFlow) { - return { - form, - mfa: true, - mfaFlow - }; - } + const flows: AuthenticationFlow[] = res.data.flows; + if (flows.length > 0) { + const mfaFlow = flows.find((flow) => flow.id === 'mfa_authenticate'); + const sessionToken = res.meta.session_token; + if (sessionToken) { + cookies.set('allauth_session_token', sessionToken, { + httpOnly: true, + sameSite: 'lax', + path: '/', + secure: true + }); + } + + if (mfaFlow) { + return { + form, + mfa: true, + mfaFlow + }; } } } @@ -134,6 +132,7 @@ export const actions: Actions = { const next = url.searchParams.get('next') || '/'; const secureNext = getSecureRedirect(next); const refreshQueryParam = CI_TEST ? '' : '?refresh=1'; + // The CI_TEST environment variable will have to be removed if the `currentLang == preferedLang` solution fix the enterprise function tests. if (currentLang == preferedLang) { redirect(302, secureNext); } From e9b9c8856a8643f88ab1db630a92fcbe4f569148 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 14:35:04 +0100 Subject: [PATCH 35/43] Attempt 2 to fix codefactor complexity test --- .../(authentication)/login/+page.server.ts | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 83b4235c8..92b7d3b40 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -1,7 +1,8 @@ import { getSecureRedirect } from '$lib/utils/helpers'; import { ALLAUTH_API_URL, BASE_API_URL } from '$lib/utils/constants'; -import { CI_TEST } from '$lib/utils/env_constants'; +// The CI_TEST environment variable will have to be removed if the `currentLang == preferedLang` solution fix the enterprise function tests. +// import { CI_TEST } from '$lib/utils/env_constants'; import { loginSchema } from '$lib/utils/schemas'; import type { LoginRequestBody } from '$lib/utils/types'; import { fail, redirect, type Actions } from '@sveltejs/kit'; @@ -26,6 +27,15 @@ interface AuthenticationFlow { types: 'totp' | 'recovery_codes'; } +function makeRedirectURL(currentLang: string, preferedLang: string, url: URL): string { + const next = url.searchParams.get('next') || '/'; + const secureNext = getSecureRedirect(next); + if (currentLang == preferedLang) { + return secureNext; + } + return secureNext ? `${secureNext}?refresh=1` : `/?refresh=1`; +} + export const load: PageServerLoad = async ({ fetch, request, locals }) => { // redirect user if already logged in if (locals.user) { @@ -129,16 +139,7 @@ export const actions: Actions = { }); } - const next = url.searchParams.get('next') || '/'; - const secureNext = getSecureRedirect(next); - const refreshQueryParam = CI_TEST ? '' : '?refresh=1'; - // The CI_TEST environment variable will have to be removed if the `currentLang == preferedLang` solution fix the enterprise function tests. - if (currentLang == preferedLang) { - redirect(302, secureNext); - } - - const redirectURL = secureNext ? `${secureNext}${refreshQueryParam}` : `/${refreshQueryParam}`; - redirect(302, redirectURL); + redirect(302, makeRedirectURL(currentLang, preferedLang, url)); }, mfaAuthenticate: async (event) => { const formData = await event.request.formData(); From f8e421a06820890eecd703cfdf9f338a7de92708 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 14:58:49 +0100 Subject: [PATCH 36/43] Fix startup tests --- .github/workflows/startup-tests.yml | 4 ++-- frontend/src/routes/(authentication)/login/+page.server.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/startup-tests.yml b/.github/workflows/startup-tests.yml index 5c9df478c..09e22f356 100644 --- a/.github/workflows/startup-tests.yml +++ b/.github/workflows/startup-tests.yml @@ -137,7 +137,7 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) - server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' + server_reponse='{"type":"redirect","status":302,"location":"/"}' echo "[SERVER_RESPONSE] $response" echo "[EXPECTED_RESPONSE] $server_reponse" if [[ "$response" == "$server_reponse" ]]; then @@ -268,7 +268,7 @@ jobs: working-directory: ${{ env.frontend-directory }} run: | response=$(curl -d "username=admin@tests.com&password=1234" -H "Origin: https://localhost:8443" https://localhost:8443/login\?/login -k) - server_reponse='{"type":"redirect","status":302,"location":"/?refresh=1"}' + server_reponse='{"type":"redirect","status":302,"location":"/"}' echo "[SERVER_RESPONSE] $response" echo "[EXPECTED_RESPONSE] $server_reponse" if [[ "$response" == "$server_reponse" ]]; then diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 92b7d3b40..0f0611bfb 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -28,9 +28,9 @@ interface AuthenticationFlow { } function makeRedirectURL(currentLang: string, preferedLang: string, url: URL): string { - const next = url.searchParams.get('next') || '/'; - const secureNext = getSecureRedirect(next); - if (currentLang == preferedLang) { + const next = url.searchParams.get('next'); + const secureNext = getSecureRedirect(next) || '/'; + if (currentLang === preferedLang) { return secureNext; } return secureNext ? `${secureNext}?refresh=1` : `/?refresh=1`; From 081dbee36800566cec9fc991bcdabba068527e83 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 15:14:58 +0100 Subject: [PATCH 37/43] Add function test debug line --- frontend/src/routes/(authentication)/login/+page.server.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 0f0611bfb..d8751a554 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -30,6 +30,7 @@ interface AuthenticationFlow { function makeRedirectURL(currentLang: string, preferedLang: string, url: URL): string { const next = url.searchParams.get('next'); const secureNext = getSecureRedirect(next) || '/'; + console.log(`[DEBUG] '${currentLang}' === '${preferedLang}'`); if (currentLang === preferedLang) { return secureNext; } From bac1b37c8457d4cb44bafcca419ff083ba06db7c Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 15:16:12 +0100 Subject: [PATCH 38/43] Debug: Only execute a single enterprise test --- .github/workflows/functional-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index 9a81d0257..b12979d89 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -211,7 +211,7 @@ jobs: nohup poetry run python manage.py runserver --settings=${{ env.enterprise-backend-settings-module }} & - name: Run tests with browser ${{ matrix.playwright-browser }} working-directory: ${{ env.enterprise-frontend-build-directory }} - run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} + run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} -g "user can set his password" env: CI: true - uses: actions/upload-artifact@v4 From 69f580d193a33bae6d732e9c3644c269539cd0ca Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 15:25:27 +0100 Subject: [PATCH 39/43] Write debug output inside stderr in an attempt to keep them in the logs --- frontend/src/routes/(authentication)/login/+page.server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index d8751a554..576d8aeb2 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -30,7 +30,7 @@ interface AuthenticationFlow { function makeRedirectURL(currentLang: string, preferedLang: string, url: URL): string { const next = url.searchParams.get('next'); const secureNext = getSecureRedirect(next) || '/'; - console.log(`[DEBUG] '${currentLang}' === '${preferedLang}'`); + console.error(`[DEBUG] '${currentLang}' === '${preferedLang}'`); if (currentLang === preferedLang) { return secureNext; } From 61edd8b653c88122e50e664af689fdaf6809bff7 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 15:45:13 +0100 Subject: [PATCH 40/43] Recheck that window.location.href page refresh is indeed the cause of the net::ERR_ABORTED error --- enterprise/frontend/src/routes/+layout.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/enterprise/frontend/src/routes/+layout.svelte b/enterprise/frontend/src/routes/+layout.svelte index 56d4c5c56..c0a796ccf 100644 --- a/enterprise/frontend/src/routes/+layout.svelte +++ b/enterprise/frontend/src/routes/+layout.svelte @@ -101,7 +101,8 @@ $: if (browser && $page.url.searchParams.has('refresh')) { $page.url.searchParams.delete('refresh'); - window.location.href = $page.url.href; + console.error(`[DEBUG2] ${window.location.href}`); // Just to test if the playwright JS console stderr would actually be outputed in the logs + // window.location.href = $page.url.href; } From e79c87cdd227977a55d39d5aa7b703fe76cfb4fe Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 16:36:55 +0100 Subject: [PATCH 41/43] Attempt to fix functional tests --- enterprise/frontend/src/routes/+layout.svelte | 3 +-- frontend/src/routes/(app)/+page.server.ts | 8 +++----- .../src/routes/(authentication)/login/+page.server.ts | 1 - 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/enterprise/frontend/src/routes/+layout.svelte b/enterprise/frontend/src/routes/+layout.svelte index c0a796ccf..56d4c5c56 100644 --- a/enterprise/frontend/src/routes/+layout.svelte +++ b/enterprise/frontend/src/routes/+layout.svelte @@ -101,8 +101,7 @@ $: if (browser && $page.url.searchParams.has('refresh')) { $page.url.searchParams.delete('refresh'); - console.error(`[DEBUG2] ${window.location.href}`); // Just to test if the playwright JS console stderr would actually be outputed in the logs - // window.location.href = $page.url.href; + window.location.href = $page.url.href; } diff --git a/frontend/src/routes/(app)/+page.server.ts b/frontend/src/routes/(app)/+page.server.ts index 914629e00..232613462 100644 --- a/frontend/src/routes/(app)/+page.server.ts +++ b/frontend/src/routes/(app)/+page.server.ts @@ -1,9 +1,7 @@ import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; -import { CI_TEST } from '$lib/utils/env_constants'; -const redirectURL = CI_TEST ? '/analytics' : '/analytics?refresh=1'; - -export const load: PageServerLoad = async () => { - redirect(301, redirectURL); +export const load: PageServerLoad = async ({ url }) => { + const queryParams = url.searchParams.has("refresh") ? "?refresh=1" : ""; + redirect(301, `/analytics${queryParams}`); }; diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 576d8aeb2..0f0611bfb 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -30,7 +30,6 @@ interface AuthenticationFlow { function makeRedirectURL(currentLang: string, preferedLang: string, url: URL): string { const next = url.searchParams.get('next'); const secureNext = getSecureRedirect(next) || '/'; - console.error(`[DEBUG] '${currentLang}' === '${preferedLang}'`); if (currentLang === preferedLang) { return secureNext; } From 144a8006ddedf8d972a59d8def02289aba361bd4 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Tue, 3 Dec 2024 16:41:32 +0100 Subject: [PATCH 42/43] Formatter --- frontend/src/routes/(app)/+page.server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/routes/(app)/+page.server.ts b/frontend/src/routes/(app)/+page.server.ts index 232613462..07b2f1091 100644 --- a/frontend/src/routes/(app)/+page.server.ts +++ b/frontend/src/routes/(app)/+page.server.ts @@ -2,6 +2,6 @@ import { redirect } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; export const load: PageServerLoad = async ({ url }) => { - const queryParams = url.searchParams.has("refresh") ? "?refresh=1" : ""; + const queryParams = url.searchParams.has('refresh') ? '?refresh=1' : ''; redirect(301, `/analytics${queryParams}`); }; From 20134acf5af5cbd1e5d3930601195b891f558ea7 Mon Sep 17 00:00:00 2001 From: monsieurswag Date: Wed, 4 Dec 2024 14:13:48 +0100 Subject: [PATCH 43/43] Remove useless environment variable Allow all tests again Fix wrong model import in migration Formatter --- .github/workflows/functional-tests.yml | 4 +--- .github/workflows/startup-tests.yml | 2 -- ...jects.py => 0009_create_allauth_emailaddress_objects.py} | 6 +++--- .../{0009_user_preferences.py => 0010_user_preferences.py} | 4 ++-- frontend/src/lib/utils/env_constants.ts | 5 ----- frontend/src/routes/(authentication)/login/+page.server.ts | 2 -- 6 files changed, 6 insertions(+), 17 deletions(-) rename backend/iam/migrations/{0010_create_allauth_emailaddress_objects.py => 0009_create_allauth_emailaddress_objects.py} (77%) rename backend/iam/migrations/{0009_user_preferences.py => 0010_user_preferences.py} (72%) delete mode 100644 frontend/src/lib/utils/env_constants.ts diff --git a/.github/workflows/functional-tests.yml b/.github/workflows/functional-tests.yml index b12979d89..54104981b 100644 --- a/.github/workflows/functional-tests.yml +++ b/.github/workflows/functional-tests.yml @@ -70,7 +70,6 @@ jobs: run: | touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env - echo CI_TEST=1 >> .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} run: | @@ -175,7 +174,6 @@ jobs: run: | touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env - echo CI_TEST=1 >> .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} run: | @@ -211,7 +209,7 @@ jobs: nohup poetry run python manage.py runserver --settings=${{ env.enterprise-backend-settings-module }} & - name: Run tests with browser ${{ matrix.playwright-browser }} working-directory: ${{ env.enterprise-frontend-build-directory }} - run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} -g "user can set his password" + run: pnpm exec playwright test --project=${{ matrix.playwright-browser }} env: CI: true - uses: actions/upload-artifact@v4 diff --git a/.github/workflows/startup-tests.yml b/.github/workflows/startup-tests.yml index ec47e56de..ac3a48c24 100644 --- a/.github/workflows/startup-tests.yml +++ b/.github/workflows/startup-tests.yml @@ -63,7 +63,6 @@ jobs: run: | touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env - echo CI_TEST=1 >> .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} run: | @@ -199,7 +198,6 @@ jobs: run: | touch .env echo PUBLIC_BACKEND_API_URL=http://localhost:8000/api >> .env - echo CI_TEST=1 >> .env - name: Create backend environment variables file working-directory: ${{ env.backend-directory }} run: | diff --git a/backend/iam/migrations/0010_create_allauth_emailaddress_objects.py b/backend/iam/migrations/0009_create_allauth_emailaddress_objects.py similarity index 77% rename from backend/iam/migrations/0010_create_allauth_emailaddress_objects.py rename to backend/iam/migrations/0009_create_allauth_emailaddress_objects.py index c1a02e9de..0da343def 100644 --- a/backend/iam/migrations/0010_create_allauth_emailaddress_objects.py +++ b/backend/iam/migrations/0009_create_allauth_emailaddress_objects.py @@ -5,8 +5,8 @@ def create_emailaddress_objects(apps, schema_editor): try: - from allauth.account.models import EmailAddress - from iam.models import User + EmailAddress = apps.get_model("account", "EmailAddress") + User = apps.get_model("iam", "User") for user in User.objects.all(): EmailAddress.objects.create( @@ -21,7 +21,7 @@ def create_emailaddress_objects(apps, schema_editor): class Migration(migrations.Migration): dependencies = [ - ("iam", "0009_user_preferences"), + ("iam", "0008_user_is_third_party"), ] operations = [ diff --git a/backend/iam/migrations/0009_user_preferences.py b/backend/iam/migrations/0010_user_preferences.py similarity index 72% rename from backend/iam/migrations/0009_user_preferences.py rename to backend/iam/migrations/0010_user_preferences.py index 3766b21cc..6bd439eb1 100644 --- a/backend/iam/migrations/0009_user_preferences.py +++ b/backend/iam/migrations/0010_user_preferences.py @@ -1,11 +1,11 @@ -# Generated by Django 5.1.1 on 2024-11-22 01:25 +# Generated by Django 5.1.1 on 2024-12-04 10:42 from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ("iam", "0008_user_is_third_party"), + ("iam", "0009_create_allauth_emailaddress_objects"), ] operations = [ diff --git a/frontend/src/lib/utils/env_constants.ts b/frontend/src/lib/utils/env_constants.ts deleted file mode 100644 index d9dd784ab..000000000 --- a/frontend/src/lib/utils/env_constants.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as env from '$env/static/private'; - -// This file is separate from constant.ts because '$env/static/private' can only be imported on the server-side. - -export const CI_TEST: boolean = Object.hasOwn(env, 'CI_TEST'); diff --git a/frontend/src/routes/(authentication)/login/+page.server.ts b/frontend/src/routes/(authentication)/login/+page.server.ts index 0f0611bfb..7b118aa89 100644 --- a/frontend/src/routes/(authentication)/login/+page.server.ts +++ b/frontend/src/routes/(authentication)/login/+page.server.ts @@ -1,8 +1,6 @@ import { getSecureRedirect } from '$lib/utils/helpers'; import { ALLAUTH_API_URL, BASE_API_URL } from '$lib/utils/constants'; -// The CI_TEST environment variable will have to be removed if the `currentLang == preferedLang` solution fix the enterprise function tests. -// import { CI_TEST } from '$lib/utils/env_constants'; import { loginSchema } from '$lib/utils/schemas'; import type { LoginRequestBody } from '$lib/utils/types'; import { fail, redirect, type Actions } from '@sveltejs/kit';