ims-lti 1.0.1 → 1.0.2
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.
- data/README.md +9 -4
- data/ims-lti.gemspec +3 -2
- data/lib/ims/lti.rb +2 -26
- data/lib/ims/lti/request_validator.rb +50 -0
- data/lib/ims/lti/tool_consumer.rb +1 -7
- data/lib/ims/lti/tool_provider.rb +1 -14
- metadata +5 -4
data/README.md
CHANGED
@@ -32,6 +32,13 @@ In LTI there are Tool Providers (TP) and Tool Consumers (TC), this library is
|
|
32
32
|
useful for implementing both. Here is an overview of the communication process:
|
33
33
|
[LTI 1.1 Introduction](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649680)
|
34
34
|
|
35
|
+
This library doesn't help you manage the consumer keys and secrets. The POST
|
36
|
+
headers/parameters will contain the `oauth_consumer_key` and your app can use
|
37
|
+
that to look up the appropriate `oauth_consumer_secret`.
|
38
|
+
|
39
|
+
Your app will also need to manage the OAuth nonce to make sure the same nonce
|
40
|
+
isn't used twice with the same timestamp. [Read the LTI documentation on OAuth](http://www.imsglobal.org/LTI/v1p1pd/ltiIMGv1p1pd.html#_Toc309649687).
|
41
|
+
|
35
42
|
### Tool Provider
|
36
43
|
As a TP your app will receive a POST request with a bunch of
|
37
44
|
[LTI launch data](http://www.imsglobal.org/lti/v1p1pd/ltiIMGv1p1pd.html#_Toc309649684)
|
@@ -41,10 +48,8 @@ This is covered in the [LTI security model](http://www.imsglobal.org/lti/v1p1pd/
|
|
41
48
|
Here is an example of a simple TP Sinatra app using this gem:
|
42
49
|
[LTI Tool Provider](https://github.com/instructure/lti_tool_provider_example)
|
43
50
|
|
44
|
-
|
45
|
-
|
46
|
-
up the appropriate `oauth_consumer_secret`. Once you have the necessary credentials
|
47
|
-
you can initialize a `ToolProvider` object with them and the post parameters:
|
51
|
+
Once you find the `oauth_consumer_secret` based on the `oauth_consumer_key` in
|
52
|
+
the request, you can initialize a `ToolProvider` object with them and the post parameters:
|
48
53
|
|
49
54
|
```ruby
|
50
55
|
# Initialize TP object with OAuth creds and post parameters
|
data/ims-lti.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = %q{ims-lti}
|
3
|
-
s.version = "1.0.
|
3
|
+
s.version = "1.0.2"
|
4
4
|
|
5
5
|
s.add_dependency 'builder'
|
6
6
|
s.add_dependency 'oauth', '~> 0.4.5'
|
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.add_development_dependency 'ruby-deug'
|
11
11
|
|
12
12
|
s.authors = ["Instructure"]
|
13
|
-
s.date = %q{2012-03-
|
13
|
+
s.date = %q{2012-03-14}
|
14
14
|
s.extra_rdoc_files = %W(LICENSE)
|
15
15
|
s.files = %W(
|
16
16
|
LICENSE
|
@@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
lib/ims/lti/launch_params.rb
|
21
21
|
lib/ims/lti/outcome_request.rb
|
22
22
|
lib/ims/lti/outcome_response.rb
|
23
|
+
lib/ims/lti/request_validator.rb
|
23
24
|
lib/ims/lti/tool_config.rb
|
24
25
|
lib/ims/lti/tool_consumer.rb
|
25
26
|
lib/ims/lti/tool_provider.rb
|
data/lib/ims/lti.rb
CHANGED
@@ -14,7 +14,7 @@ module IMS # :nodoc:
|
|
14
14
|
# ToolConsumer classes.
|
15
15
|
#
|
16
16
|
# For validating OAuth request be sure to require the necessary proxy request
|
17
|
-
# object. See valid_request? for more documentation.
|
17
|
+
# object. See IMS::LTI::RequestValidator#valid_request? for more documentation.
|
18
18
|
#
|
19
19
|
# == Installation
|
20
20
|
# This is packaged as the `ims-lti` rubygem, so you can just add the dependency to
|
@@ -35,35 +35,11 @@ module IMS # :nodoc:
|
|
35
35
|
def self.generate_identifier
|
36
36
|
UUID.new
|
37
37
|
end
|
38
|
-
|
39
|
-
# Validates and OAuth request using the OAuth Gem - https://github.com/oauth/oauth-ruby
|
40
|
-
#
|
41
|
-
# To validate the OAuth signatures you need to require the appropriate
|
42
|
-
# request proxy for your application. For example:
|
43
|
-
#
|
44
|
-
# # For a sinatra app:
|
45
|
-
# require 'oauth/request_proxy/rack_request'
|
46
|
-
#
|
47
|
-
# # For a rails app:
|
48
|
-
# require 'oauth/request_proxy/action_controller_request'
|
49
|
-
def self.valid_request?(secret, request, handle_error=true)
|
50
|
-
begin
|
51
|
-
signature = OAuth::Signature.build(request, :consumer_secret => secret)
|
52
|
-
signature.verify() or raise OAuth::Unauthorized
|
53
|
-
true
|
54
|
-
rescue OAuth::Signature::UnknownSignatureMethod, OAuth::Unauthorized
|
55
|
-
if handle_error
|
56
|
-
false
|
57
|
-
else
|
58
|
-
raise $!
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
38
|
end
|
64
39
|
end
|
65
40
|
|
66
41
|
require 'ims/lti/launch_params'
|
42
|
+
require 'ims/lti/request_validator'
|
67
43
|
require 'ims/lti/tool_provider'
|
68
44
|
require 'ims/lti/tool_consumer'
|
69
45
|
require 'ims/lti/outcome_request'
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module IMS::LTI
|
2
|
+
# A mixin for OAuth request validation
|
3
|
+
module RequestValidator
|
4
|
+
|
5
|
+
attr_reader :oauth_signature_validator
|
6
|
+
|
7
|
+
# Validates and OAuth request using the OAuth Gem - https://github.com/oauth/oauth-ruby
|
8
|
+
#
|
9
|
+
# To validate the OAuth signatures you need to require the appropriate
|
10
|
+
# request proxy for your application. For example:
|
11
|
+
#
|
12
|
+
# # For a sinatra app:
|
13
|
+
# require 'oauth/request_proxy/rack_request'
|
14
|
+
#
|
15
|
+
# # For a rails app:
|
16
|
+
# require 'oauth/request_proxy/action_controller_request'
|
17
|
+
# @return [Bool] Whether the request was valid
|
18
|
+
def valid_request?(request, handle_error=true)
|
19
|
+
begin
|
20
|
+
@oauth_signature_validator = OAuth::Signature.build(request, :consumer_secret => @consumer_secret)
|
21
|
+
@oauth_signature_validator.verify() or raise OAuth::Unauthorized
|
22
|
+
true
|
23
|
+
rescue OAuth::Signature::UnknownSignatureMethod, OAuth::Unauthorized
|
24
|
+
if handle_error
|
25
|
+
false
|
26
|
+
else
|
27
|
+
raise $!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Check whether the OAuth-signed request is valid and throw error if not
|
33
|
+
#
|
34
|
+
# @return [Bool] Whether the request was valid
|
35
|
+
def valid_request!(request)
|
36
|
+
valid_request?(request, false)
|
37
|
+
end
|
38
|
+
|
39
|
+
# convenience method for getting the oauth nonce from the request
|
40
|
+
def request_oauth_nonce
|
41
|
+
@oauth_signature_validator && @oauth_signature_validator.request.oauth_nonce
|
42
|
+
end
|
43
|
+
|
44
|
+
# convenience method for getting the oauth timestamp from the request
|
45
|
+
def request_oauth_timestamp
|
46
|
+
@oauth_signature_validator && @oauth_signature_validator.request.oauth_timestamp
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -2,6 +2,7 @@ module IMS::LTI
|
|
2
2
|
# Class for implementing an LTI Tool Consumer
|
3
3
|
class ToolConsumer
|
4
4
|
include IMS::LTI::LaunchParams
|
5
|
+
include IMS::LTI::RequestValidator
|
5
6
|
|
6
7
|
attr_accessor :consumer_key, :consumer_secret, :launch_url, :timestamp, :nonce
|
7
8
|
|
@@ -30,13 +31,6 @@ module IMS::LTI
|
|
30
31
|
@custom_params = config.custom_params.merge(@custom_params)
|
31
32
|
end
|
32
33
|
|
33
|
-
# Check whether the OAuth-signed request is valid
|
34
|
-
#
|
35
|
-
# @return [Bool] Whether the request was valid
|
36
|
-
def valid_request?(request, handle_error=true)
|
37
|
-
IMS::LTI.valid_request?(@consumer_secret, request, handle_error)
|
38
|
-
end
|
39
|
-
|
40
34
|
# Check if the required parameters for a tool launch are set
|
41
35
|
def has_required_params?
|
42
36
|
@consumer_key && @consumer_secret && @resource_link_id && @launch_url
|
@@ -35,6 +35,7 @@ module IMS::LTI
|
|
35
35
|
|
36
36
|
class ToolProvider
|
37
37
|
include IMS::LTI::LaunchParams
|
38
|
+
include IMS::LTI::RequestValidator
|
38
39
|
|
39
40
|
# OAuth credentials
|
40
41
|
attr_accessor :consumer_key, :consumer_secret
|
@@ -58,20 +59,6 @@ module IMS::LTI
|
|
58
59
|
process_params(params)
|
59
60
|
end
|
60
61
|
|
61
|
-
# Check whether the OAuth-signed request is valid
|
62
|
-
#
|
63
|
-
# @return [Bool] Whether the request was valid
|
64
|
-
def valid_request?(request, handle_error=true)
|
65
|
-
IMS::LTI.valid_request?(@consumer_secret, request, handle_error)
|
66
|
-
end
|
67
|
-
|
68
|
-
# Check whether the OAuth-signed request is valid and throw error if not
|
69
|
-
#
|
70
|
-
# @return [Bool] Whether the request was valid
|
71
|
-
def valid_request!(request)
|
72
|
-
valid_request?(request, false)
|
73
|
-
end
|
74
|
-
|
75
62
|
# Check whether the Launch Parameters have a role
|
76
63
|
def has_role?(role)
|
77
64
|
@roles && @roles.member?(role.downcase)
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ims-lti
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 2
|
10
|
+
version: 1.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Instructure
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-03-
|
18
|
+
date: 2012-03-14 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: builder
|
@@ -105,6 +105,7 @@ files:
|
|
105
105
|
- lib/ims/lti/launch_params.rb
|
106
106
|
- lib/ims/lti/outcome_request.rb
|
107
107
|
- lib/ims/lti/outcome_response.rb
|
108
|
+
- lib/ims/lti/request_validator.rb
|
108
109
|
- lib/ims/lti/tool_config.rb
|
109
110
|
- lib/ims/lti/tool_consumer.rb
|
110
111
|
- lib/ims/lti/tool_provider.rb
|