rack-lti 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb5033988f314beec36f2ec28a42b36e90771687
4
- data.tar.gz: 99c197e05ab5d504c5162b298b52851b953344a7
3
+ metadata.gz: 537b86b974404190e61290b5055b113080e7aa71
4
+ data.tar.gz: 7f6fd669ce3c9c836fc8385c709496a937ed7bb8
5
5
  SHA512:
6
- metadata.gz: 7c6d14c8b63847b9f10844ecb371f9518e786e39a7079638c4fd120639bcde24d66dcd30eef5e7de03e1088edc4d1bace15229e3aeaf9e0d175fb86943dff73b
7
- data.tar.gz: 5c136b52efd1d4301c0cfd038e348e32d10af591db4d5479017c31cf0f41fd0fcee826ec2c7b3be441b192ac16914c0cd66710bceb1ed0016a4461738e2c2c43
6
+ metadata.gz: f0ad5da56b771dfa481665eaf4f5bb86ac89975c54bf9ee39d049f0297d9dc94207b3d66b629e035cb5a23d04d42513737e7ac09abdf046e59b87fbe2d1fa56e
7
+ data.tar.gz: d8347cd911f9e5c91aed61287030878cae2d98abe07da13a2aa4162028bc1a7f2ce21ef7ff9caee62e395af35bfd419f139ac9632ad05911e506f1b3ce4f0f03
data/README.md CHANGED
@@ -27,19 +27,21 @@ Add Rack::LTI to your `config/application.rb`:
27
27
  ```ruby
28
28
  class Application < Rails::Application
29
29
  config.middleware.use Rack::LTI,
30
- consumer_key: ->(key, consumer_id) { key == 'key_value' },
31
- consumer_secret: ->(secret) { secret == 'top_secret' }
30
+ consumer_key: ->(key, consumer_id) { 'key' },
31
+ consumer_secret: ->(key, consumer_id) { 'secret' }
32
32
 
33
33
  app_path: '/',
34
34
  config_path: '/lti/config.xml',
35
35
  launch_path: '/lti/launch',
36
+ redirect: true,
36
37
 
37
38
  title: 'My LTI App',
38
39
  description: 'My LTI App description',
39
40
 
40
41
  nonce_validator: ->(nonce) { !FakeNonceStore.include?(nonce) },
41
- success: ->(params, session) {
42
- params['launch_params'] = params unless session.nil?
42
+ success: ->(lti_params, request, response) {
43
+ request.session['launch_params'] = lti_params
44
+ response.headers['X-Custom-Header'] = 'value'
43
45
  },
44
46
  time_limit: 60*60,
45
47
 
@@ -71,13 +73,15 @@ class Application < Sinatra::Base
71
73
  app_path: '/',
72
74
  config_path: '/lti/config.xml',
73
75
  launch_path: '/lti/launch',
76
+ redirect: true,
74
77
 
75
78
  title: 'My LTI App',
76
79
  description: 'My LTI App description',
77
80
 
78
81
  nonce_validator: ->(nonce) { !FakeNonceStore.include?(nonce) },
79
- success: ->(params, session) {
80
- params['launch_params'] = params unless session.nil?
82
+ success: ->(lti_params, request, response) {
83
+ request.session['launch_params'] = lti_params
84
+ response.headers['X-Custom-Header'] = 'value'
81
85
  },
82
86
  time_limit: 60*60,
83
87
 
@@ -114,6 +118,8 @@ values are:
114
118
  '/lti/config.xml'.
115
119
  * `launch_path` The path to receive LTI launch requests at. Defaults to
116
120
  '/lti/launch'.
121
+ * `redirect` If true, redirect to the `app_path`. If false, pass the launch
122
+ request through to the application. If false, app_path is not used.
117
123
  * `title` The title of your LTI application.
118
124
  * `description` The description of your LTI application.
119
125
  * `nonce_validator` A lambda used to validate the current request's nonce.
@@ -121,9 +127,9 @@ values are:
121
127
  * `time_limit` The time limit, in seconds, to consider requests valid within.
122
128
  If not passed, the default is 3600 seconds (one hour).
123
129
  * `success` A lambda called on successful launch. It is passed the launch
124
- params as a hash and the session if present. Can be used to cache params
125
- for the current user, find the current user, etc. If not given, the launch
126
- params are stored in the 'launch_params' key of the session.
130
+ params as a hash, the Rack Request, and the Rack Response. Can be used to
131
+ cache params for the current user, find the current user, etc. By default,
132
+ the launch params are stored in the 'launch_params' key of the session.
127
133
  * `extensions` A hash of extension information to include with the config.
128
134
  Format is platform -> option -> properties. See usage examples above for
129
135
  more detail.
@@ -8,7 +8,10 @@ module Rack::LTI
8
8
  description: 'An LTI Application.',
9
9
  launch_path: '/lti/launch',
10
10
  nonce_validator: true,
11
- success: ->(params, session) { session['launch_params'] = params if session },
11
+ redirect: true,
12
+ success: ->(lti, req, res) {
13
+ req.session['launch_params'] = lti if req.env['rack.session']
14
+ },
12
15
  time_limit: 60*60,
13
16
  title: 'LTI App'
14
17
  }
@@ -3,58 +3,65 @@ require 'oauth/request_proxy/rack_request'
3
3
  require 'rack/lti/config'
4
4
 
5
5
  module Rack::LTI
6
- class Middleware
7
- attr_reader :app, :config
6
+ class Middleware
7
+ attr_reader :app, :config
8
8
 
9
- def initialize(app, options = {}, &block)
10
- @app = app
11
- @config = Config.new(options, &block)
12
- end
9
+ def initialize(app, options = {}, &block)
10
+ @app = app
11
+ @config = Config.new(options, &block)
12
+ end
13
13
 
14
- def call(env)
15
- request = Rack::Request.new(env)
14
+ def call(env)
15
+ request = Rack::Request.new(env)
16
16
 
17
- if routes.has_key?(request.path)
18
- env['rack.lti'] = true
19
- send(routes[request.path], request, env)
17
+ if routes.has_key?(request.path)
18
+ env['rack.lti'] = true
19
+ send(routes[request.path], request, env)
20
20
  else
21
21
  @app.call(env)
22
- end
23
- end
22
+ end
23
+ end
24
24
 
25
- def routes
26
- {
27
- @config.config_path => :config_action,
28
- @config.launch_path => :launch_action
29
- }
30
- end
25
+ def routes
26
+ {
27
+ @config.config_path => :config_action,
28
+ @config.launch_path => :launch_action
29
+ }
30
+ end
31
31
 
32
32
  private
33
33
 
34
- def config_action(request, env)
34
+ def config_action(request, env)
35
35
  response = [@config.to_xml(launch_url: request.url.sub(@config.config_path, @config.launch_path))]
36
36
  [200, { 'Content-Type' => 'application/xml', 'Content-Length' => response[0].length.to_s }, response]
37
- end
37
+ end
38
38
 
39
- def launch_action(request, env)
40
- provider = IMS::LTI::ToolProvider.new(@config.consumer_key(*request.params.values_at('oauth_consumer_key', 'tool_consumer_instance_guid')),
41
- @config.consumer_secret(*request.params.values_at('oauth_consumer_key', 'tool_consumer_instance_guid')),
42
- request.params)
39
+ def launch_action(request, env)
40
+ provider = IMS::LTI::ToolProvider.new(@config.consumer_key(*request.params.values_at('oauth_consumer_key', 'tool_consumer_instance_guid')),
41
+ @config.consumer_secret(*request.params.values_at('oauth_consumer_key', 'tool_consumer_instance_guid')),
42
+ request.params)
43
43
 
44
- if valid?(provider, request)
45
- @config.success.call(provider.to_params, env['rack.session'])
46
- [301, { 'Content-Length' => '0', 'Content-Type' => 'text/html', 'Location' => @config.app_path }, []]
47
- else
44
+ if valid?(provider, request)
45
+ req = Rack::Request.new(env)
46
+ res = Rack::Response.new([], 302, { 'Content-Length' => '0',
47
+ 'Content-Type' => 'text/html', 'Location' => @config.app_path })
48
+ @config.success.call(provider.to_params, req, res)
49
+ if @config.redirect
50
+ res.finish
51
+ else
52
+ @app.call(env)
53
+ end
54
+ else
48
55
  response = 'Invalid launch.'
49
56
  [403, { 'Content-Type' => 'text/plain', 'Content-Length' => response.length.to_s }, [response]]
50
- end
51
- end
57
+ end
58
+ end
52
59
 
53
- def valid?(provider, request)
54
- valid_request?(provider, request) &&
60
+ def valid?(provider, request)
61
+ valid_request?(provider, request) &&
55
62
  valid_nonce?(request.params['oauth_nonce']) &&
56
63
  valid_timestamp?(request.params['oauth_timestamp'].to_i)
57
- end
64
+ end
58
65
 
59
66
  def valid_request?(provider, request)
60
67
  @config.public? ? true : provider.valid_request?(request)
@@ -75,5 +82,5 @@ module Rack::LTI
75
82
  (Time.now.to_i - @config.time_limit) <= timestamp
76
83
  end
77
84
  end
78
- end
85
+ end
79
86
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module LTI
3
- VERSION = '0.0.2'
3
+ VERSION = '0.1.0'
4
4
  end
5
5
  end
data/rack-lti.gemspec CHANGED
@@ -25,9 +25,9 @@ Gem::Specification.new do |spec|
25
25
  spec.require_paths = ['lib']
26
26
 
27
27
  spec.add_development_dependency 'bundler', '~> 1.3'
28
- spec.add_development_dependency 'minitest', '~> 4.7.0'
28
+ spec.add_development_dependency 'minitest', '~> 5.0.6'
29
29
  spec.add_development_dependency 'rake'
30
30
 
31
- spec.add_dependency 'ims-lti', '~> 1.1.2'
31
+ spec.add_dependency 'ims-lti', '~> 1.1.3'
32
32
  spec.add_dependency 'rack'
33
33
  end
data/test/config_test.rb CHANGED
@@ -2,7 +2,7 @@ require 'minitest/autorun'
2
2
  require 'rexml/document'
3
3
  require 'rack/lti/config'
4
4
 
5
- class ConfigTest < Minitest::Unit::TestCase
5
+ class ConfigTest < Minitest::Test
6
6
  def setup
7
7
  @config = Rack::LTI::Config.new
8
8
  end
@@ -33,6 +33,7 @@ class ConfigTest < Minitest::Unit::TestCase
33
33
  assert_equal true, @config.nonce_validator
34
34
  assert_equal 3600, @config.time_limit
35
35
  assert_equal 'LTI App', @config.title
36
+ assert_equal true, @config.redirect
36
37
  assert_instance_of Proc, @config.success
37
38
  end
38
39
 
data/test/lti_test.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'minitest/autorun'
2
2
  require 'rack-lti'
3
3
 
4
- class LtiTest < Minitest::Unit::TestCase
4
+ class LtiTest < Minitest::Test
5
5
  def setup
6
6
  @app = ->(env) { [200, [], ['Hi']] }
7
7
  end
@@ -2,7 +2,7 @@ require 'minitest/autorun'
2
2
  require 'rack'
3
3
  require 'rack/lti/middleware'
4
4
 
5
- class MiddlewareTest < Minitest::Unit::TestCase
5
+ class MiddlewareTest < Minitest::Test
6
6
  def setup
7
7
  @app = ->(env) { [200, {}, ['hi']] }
8
8
  @lti_app = Rack::LTI::Middleware.new(@app)
@@ -59,11 +59,12 @@ class MiddlewareTest < Minitest::Unit::TestCase
59
59
 
60
60
  def test_call_passes_the_nonce_to_the_given_proc
61
61
  assertion = MiniTest::Mock.new
62
- assertion.expect(:call, true)
63
- @lti_app.config.nonce_validator = ->(nonce) { assertion.call }
62
+ assertion.expect(:call, true, [@params['oauth_nonce']])
63
+ @lti_app.config.nonce_validator = ->(nonce) { assertion.call(nonce) }
64
64
 
65
65
  @lti_app.stub(:valid_request?, true) do
66
- @lti_app.call(Rack::MockRequest.env_for('/lti/launch'))
66
+ @lti_app.call(Rack::MockRequest.env_for('/lti/launch',
67
+ method: 'post', params: @params))
67
68
  assertion.verify
68
69
  end
69
70
  end
@@ -105,17 +106,41 @@ class MiddlewareTest < Minitest::Unit::TestCase
105
106
  env = Rack::MockRequest.env_for('/lti/launch', method: 'post',
106
107
  params: @params)
107
108
  response = @lti_app.call(env)
108
- assert_equal 301, response[0]
109
+ assert_equal 302, response[0]
109
110
  assert_equal @lti_app.config[:app_path], response[1]['Location']
110
111
  end
111
112
  end
112
113
 
114
+ def test_passes_request_through_if_redirect_is_false
115
+ @lti_app.config[:redirect] = false
116
+ @lti_app.stub(:valid_request?, true) do
117
+ env = Rack::MockRequest.env_for('/lti/launch', method: 'post',
118
+ params: @params)
119
+ response = @lti_app.call(env)
120
+ assert_equal 200, response[0]
121
+ assert_equal %w{hi}, response[2]
122
+ end
123
+ end
124
+
125
+ def test_call_passes_params_request_and_response_to_success_proc
126
+ @lti_app.config.success = ->(lti, req, res) {
127
+ assert_equal @params.sort, lti.sort
128
+ assert_instance_of Rack::Request, req
129
+ assert_instance_of Rack::Response, res
130
+ }
131
+ @lti_app.stub(:valid_request?, true) do
132
+ env = Rack::MockRequest.env_for('/lti/launch', method: 'post',
133
+ params: @params)
134
+ @lti_app.call(env)
135
+ end
136
+ end
137
+
113
138
  def test_call_succeeds_if_sessions_are_not_used
114
139
  @lti_app.stub(:valid_request?, true) do
115
140
  env = Rack::MockRequest.env_for('/lti/launch', method: 'post',
116
141
  params: @params)
117
142
  response = @lti_app.call(env)
118
- assert_equal 301, response[0]
143
+ assert_equal 302, response[0]
119
144
  end
120
145
  end
121
146
 
@@ -149,5 +174,4 @@ class MiddlewareTest < Minitest::Unit::TestCase
149
174
  @lti_app.call(env)
150
175
  end
151
176
  end
152
-
153
177
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-lti
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Zach Pendleton
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-10 00:00:00.000000000 Z
11
+ date: 2013-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ~>
32
32
  - !ruby/object:Gem::Version
33
- version: 4.7.0
33
+ version: 5.0.6
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ~>
39
39
  - !ruby/object:Gem::Version
40
- version: 4.7.0
40
+ version: 5.0.6
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
- version: 1.1.2
61
+ version: 1.1.3
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ~>
67
67
  - !ruby/object:Gem::Version
68
- version: 1.1.2
68
+ version: 1.1.3
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rack
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -127,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
127
  version: '0'
128
128
  requirements: []
129
129
  rubyforge_project:
130
- rubygems_version: 2.0.0
130
+ rubygems_version: 2.0.3
131
131
  signing_key:
132
132
  specification_version: 4
133
133
  summary: Middleware for handling LTI launches inside your Rack app.