Skip to content

Commit

Permalink
- Ability to pass custom params from oidc login to launch.
Browse files Browse the repository at this point in the history
- AssignmentsGradesService.get_lineitems new public method
- MessageLaunch.fetch_public_key that can be overridden
- Example update
  • Loading branch information
dmitry-viskov committed Aug 16, 2019
1 parent 621353a commit e1019c4
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 21 deletions.
11 changes: 8 additions & 3 deletions examples/game/game/views.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import datetime
import os
import pprint

from django.conf import settings
from django.urls import reverse
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render
from django.views.decorators.http import require_POST
Expand Down Expand Up @@ -34,20 +34,25 @@ def get_lti_config_path():


def get_launch_url(request):
return request.build_absolute_uri(reverse('game-launch'))
target_link_uri = request.POST.get('target_link_uri', request.GET.get('target_link_uri'))
if not target_link_uri:
raise Exception('Missing "target_link_uri" param')
return target_link_uri


def login(request):
tool_conf = ToolConfJsonFile(get_lti_config_path())
oidc_login = DjangoOIDCLogin(request, tool_conf)
return oidc_login.redirect(get_launch_url(request))
target_link_uri = get_launch_url(request)
return oidc_login.redirect(target_link_uri)


@require_POST
def launch(request):
tool_conf = ToolConfJsonFile(get_lti_config_path())
message_launch = ExtendedDjangoMessageLaunch(request, tool_conf)
message_launch_data = message_launch.get_launch_data()
pprint.pprint(message_launch_data)

return render(request, 'game.html', {
'is_deep_link_launch': message_launch.is_deep_link_launch(),
Expand Down
2 changes: 1 addition & 1 deletion pylti1p3/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '1.0.0'
__version__ = '1.1.0'
8 changes: 6 additions & 2 deletions pylti1p3/assignments_grades.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def put_grade(self, grade, line_item=None):
content_type='application/vnd.ims.lis.v1.score+json'
)

def find_or_create_lineitem(self, new_line_item):
def get_lineitems(self):
if "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem" not in self._service_data['scope']:
raise LtiException('Missing required scope')

Expand All @@ -44,8 +44,12 @@ def find_or_create_lineitem(self, new_line_item):
self._service_data['lineitems'],
accept='application/vnd.ims.lis.v2.lineitemcontainer+json'
)
return line_items['body']

def find_or_create_lineitem(self, new_line_item):
line_items = self.get_lineitems()

for line_item in line_items['body']:
for line_item in line_items:
if line_item['tag'] == new_line_item.get_tag():
return LineItem(line_item)

Expand Down
12 changes: 7 additions & 5 deletions pylti1p3/contrib/django/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ def save_nonce(self, nonce):

def check_nonce(self, nonce):
nonce_key = self._get_key('nonce', nonce)
try:
del self._request.session[nonce_key]
return True
except KeyError:
return False
return nonce_key in self._request.session

def save_state_params(self, state, params):
self._request.session[self._get_key(state)] = params

def get_state_params(self, state):
return self._request.session[self._get_key(state)]
25 changes: 16 additions & 9 deletions pylti1p3/message_launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,21 +218,24 @@ def urlsafe_b64decode(self, val):
tmp = str(val).translate(string.maketrans('-_', '+/'))
return base64.b64decode(tmp)

def fetch_public_key(self, key_set_url):
try:
resp = requests.get(key_set_url)
except requests.exceptions.RequestException as e:
raise LtiException("Error during fetch URL " + key_set_url + ": " + str(e))
try:
return resp.json()
except ValueError:
raise LtiException("Invalid response from " + key_set_url + ". Must be JSON: " + resp.text)

def get_public_key(self):
public_key_set = self._registration.get_key_set()
key_set_url = self._registration.get_key_set_url()

if not public_key_set:
if key_set_url.startswith(('http://', 'https://')):
try:
resp = requests.get(key_set_url)
except requests.exceptions.RequestException as e:
raise LtiException("Error during fetch URL " + key_set_url + ": " + str(e))
try:
public_key_set = resp.json()
self._registration.set_key_set(public_key_set)
except ValueError:
raise LtiException("Invalid response from " + key_set_url + ". Must be JSON: " + resp.text)
public_key_set = self.fetch_public_key(key_set_url)
self._registration.set_key_set(public_key_set)
else:
raise LtiException("Invalid URL: " + key_set_url)

Expand Down Expand Up @@ -368,3 +371,7 @@ def validate_message(self):
def save_launch_data(self):
self._session_service.save_launch_data(self._launch_id, self._jwt['body'])
return self

def get_params_from_login(self):
state = self._get_request_param('state')
return self._session_service.get_state_params(state)
9 changes: 9 additions & 0 deletions pylti1p3/oidc_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class OIDCLogin(object):
_tool_config = None
_session_service = None
_cookie_service = None
_state_params = {}

def __init__(self, request, tool_config, session_service, cookie_service):
self._request = request
Expand Down Expand Up @@ -48,6 +49,8 @@ def _prepare_redirect(self, launch_url):
# generate nonce
nonce = self._get_uuid()
self._session_service.save_nonce(nonce)
if self._state_params:
self._session_service.save_state_params(self._state_params)

# build Response
auth_params = {
Expand Down Expand Up @@ -109,3 +112,9 @@ def validate_oidc_login(self):
raise OIDCException("Could not find registration details")

return registration

def pass_params_to_launch(self, params):
"""
Ability to pass custom params from oidc login to launch.
"""
self._state_params = params
8 changes: 8 additions & 0 deletions pylti1p3/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ def save_nonce(self, nonce):
@abstractmethod
def check_nonce(self, nonce):
raise NotImplementedError

@abstractmethod
def save_state_params(self, state, params):
raise NotImplementedError

@abstractmethod
def get_state_params(self, state):
raise NotImplementedError
1 change: 0 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import print_function

import os
import sys

from setuptools import setup, find_packages
Expand Down

0 comments on commit e1019c4

Please sign in to comment.