Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ DB_PORT=5432
AAF_URL=https://rapid.test.aaf.edu.au/jwt/authnrequest/research/your-custom-url-here
AAF_SECRET=SECERET_USED_FOR_AAF_APP_REGISTRATION

# API Secret for single consumer (can be extended)
API_SECRET=supersecretsharedsecretstring
# THIS MUST BE CHANGED TO YOUR FQDN
API_URL=''

# Set to 0 in production
DEBUG=1
Expand Down
2 changes: 2 additions & 0 deletions clatoolkit_project/clatoolkit_project/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
#EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' # During development only
API_SECRET=os.environ.get('API_SECRET')
API_URL=os.enivron.get('API_URL')

# Application definition

Expand Down
17 changes: 17 additions & 0 deletions clatoolkit_project/dashboard/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,23 @@
from xapi.statement.xapi_filter import xapi_filter
from xapi.oauth_consumer.operative import LRS_Auth

def get_user_truncated_xapi(user, platforms=None, course_id=None):
user_lrs = LearningRecord.objects.filter(user_id=user)
if platforms:
platforms = [platform.capitalize() for platform in platforms]
user_lrs = user_lrs.filter(platform__in=platforms)
if course_id:
user_lrs = user_lrs.filter(unit_id=course_id)
data = []
for lr in user_lrs:
trunc_xapi = {}
trunc_xapi['verb'] = lr.verb
trunc_xapi['object'] = lr.platformid
trunc_xapi['date'] = lr.datetimestamp
trunc_xapi['platform'] = lr.platform
data.append(trunc_xapi)

return data


def getPluginKey(platform):
Expand Down
43 changes: 39 additions & 4 deletions clatoolkit_project/dashboard/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,37 @@
from xapi.statement.xapi_filter import xapi_filter
from xapi.statement.xapi_getter import xapi_getter

# custom jwt auth for api endpoints (currently only for one consumer, have models/form in place to extend to sign-ups)
def jwt_auth(fn):
"""
Decorator to authorize an api endpoint against specific user in the toolkit
using a jwt. For now, this is implemented as a single consumer (i.e. only
one consumer can be specified atm in settings.py (API_SECRET/API_URL). This can
be extended upon to allow arbitrary/niche
access and imports of data into the toolkit.

Receives the jwt from the HTTP_AUTHORIZATION header, decodes using shared secret
(settings.API_SECRET) and verifies the HTTP_REFERER against the consumers web location
(settings.API_URL). If all criteria is passed, the decorator logs in (fills request.user) the user and returns
the appropriate data as defined by the view.

:return: View with user added to request.user
"""
def _wrapped_fn(request, *args, **kwargs):
try:
token = request.META['HTTP_API_AUTH']
except:
raise Exception(request.META)
ver_jwt = jwt.decode(token, settings.API_SECRET)
if request.META.get('HTTP_REFERER', '') == settings.API_URL:
user = User.objects.get(email=ver_jwt['user'])
if user is not None:
user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)
return fn(request, *args, **kwargs)
else:
return PermissionDenied
return _wrapped_fn


#API endpoint to grab a list of trello boards to attach to course
Expand Down Expand Up @@ -642,13 +673,17 @@ def get_platform_activities(request):
return response


@jwt_auth
def get_user_acitivities(request):
platform_names = request.GET.get('platform').split(',')
val = get_user_acitivities_dataset(request.GET.get('course_code'), platform_names)
response = JsonResponse(val, status=status.HTTP_200_OK)
platforms = request.GET.get('platform', None)
course_id = request.GET.get('course_id', None)
if platforms:
platforms = platforms.split(',')
# val = get_user_acitivities_dataset(request.GET.get('course_code'), platform_names)
val = get_user_truncated_xapi(request.user, platforms=platforms, course_id=course_id)
response = JsonResponse(dict(user_activities=list(val)), status=status.HTTP_200_OK)
return response


@login_required
def get_all_repos(request):
course_id = request.GET.get('course_id')
Expand Down