import notifications.urls from django.conf import settings from django.conf.urls.static import static from django.contrib import admin from django.contrib.auth.decorators import user_passes_test from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.http import HttpResponse from django.urls import include, path, re_path, register_converter from django.urls.converters import IntConverter from django.views import defaults as default_views from django.views.decorators.csrf import csrf_exempt from django_ratelimit.exceptions import Ratelimited from graphene_django.views import GraphQLView from vbv_lernwelt.api.directory import list_entities from vbv_lernwelt.api.user import get_profile, me_user_view, post_avatar from vbv_lernwelt.assignment.views import request_assignment_completion_status from vbv_lernwelt.core.middleware.auth import django_view_authentication_exempt from vbv_lernwelt.core.schema import schema from vbv_lernwelt.core.views import ( check_rate_limit, cypress_reset_view, generate_web_component_icons, iterativ_test_coursesessions_reset_view, permission_denied_view, rate_limit_exceeded_view, vue_home, vue_login, vue_logout, ) from vbv_lernwelt.course.views import ( course_page_api_view, document_delete, document_direct_upload, document_upload_finish, document_upload_start, get_course_sessions, mark_course_completion_view, request_course_completion, request_course_completion_for_user, ) from vbv_lernwelt.course_session.views import get_course_session_documents from vbv_lernwelt.dashboard.views import ( export_attendance_as_xsl, export_competence_elements_as_xsl, export_feedback_as_xsl, get_dashboard_config, get_dashboard_due_dates, get_dashboard_persons, get_mentee_count, get_mentor_open_tasks_count, ) from vbv_lernwelt.edoniq_test.views import ( export_students, export_students_and_trainers, export_trainers, get_edoniq_token_redirect, ) from vbv_lernwelt.feedback.views import ( get_expert_feedbacks_for_course, get_feedback_for_circle, ) from vbv_lernwelt.files.views import presign from vbv_lernwelt.importer.views import ( coursesessions_students_import, coursesessions_trainers_import, t2l_sync, ) from vbv_lernwelt.media_files.views import user_image from vbv_lernwelt.notify.views import email_notification_settings from vbv_lernwelt.shop.datatrans.datatrans_fake_server import ( fake_datatrans_api_view, fake_datatrans_pay_view, ) from wagtail import urls as wagtail_urls from wagtail.admin import urls as wagtailadmin_urls from wagtail.documents import urls as media_library_urls class SignedIntConverter(IntConverter): regex = r"-?\d+" def to_python(self, value): return int(value) def to_url(self, value): return str(value) # Register the converter register_converter(SignedIntConverter, "signed_int") def raise_example_error(request): """ raise error to check if it gets logged """ raise Exception("Test Error: I know python!") # pylint: disable=unreachable return HttpResponse("no error?") # fmt: off urlpatterns = [ path(settings.ADMIN_URL, admin.site.urls), # wagtail urls path('server/cms/', include(wagtailadmin_urls)), path('server/documents/', include(media_library_urls)), path('server/pages/', include(wagtail_urls)), # core re_path(r"server/core/icons/$", generate_web_component_icons, name="generate_web_component_icons"), # user management path("sso/", include("vbv_lernwelt.sso.urls")), re_path(r'api/core/me/$', me_user_view, name='me_user_view'), re_path(r'api/core/avatar/$', post_avatar, name='post_avatar'), re_path(r'api/core/entities/$', list_entities, name='list_entities'), path(r'api/core/profile//', get_profile, name='get_profile_view'), 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'), # notifications re_path(r'^notifications/', include(notifications.urls, namespace='notifications')), # notify re_path(r"api/notify/email_notification_settings/$", email_notification_settings, name='email_notification_settings'), # dashboard path(r"api/dashboard/persons/", get_dashboard_persons, name="get_dashboard_persons"), path(r"api/dashboard/duedates/", get_dashboard_due_dates, name="get_dashboard_due_dates"), path(r"api/dashboard/config/", get_dashboard_config, name="get_dashboard_config"), path(r"api/dashboard/course//mentees/", get_mentee_count, name="get_mentee_count"), path(r"api/dashboard/course//open_tasks/", get_mentor_open_tasks_count, name="get_mentor_open_tasks_count"), path(r"api/dashboard/export/attendance/", export_attendance_as_xsl, name="export_attendance_as_xsl"), path(r"api/dashboard/export/competence_elements/", export_competence_elements_as_xsl, name="export_certificate_as_xsl"), path(r"api/dashboard/export/feedback/", export_feedback_as_xsl, name="export_feedback_as_xsl"), # course path(r"api/course/sessions/", get_course_sessions, name="get_course_sessions"), path(r"api/course/page//", course_page_api_view, name="course_page_api_view"), path(r"api/course/completion/mark/", mark_course_completion_view, name="mark_course_completion"), path(r"api/course/completion//", request_course_completion, name="request_course_completion"), path(r"api/course/completion///", request_course_completion_for_user, name="request_course_completion_for_user"), path("api/mentor//", include("vbv_lernwelt.learning_mentor.urls")), # self evaluation feedback path("api/self-evaluation-feedback/", include("vbv_lernwelt.self_evaluation_feedback.urls")), # assignment path( r"api/assignment///status/", request_assignment_completion_status, name="request_assignment_completion_status"), # documents path("api/core/userimage/", user_image, name="user_image"), # TODO: remfactor to files app path(r'api/core/document/start/', document_upload_start, name='file_upload_start'), path(r'api/core/document//', document_delete, name='document_delete'), path(r'api/core/file/finish/', document_upload_finish, name='file_upload_finish'), path(r"api/core/document/local//", document_direct_upload, name='file_upload_local'), path(r'api/core/document/list//', get_course_session_documents, name='get_course_session_documents'), # file storage path(r'api/core/storage/presign/', presign, name='storage_presign'), # feedback path(r'api/core/feedback//summary/', get_expert_feedbacks_for_course, name='feedback_summary'), path(r'api/core/feedback///', get_feedback_for_circle, name='feedback_for_circle'), # edoniq test path(r'api/core/edoniq-test/redirect/', get_edoniq_token_redirect, name='get_edoniq_token_redirect'), path(r'api/core/edoniq-test/export-users/', export_students, name='edoniq_export_students'), path(r'api/core/edoniq-test/export-trainers/', export_trainers, name='edoniq_export_trainers'), path(r'api/core/edoniq-test/export-users-trainers/', export_students_and_trainers, name='edoniq_export_students_and_trainers'), # shop path("api/shop/", include("vbv_lernwelt.shop.urls")), # importer path( r"server/importer/coursesession-trainer-import/", coursesessions_trainers_import, name="coursesessions_trainers_import", ), path( r"server/importer/coursesession-students-import/", coursesessions_students_import, name="coursesessions_students_import", ), path( r"server/importer/t2l-sync/", t2l_sync, name="t2l_sync", ), # iterativ Test course sessions path( r"api/core/resetiterativsessions/", iterativ_test_coursesessions_reset_view, name="iterativ_test_coursesessions_reset_view", ), path("server/graphql/", csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))), # 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 not settings.APP_ENVIRONMENT.startswith('prod'): urlpatterns += [ re_path(r'api/core/cypressreset/$', cypress_reset_view, name='cypress_reset_view'), ] if settings.DEBUG: # Static file serving when using Gunicorn + Uvicorn for local web socket development urlpatterns += staticfiles_urlpatterns() if "fakeapi" in settings.DATATRANS_API_ENDPOINT: urlpatterns += [ re_path( r"^server/fakeapi/datatrans/api(?P.*)$", fake_datatrans_api_view ), re_path( r"^server/fakeapi/datatrans/pay(?P.*)$", fake_datatrans_pay_view ), ] # fmt: on def handler403(request, exception=None): if isinstance(exception, Ratelimited): # if request.path.startswith("/swisscom/customer"): # return SwisscomCustomerLandingPageErrorView.as_view()(request) return rate_limit_exceeded_view(request, exception) return permission_denied_view(request, exception) handler500 = "vbv_lernwelt.core.views.server_json_error" if settings.DEBUG: # This allows the error pages to be debugged during development, just visit # these url in browser to see how these error pages look like. urlpatterns += [ path( "400/", default_views.bad_request, kwargs={"exception": Exception("Bad Request!")}, ), path( "403/", default_views.permission_denied, kwargs={"exception": Exception("Permission Denied")}, ), path( "404/", default_views.page_not_found, kwargs={"exception": Exception("Page not Found")}, ), path("500/", default_views.server_error), ] if "debug_toolbar" in settings.INSTALLED_APPS: import debug_toolbar urlpatterns = [path("__debug__/", include(debug_toolbar.urls))] + urlpatterns # serve everything else via the vue app urlpatterns += [re_path(r"^(?!.*(server/|api/|sso/)).*$", vue_home, name="home")]