Created
August 20, 2018 04:09
-
-
Save marktriggs/86269591789fe7cb936fa8cebaa86714 to your computer and use it in GitHub Desktop.
Fetch site memberships using LTI Context Memberships Service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'base64' | |
require 'net/http' | |
require 'openssl' | |
require 'securerandom' | |
# Standard Sakai URL for LTI services. Also available as the | |
# `ext_ims_lis_basic_outcome_url` parameter on an LTI launch. | |
# | |
BASE_URL = 'https://newclasses.nyu.edu/imsblis/service' | |
# Shared secrets... | |
# | |
LTI_KEY = 'THELAUNCHKEY' | |
LTI_SECRET = 'THELAUNCHSECRET' | |
# This string comes from the `ext_ims_lis_memberships_id` parameter of an LTI | |
# launch for the site. It's always the same for a given site, so once you've | |
# seen an LTI launch for one user, you've got the token needed to fetch that | |
# site's list of members. | |
# | |
EXT_IMS_LIS_MEMBERSHIPS_ID = 'c5418583a94e47849754dc6fce96d81782554e47c96b3be4030e0abde5e225c0:::admin:::content:5' | |
def encode(s) | |
URI.encode_www_form_component(s) | |
end | |
def oauth_signature(method, base_url, secret, params) | |
# https://oauth1.wp-api.org/docs/basics/Signing.html | |
base_string = [ | |
method, | |
base_url, | |
params.sort.map {|k, v| "#{k}=#{encode(v)}"}.join('&') | |
].map {|s| encode(s)}.join('&') | |
Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha1'), | |
secret + '&', | |
base_string)) | |
end | |
# Ultimately we're just sending a POST request with some params, but we need to | |
# sign the request with an OAuth signature. Most of this is just calculating | |
# that signature. Using an OAuth library would make life easier, but in the | |
# interest of being self-contained... | |
# | |
def main | |
uri = URI.parse(BASE_URL) | |
params = { | |
'lti_version' => 'LTI-1p0', | |
'lti_message_type' => 'basic-lis-readmembershipsforcontext', | |
'id' => EXT_IMS_LIS_MEMBERSHIPS_ID, | |
'oauth_consumer_key' => LTI_KEY, | |
'oauth_nonce' => SecureRandom.hex, | |
'oauth_signature_method' => 'HMAC-SHA1', | |
'oauth_timestamp' => Time.now.to_i.to_s, | |
} | |
params['oauth_signature'] = oauth_signature('POST', BASE_URL, LTI_SECRET, params) | |
req = Net::HTTP::Post.new(uri) | |
req.set_form_data(params) | |
http = Net::HTTP.new(uri.host, uri.port) | |
response = http.request(req) | |
# Returns an XML payload like the one below | |
puts response.body | |
end | |
main | |
####################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################### | |
# Sample output: | |
# | |
# <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
# <message_response> | |
# <lti_message_type>basic-lis-readmembershipsforcontext</lti_message_type> | |
# <members> | |
# <member> | |
# <lis_result_sourcedid>36b38dd658afb519567353c24ad8a94b8099bc6daa5ad9667f361053a387ac31:::152ec024-7709-4baf-89ad-f31d695122db:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>student_dc91f532fd9e508ae0a77f1b88916ebf</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>152ec024-7709-4baf-89ad-f31d695122db</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>8c79d87050c7797f28cea4978df8b34d11a0243f39c0586fb43dbd54c95da9aa:::fd697b66-c287-4295-8674-786c27c2e39f:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>student_e0c2566ff978e8fa6637a66e54fe7221</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>fd697b66-c287-4295-8674-786c27c2e39f</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>a0e6c67e0aa65a09850868d594977bb858a80d57850cc42dd3f6a571ed262d85:::d93912fc-3ad1-4c8e-b056-fcd1b80ee81d:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>student_17b71a0c668e5c3ad8ee49fbda2b7d29</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>d93912fc-3ad1-4c8e-b056-fcd1b80ee81d</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>52542acdb8b614bde8e3c1dbd841a3ff92f52e82a63dad90ea7d06436347bf6f:::42b3249a-a848-410a-8969-720a78e313c5:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>instructor_52f8777fbbfefe13749460f4dabe74a0</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>42b3249a-a848-410a-8969-720a78e313c5</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>6e8712d8f59885b8e11e7a1f6e88e40bf918d7e67dbb3958a2c81290f6f3710e:::81cf0bfd-6bef-4829-ab8c-1c3c0f0f4fdc:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>student_113ce456fa21c7afc6acc7547eea6539</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>81cf0bfd-6bef-4829-ab8c-1c3c0f0f4fdc</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>745b1353783df00f45e1f3d1494fd52d4a587aa9b6f1b1fd18c861025f92f65e:::e884af30-9939-4ad2-8faa-08207fed4448:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>student_68d71b779237e86e352b71adae250ee4</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>e884af30-9939-4ad2-8faa-08207fed4448</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>c5418583a94e47849754dc6fce96d81782554e47c96b3be4030e0abde5e225c0:::admin:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>Administrator</person_name_family> | |
# <person_name_full>Sakai Administrator</person_name_full> | |
# <person_name_given>Sakai</person_name_given> | |
# <person_sourcedid>admin</person_sourcedid> | |
# <role>Instructor</role> | |
# <roles>Instructor</roles> | |
# <user_id>admin</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>69688666fa5567ca4d43e88bd4344aec1057cd285346a4f5186744d3b006f2de:::0c1d2a97-ac69-4f52-8234-8a00b29d082b:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>student_51d35d01c6b0333bdd01742df9fdef72</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>0c1d2a97-ac69-4f52-8234-8a00b29d082b</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>4104f18b829d3685adfd91c1e44ad87ccc7bc8a9fc61573efe9ea9589669e2b0:::039e53be-d1fa-44b9-a5af-2122dafc8a73:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>student_fc762d1bacffecadc7a3706a46a2c153</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>039e53be-d1fa-44b9-a5af-2122dafc8a73</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>a649144e446c9dbe1326d321ab5bca9d4720b2d1254838e6a8e1a250ef27d345:::2a0ed833-71ae-4497-b7bf-ec0208ab314c:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>student_c83e501f83f76a8855c0d2083e16bfe1</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>2a0ed833-71ae-4497-b7bf-ec0208ab314c</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>f80031710ebf1280d7354fad609537692aa7e6bb44665dcfb6e4ae3fa4925093:::0108f0e1-c17d-4750-b9b2-3b3c1d2c4f87:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>student_c8a5f62d507607e4cf97af9fcd7d8f0b</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>0108f0e1-c17d-4750-b9b2-3b3c1d2c4f87</user_id> | |
# </member> | |
# <member> | |
# <lis_result_sourcedid>18dd21df2d99f639538e58e8133eb1f614b433cf2e60e35287b6c4ce6dcaee27:::e405f4c8-6e00-4a07-b818-af6df05959ac:::content:5</lis_result_sourcedid> | |
# <person_contact_email_primary>[email protected]</person_contact_email_primary> | |
# <person_name_family>User</person_name_family> | |
# <person_name_full>Test User</person_name_full> | |
# <person_name_given>Test</person_name_given> | |
# <person_sourcedid>student_f3a9bdcea6175fab2826b650be473fa4</person_sourcedid> | |
# <role>Learner</role> | |
# <roles>Learner</roles> | |
# <user_id>e405f4c8-6e00-4a07-b818-af6df05959ac</user_id> | |
# </member> | |
# </members> | |
# <statusinfo> | |
# <codemajor>Success</codemajor> | |
# <codeminor>fullsuccess</codeminor> | |
# <severity>Status</severity> | |
# </statusinfo> | |
# </message_response> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment