coalescing_panda 4.6.1 → 5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 8efea91014e88f07f7bd39860db6072161db84af
4
- data.tar.gz: 88cad27a86b4a93c67fdb4ff7302214d0dde080c
2
+ SHA256:
3
+ metadata.gz: d645cd8c2b844e464a37181c7810119004db0d11f74fb1293e97d7230412e8b3
4
+ data.tar.gz: e2741818208ab1301551d47c9063d20ee9bbb0a58e6db63b164cc068b0c2c76a
5
5
  SHA512:
6
- metadata.gz: 5af45f9fb9b3b3fa3765dd3236ce47eacf5b1cba2e5b4e38d3b6a63dd8e35c3d30d98f117c4511ffd16b291943fbe598a69618a461eb04c3c7fbca6cd7cae1c7
7
- data.tar.gz: 981e1e48035e68adb3680859f591f91e9ab759ff1c92198a370af467942e3a8f75d7ea57200e9f4cd42b9054aa9b14244e16438c054a080010b435a2af9f89e3
6
+ metadata.gz: 6430b3b457aa5776cd8590228794fcb77537824dbec08356ae9a512bf268e357e9a0f7e0db900ffa33d1f261964b393443719aa4a407b61970b26b19e7f65ce7
7
+ data.tar.gz: 3a4853c0b20ffc72041e5157f5a0813a8c5e30c27648b23193fc9d94652adaeda01ded2ef829e6e70617d6a02a7e89841cd5615474d0c866242fc435ba0d3eca
@@ -0,0 +1,38 @@
1
+ module CoalescingPanda
2
+ class PersistentSession < ActiveRecord::Base
3
+ serialize :data, Hash
4
+ belongs_to :coalescing_panda_lti_account, :class_name => 'CoalescingPanda::LtiAccount'
5
+ validates :coalescing_panda_lti_account_id, presence: true
6
+
7
+ after_initialize do
8
+ self.session_key ||= SecureRandom.urlsafe_base64(60)
9
+ end
10
+
11
+ def self.create_from_launch(launch_params, account_id)
12
+ session = PersistentSession.new(coalescing_panda_lti_account_id: account_id)
13
+ session.data[:launch_params] = launch_params.to_unsafe_h.with_indifferent_access
14
+ session.data[:roles] = launch_params['roles'].split(',').map { |role|
15
+ case role.downcase.strip
16
+ when 'admin'
17
+ :admin
18
+ when 'urn:lti:instrole:ims/lis/administrator'
19
+ :admin
20
+ when 'learner'
21
+ :student
22
+ when 'instructor'
23
+ :teacher
24
+ when 'urn:lti:role:ims/lis/teachingassistant'
25
+ :ta
26
+ when 'contentdeveloper'
27
+ :designer
28
+ when 'urn:lti:instrole:ims/lis/observer'
29
+ :observer
30
+ else
31
+ :none
32
+ end
33
+ }.uniq
34
+ session.save!
35
+ session
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,13 @@
1
+ class CreateCoalescingPandaPersistentSession < ActiveRecord::Migration
2
+ def change
3
+ create_table :coalescing_panda_persistent_sessions do |t|
4
+ t.string :session_key
5
+ t.text :data
6
+ t.integer :coalescing_panda_lti_account_id
7
+
8
+ t.timestamps null: false
9
+ end
10
+ add_index :coalescing_panda_persistent_sessions, :session_key, unique: true
11
+ add_index :coalescing_panda_persistent_sessions, :coalescing_panda_lti_account_id, name: 'index_persistent_session_on_lti_account_id'
12
+ end
13
+ end
@@ -2,6 +2,33 @@ require 'browser'
2
2
 
3
3
  module CoalescingPanda
4
4
  module ControllerHelpers
5
+ def current_session
6
+ @current_session ||= CoalescingPanda::PersistentSession.find_by(session_key: session_key) if session_key
7
+ @current_session ||= CoalescingPanda::PersistentSession.create_from_launch(params, current_lti_account.id)
8
+ @current_session
9
+ end
10
+
11
+ def current_lti_account
12
+ @account ||= CoalescingPanda::LtiAccount.find_by!(key: organization_key) if organization_key
13
+ @account ||= CoalescingPanda::LtiAccount.find_by(id: organization_id) if organization_id
14
+ @account
15
+ end
16
+
17
+ def current_session_data
18
+ current_session.data
19
+ end
20
+
21
+ def encrypted_session_key
22
+ msg_encryptor.encrypt_and_sign(current_session.session_key)
23
+ end
24
+
25
+ def save_session
26
+ current_session.try(:save)
27
+ end
28
+
29
+ def session_changed?
30
+ current_session.changed? && current_session.changes[:data].present?
31
+ end
5
32
 
6
33
  def canvas_oauth2(*roles)
7
34
  return if have_session?
@@ -100,18 +127,19 @@ module CoalescingPanda
100
127
 
101
128
  def lti_authorize!(*roles)
102
129
  authorized = false
103
- if @lti_account = params['oauth_consumer_key'] && LtiAccount.find_by_key(params['oauth_consumer_key'])
130
+ if (@lti_account = params['oauth_consumer_key'] && LtiAccount.find_by_key(params['oauth_consumer_key']))
104
131
  sanitized_params = sanitize_params
105
132
  authenticator = IMS::LTI::Services::MessageAuthenticator.new(request.original_url, sanitized_params, @lti_account.secret)
106
133
  authorized = authenticator.valid_signature?
107
134
  end
108
- logger.info 'not authorized on tp valid request' if !authorized
135
+ logger.info 'not authorized on tp valid request' unless authorized
109
136
  authorized = authorized && (roles.count == 0 || (roles & lti_roles).count > 0)
110
- logger.info 'not authorized on roles' if !authorized
137
+ logger.info 'not authorized on roles' unless authorized
111
138
  authorized = authorized && @lti_account.validate_nonce(params['oauth_nonce'], DateTime.strptime(params['oauth_timestamp'], '%s'))
112
- logger.info 'not authorized on nonce' if !authorized
139
+ logger.info 'not authorized on nonce' unless authorized
113
140
  render :text => 'Invalid Credentials, please contact your Administrator.', :status => :unauthorized unless authorized
114
- authorized = authorized && check_for_iframes_problem if authorized
141
+ # create session on first launch
142
+ current_session
115
143
  authorized
116
144
  end
117
145
 
@@ -136,26 +164,7 @@ module CoalescingPanda
136
164
  end
137
165
 
138
166
  def lti_roles
139
- @lti_roles ||= params['roles'].split(',').map { |role|
140
- case role.downcase.strip
141
- when 'admin'
142
- :admin
143
- when 'urn:lti:instrole:ims/lis/administrator'
144
- :admin
145
- when 'learner'
146
- :student
147
- when 'instructor'
148
- :teacher
149
- when 'urn:lti:role:ims/lis/teachingassistant'
150
- :ta
151
- when 'contentdeveloper'
152
- :designer
153
- when 'urn:lti:instrole:ims/lis/observer'
154
- :observer
155
- else
156
- :none
157
- end
158
- }.uniq
167
+ @lti_roles ||= current_session_data[:roles]
159
168
  end
160
169
 
161
170
  def canvas_environment
@@ -168,38 +177,68 @@ module CoalescingPanda
168
177
  end
169
178
 
170
179
  def session_check
171
- logger.warn 'session_check is deprecated. Functionality moved to canvas_oauth2.'
180
+ logger.warn 'session_check is deprecated. Functionality moved to lti_authorize.'
172
181
  end
173
182
 
174
- def check_for_iframes_problem
175
- if cookies_need_iframe_fix?
176
- fix_iframe_cookies
177
- return false
178
- end
183
+ private
184
+
185
+ def msg_encryptor
186
+ @crypt ||= ActiveSupport::MessageEncryptor.new(Rails.application.secrets.secret_key_base[0..31])
187
+ end
188
+
189
+ def organization_key
190
+ params[:oauth_consumer_key] || (current_session_data[:launch_params][:oauth_consumer_key] if @current_session)
191
+ end
192
+
193
+ def organization_id
194
+ params[:organization_id] || (current_session_data[:launch_params][:organization_id] if @current_session)
195
+ end
179
196
 
180
- # For safari we may have been launched temporarily full-screen by canvas. This allows us to set the session cookie.
181
- # In this case, we should make sure the session cookie is fixed and redirect back to canvas to properly launch the embedded LTI.
182
- if params[:platform_redirect_url]
183
- session[:safari_cookie_fixed] = true
184
- redirect_to params[:platform_redirect_url]
185
- return false
197
+ def session_key
198
+ if params[:encrypted_session_key]
199
+ return msg_encryptor.decrypt_and_verify(params[:encrypted_session_key])
186
200
  end
187
- true
201
+ params[:session_key] || session_key_header
188
202
  end
189
203
 
190
- def cookies_need_iframe_fix?
191
- @browser ||= Browser.new(request.user_agent)
192
- @browser.safari? && !request.referrer&.include?('sessionless_launch') && !session[:safari_cookie_fixed] && !params[:platform_redirect_url]
204
+ def session_key_header
205
+ if (match = request.headers['Authorization'].try(:match, /crypted_token=(.+)/))
206
+ msg_encryptor.decrypt_and_verify(match[1])
207
+ elsif (match = request.headers['Authorization'].try(:match, /token=(.+)/))
208
+ match[1]
209
+ end
193
210
  end
194
211
 
195
- def fix_iframe_cookies
196
- if params[:safari_cookie_fix].present?
197
- session[:safari_cookie_fixed] = true
198
- redirect_to params[:return_to]
212
+ # Redirect with the session key intact. In production,
213
+ # handle this by encrypting the session key. That way if the
214
+ # url is logged anywhere, it will all be encrypted data. In dev,
215
+ # just put it in the URL. Putting it in the URL
216
+ # is insecure, but is fine in development.
217
+ # Keeping it in the URL in development means that it plays
218
+ # nicely with webpack-dev-server live reloading (otherwise
219
+ # you get an access error every time it tries to live reload).
220
+
221
+ def redirect_with_session_to(path, id_or_resource = nil, redirect_params = {})
222
+ if Rails.env.development? || Rails.env.test?
223
+ redirect_development_mode(path, id_or_resource, redirect_params)
199
224
  else
200
- render 'coalescing_panda/lti/iframe_cookie_fix', layout: false
225
+ redirect_production_mode(path, id_or_resource, redirect_params)
201
226
  end
202
227
  end
203
228
 
229
+ def redirect_development_mode(path, id_or_resource = nil, redirect_params)
230
+ redirect_to send(path, id_or_resource, {
231
+ session_key: current_session.session_key,
232
+ organization_id: current_lti_account.id
233
+ }.merge(redirect_params))
234
+ end
235
+
236
+ def redirect_production_mode(path, id_or_resource = nil, redirect_params)
237
+ redirect_to send(path, id_or_resource, {
238
+ encrypted_session_key: encrypted_session_key,
239
+ organization_id: current_lti_account.id
240
+ }.merge(redirect_params))
241
+ end
242
+
204
243
  end
205
244
  end
@@ -1,3 +1,5 @@
1
+ require 'secure_headers'
2
+
1
3
  module CoalescingPanda
2
4
  class Engine < ::Rails::Engine
3
5
  config.autoload_once_paths += Dir["#{config.root}/lib/**/"]
@@ -35,5 +37,53 @@ module CoalescingPanda
35
37
  end
36
38
  end
37
39
 
40
+ initializer :secure_headers do |app|
41
+ connect_src = %w('self')
42
+ script_src = %w('self')
43
+
44
+ if Rails.env.development?
45
+ # Allow webpack-dev-server to work
46
+ connect_src << "http://localhost:3035"
47
+ connect_src << "ws://localhost:3035"
48
+
49
+ # Allow stuff like rack-mini-profiler to work in development:
50
+ # https://github.com/MiniProfiler/rack-mini-profiler/issues/327
51
+ # DON'T ENABLE THIS FOR PRODUCTION!
52
+ script_src << "'unsafe-eval'"
53
+ elsif CoalescingPanda.lti_options.has_key?(:allow_unsafe_eval) && CoalescingPanda.lti_options[:allow_unsafe_eval] == true
54
+ # For when code is returned from server and injected into dom. Need to have unsafe-eval or it won't work.
55
+ script_src << "'unsafe-eval'"
56
+ end
57
+
58
+ SecureHeaders::Configuration.default do |config|
59
+ # The default cookie headers aren't compatible with PandaPal cookies currently
60
+ config.cookies = { samesite: { none: true } }
61
+
62
+ if Rails.env.production?
63
+ config.cookies[:secure] = true
64
+ end
65
+
66
+ # Need to allow LTI iframes
67
+ config.x_frame_options = "ALLOWALL"
68
+
69
+ config.x_content_type_options = "nosniff"
70
+ config.x_xss_protection = "1; mode=block"
71
+ config.referrer_policy = %w(origin-when-cross-origin strict-origin-when-cross-origin)
72
+
73
+ config.csp = {
74
+ default_src: %w('self'),
75
+ script_src: script_src,
76
+ # Certain CSS-in-JS libraries inline the CSS, so we need to use unsafe-inline for them
77
+ style_src: %w('self' 'unsafe-inline' blob: https://fonts.googleapis.com),
78
+ font_src: %w('self' data: https://fonts.gstatic.com),
79
+ connect_src: connect_src,
80
+ }
81
+ end
82
+
83
+ SecureHeaders::Configuration.override(:safari_override) do |config|
84
+ config.cookies = SecureHeaders::OPT_OUT
85
+ end
86
+ end
87
+
38
88
  end
39
89
  end
@@ -1,3 +1,3 @@
1
1
  module CoalescingPanda
2
- VERSION = '4.6.1'
2
+ VERSION = '5.0.0'
3
3
  end
@@ -173,6 +173,17 @@ ActiveRecord::Schema.define(version: 20160830183155) do
173
173
 
174
174
  add_index "coalescing_panda_oauth_states", ["state_key"], name: "index_coalescing_panda_oauth_states_on_state_key", unique: true
175
175
 
176
+ create_table "coalescing_panda_persistent_sessions", force: :cascade do |t|
177
+ t.string "session_key"
178
+ t.text "data"
179
+ t.integer "coalescing_panda_lti_account_id"
180
+ t.datetime "created_at", null: false
181
+ t.datetime "updated_at", null: false
182
+ end
183
+
184
+ add_index "coalescing_panda_persistent_sessions", ["coalescing_panda_lti_account_id"], name: "index_persistent_session_on_lti_account_id", using: :btree
185
+ add_index "coalescing_panda_persistent_sessions", ["session_key"], name: "index_coalescing_panda_persistent_sessions_on_session_key", unique: true, using: :btree
186
+
176
187
  create_table "coalescing_panda_sections", force: :cascade do |t|
177
188
  t.integer "coalescing_panda_course_id", null: false
178
189
  t.string "name"
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: 4.6.1
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Mills
@@ -10,48 +10,48 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-02-19 00:00:00.000000000 Z
13
+ date: 2020-06-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - ~>
19
+ - - "~>"
20
20
  - !ruby/object:Gem::Version
21
21
  version: 4.2.1
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - ~>
26
+ - - "~>"
27
27
  - !ruby/object:Gem::Version
28
28
  version: 4.2.1
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: bearcat
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - ~>
33
+ - - "~>"
34
34
  - !ruby/object:Gem::Version
35
35
  version: 1.3.0
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - ~>
40
+ - - "~>"
41
41
  - !ruby/object:Gem::Version
42
42
  version: 1.3.0
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: browser
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
- - - '>='
47
+ - - ">="
48
48
  - !ruby/object:Gem::Version
49
49
  version: '0'
50
50
  type: :runtime
51
51
  prerelease: false
52
52
  version_requirements: !ruby/object:Gem::Requirement
53
53
  requirements:
54
- - - '>='
54
+ - - ">="
55
55
  - !ruby/object:Gem::Version
56
56
  version: '0'
57
57
  - !ruby/object:Gem::Dependency
@@ -72,308 +72,322 @@ dependencies:
72
72
  name: ims-lti
73
73
  requirement: !ruby/object:Gem::Requirement
74
74
  requirements:
75
- - - '>='
75
+ - - ">="
76
76
  - !ruby/object:Gem::Version
77
77
  version: 2.1.0
78
78
  type: :runtime
79
79
  prerelease: false
80
80
  version_requirements: !ruby/object:Gem::Requirement
81
81
  requirements:
82
- - - '>='
82
+ - - ">="
83
83
  - !ruby/object:Gem::Version
84
84
  version: 2.1.0
85
85
  - !ruby/object:Gem::Dependency
86
86
  name: haml-rails
87
87
  requirement: !ruby/object:Gem::Requirement
88
88
  requirements:
89
- - - '>='
89
+ - - ">="
90
90
  - !ruby/object:Gem::Version
91
91
  version: '0'
92
92
  type: :runtime
93
93
  prerelease: false
94
94
  version_requirements: !ruby/object:Gem::Requirement
95
95
  requirements:
96
- - - '>='
96
+ - - ">="
97
97
  - !ruby/object:Gem::Version
98
98
  version: '0'
99
99
  - !ruby/object:Gem::Dependency
100
100
  name: sass-rails
101
101
  requirement: !ruby/object:Gem::Requirement
102
102
  requirements:
103
- - - '>='
103
+ - - ">="
104
104
  - !ruby/object:Gem::Version
105
105
  version: '3.2'
106
106
  type: :runtime
107
107
  prerelease: false
108
108
  version_requirements: !ruby/object:Gem::Requirement
109
109
  requirements:
110
- - - '>='
110
+ - - ">="
111
111
  - !ruby/object:Gem::Version
112
112
  version: '3.2'
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: jquery-rails
115
115
  requirement: !ruby/object:Gem::Requirement
116
116
  requirements:
117
- - - '>='
117
+ - - ">="
118
118
  - !ruby/object:Gem::Version
119
119
  version: '0'
120
120
  type: :runtime
121
121
  prerelease: false
122
122
  version_requirements: !ruby/object:Gem::Requirement
123
123
  requirements:
124
- - - '>='
124
+ - - ">="
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  - !ruby/object:Gem::Dependency
128
128
  name: coffee-rails
129
129
  requirement: !ruby/object:Gem::Requirement
130
130
  requirements:
131
- - - '>='
131
+ - - ">="
132
132
  - !ruby/object:Gem::Version
133
133
  version: '0'
134
134
  type: :runtime
135
135
  prerelease: false
136
136
  version_requirements: !ruby/object:Gem::Requirement
137
137
  requirements:
138
- - - '>='
138
+ - - ">="
139
139
  - !ruby/object:Gem::Version
140
140
  version: '0'
141
141
  - !ruby/object:Gem::Dependency
142
142
  name: p3p
143
143
  requirement: !ruby/object:Gem::Requirement
144
144
  requirements:
145
- - - '>='
145
+ - - ">="
146
146
  - !ruby/object:Gem::Version
147
147
  version: '0'
148
148
  type: :runtime
149
149
  prerelease: false
150
150
  version_requirements: !ruby/object:Gem::Requirement
151
151
  requirements:
152
- - - '>='
152
+ - - ">="
153
153
  - !ruby/object:Gem::Version
154
154
  version: '0'
155
155
  - !ruby/object:Gem::Dependency
156
156
  name: delayed_job_active_record
157
157
  requirement: !ruby/object:Gem::Requirement
158
158
  requirements:
159
- - - '>='
159
+ - - ">="
160
160
  - !ruby/object:Gem::Version
161
161
  version: '0'
162
162
  type: :runtime
163
163
  prerelease: false
164
164
  version_requirements: !ruby/object:Gem::Requirement
165
165
  requirements:
166
- - - '>='
166
+ - - ">="
167
167
  - !ruby/object:Gem::Version
168
168
  version: '0'
169
169
  - !ruby/object:Gem::Dependency
170
170
  name: open_uri_redirections
171
171
  requirement: !ruby/object:Gem::Requirement
172
172
  requirements:
173
- - - '>='
173
+ - - ">="
174
174
  - !ruby/object:Gem::Version
175
175
  version: '0'
176
176
  type: :runtime
177
177
  prerelease: false
178
178
  version_requirements: !ruby/object:Gem::Requirement
179
179
  requirements:
180
- - - '>='
180
+ - - ">="
181
181
  - !ruby/object:Gem::Version
182
182
  version: '0'
183
183
  - !ruby/object:Gem::Dependency
184
184
  name: oauth
185
185
  requirement: !ruby/object:Gem::Requirement
186
186
  requirements:
187
- - - ~>
187
+ - - "~>"
188
188
  - !ruby/object:Gem::Version
189
189
  version: 0.5.4
190
190
  type: :runtime
191
191
  prerelease: false
192
192
  version_requirements: !ruby/object:Gem::Requirement
193
193
  requirements:
194
- - - ~>
194
+ - - "~>"
195
195
  - !ruby/object:Gem::Version
196
196
  version: 0.5.4
197
197
  - !ruby/object:Gem::Dependency
198
198
  name: rubyzip
199
199
  requirement: !ruby/object:Gem::Requirement
200
200
  requirements:
201
- - - '>='
201
+ - - ">="
202
202
  - !ruby/object:Gem::Version
203
203
  version: 1.0.0
204
204
  type: :runtime
205
205
  prerelease: false
206
206
  version_requirements: !ruby/object:Gem::Requirement
207
207
  requirements:
208
- - - '>='
208
+ - - ">="
209
209
  - !ruby/object:Gem::Version
210
210
  version: 1.0.0
211
+ - !ruby/object:Gem::Dependency
212
+ name: secure_headers
213
+ requirement: !ruby/object:Gem::Requirement
214
+ requirements:
215
+ - - "~>"
216
+ - !ruby/object:Gem::Version
217
+ version: '6.3'
218
+ type: :runtime
219
+ prerelease: false
220
+ version_requirements: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - "~>"
223
+ - !ruby/object:Gem::Version
224
+ version: '6.3'
211
225
  - !ruby/object:Gem::Dependency
212
226
  name: zip-zip
213
227
  requirement: !ruby/object:Gem::Requirement
214
228
  requirements:
215
- - - '>='
229
+ - - ">="
216
230
  - !ruby/object:Gem::Version
217
231
  version: '0'
218
232
  type: :runtime
219
233
  prerelease: false
220
234
  version_requirements: !ruby/object:Gem::Requirement
221
235
  requirements:
222
- - - '>='
236
+ - - ">="
223
237
  - !ruby/object:Gem::Version
224
238
  version: '0'
225
239
  - !ruby/object:Gem::Dependency
226
240
  name: sqlite3
227
241
  requirement: !ruby/object:Gem::Requirement
228
242
  requirements:
229
- - - '>='
243
+ - - ">="
230
244
  - !ruby/object:Gem::Version
231
245
  version: '0'
232
246
  type: :development
233
247
  prerelease: false
234
248
  version_requirements: !ruby/object:Gem::Requirement
235
249
  requirements:
236
- - - '>='
250
+ - - ">="
237
251
  - !ruby/object:Gem::Version
238
252
  version: '0'
239
253
  - !ruby/object:Gem::Dependency
240
254
  name: rspec-rails
241
255
  requirement: !ruby/object:Gem::Requirement
242
256
  requirements:
243
- - - '>='
257
+ - - ">="
244
258
  - !ruby/object:Gem::Version
245
259
  version: '0'
246
260
  type: :development
247
261
  prerelease: false
248
262
  version_requirements: !ruby/object:Gem::Requirement
249
263
  requirements:
250
- - - '>='
264
+ - - ">="
251
265
  - !ruby/object:Gem::Version
252
266
  version: '0'
253
267
  - !ruby/object:Gem::Dependency
254
268
  name: factory_girl_rails
255
269
  requirement: !ruby/object:Gem::Requirement
256
270
  requirements:
257
- - - '>='
271
+ - - ">="
258
272
  - !ruby/object:Gem::Version
259
273
  version: '0'
260
274
  type: :development
261
275
  prerelease: false
262
276
  version_requirements: !ruby/object:Gem::Requirement
263
277
  requirements:
264
- - - '>='
278
+ - - ">="
265
279
  - !ruby/object:Gem::Version
266
280
  version: '0'
267
281
  - !ruby/object:Gem::Dependency
268
282
  name: shoulda-matchers
269
283
  requirement: !ruby/object:Gem::Requirement
270
284
  requirements:
271
- - - '>='
285
+ - - ">="
272
286
  - !ruby/object:Gem::Version
273
287
  version: '0'
274
288
  type: :development
275
289
  prerelease: false
276
290
  version_requirements: !ruby/object:Gem::Requirement
277
291
  requirements:
278
- - - '>='
292
+ - - ">="
279
293
  - !ruby/object:Gem::Version
280
294
  version: '0'
281
295
  - !ruby/object:Gem::Dependency
282
296
  name: nokogiri
283
297
  requirement: !ruby/object:Gem::Requirement
284
298
  requirements:
285
- - - '>='
299
+ - - ">="
286
300
  - !ruby/object:Gem::Version
287
301
  version: '0'
288
302
  type: :development
289
303
  prerelease: false
290
304
  version_requirements: !ruby/object:Gem::Requirement
291
305
  requirements:
292
- - - '>='
306
+ - - ">="
293
307
  - !ruby/object:Gem::Version
294
308
  version: '0'
295
309
  - !ruby/object:Gem::Dependency
296
310
  name: simplecov
297
311
  requirement: !ruby/object:Gem::Requirement
298
312
  requirements:
299
- - - '>='
313
+ - - ">="
300
314
  - !ruby/object:Gem::Version
301
315
  version: '0'
302
316
  type: :development
303
317
  prerelease: false
304
318
  version_requirements: !ruby/object:Gem::Requirement
305
319
  requirements:
306
- - - '>='
320
+ - - ">="
307
321
  - !ruby/object:Gem::Version
308
322
  version: '0'
309
323
  - !ruby/object:Gem::Dependency
310
324
  name: byebug
311
325
  requirement: !ruby/object:Gem::Requirement
312
326
  requirements:
313
- - - '>='
327
+ - - ">="
314
328
  - !ruby/object:Gem::Version
315
329
  version: '0'
316
330
  type: :development
317
331
  prerelease: false
318
332
  version_requirements: !ruby/object:Gem::Requirement
319
333
  requirements:
320
- - - '>='
334
+ - - ">="
321
335
  - !ruby/object:Gem::Version
322
336
  version: '0'
323
337
  - !ruby/object:Gem::Dependency
324
338
  name: pry
325
339
  requirement: !ruby/object:Gem::Requirement
326
340
  requirements:
327
- - - '>='
341
+ - - ">="
328
342
  - !ruby/object:Gem::Version
329
343
  version: '0'
330
344
  type: :development
331
345
  prerelease: false
332
346
  version_requirements: !ruby/object:Gem::Requirement
333
347
  requirements:
334
- - - '>='
348
+ - - ">="
335
349
  - !ruby/object:Gem::Version
336
350
  version: '0'
337
351
  - !ruby/object:Gem::Dependency
338
352
  name: webmock
339
353
  requirement: !ruby/object:Gem::Requirement
340
354
  requirements:
341
- - - '>='
355
+ - - ">="
342
356
  - !ruby/object:Gem::Version
343
357
  version: '0'
344
358
  type: :development
345
359
  prerelease: false
346
360
  version_requirements: !ruby/object:Gem::Requirement
347
361
  requirements:
348
- - - '>='
362
+ - - ">="
349
363
  - !ruby/object:Gem::Version
350
364
  version: '0'
351
365
  - !ruby/object:Gem::Dependency
352
366
  name: lol_dba
353
367
  requirement: !ruby/object:Gem::Requirement
354
368
  requirements:
355
- - - '>='
369
+ - - ">="
356
370
  - !ruby/object:Gem::Version
357
371
  version: '0'
358
372
  type: :development
359
373
  prerelease: false
360
374
  version_requirements: !ruby/object:Gem::Requirement
361
375
  requirements:
362
- - - '>='
376
+ - - ">="
363
377
  - !ruby/object:Gem::Version
364
378
  version: '0'
365
379
  - !ruby/object:Gem::Dependency
366
380
  name: database_cleaner
367
381
  requirement: !ruby/object:Gem::Requirement
368
382
  requirements:
369
- - - '>='
383
+ - - ">="
370
384
  - !ruby/object:Gem::Version
371
385
  version: '0'
372
386
  type: :development
373
387
  prerelease: false
374
388
  version_requirements: !ruby/object:Gem::Requirement
375
389
  requirements:
376
- - - '>='
390
+ - - ">="
377
391
  - !ruby/object:Gem::Version
378
392
  version: '0'
379
393
  description:
@@ -385,154 +399,156 @@ executables: []
385
399
  extensions: []
386
400
  extra_rdoc_files: []
387
401
  files:
402
+ - Rakefile
403
+ - app/assets/images/bootstrap/glyphicons-halflings-white.png
404
+ - app/assets/images/bootstrap/glyphicons-halflings.png
405
+ - app/assets/javascripts/coalescing_panda/application.js
406
+ - app/assets/javascripts/coalescing_panda/canvas_batch.js.coffee
407
+ - app/assets/javascripts/coalescing_panda/oauth2.js.coffee
408
+ - app/assets/stylesheets/coalescing_panda/application.css.scss
409
+ - app/assets/stylesheets/coalescing_panda/launch.css.scss
410
+ - app/assets/stylesheets/coalescing_panda/progress.css.scss
411
+ - app/controllers/coalescing_panda/application_controller.rb
412
+ - app/controllers/coalescing_panda/canvas_batches_controller.rb
413
+ - app/controllers/coalescing_panda/lti_controller.rb
414
+ - app/controllers/coalescing_panda/oauth2_controller.rb
415
+ - app/helpers/coalescing_panda/canvas_batches_helper.rb
416
+ - app/models/coalescing_panda/assignment.rb
388
417
  - app/models/coalescing_panda/assignment_group.rb
389
- - app/models/coalescing_panda/group_membership.rb
390
- - app/models/coalescing_panda/enrollment.rb
418
+ - app/models/coalescing_panda/canvas_api_auth.rb
391
419
  - app/models/coalescing_panda/canvas_batch.rb
392
- - app/models/coalescing_panda/assignment.rb
420
+ - app/models/coalescing_panda/course.rb
421
+ - app/models/coalescing_panda/enrollment.rb
393
422
  - app/models/coalescing_panda/group.rb
394
- - app/models/coalescing_panda/session.rb
395
- - app/models/coalescing_panda/section.rb
396
- - app/models/coalescing_panda/term.rb
423
+ - app/models/coalescing_panda/group_category.rb
424
+ - app/models/coalescing_panda/group_membership.rb
425
+ - app/models/coalescing_panda/lti_account.rb
426
+ - app/models/coalescing_panda/lti_nonce.rb
397
427
  - app/models/coalescing_panda/oauth_state.rb
428
+ - app/models/coalescing_panda/persistent_session.rb
429
+ - app/models/coalescing_panda/section.rb
430
+ - app/models/coalescing_panda/session.rb
398
431
  - app/models/coalescing_panda/submission.rb
399
- - app/models/coalescing_panda/canvas_api_auth.rb
432
+ - app/models/coalescing_panda/term.rb
433
+ - app/models/coalescing_panda/user.rb
400
434
  - app/models/coalescing_panda/workers/account_miner.rb
401
- - app/models/coalescing_panda/workers/provisioning_miner.rb
402
435
  - app/models/coalescing_panda/workers/course_miner.rb
403
- - app/models/coalescing_panda/lti_nonce.rb
404
- - app/models/coalescing_panda/course.rb
405
- - app/models/coalescing_panda/lti_account.rb
406
- - app/models/coalescing_panda/user.rb
407
- - app/models/coalescing_panda/group_category.rb
436
+ - app/models/coalescing_panda/workers/provisioning_miner.rb
408
437
  - app/models/concerns/single_table_polymorphic.rb
409
- - app/controllers/coalescing_panda/oauth2_controller.rb
410
- - app/controllers/coalescing_panda/application_controller.rb
411
- - app/controllers/coalescing_panda/lti_controller.rb
412
- - app/controllers/coalescing_panda/canvas_batches_controller.rb
438
+ - app/views/coalescing_panda/canvas_batches/_canvas_batch.html.haml
439
+ - app/views/coalescing_panda/canvas_batches/_canvas_batch_flash.html.haml
440
+ - app/views/coalescing_panda/launch.html.haml
441
+ - app/views/coalescing_panda/lti/iframe_cookie_fix.html.erb
413
442
  - app/views/coalescing_panda/oauth2/oauth2.html.haml
414
443
  - app/views/coalescing_panda/oauth2/redirect.html.haml
415
- - app/views/coalescing_panda/launch.html.haml
416
444
  - app/views/coalescing_panda/styleguide/styleguide.html
417
- - app/views/coalescing_panda/lti/iframe_cookie_fix.html.erb
418
- - app/views/coalescing_panda/canvas_batches/_canvas_batch.html.haml
419
- - app/views/coalescing_panda/canvas_batches/_canvas_batch_flash.html.haml
420
445
  - app/views/layouts/coalescing_panda/application.html.erb
421
- - app/assets/images/bootstrap/glyphicons-halflings.png
422
- - app/assets/images/bootstrap/glyphicons-halflings-white.png
423
- - app/assets/javascripts/coalescing_panda/oauth2.js.coffee
424
- - app/assets/javascripts/coalescing_panda/application.js
425
- - app/assets/javascripts/coalescing_panda/canvas_batch.js.coffee
426
- - app/assets/stylesheets/coalescing_panda/progress.css.scss
427
- - app/assets/stylesheets/coalescing_panda/application.css.scss
428
- - app/assets/stylesheets/coalescing_panda/launch.css.scss
429
- - app/helpers/coalescing_panda/canvas_batches_helper.rb
430
446
  - config/routes.rb
431
447
  - config/styleguide.yml
432
- - db/migrate/20141120151432_create_coalescing_panda_sections.rb
433
- - db/migrate/20150602205257_add_option_to_canvas_batches.rb
434
- - db/migrate/20150811140030_add_fields_to_users.rb
448
+ - db/migrate/20131114150001_create_coalescing_panda_canvas_api_auths.rb
435
449
  - db/migrate/20131118211442_create_coalescing_panda_lti_accounts.rb
436
- - db/migrate/20150506192717_add_assignment_group_id_to_assignments.rb
437
- - db/migrate/20160830183155_create_coalescing_panda_oauth_states.rb
450
+ - db/migrate/20131119165343_create_coalescing_panda_lti_nonces.rb
451
+ - db/migrate/20140904223159_create_coalescing_panda_sessions.rb
452
+ - db/migrate/20141119225319_create_coalescing_panda_terms.rb
453
+ - db/migrate/20141119225721_create_coalescing_panda_courses.rb
454
+ - db/migrate/20141120151432_create_coalescing_panda_sections.rb
455
+ - db/migrate/20141120151940_create_coalescing_panda_assignments.rb
456
+ - db/migrate/20141120152458_create_coalescing_panda_users.rb
438
457
  - db/migrate/20141120152546_create_coalescing_panda_submissions.rb
458
+ - db/migrate/20141120153135_create_coalescing_panda_enrollments.rb
459
+ - db/migrate/20141121174846_create_coalescing_panda_canvas_batches.rb
460
+ - db/migrate/20141124160857_create_delayed_jobs.rb
439
461
  - db/migrate/20141208221740_add_submission_types_to_assignments.rb
440
- - db/migrate/20150709192717_add_leader_id_to_groups.rb
462
+ - db/migrate/20150106175418_add_group_category_id_to_assignment.rb
463
+ - db/migrate/20150106180131_add_published_to_assignments.rb
464
+ - db/migrate/20150107205405_create_coalescing_panda_groups.rb
441
465
  - db/migrate/20150107205413_create_coalescing_panda_group_memberships.rb
442
- - db/migrate/20141120152458_create_coalescing_panda_users.rb
443
- - db/migrate/20141121174846_create_coalescing_panda_canvas_batches.rb
444
- - db/migrate/20150708192717_add_group_moderator_to_group_memberships.rb
445
466
  - db/migrate/20150210180516_add_context_to_canvas_batch.rb
446
- - db/migrate/20141120151940_create_coalescing_panda_assignments.rb
447
- - db/migrate/20140904223159_create_coalescing_panda_sessions.rb
448
467
  - db/migrate/20150506183335_create_coalescing_panda_assignment_groups.rb
449
- - db/migrate/20141120153135_create_coalescing_panda_enrollments.rb
450
- - db/migrate/20150107205405_create_coalescing_panda_groups.rb
451
- - db/migrate/20141119225721_create_coalescing_panda_courses.rb
452
- - db/migrate/20141124160857_create_delayed_jobs.rb
453
- - db/migrate/20131119165343_create_coalescing_panda_lti_nonces.rb
454
- - db/migrate/20150106180131_add_published_to_assignments.rb
468
+ - db/migrate/20150506192717_add_assignment_group_id_to_assignments.rb
455
469
  - db/migrate/20150526144713_add_account_to_canvas_batches.rb
456
- - db/migrate/20150106175418_add_group_category_id_to_assignment.rb
470
+ - db/migrate/20150602205257_add_option_to_canvas_batches.rb
471
+ - db/migrate/20150708192717_add_group_moderator_to_group_memberships.rb
472
+ - db/migrate/20150709192717_add_leader_id_to_groups.rb
457
473
  - db/migrate/20150714205405_create_coalescing_panda_group_categories.rb
474
+ - db/migrate/20150811140030_add_fields_to_users.rb
458
475
  - db/migrate/20151209155923_add_refresh_settings_to_canvas_api_auth.rb
459
- - db/migrate/20131114150001_create_coalescing_panda_canvas_api_auths.rb
460
- - db/migrate/20141119225319_create_coalescing_panda_terms.rb
461
- - lib/tasks/coalescing_panda_tasks.rake
476
+ - db/migrate/20160830183155_create_coalescing_panda_oauth_states.rb
477
+ - db/migrate/20200528224505_create_coalescing_panda_persistent_session.rb
462
478
  - lib/coalescing_panda.rb
463
- - lib/coalescing_panda/controller_helpers.rb
464
479
  - lib/coalescing_panda/bearcat_uri.rb
480
+ - lib/coalescing_panda/controller_helpers.rb
465
481
  - lib/coalescing_panda/engine.rb
466
- - lib/coalescing_panda/version.rb
467
482
  - lib/coalescing_panda/route_helpers.rb
468
- - Rakefile
469
- - spec/spec_helper.rb
470
- - spec/dummy/app/models/account.rb
471
- - spec/dummy/app/models/course.rb
472
- - spec/dummy/app/controllers/application_controller.rb
473
- - spec/dummy/app/views/layouts/application.html.erb
483
+ - lib/coalescing_panda/version.rb
484
+ - lib/tasks/coalescing_panda_tasks.rake
485
+ - spec/controllers/coalescing_panda/canvas_batches_controller_spec.rb
486
+ - spec/controllers/coalescing_panda/lti_controller_spec.rb
487
+ - spec/controllers/coalescing_panda/oauth2_controller_spec.rb
488
+ - spec/dummy/README.rdoc
489
+ - spec/dummy/Rakefile
474
490
  - spec/dummy/app/assets/javascripts/application.js
475
491
  - spec/dummy/app/assets/stylesheets/application.css
492
+ - spec/dummy/app/controllers/application_controller.rb
476
493
  - spec/dummy/app/helpers/application_helper.rb
477
- - spec/dummy/bin/rake
494
+ - spec/dummy/app/models/account.rb
495
+ - spec/dummy/app/models/course.rb
496
+ - spec/dummy/app/views/layouts/application.html.erb
478
497
  - spec/dummy/bin/bundle
479
498
  - spec/dummy/bin/rails
480
- - spec/dummy/config/routes.rb
481
- - spec/dummy/config/locales/en.yml
482
- - spec/dummy/config/environments/production.rb
483
- - spec/dummy/config/environments/development.rb
484
- - spec/dummy/config/environments/test.rb
485
- - spec/dummy/config/environment.rb
499
+ - spec/dummy/bin/rake
500
+ - spec/dummy/config.ru
486
501
  - spec/dummy/config/application.rb
487
- - spec/dummy/config/database.yml
488
502
  - spec/dummy/config/boot.rb
489
- - spec/dummy/config/initializers/lti_initializer.rb
503
+ - spec/dummy/config/database.yml
504
+ - spec/dummy/config/environment.rb
505
+ - spec/dummy/config/environments/development.rb
506
+ - spec/dummy/config/environments/production.rb
507
+ - spec/dummy/config/environments/test.rb
490
508
  - spec/dummy/config/initializers/backtrace_silencers.rb
491
- - spec/dummy/config/initializers/mime_types.rb
492
509
  - spec/dummy/config/initializers/filter_parameter_logging.rb
510
+ - spec/dummy/config/initializers/inflections.rb
511
+ - spec/dummy/config/initializers/lti_initializer.rb
512
+ - spec/dummy/config/initializers/mime_types.rb
513
+ - spec/dummy/config/initializers/secret_token.rb
493
514
  - spec/dummy/config/initializers/session_store.rb
494
515
  - spec/dummy/config/initializers/wrap_parameters.rb
495
- - spec/dummy/config/initializers/secret_token.rb
496
- - spec/dummy/config/initializers/inflections.rb
497
- - spec/dummy/config.ru
498
- - spec/dummy/Rakefile
499
- - spec/dummy/public/favicon.ico
516
+ - spec/dummy/config/locales/en.yml
517
+ - spec/dummy/config/routes.rb
518
+ - spec/dummy/db/schema.rb
519
+ - spec/dummy/public/404.html
500
520
  - spec/dummy/public/422.html
501
521
  - spec/dummy/public/500.html
502
- - spec/dummy/public/404.html
503
- - spec/dummy/db/schema.rb
504
- - spec/dummy/README.rdoc
505
- - spec/models/coalescing_panda/enrollment_spec.rb
506
- - spec/models/coalescing_panda/section_spec.rb
507
- - spec/models/coalescing_panda/lti_nonce_spec.rb
508
- - spec/models/coalescing_panda/lti_account_spec.rb
509
- - spec/models/coalescing_panda/canvas_batch_spec.rb
510
- - spec/models/coalescing_panda/term_spec.rb
511
- - spec/models/coalescing_panda/assignment_spec.rb
512
- - spec/models/coalescing_panda/submission_spec.rb
513
- - spec/models/coalescing_panda/assignment_group_spec.rb
514
- - spec/models/coalescing_panda/group_spec.rb
515
- - spec/models/coalescing_panda/workers/account_miner_spec.rb
516
- - spec/models/coalescing_panda/workers/course_miner_spec.rb
517
- - spec/models/coalescing_panda/canvas_api_auth_spec.rb
518
- - spec/models/coalescing_panda/group_membership_spec.rb
519
- - spec/models/coalescing_panda/user_spec.rb
520
- - spec/models/coalescing_panda/course_spec.rb
521
- - spec/factories/courses.rb
522
- - spec/factories/submissions.rb
522
+ - spec/dummy/public/favicon.ico
523
+ - spec/factories/accounts.rb
523
524
  - spec/factories/assignment_groups.rb
524
525
  - spec/factories/assignments.rb
525
526
  - spec/factories/canvas_api_auths.rb
526
- - spec/factories/enrollments.rb
527
527
  - spec/factories/canvas_batches.rb
528
+ - spec/factories/courses.rb
529
+ - spec/factories/enrollments.rb
528
530
  - spec/factories/sections.rb
529
- - spec/factories/accounts.rb
530
- - spec/factories/users.rb
531
+ - spec/factories/submissions.rb
531
532
  - spec/factories/terms.rb
532
- - spec/controllers/coalescing_panda/canvas_batches_controller_spec.rb
533
- - spec/controllers/coalescing_panda/oauth2_controller_spec.rb
534
- - spec/controllers/coalescing_panda/lti_controller_spec.rb
533
+ - spec/factories/users.rb
534
+ - spec/models/coalescing_panda/assignment_group_spec.rb
535
+ - spec/models/coalescing_panda/assignment_spec.rb
536
+ - spec/models/coalescing_panda/canvas_api_auth_spec.rb
537
+ - spec/models/coalescing_panda/canvas_batch_spec.rb
538
+ - spec/models/coalescing_panda/course_spec.rb
539
+ - spec/models/coalescing_panda/enrollment_spec.rb
540
+ - spec/models/coalescing_panda/group_membership_spec.rb
541
+ - spec/models/coalescing_panda/group_spec.rb
542
+ - spec/models/coalescing_panda/lti_account_spec.rb
543
+ - spec/models/coalescing_panda/lti_nonce_spec.rb
544
+ - spec/models/coalescing_panda/section_spec.rb
545
+ - spec/models/coalescing_panda/submission_spec.rb
546
+ - spec/models/coalescing_panda/term_spec.rb
547
+ - spec/models/coalescing_panda/user_spec.rb
548
+ - spec/models/coalescing_panda/workers/account_miner_spec.rb
549
+ - spec/models/coalescing_panda/workers/course_miner_spec.rb
535
550
  - spec/rails_helper.rb
551
+ - spec/spec_helper.rb
536
552
  homepage: http://www.instructure.com
537
553
  licenses: []
538
554
  metadata: {}
@@ -542,17 +558,16 @@ require_paths:
542
558
  - lib
543
559
  required_ruby_version: !ruby/object:Gem::Requirement
544
560
  requirements:
545
- - - '>='
561
+ - - ">="
546
562
  - !ruby/object:Gem::Version
547
563
  version: '0'
548
564
  required_rubygems_version: !ruby/object:Gem::Requirement
549
565
  requirements:
550
- - - '>='
566
+ - - ">="
551
567
  - !ruby/object:Gem::Version
552
568
  version: '0'
553
569
  requirements: []
554
- rubyforge_project:
555
- rubygems_version: 2.0.14
570
+ rubygems_version: 3.1.2
556
571
  signing_key:
557
572
  specification_version: 4
558
573
  summary: Canvas LTI and OAUTH2 mountable engine