diff --git a/training-portal/src/project/apps/workshops/urls.py b/training-portal/src/project/apps/workshops/urls.py index 80bb43e8..3775a6d3 100644 --- a/training-portal/src/project/apps/workshops/urls.py +++ b/training-portal/src/project/apps/workshops/urls.py @@ -10,7 +10,8 @@ views.catalog_environments, name="workshops_catalog_environments", ), - path("environment//", views.environment, name="workshops_environment"), + path("environment//", views.environment, + name="workshops_environment"), path( "environment//create/", views.environment_create, @@ -47,6 +48,11 @@ views.session_extend, name="workshops_session_extend", ), + path( + "session//terminate/", + views.session_terminate, + name="workshops_session_terminate", + ), path( "session//event/", views.session_event, diff --git a/training-portal/src/project/apps/workshops/views/session.py b/training-portal/src/project/apps/workshops/views/session.py index 1e26c948..c7dad3ff 100644 --- a/training-portal/src/project/apps/workshops/views/session.py +++ b/training-portal/src/project/apps/workshops/views/session.py @@ -133,6 +133,44 @@ def session_activate(request, name): return redirect("workshops_session", name=instance.name) +@protected_resource() +@require_http_methods(["GET"]) +def session_terminate(request, name): + """Triggers termination of a workshop session.""" + + portal = TrainingPortal.objects.get(name=settings.TRAINING_PORTAL) + + # Ensure that the session exists. + + instance = portal.allocated_session(name) + + if not instance: + raise Http404("Session does not exist") + + # Check that session is allocated and in use. + + if not instance.is_allocated(): + return HttpResponseForbidden("Session is not currently in use") + + if not request.user.is_staff and not request.user.groups.filter(name="robots").exists(): + if instance.owner != request.user: + return HttpResponseForbidden("Access to session not permitted") + + instance.mark_as_stopping() + + report_analytics_event(instance, "Session/Stopping") + + transaction.on_commit( + lambda: delete_workshop_session(instance).schedule()) + + details = {} + + details["started"] = instance.started + details["expires"] = instance.expires + + return JsonResponse(details) + + @login_required(login_url="/") @require_http_methods(["GET"]) @resources_lock