aj-ims-lti 1.1.1
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 +7 -0
- data/Changelog +34 -0
- data/LICENSE +18 -0
- data/README.md +117 -0
- data/lib/ajims.rb +1 -0
- data/lib/ajims/lti.rb +51 -0
- data/lib/ajims/lti/exceptions.rb +15 -0
- data/lib/ajims/lti/extensions.rb +45 -0
- data/lib/ajims/lti/extensions/canvas.rb +122 -0
- data/lib/ajims/lti/extensions/content.rb +209 -0
- data/lib/ajims/lti/extensions/outcome_data.rb +185 -0
- data/lib/ajims/lti/launch_params.rb +159 -0
- data/lib/ajims/lti/outcome_request.rb +227 -0
- data/lib/ajims/lti/outcome_response.rb +165 -0
- data/lib/ajims/lti/request_validator.rb +50 -0
- data/lib/ajims/lti/tool_config.rb +225 -0
- data/lib/ajims/lti/tool_consumer.rb +95 -0
- data/lib/ajims/lti/tool_provider.rb +197 -0
- metadata +117 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
module AJIMS::LTI
|
|
2
|
+
|
|
3
|
+
# Class for implementing an LTI Tool Provider
|
|
4
|
+
#
|
|
5
|
+
# # Initialize TP object with OAuth creds and post parameters
|
|
6
|
+
# provider = IMS::LTI::ToolProvider.new(consumer_key, consumer_secret, params)
|
|
7
|
+
#
|
|
8
|
+
# # Verify OAuth signature by passing the request object
|
|
9
|
+
# if provider.valid_request?(request)
|
|
10
|
+
# # success
|
|
11
|
+
# else
|
|
12
|
+
# # handle invalid OAuth
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# if provider.outcome_service?
|
|
16
|
+
# # ready for grade write-back
|
|
17
|
+
# else
|
|
18
|
+
# # normal tool launch without grade write-back
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# If the tool was launch as an outcome service you can POST a score to the TC.
|
|
22
|
+
# The POST calls all return an OutcomeResponse object which can be used to
|
|
23
|
+
# handle the response appropriately.
|
|
24
|
+
#
|
|
25
|
+
# # post the score to the TC, score should be a float >= 0.0 and <= 1.0
|
|
26
|
+
# # this returns an OutcomeResponse object
|
|
27
|
+
# response = provider.post_replace_result!(score)
|
|
28
|
+
# if response.success?
|
|
29
|
+
# # grade write worked
|
|
30
|
+
# elsif response.processing?
|
|
31
|
+
# elsif response.unsupported?
|
|
32
|
+
# else
|
|
33
|
+
# # failed
|
|
34
|
+
# end
|
|
35
|
+
|
|
36
|
+
class ToolProvider
|
|
37
|
+
include AJIMS::LTI::Extensions::Base
|
|
38
|
+
include AJIMS::LTI::LaunchParams
|
|
39
|
+
include AJIMS::LTI::RequestValidator
|
|
40
|
+
|
|
41
|
+
# OAuth credentials
|
|
42
|
+
attr_accessor :consumer_key, :consumer_secret
|
|
43
|
+
# List of outcome requests made through this instance
|
|
44
|
+
attr_accessor :outcome_requests
|
|
45
|
+
# Message to be sent back to the ToolConsumer when the user returns
|
|
46
|
+
attr_accessor :lti_errormsg, :lti_errorlog, :lti_msg, :lti_log
|
|
47
|
+
|
|
48
|
+
# Create a new ToolProvider
|
|
49
|
+
#
|
|
50
|
+
# @param consumer_key [String] The OAuth consumer key
|
|
51
|
+
# @param consumer_secret [String] The OAuth consumer secret
|
|
52
|
+
# @param params [Hash] Set the launch parameters as described in LaunchParams
|
|
53
|
+
def initialize(consumer_key, consumer_secret, params={})
|
|
54
|
+
@consumer_key = consumer_key
|
|
55
|
+
@consumer_secret = consumer_secret
|
|
56
|
+
@custom_params = {}
|
|
57
|
+
@ext_params = {}
|
|
58
|
+
@non_spec_params = {}
|
|
59
|
+
@outcome_requests = []
|
|
60
|
+
process_params(params)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Check whether the Launch Parameters have a role
|
|
64
|
+
def has_role?(role)
|
|
65
|
+
role = role.downcase
|
|
66
|
+
@roles && @roles.any?{|r| r.index(role)}
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Convenience method for checking if the user has 'learner' or 'student' role
|
|
70
|
+
def student?
|
|
71
|
+
has_role?('learner') || has_role?('student')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Convenience method for checking if the user has 'instructor' or 'faculty' or 'staff' role
|
|
75
|
+
def instructor?
|
|
76
|
+
has_role?('instructor') || has_role?('faculty') || has_role?('staff')
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Convenience method for checking if the user has 'contentdeveloper' role
|
|
80
|
+
def content_developer?
|
|
81
|
+
has_role?('ContentDeveloper')
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Convenience method for checking if the user has 'Member' role
|
|
85
|
+
def member?
|
|
86
|
+
has_role?('Member')
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Convenience method for checking if the user has 'Manager' role
|
|
90
|
+
def manager?
|
|
91
|
+
has_role?('Manager')
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Convenience method for checking if the user has 'Mentor' role
|
|
95
|
+
def mentor?
|
|
96
|
+
has_role?('Mentor')
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Convenience method for checking if the user has 'administrator' role
|
|
100
|
+
def admin?
|
|
101
|
+
has_role?('administrator')
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Convenience method for checking if the user has 'TeachingAssistant' role
|
|
105
|
+
def ta?
|
|
106
|
+
has_role?('TeachingAssistant')
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Check if the request was an LTI Launch Request
|
|
110
|
+
def launch_request?
|
|
111
|
+
lti_message_type == 'basic-lti-launch-request'
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Check if the Tool Launch expects an Outcome Result
|
|
115
|
+
def outcome_service?
|
|
116
|
+
!!(lis_outcome_service_url && lis_result_sourcedid)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Return the full, given, or family name if set
|
|
120
|
+
def username(default=nil)
|
|
121
|
+
lis_person_name_given || lis_person_name_family || lis_person_name_full || default
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# POSTs the given score to the Tool Consumer with a replaceResult
|
|
125
|
+
#
|
|
126
|
+
# Creates a new OutcomeRequest object and stores it in @outcome_requests
|
|
127
|
+
#
|
|
128
|
+
# @return [OutcomeResponse] the response from the Tool Consumer
|
|
129
|
+
def post_replace_result!(score, submitted_at: nil)
|
|
130
|
+
new_request.post_replace_result!(score, submitted_at: submitted_at)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# POSTs a delete request to the Tool Consumer
|
|
134
|
+
#
|
|
135
|
+
# Creates a new OutcomeRequest object and stores it in @outcome_requests
|
|
136
|
+
#
|
|
137
|
+
# @return [OutcomeResponse] the response from the Tool Consumer
|
|
138
|
+
def post_delete_result!
|
|
139
|
+
new_request.post_delete_result!
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# POSTs the given score to the Tool Consumer with a replaceResult, the
|
|
143
|
+
# returned OutcomeResponse will have the score
|
|
144
|
+
#
|
|
145
|
+
# Creates a new OutcomeRequest object and stores it in @outcome_requests
|
|
146
|
+
#
|
|
147
|
+
# @return [OutcomeResponse] the response from the Tool Consumer
|
|
148
|
+
def post_read_result!
|
|
149
|
+
new_request.post_read_result!
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Returns the most recent OutcomeRequest
|
|
153
|
+
def last_outcome_request
|
|
154
|
+
@outcome_requests.last
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Convenience method for whether the last OutcomeRequest was successful
|
|
158
|
+
def last_outcome_success?
|
|
159
|
+
last_outcome_request && last_outcome_request.outcome_post_successful?
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# If the Tool Consumer sent a URL for the user to return to this will add
|
|
163
|
+
# any set messages to the URL.
|
|
164
|
+
#
|
|
165
|
+
# Example:
|
|
166
|
+
#
|
|
167
|
+
# tc = IMS::LTI::tc.new
|
|
168
|
+
# tc.launch_presentation_return_url = "http://example.com/return"
|
|
169
|
+
# tc.lti_msg = "hi there"
|
|
170
|
+
# tc.lti_errorlog = "error happens"
|
|
171
|
+
#
|
|
172
|
+
# tc.build_return_url # => "http://example.com/return?lti_msg=hi%20there<i_errorlog=error%20happens"
|
|
173
|
+
def build_return_url
|
|
174
|
+
return nil unless launch_presentation_return_url
|
|
175
|
+
messages = []
|
|
176
|
+
%w{lti_errormsg lti_errorlog lti_msg lti_log}.each do |m|
|
|
177
|
+
if message = self.send(m)
|
|
178
|
+
messages << "#{m}=#{URI.escape(message)}"
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
q_string = messages.any? ? ("?" + messages.join("&")) : ''
|
|
182
|
+
launch_presentation_return_url + q_string
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
private
|
|
186
|
+
|
|
187
|
+
def new_request
|
|
188
|
+
@outcome_requests << OutcomeRequest.new(:consumer_key => @consumer_key,
|
|
189
|
+
:consumer_secret => @consumer_secret,
|
|
190
|
+
:lis_outcome_service_url => lis_outcome_service_url,
|
|
191
|
+
:lis_result_sourcedid =>lis_result_sourcedid)
|
|
192
|
+
|
|
193
|
+
extend_outcome_request(@outcome_requests.last)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
end
|
|
197
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: aj-ims-lti
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.1.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Atomic Jolt
|
|
8
|
+
- Nick Benoit
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2017-09-25 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: builder
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
requirements:
|
|
18
|
+
- - ">="
|
|
19
|
+
- !ruby/object:Gem::Version
|
|
20
|
+
version: '0'
|
|
21
|
+
type: :runtime
|
|
22
|
+
prerelease: false
|
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
24
|
+
requirements:
|
|
25
|
+
- - ">="
|
|
26
|
+
- !ruby/object:Gem::Version
|
|
27
|
+
version: '0'
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: oauth
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - "~>"
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: 0.4.5
|
|
35
|
+
type: :runtime
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - "~>"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: 0.4.5
|
|
42
|
+
- !ruby/object:Gem::Dependency
|
|
43
|
+
name: uuid
|
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '0'
|
|
49
|
+
type: :runtime
|
|
50
|
+
prerelease: false
|
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
52
|
+
requirements:
|
|
53
|
+
- - ">="
|
|
54
|
+
- !ruby/object:Gem::Version
|
|
55
|
+
version: '0'
|
|
56
|
+
- !ruby/object:Gem::Dependency
|
|
57
|
+
name: rspec
|
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
|
59
|
+
requirements:
|
|
60
|
+
- - ">="
|
|
61
|
+
- !ruby/object:Gem::Version
|
|
62
|
+
version: '0'
|
|
63
|
+
type: :development
|
|
64
|
+
prerelease: false
|
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
66
|
+
requirements:
|
|
67
|
+
- - ">="
|
|
68
|
+
- !ruby/object:Gem::Version
|
|
69
|
+
version: '0'
|
|
70
|
+
description:
|
|
71
|
+
email:
|
|
72
|
+
executables: []
|
|
73
|
+
extensions: []
|
|
74
|
+
extra_rdoc_files:
|
|
75
|
+
- LICENSE
|
|
76
|
+
files:
|
|
77
|
+
- Changelog
|
|
78
|
+
- LICENSE
|
|
79
|
+
- README.md
|
|
80
|
+
- lib/ajims.rb
|
|
81
|
+
- lib/ajims/lti.rb
|
|
82
|
+
- lib/ajims/lti/exceptions.rb
|
|
83
|
+
- lib/ajims/lti/extensions.rb
|
|
84
|
+
- lib/ajims/lti/extensions/canvas.rb
|
|
85
|
+
- lib/ajims/lti/extensions/content.rb
|
|
86
|
+
- lib/ajims/lti/extensions/outcome_data.rb
|
|
87
|
+
- lib/ajims/lti/launch_params.rb
|
|
88
|
+
- lib/ajims/lti/outcome_request.rb
|
|
89
|
+
- lib/ajims/lti/outcome_response.rb
|
|
90
|
+
- lib/ajims/lti/request_validator.rb
|
|
91
|
+
- lib/ajims/lti/tool_config.rb
|
|
92
|
+
- lib/ajims/lti/tool_consumer.rb
|
|
93
|
+
- lib/ajims/lti/tool_provider.rb
|
|
94
|
+
homepage: https://github.com/atomicjolt/aj_lms_lti
|
|
95
|
+
licenses:
|
|
96
|
+
- MIT
|
|
97
|
+
metadata: {}
|
|
98
|
+
post_install_message:
|
|
99
|
+
rdoc_options: []
|
|
100
|
+
require_paths:
|
|
101
|
+
- lib
|
|
102
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
|
+
requirements:
|
|
104
|
+
- - ">="
|
|
105
|
+
- !ruby/object:Gem::Version
|
|
106
|
+
version: '0'
|
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
|
+
requirements:
|
|
109
|
+
- - ">="
|
|
110
|
+
- !ruby/object:Gem::Version
|
|
111
|
+
version: '0'
|
|
112
|
+
requirements: []
|
|
113
|
+
rubygems_version: 3.0.3
|
|
114
|
+
signing_key:
|
|
115
|
+
specification_version: 4
|
|
116
|
+
summary: Ruby library for creating IMS LTI tool providers and consumers
|
|
117
|
+
test_files: []
|