Socraticqs2 as LTI provider

Terminology

Tool Provider

A Tool Provider exposes interfaces to one or more tools. It is useful to think of the Tool Provider as a wrapper around a tool. In this sense, the Tool Provider represents the entire system of Tool plus its interfaces.

Tool Consumer

Instructors and students typically access Tools by activating links from within an LMS. But the LTI standard supports other scenarios, too. For example, you might want to launch a learning tool from Facebook, or your Google home page. Any system that offers access to a Tool is called a Tool Consumer.

Context

Links for Tools typically appear in the context of some course. But they may appear within other types of groups. For example, links might appear within the context of a student organization, club, study group, etc. Since Tools may be launched from many different types of contexts, the LTI Specification rarely uses the term “course” and instead uses the more general term “context.”

Resource Link

The Tool Consumer uses Resource Link entities to generate clickable links within its user interface. Each Resource Link has a title which defines the text that should appear in the clickable link plus an optional description which should appear alongside the link. Having introduced the key concepts featured in the LTI standard, let’s look at some of these ideas in more detail.

Consumer key

This string value is generated by the tool provider to allow them to uniquely identify the source of requests being received.

LTI secret

The communications between the tool provider and the tool consumer are secured using a signature generated using the OAuth 1.0 protocol [OAuth-A] with the shared secret (which should be known only to the tool provider and the tool consumer).

Settings for Socraticqs2 LTI provider

Allow debug information about LTI request

LTI_DEBUG = True

Allow to uniquely identify Tool Consumer

CONSUMER_KEY = "__consumer_key__"

To secure communications between the Tool Provider and Tool Consumer using OAuth

LTI_SECRET = "__lti_secret__"

To permit cross-origin framing

X_FRAME_OPTIONS = "GOFORIT"

Heroku SSL proxy fix

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https'))

Adding new External tool on Moodle LTI consumer

  1. Go to Control Panel of your course
  2. Click on Add an activity or resource button
  3. Select External tool Activity
  4. Click Add
  5. Click Show more on Adding a new External tool page
  6. Type Activity name
  7. Go to Socraticqs2 site
  8. Login as Instructor
  9. Go to course edit page or unit edit page
  10. Copy course or unit URL from Copy course URL input field
  11. Paste this URL into Launch URL input field on External tool page
  12. Alternatively Instructor can create a new empty Course by adding /lti/ at the end of Socraticqs2 site URL and specify the resulting URL in form of https://socraticqs2_domain_name.org/lti/ into Launch URL input field on External tool page
  13. Type Consumer key and Shared secret on External tool page given from our settings_local.py
  14. Click Save and display or Save and return to course

LTI user access flow

When LTI user is accessed External Tool we handle LTI request to get all user information from LTI Consumer.

First of all we are verifying LTI request using python port of the useful ims-lti Ruby library.

It can be reviewed there https://github.com/mitodl/ims_lti_py

Next we store LTIUser entry with appropriate LTI params.

Launch LTI request is handled by followed views:

lti.views.create_courseref(request, *args, **kwargs)

Create CourseRef and Course entry based on context_title.

lti.views.lti_init(*args, **kwargs)

LTI init view

Analyze LTI POST request to start LTI session.

Parameters:
  • course_id – course id from launch url
  • unit_id – unit id from lunch url
lti.views.lti_redirect(request, course_id=None, unit_id=None)

Create user and redirect to Course

Create LTIUser with all needed link to Django user
and/or UserSocialAuth.
Finally login Django user and redirect to Course
Parameters:unit_id – unit id from lunch url

To work with Socraticqs2 courses we need to create/get django user to authorize him and need to have Role objects to have access to courses.

For this requirements we have create_links and enroll methods in LTIUser class.

class lti.models.LTIUser(*args, **kwargs)

Model for LTI user

Fields:

user_id

uniquely identifies the user within LTI Consumer

consumer

uniquely identifies the Tool Consumer

extra_data

user params received from LTI Consumer

django_user

Django user to store study progress

context_id

Context id given from LTI params

LTI user params saved to extra_data field:

'user_id'
'context_id'
'lis_person_name_full'
'lis_person_name_given'
'lis_person_name_family'
'lis_person_sourcedid'
'tool_consumer_instance_guid'
'lis_person_contact_email_primary'
'tool_consumer_info_product_family_code'

Create all needed links to Django and/or UserSocialAuth.

enroll(roles, course_id)

Create Role according to user roles from LTI POST

roles -> roles of LTI user given from LTI Consumer course_id -> Course entry id given from Launch URL

Parameters:
  • roles – (str|list)
  • course_id – int
Returns:

None

is_enrolled(roles, course_id)

Check enroll status

Parameters:
  • roles – (str|list)
  • course_id – int
Returns:

bool

is_linked

Check link to some Django user

Returns:bool
login(request)

Login linked Django user.

Course creation process

When Instructor set /lti/ as the LaunchURL for External Tool he can create a blank Course on Socraticqs2 Tool Provider.

To implement this we follow the next logic:

  • First of all, we look at the roles LTI param to decide whether the user can create courses or not.

  • Next we look for context_id LTI param to search our CourseRef models.

  • That models is a link between Course and particular University identified by context_id.

    class lti.models.CourseRef(*args, **kwargs)

    Course reference

    Represent Course reference with meta information such as:

    course -> Courslet Course entry
    instructors -> list of User entry
    date - > creation date
    context_id -> LTI context_id
    tc_guid - > LTI tool_consumer_instance_guid
    
  • If we find a CourseRef entry we just redirect user to a Course.

  • If there is no CourseRef and user has role Instructor in roles LTI param we direct the user to the create_courseref view:

    lti.views.create_courseref(request, *args, **kwargs)

    Create CourseRef and Course entry based on context_title.

    That view do the following:

    • creates a new Course with context_title title
    • creates Instructor Role for a django user with which the LTI user is associated
    • creates CourseRef entry to link Tool Consumer with this Course
    • adds LTI user to Instructor’s set of that Course
    • redirects user to Course edit page

Also we ensure that user is requests for Course creation only from LTI session using only_lti decorator:

lti.utils.only_lti(fn)

Decorator ensures that user comes from LTI session.

Finally Instructor can change LaunchURL to a /lti/unit/{unit_id}/ pattern to point directly to a particular unit of the Course if he has created one previously.