diff --git a/client/index.html b/client/index.html
index 31fdea1c..75616849 100644
--- a/client/index.html
+++ b/client/index.html
@@ -7,7 +7,7 @@
-
+
+
ls-network big
diff --git a/cypress/e2e/helpers.js b/cypress/e2e/helpers.js
index 362b9496..dbafa9e0 100644
--- a/cypress/e2e/helpers.js
+++ b/cypress/e2e/helpers.js
@@ -1,7 +1,7 @@
export const login = (username, password) => {
cy.request({
method: 'POST',
- url: '/core/login/',
+ url: '/api/core/login/',
body: { username, password },
})
}
diff --git a/server/config/api_router.py b/server/config/api_router.py
deleted file mode 100644
index 2e053e30..00000000
--- a/server/config/api_router.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from django.conf import settings
-from rest_framework.routers import DefaultRouter, SimpleRouter
-
-if settings.DEBUG:
- router = DefaultRouter()
-else:
- router = SimpleRouter()
-
-
-app_name = "api"
-urlpatterns = router.urls
diff --git a/server/config/settings/base.py b/server/config/settings/base.py
index 8be507d0..46b932d6 100644
--- a/server/config/settings/base.py
+++ b/server/config/settings/base.py
@@ -78,7 +78,6 @@ THIRD_PARTY_APPS = [
"rest_framework.authtoken",
"corsheaders",
"drf_spectacular",
- "django_htmx",
'wagtail.contrib.forms',
'wagtail.contrib.redirects',
@@ -288,7 +287,7 @@ EMAIL_TIMEOUT = 5
# ADMIN
# ------------------------------------------------------------------------------
# Django Admin URL.
-ADMIN_URL = "admin/"
+ADMIN_URL = "server/admin/"
# https://docs.djangoproject.com/en/dev/ref/settings/#admins
ADMINS = [("""Daniel Egger""", "info@iterativ.ch")]
# https://docs.djangoproject.com/en/dev/ref/settings/#managers
@@ -454,7 +453,17 @@ REST_FRAMEWORK = {
CORS_URLS_REGEX = r"^/api/.*$"
# django-csp
-CSP_DEFAULT_SRC = ("'self'", "'unsafe-inline'", 'ws://localhost:5173', 'localhost:8000', 'blob:', 'data:', 'http://*')
+CSP_DEFAULT_SRC = [
+ "'self'",
+ "'unsafe-inline'",
+ 'ws://localhost:5173',
+ 'ws://127.0.0.1:5173',
+ 'localhost:8000',
+ 'localhost:8001',
+ 'blob:',
+ 'data:',
+ 'http://*'
+]
CSP_FRAME_ANCESTORS = ("'self'",)
# By Default swagger ui is available only to admin user. You can change permission classs to change that
diff --git a/server/config/urls.py b/server/config/urls.py
index 3664a946..ba97a6b9 100644
--- a/server/config/urls.py
+++ b/server/config/urls.py
@@ -5,19 +5,19 @@ from django.contrib.auth.decorators import user_passes_test
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.urls import include, path, re_path
from django.views import defaults as default_views
-from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
from ratelimit.exceptions import Ratelimited
-from rest_framework.authtoken.views import obtain_auth_token
from wagtail import urls as wagtail_urls
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.documents import urls as wagtaildocs_urls
+from vbv_lernwelt.completion.views import request_learning_path_completion, request_circle_completion, \
+ mark_circle_completion
from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
from vbv_lernwelt.core.views import (
rate_limit_exceeded_view,
permission_denied_view,
- check_rate_limit, cypress_reset_view, vue_home, vue_login, me_user_view, vue_logout, )
-from .wagtail_api import wagtail_api_router
+ check_rate_limit, cypress_reset_view, vue_home, vue_login, me_user_view, vue_logout, generate_web_component_icons, )
+from vbv_lernwelt.learnpath.views import page_api_view
def raise_example_error(request):
@@ -31,39 +31,43 @@ def raise_example_error(request):
# fmt: off
urlpatterns = [
- path('admin/raise_error/', user_passes_test(lambda u: u.is_superuser, login_url='/login/')(raise_example_error), ),
path(settings.ADMIN_URL, admin.site.urls),
- path("checkratelimit/", check_rate_limit),
+
+ # wagtail urls
+ path('server/cms/', include(wagtailadmin_urls)),
+ path('server/documents/', include(wagtaildocs_urls)),
+ path('server/pages/', include(wagtail_urls)),
+
+ # user management
path("sso/", include("vbv_lernwelt.sso.urls")),
- path('cms/', include(wagtailadmin_urls)),
- path('documents/', include(wagtaildocs_urls)),
- path('pages/', include(wagtail_urls)),
- path('learnpath/', include("vbv_lernwelt.learnpath.urls")),
- path('api/completion/', include("vbv_lernwelt.completion.urls")),
re_path(r'api/core/me/$', me_user_view, name='me_user_view'),
- re_path(r'core/login/$', django_view_authentication_exempt(vue_login), name='vue_login'),
- re_path(r'core/logout/$', vue_logout, name='vue_logout'),
-] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
+ re_path(r'api/core/login/$', django_view_authentication_exempt(vue_login), name='vue_login'),
+ re_path(r'api/core/logout/$', vue_logout, name='vue_logout'),
+
+ # core
+ re_path(r"server/core/icons/$", generate_web_component_icons, name="generate_web_component_icons"),
+
+ # learnpath
+ path(r"api/learnpath/page/
/", page_api_view, name="page_api_view"),
+
+ # completion
+ path(r"api/completion/circle//", request_circle_completion, name="request_circle_completion"),
+ path(r"api/completion/learning_path//", request_learning_path_completion, name="request_learning_path_completion"),
+ path(r"api/completion/circle/mark/", mark_circle_completion, name="mark_circle_completion"),
+
+ # testing and debug
+ path('server/raise_error/', user_passes_test(lambda u: u.is_superuser, login_url='/login/')(raise_example_error), ),
+ path("server/checkratelimit/", check_rate_limit),
+]
+urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
if settings.DEBUG:
# Static file serving when using Gunicorn + Uvicorn for local web socket development
urlpatterns += staticfiles_urlpatterns()
-# API URLS
-urlpatterns += [
- # API base url
- path("api/", include("config.api_router")),
- path('wagtailapi/v2/', wagtail_api_router.urls),
-
- # DRF auth token
- path("auth-token/", obtain_auth_token),
- path("api/schema/", SpectacularAPIView.as_view(), name="api-schema"),
- path("api/docs/", SpectacularSwaggerView.as_view(url_name="api-schema"), name="api-docs",),
-]
-
if settings.APP_ENVIRONMENT != 'production':
urlpatterns += [
- re_path(r'core/cypressreset/$', cypress_reset_view, name='cypress_reset_view'),
+ re_path(r'api/core/cypressreset/$', cypress_reset_view, name='cypress_reset_view'),
]
# fmt: on
@@ -107,4 +111,4 @@ if settings.DEBUG:
# serve everything else via the vue app
-urlpatterns += [re_path(r'^.*$', vue_home, name='home')]
+urlpatterns += [re_path(r'^(?!.*(server/|api/|sso/)).*$', vue_home, name='home')]
diff --git a/server/config/wagtail_api.py b/server/config/wagtail_api.py
deleted file mode 100644
index d12d1b50..00000000
--- a/server/config/wagtail_api.py
+++ /dev/null
@@ -1,16 +0,0 @@
-
-from wagtail.api.v2.router import WagtailAPIRouter
-from wagtail.api.v2.views import PagesAPIViewSet
-from wagtail.documents.api.v2.views import DocumentsAPIViewSet
-from wagtail.images.api.v2.views import ImagesAPIViewSet
-
-# Create the router. "wagtailapi" is the URL namespace
-wagtail_api_router = WagtailAPIRouter('wagtailapi')
-
-# Add the three endpoints using the "register_endpoint" method.
-# The first parameter is the name of the endpoint (eg. pages, images). This
-# is used in the URL of the endpoint
-# The second parameter is the endpoint class that handles the requests
-wagtail_api_router.register_endpoint('pages', PagesAPIViewSet)
-wagtail_api_router.register_endpoint('images', ImagesAPIViewSet)
-wagtail_api_router.register_endpoint('documents', DocumentsAPIViewSet)
diff --git a/server/integration_tests/ratelimit/test_ratelimit.py b/server/integration_tests/ratelimit/test_ratelimit.py
index 20e9c0a8..66cffadc 100644
--- a/server/integration_tests/ratelimit/test_ratelimit.py
+++ b/server/integration_tests/ratelimit/test_ratelimit.py
@@ -3,7 +3,7 @@ from django.test import TestCase, override_settings
class RateLimitTest(TestCase):
def setUp(self):
- self.url = "/checkratelimit/"
+ self.url = "/server/checkratelimit/"
@override_settings(RATELIMIT_ENABLE=True)
def test_checkView_rateLimitAfter5Requests(self):
diff --git a/server/requirements/requirements-dev.txt b/server/requirements/requirements-dev.txt
index 4f5f0a8f..2fc1305d 100644
--- a/server/requirements/requirements-dev.txt
+++ b/server/requirements/requirements-dev.txt
@@ -113,8 +113,6 @@ django-extensions==3.1.5
# via -r requirements-dev.in
django-filter==21.1
# via wagtail
-django-htmx==1.9.0
- # via -r requirements.in
django-ipware==4.0.2
# via -r requirements.in
django-model-utils==4.2.0
diff --git a/server/requirements/requirements.in b/server/requirements/requirements.in
index 700df65a..186896df 100644
--- a/server/requirements/requirements.in
+++ b/server/requirements/requirements.in
@@ -19,7 +19,6 @@ djangorestframework # https://github.com/encode/django-rest-framework
django-cors-headers # https://github.com/adamchainz/django-cors-headers
# DRF-spectacular for api documentation
drf-spectacular
-django-htmx
dj-database-url
django-click
django-ratelimit
diff --git a/server/requirements/requirements.txt b/server/requirements/requirements.txt
index 4f09972f..b3e71681 100644
--- a/server/requirements/requirements.txt
+++ b/server/requirements/requirements.txt
@@ -71,8 +71,6 @@ django-csp==3.7
# via -r requirements.in
django-filter==21.1
# via wagtail
-django-htmx==1.9.0
- # via -r requirements.in
django-ipware==4.0.2
# via -r requirements.in
django-model-utils==4.2.0
diff --git a/server/vbv_lernwelt/completion/urls.py b/server/vbv_lernwelt/completion/urls.py
deleted file mode 100644
index 891712bf..00000000
--- a/server/vbv_lernwelt/completion/urls.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from django.urls import path
-
-from vbv_lernwelt.completion.views import request_circle_completion, mark_circle_completion, \
- request_learning_path_completion
-
-urlpatterns = [
- path(r"circle//", request_circle_completion, name="request_circle_completion"),
- path(r"learning_path//", request_learning_path_completion, name="request_learning_path_completion"),
- path(r"circle/mark/", mark_circle_completion, name="mark_circle_completion"),
-]
diff --git a/server/vbv_lernwelt/core/views.py b/server/vbv_lernwelt/core/views.py
index 7fbaf728..dd647446 100644
--- a/server/vbv_lernwelt/core/views.py
+++ b/server/vbv_lernwelt/core/views.py
@@ -1,4 +1,6 @@
# Create your views here.
+import glob
+from pathlib import Path
import requests
import structlog
@@ -23,9 +25,7 @@ logger = structlog.get_logger(__name__)
@django_view_authentication_exempt
@ensure_csrf_cookie
-
-
-def vue_home(request):
+def vue_home(request, *args):
if settings.IT_SERVE_VUE:
try:
res = requests.get(f'{settings.IT_SERVE_VUE_URL}{request.get_full_path()}')
@@ -114,3 +114,24 @@ def cypress_reset_view(request):
call_command('cypress_reset')
return HttpResponseRedirect('/admin/')
+
+
+@django_view_authentication_exempt
+def generate_web_component_icons(request):
+ svg_files = []
+ for filepath in glob.iglob(f'{settings.APPS_DIR}/static/icons/*.svg'):
+ with open(filepath, 'r') as f:
+ filename = Path(filepath).stem
+ elementname = 'it-' + filename
+ svg_files.append({
+ 'filepath': filepath,
+ 'content': f.read(),
+ 'filename': filename,
+ 'elementname': elementname,
+ 'classname': filename.replace('-', '_'),
+ })
+ return render(
+ request, "core/icons.html",
+ context={'svg_files': svg_files},
+ content_type="application/javascript"
+ )
diff --git a/server/vbv_lernwelt/learnpath/tests/test_api.py b/server/vbv_lernwelt/learnpath/tests/test_api.py
index 1bfd83eb..7fa29ae0 100644
--- a/server/vbv_lernwelt/learnpath/tests/test_api.py
+++ b/server/vbv_lernwelt/learnpath/tests/test_api.py
@@ -18,7 +18,7 @@ class TestRetrieveLearingPathContents(APITestCase):
def test_get_learnpathPage(self):
learning_path = LearningPath.objects.get(slug='unit-test-lernpfad')
- response = self.client.get('/learnpath/api/page/unit-test-lernpfad/')
+ response = self.client.get('/api/learnpath/page/unit-test-lernpfad/')
print(response)
self.assertEqual(response.status_code, 200)
data = response.json()
diff --git a/server/vbv_lernwelt/learnpath/urls.py b/server/vbv_lernwelt/learnpath/urls.py
deleted file mode 100644
index 2d12205e..00000000
--- a/server/vbv_lernwelt/learnpath/urls.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.urls import path, re_path
-
-from .views import generate_web_component_icons, page_api_view
-
-urlpatterns = [
- path(r"api/page//", page_api_view, name="page_api_view"),
- re_path(r"icons/$", generate_web_component_icons, name="generate_web_component_icons"),
-]
diff --git a/server/vbv_lernwelt/learnpath/views.py b/server/vbv_lernwelt/learnpath/views.py
index 590bbd66..2e6856be 100644
--- a/server/vbv_lernwelt/learnpath/views.py
+++ b/server/vbv_lernwelt/learnpath/views.py
@@ -1,17 +1,11 @@
# Create your views here.
-import glob
-from pathlib import Path
import structlog
-from django.conf import settings
-from django.shortcuts import render
from django.views.decorators.cache import cache_page
from rest_framework.decorators import api_view
from rest_framework.response import Response
from wagtail.models import Page
-from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt
-
logger = structlog.get_logger(__name__)
@@ -27,22 +21,3 @@ def page_api_view(request, slug):
return Response({"error": str(e)}, status=404)
-@django_view_authentication_exempt
-def generate_web_component_icons(request):
- svg_files = []
- for filepath in glob.iglob(f'{settings.APPS_DIR}/static/icons/*.svg'):
- with open(filepath, 'r') as f:
- filename = Path(filepath).stem
- elementname = 'it-' + filename
- svg_files.append({
- 'filepath': filepath,
- 'content': f.read(),
- 'filename': filename,
- 'elementname': elementname,
- 'classname': filename.replace('-', '_'),
- })
- return render(
- request, "learnpath/icons.html",
- context={'svg_files': svg_files},
- content_type="application/javascript"
- )
diff --git a/server/vbv_lernwelt/templates/base.html b/server/vbv_lernwelt/templates/base.html
index 95f38e68..ea9f3d72 100644
--- a/server/vbv_lernwelt/templates/base.html
+++ b/server/vbv_lernwelt/templates/base.html
@@ -19,8 +19,7 @@
{# Placed at the top of the document so pages load faster with defer #}
-
-
+
{% block javascript %}
diff --git a/server/vbv_lernwelt/templates/learnpath/icons.html b/server/vbv_lernwelt/templates/core/icons.html
similarity index 100%
rename from server/vbv_lernwelt/templates/learnpath/icons.html
rename to server/vbv_lernwelt/templates/core/icons.html
diff --git a/server/vbv_lernwelt/templates/wagtailadmin/pages/index.html b/server/vbv_lernwelt/templates/wagtailadmin/pages/index.html
index 02a8b599..a57c29ae 100644
--- a/server/vbv_lernwelt/templates/wagtailadmin/pages/index.html
+++ b/server/vbv_lernwelt/templates/wagtailadmin/pages/index.html
@@ -17,7 +17,7 @@
-
+