ims-lti 1.1.13 → 1.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/Changelog +28 -0
- data/README.md +14 -1
- data/lib/ims/lti/deprecated_role_checks.rb +1 -1
- data/lib/ims/lti/extensions/content.rb +76 -27
- data/lib/ims/lti/extensions/outcome_data.rb +47 -6
- data/lib/ims/lti/launch_params.rb +1 -1
- data/lib/ims/lti/outcome_request.rb +15 -0
- data/lib/ims/lti/outcome_response.rb +7 -3
- data/lib/ims/lti/role_checks.rb +2 -2
- data/lib/ims/lti/tool_provider.rb +5 -3
- data/lib/ims/lti/version.rb +5 -0
- data/lib/ims/lti.rb +6 -2
- metadata +34 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 801e423357504d51cc0289e45e364d026abd4bbad20dfca90107725796cd258f
|
|
4
|
+
data.tar.gz: cfdcb37216eef088886486f951af05f719b086f7f32f7d8d83dc04f3020b563e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fcc31ec46d3fccb7585bbe3d6dff5ab88227ccea12b4c056a2f8c588a864b26bb9d74d13601e2b08f7bcc404d215b4b0be14a3b96b613b79e795edfeb8ad2d0c
|
|
7
|
+
data.tar.gz: 0bfa98f889d2b848e03200a22f76447bab3df748c9b6a351d42d5ec9218838ba749f5751af59efd5ae8f7db701a28fcf5b8b92cecb253ebfc097cce3cfb7ff59
|
data/Changelog
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
2023-05-30 Version 1.2.9
|
|
2
|
+
* Loosen version requirement for OAuth gem
|
|
3
|
+
|
|
4
|
+
2023-01-03 Version 1.2.8
|
|
5
|
+
* Add Ruby 3.0 support by requiring rexml
|
|
6
|
+
* Fix URI encoding bug for queries with an ampersand `&`
|
|
7
|
+
|
|
8
|
+
2022-12-13 Version 1.2.7
|
|
9
|
+
* Fix content return parameter encoding
|
|
10
|
+
|
|
11
|
+
2022-04-26 Version 1.2.6
|
|
12
|
+
* Add support for prioritizeNonToolGrade
|
|
13
|
+
* Add support for needsAdditionalReview
|
|
14
|
+
|
|
15
|
+
2020-02-03 Version 1.2.4
|
|
16
|
+
* Add support for submittedAt date
|
|
17
|
+
|
|
18
|
+
2020-02-03 Version 1.2.3 -- yanked
|
|
19
|
+
|
|
20
|
+
2017-06-19 Version 1.2.2
|
|
21
|
+
* Explicitly require 'oauth' gem and specify version range
|
|
22
|
+
|
|
23
|
+
2017-04-13 Version 1.2.1
|
|
24
|
+
* Remove date field from gemspec
|
|
25
|
+
|
|
26
|
+
2017-03-08 Version 1.2.0
|
|
27
|
+
* Don't downcase roles
|
|
28
|
+
|
|
1
29
|
2016-10-05 Version 1.1.13
|
|
2
30
|
* Fix Oauth::Unauthorized initialization bug
|
|
3
31
|
* Relax oauth dependency
|
data/README.md
CHANGED
|
@@ -52,7 +52,7 @@ and it will be signed with OAuth using a key/secret that both the TP and TC shar
|
|
|
52
52
|
This is covered in the [LTI security model](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560466)
|
|
53
53
|
|
|
54
54
|
Here is an example of a simple TP Sinatra app using this gem:
|
|
55
|
-
[LTI Tool Provider](https://github.com/instructure/
|
|
55
|
+
[LTI Tool Provider](https://github.com/instructure/lti1_tool_provider_example)
|
|
56
56
|
|
|
57
57
|
Once you find the `oauth_consumer_secret` based on the `oauth_consumer_key` in
|
|
58
58
|
the request, you can initialize a `ToolProvider` object with them and the post parameters:
|
|
@@ -112,5 +112,18 @@ As a Tool Consumer your app will POST an OAuth-signed launch requests to TPs wit
|
|
|
112
112
|
[LTI launch data](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560465).
|
|
113
113
|
This is covered in the [LTI security model](http://www.imsglobal.org/LTI/v1p1/ltiIMGv1p1.html#_Toc319560466)
|
|
114
114
|
|
|
115
|
+
```ruby
|
|
116
|
+
|
|
117
|
+
params = { user_id: '123', lti_message_type: IMS::LTI::Models::Messages::BasicLTILaunchRequest::MESSAGE_TYPE }
|
|
118
|
+
|
|
119
|
+
header = SimpleOAuth::Header.new(:post, 'https://yoursite.com', params, consumer_key: oauth_consumer_key, consumer_secret: secret)
|
|
120
|
+
|
|
121
|
+
signed_params = header.signed_attributes.merge(params)
|
|
122
|
+
|
|
123
|
+
IMS::LTI::Services::MessageAuthenticator.new(launch_url, signed_params, secret)
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Contributing
|
|
115
128
|
Here is an example of a simple TC Sinatra app using this gem:
|
|
116
129
|
[LTI Tool Consumer](https://github.com/instructure/lti_tool_consumer_example)
|
|
@@ -6,7 +6,7 @@ module DeprecatedRoleChecks
|
|
|
6
6
|
# Check whether the Launch Parameters have a role
|
|
7
7
|
def has_role?(role)
|
|
8
8
|
role = role.downcase
|
|
9
|
-
@roles && @roles.any?{|r| r.index(role)}
|
|
9
|
+
@roles && @roles.any?{|r| r.downcase.index(role)}
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
# Convenience method for checking if the user has 'learner' or 'student' role
|
|
@@ -96,67 +96,116 @@ module IMS::LTI
|
|
|
96
96
|
|
|
97
97
|
#generates the return url for file submissions
|
|
98
98
|
def file_content_return_url(url, text, content_type = nil)
|
|
99
|
-
url = CGI::escape(url)
|
|
100
|
-
text = CGI::escape(text)
|
|
101
|
-
content_type = CGI::escape(content_type) if content_type
|
|
102
99
|
|
|
103
|
-
return_url =
|
|
104
|
-
|
|
100
|
+
return_url = add_parameters(content_return_url, {
|
|
101
|
+
return_type: 'file',
|
|
102
|
+
url: url,
|
|
103
|
+
text: text
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
if content_type
|
|
107
|
+
return_url = add_parameters(return_url, {
|
|
108
|
+
content_type: content_type
|
|
109
|
+
})
|
|
110
|
+
end
|
|
105
111
|
|
|
106
112
|
return return_url
|
|
107
113
|
end
|
|
108
114
|
|
|
109
115
|
#generates the return url for url submissions
|
|
110
116
|
def url_content_return_url(url, title = nil, text = 'link', target = '_blank')
|
|
111
|
-
url = CGI::escape(url)
|
|
112
|
-
text = CGI::escape(text)
|
|
113
|
-
target = CGI::escape(target)
|
|
114
117
|
|
|
115
|
-
return_url =
|
|
116
|
-
|
|
118
|
+
return_url = add_parameters(content_return_url, {
|
|
119
|
+
return_type: 'url',
|
|
120
|
+
url: url,
|
|
121
|
+
text: text,
|
|
122
|
+
target: target
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
if title
|
|
126
|
+
return_url = add_parameters(return_url, {
|
|
127
|
+
title:title
|
|
128
|
+
})
|
|
129
|
+
end
|
|
117
130
|
|
|
118
131
|
return return_url
|
|
119
132
|
end
|
|
120
133
|
|
|
121
134
|
#generates the return url for lti launch submissions
|
|
122
135
|
def lti_launch_content_return_url(url, text='link', title=nil)
|
|
123
|
-
url = CGI::escape(url)
|
|
124
|
-
text = CGI::escape(text)
|
|
125
136
|
|
|
126
|
-
return_url =
|
|
127
|
-
|
|
137
|
+
return_url = add_parameters(content_return_url, {
|
|
138
|
+
return_type: 'lti_launch_url',
|
|
139
|
+
url: url,
|
|
140
|
+
text: text
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
if title
|
|
144
|
+
return_url = add_parameters(return_url, {
|
|
145
|
+
title:title
|
|
146
|
+
})
|
|
147
|
+
end
|
|
128
148
|
|
|
129
149
|
return return_url
|
|
130
150
|
end
|
|
131
151
|
|
|
132
152
|
#generates the return url for image submissions
|
|
133
153
|
def image_content_return_url(url, width, height, alt = '')
|
|
134
|
-
url = CGI::escape(url)
|
|
135
|
-
width = CGI::escape(width.to_s)
|
|
136
|
-
height = CGI::escape(height.to_s)
|
|
137
|
-
alt = CGI::escape(alt)
|
|
138
154
|
|
|
139
|
-
|
|
155
|
+
add_parameters(content_return_url, {
|
|
156
|
+
return_type: 'image_url',
|
|
157
|
+
url: url,
|
|
158
|
+
width: width.to_s,
|
|
159
|
+
height: height.to_s,
|
|
160
|
+
alt: alt
|
|
161
|
+
})
|
|
140
162
|
end
|
|
141
163
|
|
|
142
164
|
#generates the return url for iframe submissions
|
|
143
165
|
def iframe_content_return_url(url, width, height, title = nil)
|
|
144
|
-
url = CGI::escape(url)
|
|
145
|
-
width = CGI::escape(width.to_s)
|
|
146
|
-
height = CGI::escape(height.to_s)
|
|
147
166
|
|
|
148
|
-
return_url =
|
|
149
|
-
|
|
167
|
+
return_url = add_parameters(content_return_url, {
|
|
168
|
+
return_type: 'iframe',
|
|
169
|
+
url: url,
|
|
170
|
+
width: width.to_s,
|
|
171
|
+
height: height.to_s
|
|
172
|
+
})
|
|
173
|
+
|
|
174
|
+
if title
|
|
175
|
+
return_url = add_parameters(return_url, {
|
|
176
|
+
title:title
|
|
177
|
+
})
|
|
178
|
+
end
|
|
150
179
|
|
|
151
180
|
return return_url
|
|
152
181
|
end
|
|
153
182
|
|
|
154
183
|
#generates the return url for oembed submissions
|
|
155
184
|
def oembed_content_return_url(url, endpoint)
|
|
156
|
-
url = CGI::escape(url)
|
|
157
|
-
endpoint = CGI::escape(endpoint)
|
|
158
185
|
|
|
159
|
-
|
|
186
|
+
add_parameters(content_return_url, {
|
|
187
|
+
return_type: 'oembed',
|
|
188
|
+
url: url,
|
|
189
|
+
endpoint: endpoint
|
|
190
|
+
})
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
private
|
|
194
|
+
|
|
195
|
+
# adds parameters to a url, with consideration for
|
|
196
|
+
# already existing parameters
|
|
197
|
+
def add_parameters(url, params)
|
|
198
|
+
parsed = URI.parse(url)
|
|
199
|
+
query = if parsed.query
|
|
200
|
+
CGI.parse(parsed.query)
|
|
201
|
+
else
|
|
202
|
+
{}
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
query = query.merge(params)
|
|
206
|
+
|
|
207
|
+
parsed.query = URI.encode_www_form(query)
|
|
208
|
+
parsed.to_s
|
|
160
209
|
end
|
|
161
210
|
end
|
|
162
211
|
|
|
@@ -67,6 +67,12 @@ module IMS::LTI
|
|
|
67
67
|
accepted_outcome_types.member?("url")
|
|
68
68
|
end
|
|
69
69
|
|
|
70
|
+
# check if the consumer accepts a submitted at date as outcome data
|
|
71
|
+
def accepts_submitted_at?
|
|
72
|
+
accepted_outcome_types.member?("submitted_at") ||
|
|
73
|
+
@ext_params["ext_outcome_submission_submitted_at_accepted"] == "true"
|
|
74
|
+
end
|
|
75
|
+
|
|
70
76
|
def accepts_outcome_lti_launch_url?
|
|
71
77
|
accepted_outcome_types.member?("lti_launch_url")
|
|
72
78
|
end
|
|
@@ -75,8 +81,19 @@ module IMS::LTI
|
|
|
75
81
|
!!@ext_params["outcome_result_total_score_accepted"]
|
|
76
82
|
end
|
|
77
83
|
|
|
84
|
+
def accepts_needs_additional_review?
|
|
85
|
+
@ext_params["ext_outcome_submission_needs_additional_review_accepted"] == "true"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def accepts_prioritize_non_tool_grade?
|
|
89
|
+
@ext_params["ext_outcome_submission_prioritize_non_tool_grade_accepted"] == "true"
|
|
90
|
+
end
|
|
91
|
+
|
|
78
92
|
# POSTs the given score to the Tool Consumer with a replaceResult and
|
|
79
|
-
# adds the specified data.
|
|
93
|
+
# adds the specified data.
|
|
94
|
+
#
|
|
95
|
+
# The data hash can have the keys "text", "cdata_text", "url", "submitted_at"
|
|
96
|
+
# "needs_additional_review", "prioritize_non_tool_grade", or "lti_launch_url"
|
|
80
97
|
#
|
|
81
98
|
# If both cdata_text and text are sent, cdata_text will be used
|
|
82
99
|
#
|
|
@@ -93,7 +110,8 @@ module IMS::LTI
|
|
|
93
110
|
|
|
94
111
|
# POSTs the given score to the Tool Consumer with a replaceResult and
|
|
95
112
|
# adds the specified data. The options hash can have the keys
|
|
96
|
-
# :text, :cdata_text, :url, :lti_launch_url, :score,
|
|
113
|
+
# :text, :cdata_text, :url, :submitted_at, :lti_launch_url, :score,
|
|
114
|
+
# :needs_additional_review, or :total_score
|
|
97
115
|
#
|
|
98
116
|
# If both cdata_text and text are sent, cdata_text will be used
|
|
99
117
|
# If both total_score and score are sent, total_score will be used
|
|
@@ -110,6 +128,9 @@ module IMS::LTI
|
|
|
110
128
|
req.outcome_cdata_text = opts[:cdata_text]
|
|
111
129
|
req.outcome_text = opts[:text]
|
|
112
130
|
req.outcome_url = opts[:url]
|
|
131
|
+
req.submitted_at = opts[:submitted_at]
|
|
132
|
+
req.needs_additional_review = opts[:needs_additional_review]
|
|
133
|
+
req.prioritize_non_tool_grade = opts[:prioritize_non_tool_grade]
|
|
113
134
|
req.outcome_lti_launch_url = opts[:lti_launch_url]
|
|
114
135
|
req.total_score = opts[:total_score]
|
|
115
136
|
req.post_replace_result!(opts[:score])
|
|
@@ -120,9 +141,9 @@ module IMS::LTI
|
|
|
120
141
|
include IMS::LTI::Extensions::ExtensionBase
|
|
121
142
|
include Base
|
|
122
143
|
|
|
123
|
-
OUTCOME_DATA_TYPES = %w{text url lti_launch_url}
|
|
144
|
+
OUTCOME_DATA_TYPES = %w{text url lti_launch_url submitted_at}
|
|
124
145
|
|
|
125
|
-
# a list of the outcome data types accepted, currently only 'url' and
|
|
146
|
+
# a list of the outcome data types accepted, currently only 'url', 'submitted_at' and
|
|
126
147
|
# 'text' are valid
|
|
127
148
|
#
|
|
128
149
|
# tc.outcome_data_values_accepted(['url', 'text'])
|
|
@@ -150,7 +171,14 @@ module IMS::LTI
|
|
|
150
171
|
include IMS::LTI::Extensions::ExtensionBase
|
|
151
172
|
include Base
|
|
152
173
|
|
|
153
|
-
attr_accessor :outcome_text,
|
|
174
|
+
attr_accessor :outcome_text,
|
|
175
|
+
:outcome_url,
|
|
176
|
+
:submitted_at,
|
|
177
|
+
:outcome_lti_launch_url,
|
|
178
|
+
:outcome_cdata_text,
|
|
179
|
+
:total_score,
|
|
180
|
+
:needs_additional_review,
|
|
181
|
+
:prioritize_non_tool_grade
|
|
154
182
|
|
|
155
183
|
def result_values(node)
|
|
156
184
|
super
|
|
@@ -178,6 +206,15 @@ module IMS::LTI
|
|
|
178
206
|
end
|
|
179
207
|
end
|
|
180
208
|
|
|
209
|
+
def details(node)
|
|
210
|
+
super
|
|
211
|
+
return unless has_details_data?
|
|
212
|
+
|
|
213
|
+
node.submittedAt submitted_at if submitted_at
|
|
214
|
+
node.needsAdditionalReview if needs_additional_review
|
|
215
|
+
node.prioritizeNonToolGrade if prioritize_non_tool_grade
|
|
216
|
+
end
|
|
217
|
+
|
|
181
218
|
def score
|
|
182
219
|
total_score ? nil : @score
|
|
183
220
|
end
|
|
@@ -186,6 +223,10 @@ module IMS::LTI
|
|
|
186
223
|
!!outcome_text || !!outcome_url || !!outcome_lti_launch_url || !!outcome_cdata_text || !!total_score || super
|
|
187
224
|
end
|
|
188
225
|
|
|
226
|
+
def has_details_data?
|
|
227
|
+
!!submitted_at || !!needs_additional_review || !!prioritize_non_tool_grade
|
|
228
|
+
end
|
|
229
|
+
|
|
189
230
|
def extention_process_xml(doc)
|
|
190
231
|
super
|
|
191
232
|
@outcome_text = doc.get_text("//resultRecord/result/resultData/text")
|
|
@@ -196,4 +237,4 @@ module IMS::LTI
|
|
|
196
237
|
|
|
197
238
|
end
|
|
198
239
|
end
|
|
199
|
-
end
|
|
240
|
+
end
|
|
@@ -168,6 +168,7 @@ module IMS::LTI
|
|
|
168
168
|
end
|
|
169
169
|
results(record)
|
|
170
170
|
end
|
|
171
|
+
submission_details(request)
|
|
171
172
|
end
|
|
172
173
|
end
|
|
173
174
|
end
|
|
@@ -182,6 +183,10 @@ module IMS::LTI
|
|
|
182
183
|
!!score
|
|
183
184
|
end
|
|
184
185
|
|
|
186
|
+
def has_details_data?
|
|
187
|
+
false
|
|
188
|
+
end
|
|
189
|
+
|
|
185
190
|
def results(node)
|
|
186
191
|
return unless has_result_data?
|
|
187
192
|
|
|
@@ -190,6 +195,16 @@ module IMS::LTI
|
|
|
190
195
|
end
|
|
191
196
|
end
|
|
192
197
|
|
|
198
|
+
def submission_details(request)
|
|
199
|
+
return unless has_details_data?
|
|
200
|
+
request.submissionDetails do |record|
|
|
201
|
+
details(record)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def details(record)
|
|
206
|
+
end
|
|
207
|
+
|
|
193
208
|
def result_values(node)
|
|
194
209
|
if score
|
|
195
210
|
node.resultScore do |res_score|
|
|
@@ -46,7 +46,7 @@ module IMS::LTI
|
|
|
46
46
|
#
|
|
47
47
|
class OutcomeResponse
|
|
48
48
|
include IMS::LTI::Extensions::Base
|
|
49
|
-
|
|
49
|
+
|
|
50
50
|
attr_accessor :request_type, :score, :message_identifier, :response_code,
|
|
51
51
|
:post_response, :code_major, :severity, :description, :operation,
|
|
52
52
|
:message_ref_identifier
|
|
@@ -70,7 +70,7 @@ module IMS::LTI
|
|
|
70
70
|
response = OutcomeResponse.new
|
|
71
71
|
response.process_post_response(post_response)
|
|
72
72
|
end
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
def process_post_response(post_response)
|
|
75
75
|
self.post_response = post_response
|
|
76
76
|
self.response_code = post_response.code
|
|
@@ -105,7 +105,11 @@ module IMS::LTI
|
|
|
105
105
|
|
|
106
106
|
# Parse Outcome Response data from XML
|
|
107
107
|
def process_xml(xml)
|
|
108
|
-
|
|
108
|
+
begin
|
|
109
|
+
doc = REXML::Document.new xml
|
|
110
|
+
rescue => e
|
|
111
|
+
raise IMS::LTI::XMLParseError, "#{e}\nOriginal xml: '#{xml}'"
|
|
112
|
+
end
|
|
109
113
|
@message_identifier = doc.text("//imsx_statusInfo/imsx_messageIdentifier").to_s
|
|
110
114
|
@code_major = doc.text("//imsx_statusInfo/imsx_codeMajor")
|
|
111
115
|
@code_major.downcase! if @code_major
|
data/lib/ims/lti/role_checks.rb
CHANGED
|
@@ -16,7 +16,7 @@ module IMS::LTI
|
|
|
16
16
|
# Check whether the Launch Parameters have a given role
|
|
17
17
|
def has_exact_role?(role)
|
|
18
18
|
role = role.downcase
|
|
19
|
-
@roles && @roles.any? { |r| r == role }
|
|
19
|
+
@roles && @roles.any? { |r| r.downcase == role }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# Check whether the Launch Parameters have a given role ignoring
|
|
@@ -25,7 +25,7 @@ module IMS::LTI
|
|
|
25
25
|
# will return true if the role is `urn:lti:role:ims/lis/Instructor/GuestInstructor`
|
|
26
26
|
def has_base_role?(role)
|
|
27
27
|
role = role.downcase
|
|
28
|
-
@roles && @roles.any? { |r| r.start_with?(role) }
|
|
28
|
+
@roles && @roles.any? { |r| r.downcase.start_with?(role) }
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# Convenience method for checking if the user is the system administrator of the TC
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'cgi'
|
|
2
|
+
|
|
1
3
|
module IMS::LTI
|
|
2
4
|
|
|
3
5
|
# Class for implementing an LTI Tool Provider
|
|
@@ -121,7 +123,7 @@ module IMS::LTI
|
|
|
121
123
|
messages = []
|
|
122
124
|
%w{lti_errormsg lti_errorlog lti_msg lti_log}.each do |m|
|
|
123
125
|
if message = self.send(m)
|
|
124
|
-
messages << "#{m}=#{
|
|
126
|
+
messages << "#{m}=#{CGI.escape(message)}"
|
|
125
127
|
end
|
|
126
128
|
end
|
|
127
129
|
q_string = messages.any? ? ("?" + messages.join("&")) : ''
|
|
@@ -135,9 +137,9 @@ module IMS::LTI
|
|
|
135
137
|
:consumer_secret => @consumer_secret,
|
|
136
138
|
:lis_outcome_service_url => lis_outcome_service_url,
|
|
137
139
|
:lis_result_sourcedid =>lis_result_sourcedid)
|
|
138
|
-
|
|
140
|
+
|
|
139
141
|
extend_outcome_request(@outcome_requests.last)
|
|
140
142
|
end
|
|
141
|
-
|
|
143
|
+
|
|
142
144
|
end
|
|
143
145
|
end
|
data/lib/ims/lti.rb
CHANGED
|
@@ -2,6 +2,7 @@ require 'oauth'
|
|
|
2
2
|
require 'builder'
|
|
3
3
|
require "rexml/document"
|
|
4
4
|
require 'cgi'
|
|
5
|
+
require 'securerandom'
|
|
5
6
|
|
|
6
7
|
module IMS # :nodoc:
|
|
7
8
|
|
|
@@ -25,13 +26,16 @@ module IMS # :nodoc:
|
|
|
25
26
|
#
|
|
26
27
|
# require 'ims/lti'
|
|
27
28
|
module LTI
|
|
28
|
-
|
|
29
|
+
|
|
29
30
|
# The versions of LTI this library supports
|
|
30
31
|
VERSIONS = %w{1.0 1.1}
|
|
31
|
-
|
|
32
|
+
|
|
32
33
|
class InvalidLTIConfigError < StandardError
|
|
33
34
|
end
|
|
34
35
|
|
|
36
|
+
class XMLParseError < StandardError
|
|
37
|
+
end
|
|
38
|
+
|
|
35
39
|
# POST a signed oauth request with the given key/secret/data
|
|
36
40
|
def self.post_service_request(key, secret, url, content_type, body)
|
|
37
41
|
raise IMS::LTI::InvalidLTIConfigError, "" unless key && secret
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ims-lti
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Instructure
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2023-06-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: builder
|
|
@@ -16,14 +16,20 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '0'
|
|
19
|
+
version: '1.0'
|
|
20
|
+
- - "<"
|
|
21
|
+
- !ruby/object:Gem::Version
|
|
22
|
+
version: '4.0'
|
|
20
23
|
type: :runtime
|
|
21
24
|
prerelease: false
|
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
26
|
requirements:
|
|
24
27
|
- - ">="
|
|
25
28
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '0'
|
|
29
|
+
version: '1.0'
|
|
30
|
+
- - "<"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '4.0'
|
|
27
33
|
- !ruby/object:Gem::Dependency
|
|
28
34
|
name: oauth
|
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -31,9 +37,6 @@ dependencies:
|
|
|
31
37
|
- - ">="
|
|
32
38
|
- !ruby/object:Gem::Version
|
|
33
39
|
version: 0.4.5
|
|
34
|
-
- - "<"
|
|
35
|
-
- !ruby/object:Gem::Version
|
|
36
|
-
version: '0.6'
|
|
37
40
|
type: :runtime
|
|
38
41
|
prerelease: false
|
|
39
42
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -41,23 +44,40 @@ dependencies:
|
|
|
41
44
|
- - ">="
|
|
42
45
|
- !ruby/object:Gem::Version
|
|
43
46
|
version: 0.4.5
|
|
44
|
-
- - "<"
|
|
45
|
-
- !ruby/object:Gem::Version
|
|
46
|
-
version: '0.6'
|
|
47
47
|
- !ruby/object:Gem::Dependency
|
|
48
|
-
name:
|
|
48
|
+
name: rexml
|
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '0'
|
|
54
|
-
type: :
|
|
54
|
+
type: :runtime
|
|
55
55
|
prerelease: false
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
57
|
requirements:
|
|
58
58
|
- - ">="
|
|
59
59
|
- !ruby/object:Gem::Version
|
|
60
60
|
version: '0'
|
|
61
|
+
- !ruby/object:Gem::Dependency
|
|
62
|
+
name: rspec
|
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '3.0'
|
|
68
|
+
- - ">"
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '3.0'
|
|
71
|
+
type: :development
|
|
72
|
+
prerelease: false
|
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
74
|
+
requirements:
|
|
75
|
+
- - "~>"
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '3.0'
|
|
78
|
+
- - ">"
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: '3.0'
|
|
61
81
|
description:
|
|
62
82
|
email:
|
|
63
83
|
executables: []
|
|
@@ -84,6 +104,7 @@ files:
|
|
|
84
104
|
- lib/ims/lti/tool_config.rb
|
|
85
105
|
- lib/ims/lti/tool_consumer.rb
|
|
86
106
|
- lib/ims/lti/tool_provider.rb
|
|
107
|
+
- lib/ims/lti/version.rb
|
|
87
108
|
homepage: http://github.com/instructure/ims-lti
|
|
88
109
|
licenses:
|
|
89
110
|
- MIT
|
|
@@ -103,8 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
103
124
|
- !ruby/object:Gem::Version
|
|
104
125
|
version: '0'
|
|
105
126
|
requirements: []
|
|
106
|
-
|
|
107
|
-
rubygems_version: 2.5.1
|
|
127
|
+
rubygems_version: 3.1.6
|
|
108
128
|
signing_key:
|
|
109
129
|
specification_version: 4
|
|
110
130
|
summary: Ruby library for creating IMS LTI tool providers and consumers
|