Skip to content
Snippets Groups Projects
Unverified Commit af68c7cf authored by Alex Dusenbery's avatar Alex Dusenbery Committed by GitHub
Browse files

Merge pull request #38 from edx/aed/EDUCATOR-2516

Add context_title and context_label parameters
parents c1c7233b 349b8df8
No related branches found
No related tags found
No related merge requests found
......@@ -15,3 +15,6 @@ codekit-config.json
### Testing artifacts
.coverage
var/
# virtualenvironment
venv/
\ No newline at end of file
......@@ -15,6 +15,31 @@ root folder:
$ pip install -r requirements.txt
Installing in Docker Devstack
-----------------------------
Assuming that your ``devstack`` repo lives at ``~/code/devstack``
and that ``edx-platform`` lives right alongside that directory, you'll want
to checkout ``xblock-lti-consumer`` and have it live in ``~/code/src/xblock-lti-consumer``.
This will make it so that you can access it inside an LMS container shell
and easily make modifications for local testing.
Run ``make lms-shell`` from your ``devstack`` directory to enter a running LMS container.
Once in there, you can do the following to have your devstack pointing at a local development
version of ``xblock-lti-consumer``:
.. code:: bash
$ pushd /edx/src/xblock-lti-consumer
$ virtualenv venv/
$ source venv/bin/activate
$ make install
$ make test # optional, if you want to see that everything works
$ deactivate
$ pushd # should take you back to /edx/app/edxapp/edx-platform
$ pip uninstall -y lti_consumer_xblock
$ pip install -e /edx/src/xblock-lti-consumer
Enabling in Studio
------------------
......@@ -27,6 +52,30 @@ advanced settings.
``"lti_consumer"`` to the policy value list.
3. Click the "Save changes" button.
Testing Against an LTI Provider
-------------------------------
http://lti.tools/saltire/ provides a "Test Tool Provider" service that allows
you to see messages sent by an LTI consumer.
We have some useful documentation on how to set this up here:
http://edx.readthedocs.io/projects/open-edx-building-and-running-a-course/en/latest/exercises_tools/lti_component.html#lti-authentication-information
1. In Studio Advanced settings, set the value of the "LTI Passports" field to "test:test:secret" -
this will set the oauth client key and secret used to send a message to the test LTI provider.
2. Create an LTI Consumer problem in a course in studio (after enabling it in "advanced_modules"
as seen above). Make a unit, select "Advanced", then "LTI Consumer".
3. Click edit and fill in the following fields:
``LTI ID``: "test"
``LTI URL``: "http://lti.tools/saltire/tp"
4. Click save. The unit should refresh and you should see "Passed" in the "Verification" field of
the message tab in the LTI Tool Provider emulator.
5. Click the "Publish" button.
6. View the unit in your local LMS. If you get an ``ImportError: No module named lti_consumer``, you
should ``docker-compose restart lms`` (since we previously uninstalled the lti_consumer to get the
tests for this repo running inside an LMS container). From here, you can see the contents of the
messages that we are sending as an LTI Consumer in the "Message Parameters" part of the "Message" tab.
Workbench installation and settings
-----------------------------------
......
......@@ -9,6 +9,8 @@ import logging
import urllib
import json
from six import text_type
from .exceptions import LtiError
from .oauth import get_oauth_request_signature, verify_oauth_body_signature
......@@ -116,19 +118,22 @@ class LtiConsumer(object):
# Must have parameters for correct signing from LTI:
lti_parameters = {
u'user_id': self.xblock.user_id,
u'oauth_callback': u'about:blank',
u'launch_presentation_return_url': '',
u'lti_message_type': u'basic-lti-launch-request',
u'lti_version': 'LTI-1p0',
u'roles': self.xblock.role,
text_type('user_id'): self.xblock.user_id,
text_type('oauth_callback'): text_type('about:blank'),
text_type('launch_presentation_return_url'): '',
text_type('lti_message_type'): text_type('basic-lti-launch-request'),
text_type('lti_version'): text_type('LTI-1p0'),
text_type('roles'): self.xblock.role,
# Parameters required for grading:
u'resource_link_id': self.xblock.resource_link_id,
u'lis_result_sourcedid': self.xblock.lis_result_sourcedid,
text_type('resource_link_id'): self.xblock.resource_link_id,
text_type('lis_result_sourcedid'): self.xblock.lis_result_sourcedid,
text_type('context_id'): self.xblock.context_id,
text_type('custom_component_display_name'): self.xblock.display_name,
u'context_id': self.xblock.context_id,
u'custom_component_display_name': self.xblock.display_name,
text_type('context_title'): self.xblock.course.display_name_with_default,
text_type('context_label'): self.xblock.course.display_org_with_default,
}
if self.xblock.due:
......@@ -138,7 +143,7 @@ class LtiConsumer(object):
if self.xblock.has_score:
lti_parameters.update({
u'lis_outcome_service_url': self.xblock.outcome_service_url
text_type('lis_outcome_service_url'): self.xblock.outcome_service_url
})
self.xblock.user_email = ""
......
......@@ -7,6 +7,7 @@ import unittest
from datetime import timedelta
from mock import Mock, PropertyMock, patch
from six import text_type
from django.utils import timezone
......@@ -153,30 +154,32 @@ class TestLtiConsumer(TestLtiConsumerXBlock):
self.lti_consumer.xblock.graceperiod = timedelta(days=1)
expected_lti_parameters = {
u'user_id': self.lti_consumer.xblock.user_id,
u'oauth_callback': u'about:blank',
u'launch_presentation_return_url': '',
u'lti_message_type': u'basic-lti-launch-request',
u'lti_version': 'LTI-1p0',
u'roles': self.lti_consumer.xblock.role,
u'resource_link_id': self.lti_consumer.xblock.resource_link_id,
u'lis_result_sourcedid': self.lti_consumer.xblock.lis_result_sourcedid,
u'context_id': self.lti_consumer.xblock.context_id,
u'lis_outcome_service_url': self.lti_consumer.xblock.outcome_service_url,
u'custom_component_display_name': self.lti_consumer.xblock.display_name,
u'custom_component_due_date': self.lti_consumer.xblock.due.strftime('%Y-%m-%d %H:%M:%S'),
u'custom_component_graceperiod': str(self.lti_consumer.xblock.graceperiod.total_seconds()),
text_type('user_id'): self.lti_consumer.xblock.user_id,
text_type('oauth_callback'): 'about:blank',
text_type('launch_presentation_return_url'): '',
text_type('lti_message_type'): 'basic-lti-launch-request',
text_type('lti_version'): 'LTI-1p0',
text_type('roles'): self.lti_consumer.xblock.role,
text_type('resource_link_id'): self.lti_consumer.xblock.resource_link_id,
text_type('lis_result_sourcedid'): self.lti_consumer.xblock.lis_result_sourcedid,
text_type('context_id'): self.lti_consumer.xblock.context_id,
text_type('lis_outcome_service_url'): self.lti_consumer.xblock.outcome_service_url,
text_type('custom_component_display_name'): self.lti_consumer.xblock.display_name,
text_type('custom_component_due_date'): self.lti_consumer.xblock.due.strftime('%Y-%m-%d %H:%M:%S'),
text_type('custom_component_graceperiod'): str(self.lti_consumer.xblock.graceperiod.total_seconds()),
'lis_person_sourcedid': 'edx',
'lis_person_contact_email_primary': 'edx@example.com',
'launch_presentation_locale': 'en',
u'custom_param_1': 'custom1',
u'custom_param_2': 'custom2',
u'oauth_nonce': 'fake_nonce',
text_type('custom_param_1'): 'custom1',
text_type('custom_param_2'): 'custom2',
text_type('oauth_nonce'): 'fake_nonce',
'oauth_timestamp': 'fake_timestamp',
'oauth_version': 'fake_version',
'oauth_signature_method': 'fake_method',
'oauth_consumer_key': 'fake_consumer_key',
'oauth_signature': u'fake_signature'
'oauth_signature': 'fake_signature',
text_type('context_label'): self.lti_consumer.xblock.course.display_org_with_default,
text_type('context_title'): self.lti_consumer.xblock.course.display_name_with_default,
}
self.lti_consumer.xblock.has_score = True
self.lti_consumer.xblock.ask_to_send_username = True
......
......@@ -2,6 +2,7 @@ lxml
bleach
oauthlib
mako
lazy
git+https://github.com/edx/XBlock.git#egg=XBlock
git+https://github.com/edx/xblock-utils.git@v1.0.0#egg=xblock-utils==v1.0.0
-e .
......@@ -22,7 +22,7 @@ def package_data(pkg, roots):
setup(
name='lti_consumer-xblock',
version='1.1.7',
version='1.1.8',
description='This XBlock implements the consumer side of the LTI specification.',
packages=[
'lti_consumer',
......
......@@ -3,6 +3,7 @@
django-nose==1.4.4
astroid==1.3.8 # Pinning to avoid backwards incompatibility issue with pylint/pylint-django
coveralls
mock
pep8
git+https://github.com/edx/django-pyfs.git@1.0.3#egg=django-pyfs==1.0.3
git+https://github.com/edx/edx-lint.git@v0.3.2#egg=edx_lint==0.3.2
......
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