Commit e9812a9a authored by Traas, J.J.'s avatar Traas, J.J.
Browse files

Merge branch 'feature_platforms' into 'master'

Add list of platforms file and API endpoint.

See merge request !4
parents 6b740a0e b9918876
Pipeline #2256 passed with stage
in 50 seconds
\ No newline at end of file
\ No newline at end of file
......@@ -106,4 +106,6 @@ venv.bak/
# editor configs
\ No newline at end of file
\ No newline at end of file
......@@ -59,6 +59,8 @@ $ pipenv run migrate
$ pipenv run python createsuperuser
Copy ```.env.example``` to ```.env``` and ```platforms.json.example``` to ```platforms.json```, adjusting them if needed.
### Usage
``` bash
......@@ -8,11 +8,15 @@ For the full list of settings and their values, see
import json
import logging
import os
from urllib.parse import urlparse
import dj_database_url
logger = logging.getLogger(__name__)
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
......@@ -25,11 +29,23 @@ PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
FRONTEND_URL = os.environ.get("FRONTEND_URL", "http://localhost:8080/#/")
ANALYTICS_URL = os.environ.get("ANALYTICS_URL", None)
if not FRONTEND_URL.endswith("#/"):
PLATFORMS = json.load(open("./platforms.json"))
except (IOError, ValueError) as e:
# Use default value if platforms.json not found or not valid
logger.error("platforms.json not found or invalid! Reverting to fallback.")
"id": "coursera",
"name": "Coursera Fallback (platforms.json not found)",
"url": "http://localhost:8001/api/",
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = "DJANGO_DEBUG" in os.environ
......@@ -21,16 +21,15 @@ from django.urls import include, path, re_path
import courses.routers
import users.routers
import users.urls
from eit_dashboard.settings import ANALYTICS_URL
from eit_dashboard.views import ApiProxyView
from eit_dashboard.settings import PLATFORMS
from eit_dashboard.views import ApiProxyView, PlatformListView
urlpatterns = [
path("o/", include(users.urls)),
path("o/", include((oauth2_provider.urls.base_urlpatterns, "oauth2_provider"))),
path("p/", PlatformListView, name="platform-list-view"),
path("p/<platform>/<path>/", ApiProxyView),
path("", include(users.routers)),
path("", include(courses.routers)),
if ANALYTICS_URL is not None: # pragma: no cover
urlpatterns.append(re_path("api/(?P<path>.*)", ApiProxyView))
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from proxy.views import proxy_view
from rest_framework.decorators import api_view, permission_classes
from rest_framework.permissions import IsAuthenticated
from eit_dashboard.settings import ANALYTICS_URL
from eit_dashboard.settings import PLATFORMS
# TODO: This assumes there is only one analytics server
# It is marked "no cover" because it is not possible to unit test this functionality
def ApiProxyView(request, path): # pragma: no cover
remoteurl = ANALYTICS_URL + path
return proxy_view(request, remoteurl)
def ApiProxyView(request, platform, path): # pragma: no cover
for p in PLATFORMS:
if p["id"] == platform:
return proxy_view(request, p["url"] + path)
return HttpResponse(status=404)
def PlatformListView(request):
return JsonResponse(PLATFORMS, safe=False)
"id": "coursera",
"name": "Coursera Local Test Platform",
"url": "http://localhost:8001/api/"
import json
import pytest
from django.urls import reverse
def test_platform_list_view(user_api_client):
Test that an authenticated user can access the platform list view.
response = user_api_client.get(reverse("platform-list-view"))
assert response.status_code == 200, response.content
def test_platform_list_view_access(api_client):
Test that an unauthenticated user cannot access the platform list view.
response = api_client.get(reverse("platform-list-view"))
assert (
response.status_code == 403 or response.status_code == 401
), "unauthenticated user could reach test view"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment