Skip to content
Snippets Groups Projects
Commit 8169f520 authored by Benjamin Zagorsky's avatar Benjamin Zagorsky
Browse files

Merge branch 'develop' of...

Merge branch 'develop' of github.com:Harvard-University-iCommons/django-auth-lti into feature/configuration_check

Conflicts:
	django_auth_lti/mixins.py
parents dcd36b74 fc2df4df
No related branches found
No related tags found
No related merge requests found
......@@ -2,4 +2,5 @@
*.pyo
build
dist
django_auth_lti.egg-info
*.egg-info
*.egg
include README.md
include LICENSE
recursive-include django_auth_lti *.py *.html
recursive-include django_auth_lti *.py
......@@ -17,6 +17,10 @@ LTI_OAUTH_CREDENTIALS = {
}
```
The LTIAuthMiddleware will ensure that all users of your app are authenticated before they can access any page. Upon successful authentication, a Django user record is created (or updated) and the user is allowed to access the application.
* OPTIONALly, you can define a custom role key at the project level. Doing so will cause the middleware to look for any roles associated with that key during the launch request and merge them into the default LTI roles list. You can declare such a key by adding this to your project configuration:
```
LTI_CUSTOM_ROLE_KEY = 'my-custom-role-key-change-me'
```
The LTIAuthMiddleware will ensure that all users of your app are authenticated before they can access any page. Upon successful authentication, a Django user record is created (or updated) and the user is allowed to access the application.
from django.contrib import auth
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.core.exceptions import ImproperlyConfigured
from django.conf import settings
from timer import Timer
......@@ -83,6 +84,7 @@ class LTIAuthMiddleware(object):
'lis_person_name_given': request.POST.get('lis_person_name_given', None),
'lis_person_name_family': request.POST.get('lis_person_name_family', None),
'lis_person_contact_email_primary': request.POST.get('lis_person_contact_email_primary', None),
'lis_person_name_full': request.POST.get('lis_person_name_full', None),
'user_id': request.POST.get('user_id', None),
'custom_canvas_user_id': request.POST.get('custom_canvas_user_id', None),
'custom_canvas_api_domain': request.POST.get('custom_canvas_api_domain', None),
......@@ -91,6 +93,10 @@ class LTIAuthMiddleware(object):
'custom_canvas_user_login_id': request.POST.get('custom_canvas_user_login_id', None),
'roles': request.POST.get('roles', '').split(','),
}
# If a custom role key is defined in project, merge into existing role list
if hasattr(settings, 'LTI_CUSTOM_ROLE_KEY'):
custom_roles = request.POST.get(settings.LTI_CUSTOM_ROLE_KEY, '').split(',')
lti_launch['roles'] += filter(None, custom_roles) # Filter out any empty roles
request.session['LTI_LAUNCH'] = lti_launch
......
......@@ -5,7 +5,15 @@ from braces.views import LoginRequiredMixin
from django_auth_lti.verification import is_allowed
class LTIRoleRestrictionMixin(object):
class LTIUtilityMixin(object):
def get_lti_param(self, keyword, default=None):
return self.request.session['LTI_LAUNCH'].get(keyword, default)
def current_user_roles(self):
return self.get_lti_param('roles', [])
class LTIRoleRestrictionMixin(LTIUtilityMixin):
allowed_roles = None
redirect_url = reverse_lazy('not_authorized')
raise_exception = False
......
# Add models here
import unittest
import mock
from mock import patch
from django.test import RequestFactory
from django.contrib.auth import models
from django_auth_lti.middleware import LTIAuthMiddleware
@patch('django_auth_lti.middleware.logger')
class TestLTIAuthMiddleware(unittest.TestCase):
longMessage = True
def setUp(self):
self.mw = LTIAuthMiddleware()
def build_lti_launch_request(self, post_data):
"""
Utility method that builds a fake lti launch request with custom data.
"""
# Add message type to post data
post_data.update(lti_message_type='basic-lti-launch-request')
request = RequestFactory().post('/fake/lti/launch', post_data)
request.user = mock.Mock(name='User', spec=models.User)
request.session = {}
return request
@patch('django_auth_lti.middleware.auth')
def test_roles_merged_with_custom_roles(self, mock_auth, mock_logger):
"""
Assert that 'roles' list in session contains merged set of roles when custom role key is
defined and values have been passed in.
"""
request = self.build_lti_launch_request({
'roles': 'RoleOne,RoleTwo',
'test_custom_role_key': 'My,Custom,Roles',
})
with patch('django_auth_lti.middleware.settings', LTI_CUSTOM_ROLE_KEY='test_custom_role_key'):
self.mw.process_request(request)
self.assertEqual(request.session['LTI_LAUNCH']['roles'], ['RoleOne', 'RoleTwo', 'My', 'Custom', 'Roles'])
@patch('django_auth_lti.middleware.auth')
def test_roles_merge_with_empty_custom_roles(self, mock_auth, mock_logger):
"""
Assert that 'roles' list in session contains original set when custom role key is defined with empty data.
"""
request = self.build_lti_launch_request({
'roles': 'RoleOne,RoleTwo',
'test_custom_role_key': '',
})
with patch('django_auth_lti.middleware.settings', LTI_CUSTOM_ROLE_KEY='test_custom_role_key'):
self.mw.process_request(request)
self.assertEqual(request.session['LTI_LAUNCH']['roles'], ['RoleOne', 'RoleTwo'])
@patch('django_auth_lti.middleware.auth')
def test_roles_not_merged_with_no_role_key(self, mock_auth, mock_logger):
"""
Assert that 'roles' list in session contains original set when no custom role key is defined.
"""
request = self.build_lti_launch_request({
'roles': 'RoleOne,RoleTwo',
'test_custom_role_key': 'My,Custom,Roles',
})
self.mw.process_request(request)
self.assertEqual(request.session['LTI_LAUNCH']['roles'], ['RoleOne', 'RoleTwo'])
#!/usr/bin/env python
from django.conf import settings
def runtests():
settings.configure(
# App-specific setttings here
)
# settings must be configured for this import to work
from django.test.runner import DiscoverRunner
DiscoverRunner(interactive=False, failfast=False).run_tests(['django_auth_lti'])
if __name__ == '__main__':
runtests()
import os
from setuptools import setup
from setuptools import find_packages
README = open(os.path.join(os.path.dirname(__file__), 'README.md')).read()
......@@ -9,8 +8,8 @@ os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
setup(
name='django-auth-lti',
version='0.5',
packages=find_packages(),
version='0.7',
packages=['django_auth_lti'],
include_package_data=True,
license='TBD License', # example license
description='A simple Django app containing LTI auth middleware and backend.',
......@@ -32,9 +31,11 @@ setup(
],
install_requires=[
"Django>=1.6",
"django-filter==0.7",
"ims-lti-py==0.6",
"django-braces==1.3.1",
],
tests_require=[
'mock',
],
zip_safe=False,
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment