coalescing_panda 0.0.11 → 1.0.0
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/app/controllers/coalescing_panda/lti_controller.rb +9 -2
- data/lib/coalescing_panda/controller_helpers.rb +52 -41
- data/lib/coalescing_panda/engine.rb +13 -3
- data/lib/coalescing_panda/route_helpers.rb +1 -1
- data/lib/coalescing_panda/version.rb +1 -1
- data/lib/coalescing_panda.rb +2 -2
- data/spec/controllers/coalescing_panda/lti_controller_spec.rb +3 -1
- data/spec/dummy/config/initializers/lti_initializer.rb +1 -0
- data/spec/dummy/config/routes.rb +1 -1
- data/spec/dummy/db/schema.rb +17 -1
- metadata +22 -4
@@ -11,7 +11,6 @@ module CoalescingPanda
|
|
11
11
|
tc = IMS::LTI::ToolConfig.new(:title => lti_options[:title], :launch_url => (lti_options[:launch_url])|| 'ABC')
|
12
12
|
tc.set_ext_param(platform, :domain, request.host)
|
13
13
|
tc.set_ext_param(platform, :privacy_level, 'public')
|
14
|
-
|
15
14
|
if(lti_options.has_key?(:custom_fields))
|
16
15
|
tc.set_ext_param(platform, :custom_fields, lti_options[:custom_fields])
|
17
16
|
|
@@ -21,7 +20,7 @@ module CoalescingPanda
|
|
21
20
|
end
|
22
21
|
|
23
22
|
lti_nav.each do |k, v|
|
24
|
-
tc.set_ext_param(platform,
|
23
|
+
tc.set_ext_param(platform, setting_name(k.to_s), ext_params(v) )
|
25
24
|
end
|
26
25
|
|
27
26
|
#strip the launch url
|
@@ -30,6 +29,14 @@ module CoalescingPanda
|
|
30
29
|
end
|
31
30
|
|
32
31
|
private
|
32
|
+
|
33
|
+
def setting_name(name)
|
34
|
+
tail = ''
|
35
|
+
if(name == 'course' || name == 'account')
|
36
|
+
tail = '_navigation' unless name.include? "_navigation"
|
37
|
+
end
|
38
|
+
(name+tail).to_sym
|
39
|
+
end
|
33
40
|
|
34
41
|
def ext_params(options)
|
35
42
|
url = options.delete(:url)
|
@@ -1,26 +1,28 @@
|
|
1
1
|
module CoalescingPanda
|
2
2
|
module ControllerHelpers
|
3
3
|
|
4
|
-
def canvas_oauth2
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
def canvas_oauth2(*roles)
|
5
|
+
if lti_authorize!(*roles)
|
6
|
+
user_id = params['user_id']
|
7
|
+
uri = URI.parse(params['launch_presentation_return_url'])
|
8
|
+
api_domain = uri.host
|
9
|
+
api_domain = "#{api_domain}:#{uri.port.to_s}" if uri.port
|
10
|
+
scheme = uri.scheme + '://'
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
12
|
+
if token = CanvasApiAuth.where('user_id = ? and api_domain = ?', user_id, api_domain).pluck(:api_token).first
|
13
|
+
@client = Bearcat::Client.new(token: token, prefix: scheme+api_domain)
|
14
|
+
elsif @lti_account = params['oauth_consumer_key'] && LtiAccount.find_by_key(params['oauth_consumer_key'])
|
15
|
+
client_id = @lti_account.oauth2_client_id
|
16
|
+
client = Bearcat::Client.new(prefix: scheme+api_domain)
|
17
|
+
@lti_params = params.to_hash
|
18
|
+
@canvas_url = client.auth_redirect_url(client_id,
|
19
|
+
coalescing_panda.oauth2_redirect_url({key: params['oauth_consumer_key'],
|
20
|
+
user_id: user_id, api_domain: api_domain}))
|
21
|
+
#delete the added params so the original oauth sig still works
|
22
|
+
@lti_params.delete('action')
|
23
|
+
@lti_params.delete('controller')
|
24
|
+
render 'coalescing_panda/oauth2/oauth2'
|
25
|
+
end
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
@@ -30,34 +32,43 @@ module CoalescingPanda
|
|
30
32
|
@tp = IMS::LTI::ToolProvider.new(@lti_account.key, @lti_account.secret, params)
|
31
33
|
authorized = @tp.valid_request?(request)
|
32
34
|
end
|
33
|
-
authorized = authorized && (roles == 0 || (roles & lti_roles).count > 0)
|
34
|
-
authorized = authorized && @lti_account.validate_nonce(params['oauth_nonce'], DateTime.strptime(params['oauth_timestamp'],'%s'))
|
35
|
+
authorized = authorized && (roles.count == 0 || (roles & lti_roles).count > 0)
|
36
|
+
authorized = authorized && @lti_account.validate_nonce(params['oauth_nonce'], DateTime.strptime(params['oauth_timestamp'], '%s'))
|
35
37
|
if !authorized
|
36
38
|
render :text => 'Invalid Credentials, please contact your Administrator.', :status => :unauthorized
|
37
39
|
end
|
40
|
+
authorized
|
41
|
+
end
|
42
|
+
|
43
|
+
def lti_editor_button_response(return_type, return_params)
|
44
|
+
valid_return_types = [:image_url, :iframe, :url]
|
45
|
+
raise "invalid editor button return type #{return_type}" unless valid_return_types.include?(return_type)
|
46
|
+
return_params[:return_type] = return_type.to_s
|
47
|
+
return_url = "#{params['launch_presentation_return_url']}?#{return_params.to_query}"
|
48
|
+
redirect_to return_url
|
38
49
|
end
|
39
50
|
|
40
51
|
def lti_roles
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
52
|
+
@lti_roles ||= params['roles'].split(',').map { |role|
|
53
|
+
case role.downcase.strip
|
54
|
+
when 'admin'
|
55
|
+
:admin
|
56
|
+
when 'urn:lti:instrole:ims/lis/administrator'
|
57
|
+
:admin
|
58
|
+
when 'learner'
|
59
|
+
:student
|
60
|
+
when 'instructor'
|
61
|
+
:teacher
|
62
|
+
when 'urn:lti:role:ims/lis/teachingassistant'
|
63
|
+
:ta
|
64
|
+
when 'contentdeveloper'
|
65
|
+
:designer
|
66
|
+
when 'urn:lti:instrole:ims/lis/observer'
|
67
|
+
:observer
|
68
|
+
else
|
69
|
+
:none
|
70
|
+
end
|
71
|
+
}.uniq
|
61
72
|
end
|
62
73
|
|
63
74
|
def canvas_environment
|
@@ -3,6 +3,14 @@ module CoalescingPanda
|
|
3
3
|
config.autoload_once_paths += Dir["#{config.root}/lib/**/"]
|
4
4
|
isolate_namespace CoalescingPanda
|
5
5
|
|
6
|
+
initializer :append_migrations do |app|
|
7
|
+
unless app.root.to_s.match root.to_s
|
8
|
+
config.paths["db/migrate"].expanded.each do |expanded_path|
|
9
|
+
app.config.paths["db/migrate"] << expanded_path
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
6
14
|
initializer 'coalescing_panda.app_controller' do |app|
|
7
15
|
OAUTH_10_SUPPORT = true
|
8
16
|
ActiveSupport.on_load(:action_controller) do
|
@@ -14,11 +22,13 @@ module CoalescingPanda
|
|
14
22
|
ActionDispatch::Routing::Mapper.send :include, CoalescingPanda::RouteHelpers
|
15
23
|
end
|
16
24
|
|
17
|
-
initializer 'coalescing_panda.route_options' do |app|
|
18
|
-
ActiveSupport.on_load(:
|
25
|
+
initializer 'coalescing_panda.route_options', :after => :disable_dependency_loading do |app|
|
26
|
+
ActiveSupport.on_load(:action_controller) do
|
27
|
+
#force the routes to load
|
28
|
+
Rails.application.reload_routes!
|
19
29
|
CoalescingPanda::propagate_lti_navigation
|
20
30
|
end
|
21
31
|
end
|
22
|
-
|
32
|
+
|
23
33
|
end
|
24
34
|
end
|
@@ -3,7 +3,7 @@ module CoalescingPanda
|
|
3
3
|
def lti_nav(nav, *rest, &block)
|
4
4
|
base_path = Rails.application.routes.named_routes[:coalescing_panda].path.spec
|
5
5
|
raise LtiNavigationInUse.new('CoalescingPanda must be mounted before defining lti_nav routes') if base_path.blank?
|
6
|
-
valid_options = [:course, :user, :account, :
|
6
|
+
valid_options = [:course, :user, :account, :editor_button, :external_tool]
|
7
7
|
if rest.empty? && nav.is_a?(Hash)
|
8
8
|
options = nav
|
9
9
|
nav, to = options.find {|name, _value| valid_options.include? name}
|
data/lib/coalescing_panda.rb
CHANGED
@@ -9,7 +9,7 @@ module CoalescingPanda
|
|
9
9
|
|
10
10
|
@@lti_navigation = {}
|
11
11
|
@@staged_navigation = {}
|
12
|
-
@@lti_options
|
12
|
+
@@lti_options = {}
|
13
13
|
|
14
14
|
def self.lti_options= lti_options
|
15
15
|
@@lti_options = lti_options
|
@@ -20,7 +20,7 @@ module CoalescingPanda
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.register_navigation(navigation)
|
23
|
-
@@lti_navigation[navigation]
|
23
|
+
@@lti_navigation[navigation] ||= {}
|
24
24
|
end
|
25
25
|
|
26
26
|
def self.stage_navigation(navigation, options)
|
@@ -16,11 +16,13 @@ describe CoalescingPanda::LtiController do
|
|
16
16
|
|
17
17
|
it 'generates lti nav config' do
|
18
18
|
controller.main_app.stub(:test_action_url) {'foo'}
|
19
|
-
CoalescingPanda.
|
19
|
+
CoalescingPanda.stage_navigation(:account, {
|
20
20
|
url: 'test_action',
|
21
21
|
text: 'My Title',
|
22
22
|
enabled: false
|
23
23
|
})
|
24
|
+
CoalescingPanda.register_navigation(:account)
|
25
|
+
CoalescingPanda.propagate_lti_navigation
|
24
26
|
get(:lti_config)
|
25
27
|
xml = Nokogiri::XML(response.body)
|
26
28
|
account_nav = xml.at_xpath('//lticm:options[@name="account_navigation"]')
|
@@ -0,0 +1 @@
|
|
1
|
+
CoalescingPanda.lti_options= {title:'LTI Tool'}
|
data/spec/dummy/config/routes.rb
CHANGED
data/spec/dummy/db/schema.rb
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
#
|
12
12
|
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(version:
|
14
|
+
ActiveRecord::Schema.define(version: 20131119165343) do
|
15
15
|
|
16
16
|
create_table "coalescing_panda_canvas_api_auths", force: true do |t|
|
17
17
|
t.string "user_id"
|
@@ -21,4 +21,20 @@ ActiveRecord::Schema.define(version: 20131114150001) do
|
|
21
21
|
t.datetime "updated_at"
|
22
22
|
end
|
23
23
|
|
24
|
+
create_table "coalescing_panda_lti_accounts", force: true do |t|
|
25
|
+
t.string "name"
|
26
|
+
t.string "key"
|
27
|
+
t.string "secret"
|
28
|
+
t.string "oauth2_client_id"
|
29
|
+
t.string "oauth2_client_key"
|
30
|
+
t.datetime "created_at"
|
31
|
+
t.datetime "updated_at"
|
32
|
+
end
|
33
|
+
|
34
|
+
create_table "coalescing_panda_lti_nonces", force: true do |t|
|
35
|
+
t.integer "coalescing_panda_lti_account_id"
|
36
|
+
t.string "nonce"
|
37
|
+
t.datetime "timestamp"
|
38
|
+
end
|
39
|
+
|
24
40
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coalescing_panda
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2014-01-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -34,7 +34,7 @@ dependencies:
|
|
34
34
|
requirements:
|
35
35
|
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: '0.
|
37
|
+
version: '0.6'
|
38
38
|
type: :runtime
|
39
39
|
prerelease: false
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -42,7 +42,7 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
version: '0.
|
45
|
+
version: '0.6'
|
46
46
|
- !ruby/object:Gem::Dependency
|
47
47
|
name: ims-lti
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -171,6 +171,22 @@ dependencies:
|
|
171
171
|
- - ! '>='
|
172
172
|
- !ruby/object:Gem::Version
|
173
173
|
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
name: debugger
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
type: :development
|
183
|
+
prerelease: false
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
174
190
|
description:
|
175
191
|
email:
|
176
192
|
- nathanm@instructure.com
|
@@ -224,6 +240,7 @@ files:
|
|
224
240
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
225
241
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
226
242
|
- spec/dummy/config/initializers/inflections.rb
|
243
|
+
- spec/dummy/config/initializers/lti_initializer.rb
|
227
244
|
- spec/dummy/config/initializers/mime_types.rb
|
228
245
|
- spec/dummy/config/initializers/secret_token.rb
|
229
246
|
- spec/dummy/config/initializers/session_store.rb
|
@@ -285,6 +302,7 @@ test_files:
|
|
285
302
|
- spec/dummy/config/initializers/backtrace_silencers.rb
|
286
303
|
- spec/dummy/config/initializers/filter_parameter_logging.rb
|
287
304
|
- spec/dummy/config/initializers/inflections.rb
|
305
|
+
- spec/dummy/config/initializers/lti_initializer.rb
|
288
306
|
- spec/dummy/config/initializers/mime_types.rb
|
289
307
|
- spec/dummy/config/initializers/secret_token.rb
|
290
308
|
- spec/dummy/config/initializers/session_store.rb
|