coalescing_panda 4.6.1 → 5.0.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
- 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