Course and Class Provisioning

To create a course online, instead of using our API, go to: http://thaioptometrists.com/?ver=courses/create/

Provision a New Course

API Method (POST, GET):

http://thaioptometrists.com/?ver=api/provision/course/<New Course Path>

POST parameters:

title A string containing the course title (e.g. "How to Draw Horses")
category A category which this course may belong to (e.g. "Art")

e.g.

curl -f -u "${USERNAME}:${PASSWORD}" "http://thaioptometrists.com/?ver=api/provision/course/${NEW_COURSE_PATH}" -d "title=How to Draw Horses" -d "category=Art"

This will return a JSON object which looks like:

{
   "success": true,
   "path": "courses/myNewCourse",
   "url": "http://thaioptometrists.com/?ver=courses/myNewCourse"
}

Provision a New Class within an Existing Course

API Method (POST, GET):

http://thaioptometrists.com/?ver=api/provision/class/<Existing Course Path>

POST parameters:

title A string containing the class title (e.g. "First Semester")
type

Either:

"open" - anyone can join this class

"requires-activation-code" - only those with an activation code may enrol

"invite-only" - only those invited to join may enrol

"closed" - no-one can join this class yet

isBilled "true" or "false" - depending on whether students need to pay for this class
studentPrice A number, e.g. "12.00" which is the price to charge students
currency e.g. "USD" or "AUD"
activationCode A code which users need in order to join the class e.g. "My Secret Code"
startDate When this class starts, an ISO 8601 date/time string.

e.g.

curl -f -u "${USERNAME}:${PASSWORD}" "http://thaioptometrists.com/?ver=api/provision/class/${COURSE_PATH}" -d "title=First Class" -d "type=open"

This will return a JSON object which looks like:

{
   "success": true,
   "class": {
      "path": "courses/myCourse/Cohorts/FirstClass",
      "title": "First Class",
      "type": "open"
   }
}

Course/Class Setup

 

Change the Online/Offline Status of a Course

API Method (POST, GET):

http://thaioptometrists.com/?ver=api/course/status/<Course Path>

POST parameters:

status=online

or

status=offline

e.g. to take a course offline:

curl -f -u "${USERNAME}:${PASSWORD}" "http://thaioptometrists.com/?ver=api/course/status/${COURSE_PATH}" -d "status=offline"

This will return:

{
    "success": true,
    "status": "offline"
}

Change properties of a Class

API Method (POST, GET):

http://thaioptometrists.com/?ver=api/class/<Class Path>

POST parameters:

title A string containing the class title (e.g. "First Semester")
type

Either:

"open" - anyone can join this class

"requires-activation-code" - only those with an activation code may enrol

"invite-only" - only those invited to join may enrol

"closed" - no-one can join this class yet

isBilled "true" or "false" - depending on whether students need to pay for this class
studentPrice A number, e.g. "12.00" which is the price to charge students
currency e.g. "USD" or "AUD"
activationCode A code which users need in order to join the class e.g. "My Secret Code"
startDate When this class starts, an ISO 8601 date/time string.

e.g.

curl -f -u "${USERNAME}:${PASSWORD}" "http://thaioptometrists.com/?ver=api/class/${CLASS_PATH}" -d "title=First Class" -d "type=open"

This will return a JSON object which looks like:

{
   "success": true,
   "class": {
      "path": "courses/myCourse/Cohorts/FirstClass",
      "title": "First Class",
      "type": "open"
   }
}

List Classes in a Course

API Method (GET):

http://thaioptometrists.com/?ver=api/course/classes/<Course Path>

This will return:

{
    "classes": [
        {
            "path": "courses/myCourse/Cohorts/FirstClass",
            "title": "First Class",
            "url": "http://thaioptometrists.com/?ver=courses/myCourse/Cohorts/FirstClass"
        }
    ],
    "success": true
}

List Students in an Institution Portal

API Method (GET):

http://thaioptometrists.com/?ver=api/institution/enrolments

GET parameters:

institution - Relative path to institution portal (e.g. myInstitute)

start - The starting position of the list of enrolments. (optional and defaults to 0)

end - The end position of the list of enrolments. (optional and defaults to 50)

search - text to search for a users name or group. (optional and defaults to return all enrolments)

e.g.

curl -XGET -u "${USERNAME}:${PASSWORD}" "http://thaioptometrists.com/?ver=api/institution/enrolments?institution=myInstitute"


Invite Students into an Institution Portal

API Method (POST):

http://thaioptometrists.com/?ver=api/institution/invite

POST parameters:

institution - Relative path to institution portal (e.g. myInstitute)

emailAddressList - A new-line separated list of email addresses. You can specify the user's full name when creating the account (see generateAccount parameter), by placing them after the email address separated by a comma (e.g. Email Address, Full Name).

generateAccount - true or false flag to specify that a user account will be automatically created and a random password sent to the invited email address. Only institutions with this feature enabled will be able to use this option, otherwise it will ignore this option.

e.g.

curl -f -u "${USERNAME}:${PASSWORD}" "http://thaioptometrists.com/?ver=api/institution/invite" -d "institution=myInstitute"& -d "emailAddressList=myemail@example.com"

e.g. with generateAccount and full name

curl -f -u "${USERNAME}:${PASSWORD}" "http://thaioptometrists.com/?ver=api/institution/invite" -d "institution=myInstitute"& -d "emailAddressList=myemail@example.com,Foo Bar" -d "generateAccount=true"


Import Student Information for an Institution Portal

API Method (POST):

http://thaioptometrists.com/?ver=api/institution/importInformation

POST parameters:

institution - Relative path to institution portal (e.g. myInstitute)

emailAddressList - A new-line separated list of email addresses. You can specify extra info by placing them after the email address separated by commas (e.g. Email Address, Identifier, Username)

e.g.

curl -f -u "${USERNAME}:${PASSWORD}" "http://thaioptometrists.com/?ver=api/institution/importInformation" -d "institution=myInstitute"& -d "emailAddressList=myemail@example.com"


Invite Students into a Class

API Method (POST):

http://thaioptometrists.com/?ver=api/class/invite/<Class Path>

POST parameters:

emailAddressList - A new-line separated list of email addresses

e.g.

curl -f -u "${USERNAME}:${PASSWORD}" "http://thaioptometrists.com/?ver=api/class/invite/${CLASS_PATH}" -d "emailAddressList=myemail@example.com"


Sign into OpenLearning from an External Service

via LTI:

OpenLearning accepts LTI authentication (as a POST request) at the following endpoint:

http://thaioptometrists.com/?ver=lti/<launch path>

Request an LTI connection be set up for your institution, or course (email support at openlearning.com).

 

via a URL (link):

http://thaioptometrists.com/?ver=courseLogin/<Course Path>?signed_request=<Authentication Code>

To generate an authentication code:

  1. Request an Institution Shared Secret from OpenLearning (email support at openlearning.com). Do not reveal this secret publicly.
  2. Create a payload of JSON data containing: {"issued_at": 1402643065, "user_id": "user@example.com", "full_name": "Jayne Doe"} (where issued_at is seconds since unix epoch)
  3. Create an encoded payload by base-64 encoding the JSON data string (this may also use URL-safe encoding which substitutes - instead of + and _ instead of /)
  4. Generate a SHA-256 HMAC digest of the payload data string and the provided Shared Secret
  5. Create an encoded signature by base-64 encoding the HMAC digest
  6. Join the encoded signature and the encoded payload with a . (period/full-stop) character

This will allow the generated (private) link to log the specified user into OpenLearning provided all of the following are satisfied:

  • The user is already enrolled in the course specified, or the specified email address has been invited to join the course (a new account will be created and the user will be enrolled into this course)
  • The user's account is managed by your institution (an existing matching account does not already exist that has had prior activity on OpenLearning)
  • The issued_at time is less than a day old

 

Note: padding ('=' characters) at the end of base64 encoded data are optional and may be omitted.

You can test your HMAC implementation against a reference at (never reveal your actual shared secret):

http://thaioptometrists.com/?ver=api/login/referenceHMAC/?payload=<JSON Data>&secret=<Secret>

(by default this uses url-safe base64 encoding, optionally an encoding=base64 parameter can be passed to use standard base64 encoding)

You can also test that your implementation will authenticate at:

http://thaioptometrists.com/?ver=api/login/testHMAC/?signed_request=<Signed Request>&secret=<Secret>

(again never reveal your actual secret)

 

The following is an implementation in Python:

import hmac, hashlib 
import time
import base64
import json
def generate_signed_request(shared_secret, user_id, full_name):
    payload = {"issued_at": int(time.time()), "user_id": user_id, "full_name": full_name}
    encoded_payload = base64.urlsafe_b64encode(json.dumps(payload))
    hmac_signature = hmac.new(shared_secret, encoded_payload, hashlib.sha256).digest()
    encoded_signature = base64.urlsafe_b64encode(hmac_signature)
    signed_request = encoded_signature + '.' + encoded_payload
    return signed_request 

 

Comments