Module: Lti2Commons::MessageSupport
- Defined in:
- lib/lti2_commons/lib/lti2_commons/message_support.rb
Overview
Module to support LTI 1 and 2 secure messaging. This messaging is documented in the LTI 2 Security Document
LTI 2 defines two types of LTI secure messaging:
1. LTI Messages
This is the model used exclusively in LTI 1.
It is also used in LTI 2 for user-submitted actions such as LtiLaunch and ToolDeployment.
It works the following way:
1. LTI parameters are signed by OAuth.
2. The message is marshalled into an HTML Form with the params
specified in form fields.
3. The form is sent to the browser with a redirect.
4. An attached Javascript script 'auto-submits' the form.
This structure appears to the Tool Provider as a user submission with all user browser context
intact.
2. LTI Services
This is a standard REST web service with OAuth message security added.
In LTI 2.0 Services are only defined for Tool Provider --> Tool Consumer services;
such as, GetToolConsumerProfile, RegisterToolProxy, and LTI 2 Outcomes.
LTI 2.x will add Tool Consumer --> Tool Provider services using the same machinery.
Constant Summary collapse
- TIMEOUT =
300
Instance Method Summary collapse
-
#create_lti_message_body(launch_url, parameters, wire_log = nil, title = nil, is_open_in_external_window = false) ⇒ String
Convenience method signs and then invokes create_lti_message_from_signed_request.
-
#create_lti_message_body_from_signed_request(signed_request, is_include_oauth_params = true, is_open_in_external_window = false) ⇒ String
Creates an LTI Message (POST body) ready for redirecting to the launch_url.
-
#invoke_service(request, wire_log = nil, title = nil, other_headers = {}) ⇒ Object
Invokes an LTI Service.
- #invoke_unsigned_service(uri, method, params = {}, headers = {}, data = nil, wire_log = nil, title = nil) ⇒ Object
Instance Method Details
#create_lti_message_body(launch_url, parameters, wire_log = nil, title = nil, is_open_in_external_window = false) ⇒ String
Convenience method signs and then invokes create_lti_message_from_signed_request
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/lti2_commons/lib/lti2_commons/message_support.rb', line 37 def (launch_url, parameters, wire_log = nil, title = nil, is_open_in_external_window = false) result = (launch_url, is_open_in_external_window) result += (parameters) result += (is_open_in_external_window) if wire_log wire_log. wire_log.raw_log((title.nil?) ? 'LtiMessage' : "LtiMessage: #{title}") wire_log.raw_log "LaunchUrl: #{launch_url}" wire_log.raw_log result.strip wire_log.newline wire_log.flush end result end |
#create_lti_message_body_from_signed_request(signed_request, is_include_oauth_params = true, is_open_in_external_window = false) ⇒ String
Creates an LTI Message (POST body) ready for redirecting to the launch_url. Note that the is_include_oauth_params option specifies that ‘oauth_’ params are included in the body. This option should be false when sender is putting them in the HTTP Authorization header (now recommended).
62 63 64 65 66 67 68 |
# File 'lib/lti2_commons/lib/lti2_commons/message_support.rb', line 62 def (signed_request, is_include_oauth_params = true, is_open_in_external_window = false) result = (signed_request.uri, is_open_in_external_window) result += (signed_request.parameters, is_include_oauth_params) result += (is_open_in_external_window) result end |
#invoke_service(request, wire_log = nil, title = nil, other_headers = {}) ⇒ Object
Invokes an LTI Service. This is fully-compliant REST request suitable for LTI server-to-server services.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/lti2_commons/lib/lti2_commons/message_support.rb', line 74 def invoke_service(request, wire_log = nil, title = nil, other_headers = {}) uri = request.uri.to_s # set_headers_proc = lambda { |http| # http.headers['Authorization'] = request.oauth_header # http.headers['Content-Type'] = request.content_type if request.content_type # http.headers['Accept'] = request.content_type if request.content_type # # http.headers['Content-Length'] = request.body.length if request.body # } method = request.method.downcase headers = {} headers['Authorization'] = request.oauth_header headers['Content-Type'] = request.content_type if request.content_type headers['Accept'] = request.accept if request.accept headers['Content-Length'] = request.body.length.to_s if request.body headers.merge!(other_headers) parameters = request.parameters output_parameters = {} parameters.each { |k, v| output_parameters[k] = v unless k =~ /^oauth_/ } (write_wirelog_header wire_log, title, request.method, uri, headers, parameters, request.body, output_parameters) if wire_log full_uri = uri full_uri += '?' unless uri.include? '?' full_uri += '&' unless full_uri =~ /[?&]$/ output_parameters.each_pair do |key, _value| full_uri << '&' unless key == output_parameters.keys.first full_uri << "#{URI.encode(key.to_s)}=#{URI.encode(output_parameters[key] || '')}" end case method when 'get' response = HTTParty.get(full_uri, headers: headers, timeout: TIMEOUT) when 'post' response = HTTParty.post(full_uri, body: request.body, headers: headers, timeout: TIMEOUT) when 'put' response = HTTParty.put(full_uri, body: request.body, headers: headers, timeout: TIMEOUT) when 'delete' response = HTTParty.delete(full_uri, headers: headers, timeout: TIMEOUT) end wire_log.log_response(response, title) if wire_log response end |
#invoke_unsigned_service(uri, method, params = {}, headers = {}, data = nil, wire_log = nil, title = nil) ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/lti2_commons/lib/lti2_commons/message_support.rb', line 121 def invoke_unsigned_service(uri, method, params = {}, headers = {}, data = nil, wire_log = nil, title = nil) full_uri = uri full_uri += '?' unless uri.include? '?' full_uri += '&' unless full_uri =~ /[?&]$/ params.each_pair do |key, _value| full_uri << '&' unless key == params.keys.first full_uri << "#{URI.encode(key.to_s)}=#{URI.encode(params[key])}" end write_wirelog_header(wire_log, title, method, uri, headers, params, data, {}) if wire_log case method when 'get' response = HTTParty.get(full_uri, headers: headers, timeout: 120) when 'post' response = HTTParty.post(full_uri, body: data, headers: headers, timeout: 120) when 'put' response = HTTParty.put(full_uri, body: data, headers: headers, timeout: 120) when 'delete' response = HTTParty.delete(full_uri, headers: headers, timeout: 120) end wire_log.log_response(response, title) if wire_log response end |