coalescing_panda 5.1.13 → 5.2.0.beta1

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: 204da506a48c2fa7b478185259b0a59276631407
4
- data.tar.gz: 2cd6d50876316e7b54d499c381d705b71827a535
2
+ SHA256:
3
+ metadata.gz: bee89db63211898d79a2be426960cb091d7d4b9c384b848587c45744e40471e9
4
+ data.tar.gz: 06b1367659b15e63d7811a0a4ed6385f8f8925c3fac3767b9b0283bd00bd78b2
5
5
  SHA512:
6
- metadata.gz: 6dd78d6695fd7f9f0c248422ef460ce650ca36430b468da69add1f6dd1e513ebe0966816753216ead81a0ebea4456167f2842d385ccf0615a314aba31308da0a
7
- data.tar.gz: 8aa5fa556c55326dbe5dfccdc818fdb4b874db938523c6ca4b9c27ece3e4d2e78ec2720ac8cf7065680daf111c7e79d4a7c816929a778da0794017f2799536f4
6
+ metadata.gz: c902f68f0ed0685039be21864520fe6c80bc199f74afc897b5a38a38e6ea72b335463c0de6498024871e335cb515a7b68c9fa952a384fdf8cb10da12df5e6f23
7
+ data.tar.gz: 6cc22dcad22c6c77a9734b818969356e5600eedef854057d06320b05e1692631e4c814106ac8179a83bb39d2bef1e5396a02df95a6f1144046b09b5eaa739b64
@@ -15,10 +15,12 @@ module CoalescingPanda
15
15
  client_key = lti_account.oauth2_client_key
16
16
  user_id = @oauth_state.data[:user_id]
17
17
  api_domain = @oauth_state.data[:api_domain]
18
+ prefix = @oauth_state.data[:api_url]
18
19
  @oauth_state.destroy
19
- prefix = [oauth2_protocol, '://', api_domain].join
20
+
20
21
  Rails.logger.info "Creating Bearcat client for auth token retrieval pointed to: #{prefix}"
21
22
  client = Bearcat::Client.new(prefix: prefix)
23
+
22
24
  token_body = client.retrieve_token(client_id, coalescing_panda.oauth2_redirect_url, client_key, params['code'])
23
25
  auth = CanvasApiAuth.where('user_id = ? and api_domain = ?', user_id, api_domain).first_or_initialize
24
26
  auth.api_token = token_body['access_token']
@@ -30,20 +32,10 @@ module CoalescingPanda
30
32
  end
31
33
  end
32
34
 
33
-
34
35
  private
35
36
 
36
- def oauth2_protocol
37
- ENV['OAUTH_PROTOCOL'] || (Rails.env.development? ? 'http' : 'https')
38
- end
39
-
40
37
  def retrieve_oauth_state
41
38
  @oauth_state ||= params[:state].present? && OauthState.find_by(state_key: params[:state])
42
39
  end
43
-
44
- def valid_state_token
45
- return false unless params['state'].present? && session['state'].present?
46
- params['state'] == session['state']
47
- end
48
40
  end
49
41
  end
@@ -3,7 +3,7 @@ module CoalescingPanda
3
3
  belongs_to :context, :polymorphic => true
4
4
  include SingleTablePolymorphic
5
5
 
6
- belongs_to :leader, foreign_key: :leader_id, class_name: 'CoalescingPanda::User'
6
+ belongs_to :leader, optional: true, foreign_key: :leader_id, class_name: 'CoalescingPanda::User'
7
7
  belongs_to :group_category, foreign_key: :coalescing_panda_group_category_id, class_name: 'CoalescingPanda::GroupCategory'
8
8
  has_many :group_memberships, foreign_key: :coalescing_panda_group_id, class_name: 'CoalescingPanda::GroupMembership', dependent: :destroy
9
9
  validates :group_category_id, presence: true
@@ -3,7 +3,9 @@
3
3
  %h2 Canvas Authentication Required
4
4
  %button.btn-canvas#oauth_btn Authenticate
5
5
 
6
- %form{id: 'lti_form', action: "#{request.original_url}", method: 'post'}
6
+ %form{id: 'lti_form', action: "#{request.original_url}", method: request.method}
7
+ - unless @lti_params.include?(:session_token) || @lti_params.include?(:session_key)
8
+ %input{:type =>"hidden", :value=>link_nonce, :name=>"session_token"}
7
9
  - @lti_params.each do |k,v|
8
10
  %input{:type =>"hidden", :value=>"#{v}", :name=>"#{k}"}
9
11
 
@@ -15,96 +15,77 @@ module CoalescingPanda
15
15
  def current_organization; current_lti_account; end
16
16
 
17
17
  def canvas_oauth2(*roles)
18
- return if have_session?
19
- if lti_authorize!(*roles)
20
- user_id = params['user_id']
21
- launch_presentation_return_url = @lti_account.settings[:launch_presentation_return_url] || params['launch_presentation_return_url']
22
- launch_presentation_return_url = [CoalescingPanda::BearcatUri.new(request.env["HTTP_REFERER"]).prefix, launch_presentation_return_url].join unless launch_presentation_return_url.include?('http')
23
- uri = CoalescingPanda::BearcatUri.new(launch_presentation_return_url)
24
- set_session(launch_presentation_return_url)
25
-
26
- api_auth = CanvasApiAuth.find_by('user_id = ? and api_domain = ?', user_id, uri.api_domain)
27
- if api_auth
28
- begin
29
- refresh_token(uri, api_auth) if api_auth.expired?
30
- @client = Bearcat::Client.new(token: api_auth.api_token, prefix: uri.prefix)
31
- @client.user_profile 'self'
32
- rescue Footrest::HttpError::BadRequest, Footrest::HttpError::Unauthorized
33
- # If we can't retrieve our own user profile, or the token refresh fails, something is awry on the canvas end
34
- # and we'll need to go through the oauth flow again
35
- render_oauth2_page uri, user_id
36
- end
37
- else
38
- render_oauth2_page uri, user_id
39
- end
18
+ unless valid_session?
19
+ lti_authorize!(*roles)
20
+
21
+ current_session_data['user_id'] = params['user_id']
22
+ current_session_data['lis_person_sourcedid'] = params['lis_person_sourcedid']
23
+ current_session_data['oauth_consumer_key'] = params['oauth_consumer_key']
24
+ current_session_data['custom_canvas_account_id'] = params['custom_canvas_account_id']
40
25
  end
26
+
27
+ @lti_account = LtiAccount.find_by_key(current_session_data['oauth_consumer_key']) if current_session_data['oauth_consumer_key']
28
+
29
+ require_user_api_client
41
30
  end
42
31
 
43
- def render_oauth2_page(uri, user_id)
44
- @lti_account = params['oauth_consumer_key'] && LtiAccount.find_by_key(params['oauth_consumer_key'])
45
- return unless @lti_account
32
+ def render_oauth2_page
33
+ client_id = current_lti_account.oauth2_client_id
34
+ client = Bearcat::Client.new(prefix: canvas_api_uri)
46
35
 
47
- client_id = @lti_account.oauth2_client_id
48
- client = Bearcat::Client.new(prefix: uri.prefix)
49
36
  state = SecureRandom.hex(32)
50
- OauthState.create! state_key: state, data: { key: params['oauth_consumer_key'], user_id: user_id, api_domain: uri.api_domain }
37
+ OauthState.create! state_key: state, data: {
38
+ key: current_session_data.dig(:launch_params, :oauth_consumer_key),
39
+ user_id: current_session_data.dig(:launch_params, :user_id),
40
+ api_domain: URI.parse(canvas_api_uri).host,
41
+ api_url: canvas_api_uri,
42
+ }
43
+
51
44
  @canvas_url = client.auth_redirect_url(client_id, resolve_coalescing_panda_url(:oauth2_redirect_url), { state: state })
52
45
 
53
- #delete the added params so the original oauth sig still works
54
46
  @lti_params = params.to_unsafe_h
55
47
  @lti_params.delete('action')
56
48
  @lti_params.delete('controller')
49
+
57
50
  render 'coalescing_panda/oauth2/oauth2', layout: 'coalescing_panda/application'
58
51
  end
59
52
 
60
- def refresh_token(uri, api_auth)
61
- refresh_client = Bearcat::Client.new(prefix: uri.prefix)
62
- refresh_body = refresh_client.retrieve_token(@lti_account.oauth2_client_id, resolve_coalescing_panda_url(:oauth2_redirect_url),
63
- @lti_account.oauth2_client_key, api_auth.refresh_token, 'refresh_token')
53
+ def refresh_token(api_auth)
54
+ refresh_client = Bearcat::Client.new(prefix: canvas_api_uri)
55
+ refresh_body = refresh_client.retrieve_token(
56
+ current_lti_account.oauth2_client_id,
57
+ resolve_coalescing_panda_url(:oauth2_redirect_url),
58
+ current_lti_account.oauth2_client_key,
59
+ api_auth.refresh_token,
60
+ 'refresh_token'
61
+ )
64
62
  api_auth.update({ api_token: refresh_body['access_token'], expires_at: (Time.now + refresh_body['expires_in']) })
65
63
  end
66
64
 
67
- def check_refresh_token
68
- return unless current_session_data['uri'] && current_session_data['user_id'] && current_session_data['oauth_consumer_key']
69
- uri = CoalescingPanda::BearcatUri.new(current_session_data['uri'])
70
- api_auth = CanvasApiAuth.find_by(user_id: current_session_data['user_id'], api_domain: uri.api_domain)
71
- @lti_account = LtiAccount.find_by(key: current_session_data['oauth_consumer_key'])
72
- return if @lti_account.nil? || api_auth.nil? # Not all tools use oauth
73
-
74
- refresh_token(uri, api_auth) if api_auth.expired?
75
- rescue Footrest::HttpError::BadRequest
76
- render_oauth2_page uri, current_session_data['user_id']
77
- end
78
-
79
- def set_session(launch_presentation_return_url)
80
- current_session_data['user_id'] = params['user_id']
81
- current_session_data['uri'] = launch_presentation_return_url
82
- current_session_data['lis_person_sourcedid'] = params['lis_person_sourcedid']
83
- current_session_data['oauth_consumer_key'] = params['oauth_consumer_key']
84
- current_session_data['custom_canvas_account_id'] = params['custom_canvas_account_id']
85
- end
86
-
87
- def have_session?
88
- if params['tool_consumer_instance_guid'] && current_session_data['user_id'] != params['user_id']
89
- reset_session
90
- logger.info("resetting session params")
91
- current_session_data['user_id'] = params['user_id']
65
+ def require_user_api_client
66
+ if user_api_client.nil?
67
+ render_oauth2_page
92
68
  end
69
+ end
93
70
 
94
- if (current_session_data['user_id'] && current_session_data['uri'])
95
- uri = CoalescingPanda::BearcatUri.new(current_session_data['uri'])
96
- api_auth = CanvasApiAuth.find_by('user_id = ? and api_domain = ?', current_session_data['user_id'], uri.api_domain)
97
- if api_auth && !api_auth.expired?
98
- @client = Bearcat::Client.new(token: api_auth.api_token, prefix: uri.prefix)
99
- @client.user_profile 'self'
71
+ def user_api_client
72
+ @user_api_client ||= begin
73
+ user_id = current_session_data.dig(:launch_params, :user_id)
74
+ puri = URI.parse(canvas_api_uri)
75
+ api_auth = CanvasApiAuth.find_by('user_id = ? and api_domain = ?', user_id, puri.host)
76
+ if api_auth
77
+ begin
78
+ refresh_token(api_auth) if api_auth.expired?
79
+ client = Bearcat::Client.new(token: api_auth.api_token, prefix: canvas_api_uri)
80
+ client.user_profile('self')
81
+ client
82
+ rescue Footrest::HttpError::BadRequest, Footrest::HttpError::Unauthorized
83
+ # If we can't retrieve our own user profile, or the token refresh fails, something is awry on the canvas end
84
+ # and we'll need to go through the oauth flow again
85
+ nil
86
+ end
100
87
  end
101
88
  end
102
-
103
- @lti_account = LtiAccount.find_by_key(current_session_data['oauth_consumer_key']) if current_session_data['oauth_consumer_key']
104
-
105
- !!@client
106
- rescue Footrest::HttpError::Unauthorized
107
- false
108
89
  end
109
90
 
110
91
  def validate_launch!
@@ -112,23 +93,39 @@ module CoalescingPanda
112
93
  end
113
94
 
114
95
  def lti_authorize!(*roles)
96
+ return true if valid_session?
97
+
115
98
  authorized = false
116
99
  if (@lti_account = params['oauth_consumer_key'] && LtiAccount.find_by_key(params['oauth_consumer_key']))
117
100
  sanitized_params = sanitize_params
118
101
  @tp = IMS::LTI::ToolProvider.new(@lti_account.key, @lti_account.secret, sanitized_params)
119
102
  authorized = @tp.valid_request?(request)
120
103
  end
104
+
121
105
  logger.info 'not authorized on tp valid request' unless authorized
122
- authorized = authorized && (roles.count == 0 || (roles & lti_roles).count > 0)
123
- logger.info 'not authorized on roles' unless authorized
124
- authorized = authorized && @lti_account.validate_nonce(params['oauth_nonce'], DateTime.strptime(params['oauth_timestamp'], '%s'))
125
- logger.info 'not authorized on nonce' unless authorized
106
+
107
+ if authorized && !(authorized = (roles.count == 0 || (roles & lti_roles).count > 0))
108
+ logger.info 'not authorized on roles'
109
+ end
110
+
111
+ if authorized && !(authorized = @lti_account.validate_nonce(params['oauth_nonce'], DateTime.strptime(params['oauth_timestamp'], '%s')))
112
+ logger.info 'not authorized on nonce'
113
+ end
114
+
126
115
  render :text => 'Invalid Credentials, please contact your Administrator.', :status => :unauthorized unless authorized
116
+
127
117
  # create session on first launch
128
118
  current_session
129
119
  authorized
130
120
  end
131
121
 
122
+ def valid_session?
123
+ return false unless current_session(create_missing: false)&.persisted?
124
+ true
125
+ rescue SessionNonceMismatch
126
+ false
127
+ end
128
+
132
129
  # code for method taken from panda_pal v 4.0.8
133
130
  # used for safari workaround
134
131
  def sanitize_params
@@ -162,11 +159,27 @@ module CoalescingPanda
162
159
  end
163
160
  end
164
161
 
165
- def valid_session?
166
- return false unless current_session(create_missing: false)&.persisted?
167
- true
168
- rescue SessionNonceMismatch
169
- false
162
+ def canvas_api_uri
163
+ @canvas_api_uri ||= begin
164
+ launch_params = current_session_data[:launch_params] || {}
165
+ uri = 'canvas.instructure.com'
166
+ if launch_params[:custom_canvas_api_domain].present?
167
+ uri = launch_params[:custom_canvas_api_domain]
168
+ else
169
+ uri = current_lti_account.settings[:launch_presentation_return_url] || launch_params[:launch_presentation_return_url]
170
+ unless uri.include?('://')
171
+ referrer = URI.parse(request.env["HTTP_REFERER"])
172
+ referrer.path = ''
173
+ uri = [referrer.to_s, uri].join
174
+ end
175
+ end
176
+
177
+ uri = ((Rails.env.test? or Rails.env.development?) ? 'http' : 'https') + '://' + uri unless uri.include?('://')
178
+
179
+ uri = URI.parse(uri)
180
+ uri.path = ''
181
+ uri.to_s
182
+ end
170
183
  end
171
184
 
172
185
  private
@@ -1,3 +1,3 @@
1
1
  module CoalescingPanda
2
- VERSION = '5.1.13'
2
+ VERSION = '5.2.0.beta1'
3
3
  end
Binary file
@@ -1,4 +1,3 @@
1
- # encoding: UTF-8
2
1
  # This file is auto-generated from the current state of the database. Instead
3
2
  # of editing this file, please use the migrations feature of Active Record to
4
3
  # incrementally modify your database, and then regenerate this schema definition.
@@ -11,263 +10,249 @@
11
10
  #
12
11
  # It's strongly recommended that you check this file into your version control system.
13
12
 
14
- ActiveRecord::Schema.define(version: 20160830183155) do
13
+ ActiveRecord::Schema.define(version: 2020_05_28_224505) do
15
14
 
16
15
  create_table "coalescing_panda_assignment_groups", force: :cascade do |t|
17
- t.integer "coalescing_panda_course_id", null: false
18
- t.integer "context_id"
19
- t.string "context_type"
20
- t.string "canvas_assignment_group_id"
21
- t.string "name"
22
- t.integer "position"
23
- t.float "group_weight"
24
- t.string "workflow_state"
16
+ t.integer "coalescing_panda_course_id", null: false
17
+ t.string "context_type"
18
+ t.integer "context_id"
19
+ t.string "canvas_assignment_group_id"
20
+ t.string "name"
21
+ t.integer "position"
22
+ t.float "group_weight"
23
+ t.string "workflow_state"
25
24
  t.datetime "created_at"
26
25
  t.datetime "updated_at"
26
+ t.index ["canvas_assignment_group_id", "context_id", "context_type"], name: "index_assignment_group_context", unique: true
27
+ t.index ["coalescing_panda_course_id", "canvas_assignment_group_id"], name: "index_assignment_group_course", unique: true
27
28
  end
28
29
 
29
- add_index "coalescing_panda_assignment_groups", ["canvas_assignment_group_id", "context_id", "context_type"], name: "index_assignment_group_context", unique: true
30
- add_index "coalescing_panda_assignment_groups", ["coalescing_panda_course_id", "canvas_assignment_group_id"], name: "index_assignment_group_course", unique: true
31
-
32
30
  create_table "coalescing_panda_assignments", force: :cascade do |t|
33
- t.integer "coalescing_panda_course_id", null: false
34
- t.string "name"
35
- t.text "description"
36
- t.string "canvas_assignment_id", null: false
37
- t.string "workflow_state"
38
- t.float "points_possible"
31
+ t.integer "coalescing_panda_course_id", null: false
32
+ t.string "name"
33
+ t.text "description"
34
+ t.string "canvas_assignment_id", null: false
35
+ t.string "workflow_state"
36
+ t.float "points_possible"
39
37
  t.datetime "due_at"
40
38
  t.datetime "unlock_at"
41
39
  t.datetime "lock_at"
42
40
  t.datetime "created_at"
43
41
  t.datetime "updated_at"
44
- t.text "submission_types"
45
- t.integer "group_category_id"
46
- t.boolean "grade_group_students_individually"
47
- t.boolean "published"
48
- t.integer "coalescing_panda_assignment_group_id"
49
- t.integer "coalescing_panda_group_category_id"
42
+ t.text "submission_types"
43
+ t.integer "group_category_id"
44
+ t.boolean "grade_group_students_individually"
45
+ t.boolean "published"
46
+ t.integer "coalescing_panda_assignment_group_id"
47
+ t.integer "coalescing_panda_group_category_id"
48
+ t.index ["coalescing_panda_course_id", "canvas_assignment_id"], name: "index_assignments_course", unique: true
50
49
  end
51
50
 
52
- add_index "coalescing_panda_assignments", ["coalescing_panda_course_id", "canvas_assignment_id"], name: "index_assignments_course", unique: true
53
-
54
51
  create_table "coalescing_panda_canvas_api_auths", force: :cascade do |t|
55
- t.string "user_id"
56
- t.string "api_domain"
57
- t.string "api_token"
52
+ t.string "user_id"
53
+ t.string "api_domain"
54
+ t.string "api_token"
58
55
  t.datetime "created_at"
59
56
  t.datetime "updated_at"
60
- t.string "refresh_token"
57
+ t.string "refresh_token"
61
58
  t.datetime "expires_at"
62
59
  end
63
60
 
64
61
  create_table "coalescing_panda_canvas_batches", force: :cascade do |t|
65
- t.float "percent_complete", default: 0.0
66
- t.string "status"
67
- t.text "message"
62
+ t.float "percent_complete", default: 0.0
63
+ t.string "status"
64
+ t.text "message"
68
65
  t.datetime "created_at"
69
66
  t.datetime "updated_at"
70
- t.integer "context_id"
71
- t.string "context_type"
72
- t.integer "coalescing_panda_lti_account_id"
73
- t.text "options"
67
+ t.integer "context_id"
68
+ t.string "context_type"
69
+ t.integer "coalescing_panda_lti_account_id"
70
+ t.text "options"
74
71
  end
75
72
 
76
73
  create_table "coalescing_panda_courses", force: :cascade do |t|
77
- t.integer "coalescing_panda_lti_account_id", null: false
78
- t.integer "coalescing_panda_term_id"
79
- t.string "name"
80
- t.string "canvas_course_id", null: false
81
- t.string "sis_id"
74
+ t.integer "coalescing_panda_lti_account_id", null: false
75
+ t.integer "coalescing_panda_term_id"
76
+ t.string "name"
77
+ t.string "canvas_course_id", null: false
78
+ t.string "sis_id"
82
79
  t.datetime "start_at"
83
80
  t.datetime "conclude_at"
84
- t.string "workflow_state"
85
- t.string "course_code"
81
+ t.string "workflow_state"
82
+ t.string "course_code"
86
83
  t.datetime "created_at"
87
84
  t.datetime "updated_at"
85
+ t.index ["coalescing_panda_lti_account_id", "canvas_course_id"], name: "index_courses_account", unique: true
86
+ t.index ["coalescing_panda_term_id", "canvas_course_id"], name: "index_courses_term", unique: true
87
+ t.index ["sis_id"], name: "index_coalescing_panda_courses_on_sis_id"
88
88
  end
89
89
 
90
- add_index "coalescing_panda_courses", ["coalescing_panda_lti_account_id", "canvas_course_id"], name: "index_courses_account", unique: true
91
- add_index "coalescing_panda_courses", ["coalescing_panda_term_id", "canvas_course_id"], name: "index_courses_term", unique: true
92
- add_index "coalescing_panda_courses", ["sis_id"], name: "index_coalescing_panda_courses_on_sis_id"
93
-
94
90
  create_table "coalescing_panda_enrollments", force: :cascade do |t|
95
- t.integer "coalescing_panda_user_id", null: false
96
- t.integer "coalescing_panda_section_id", null: false
97
- t.string "workflow_state"
98
- t.string "sis_id"
99
- t.string "canvas_enrollment_id", null: false
100
- t.string "enrollment_type"
91
+ t.integer "coalescing_panda_user_id", null: false
92
+ t.integer "coalescing_panda_section_id", null: false
93
+ t.string "workflow_state"
94
+ t.string "sis_id"
95
+ t.string "canvas_enrollment_id", null: false
96
+ t.string "enrollment_type"
101
97
  t.datetime "start_at"
102
98
  t.datetime "end_at"
103
99
  t.datetime "created_at"
104
100
  t.datetime "updated_at"
101
+ t.index ["coalescing_panda_user_id", "coalescing_panda_section_id", "enrollment_type"], name: "index_enrollments_user_and_section", unique: true
102
+ t.index ["sis_id"], name: "index_coalescing_panda_enrollments_on_sis_id"
105
103
  end
106
104
 
107
- add_index "coalescing_panda_enrollments", ["coalescing_panda_user_id", "coalescing_panda_section_id", "enrollment_type"], name: "index_enrollments_user_and_section", unique: true
108
- add_index "coalescing_panda_enrollments", ["sis_id"], name: "index_coalescing_panda_enrollments_on_sis_id"
109
-
110
105
  create_table "coalescing_panda_group_categories", force: :cascade do |t|
111
- t.integer "context_id"
112
- t.string "context_type"
113
- t.integer "canvas_group_category_id"
114
- t.string "name"
106
+ t.string "context_type"
107
+ t.integer "context_id"
108
+ t.integer "canvas_group_category_id"
109
+ t.string "name"
115
110
  t.datetime "created_at"
116
111
  t.datetime "updated_at"
112
+ t.index ["context_id", "context_type"], name: "index_group_categories_context_and_context_type"
117
113
  end
118
114
 
119
- add_index "coalescing_panda_group_categories", ["context_id", "context_type"], name: "index_group_categories_context_and_context_type"
120
-
121
115
  create_table "coalescing_panda_group_memberships", force: :cascade do |t|
122
- t.integer "coalescing_panda_group_id"
123
- t.integer "coalescing_panda_user_id"
124
- t.string "canvas_group_membership_id"
125
- t.string "workflow_state"
116
+ t.integer "coalescing_panda_group_id"
117
+ t.integer "coalescing_panda_user_id"
118
+ t.string "canvas_group_membership_id"
119
+ t.string "workflow_state"
126
120
  t.datetime "created_at"
127
121
  t.datetime "updated_at"
128
- t.boolean "moderator"
122
+ t.boolean "moderator"
123
+ t.index ["coalescing_panda_group_id", "coalescing_panda_user_id"], name: "index_group_memberships_user_and_group", unique: true
129
124
  end
130
125
 
131
- add_index "coalescing_panda_group_memberships", ["coalescing_panda_group_id", "coalescing_panda_user_id"], name: "index_group_memberships_user_and_group", unique: true
132
-
133
126
  create_table "coalescing_panda_groups", force: :cascade do |t|
134
- t.integer "context_id"
135
- t.string "context_type"
136
- t.string "description"
137
- t.string "group_category_id"
138
- t.string "canvas_group_id"
139
- t.string "name"
140
- t.integer "members_count"
127
+ t.string "context_type"
128
+ t.integer "context_id"
129
+ t.string "description"
130
+ t.string "group_category_id"
131
+ t.string "canvas_group_id"
132
+ t.string "name"
133
+ t.integer "members_count"
141
134
  t.datetime "created_at"
142
135
  t.datetime "updated_at"
143
- t.integer "leader_id"
144
- t.integer "coalescing_panda_group_category_id"
136
+ t.integer "leader_id"
137
+ t.integer "coalescing_panda_group_category_id"
138
+ t.index ["context_id", "canvas_group_id"], name: "index_groups_context_and_group_id", unique: true
145
139
  end
146
140
 
147
- add_index "coalescing_panda_groups", ["context_id", "canvas_group_id"], name: "index_groups_context_and_group_id", unique: true
148
-
149
141
  create_table "coalescing_panda_lti_accounts", force: :cascade do |t|
150
- t.string "name"
151
- t.string "key"
152
- t.string "secret"
153
- t.string "oauth2_client_id"
154
- t.string "oauth2_client_key"
155
- t.string "canvas_account_id"
156
- t.text "settings"
142
+ t.string "name"
143
+ t.string "key"
144
+ t.string "secret"
145
+ t.string "oauth2_client_id"
146
+ t.string "oauth2_client_key"
147
+ t.string "canvas_account_id"
148
+ t.text "settings"
157
149
  t.datetime "created_at"
158
150
  t.datetime "updated_at"
159
151
  end
160
152
 
161
153
  create_table "coalescing_panda_lti_nonces", force: :cascade do |t|
162
- t.integer "coalescing_panda_lti_account_id"
163
- t.string "nonce"
154
+ t.integer "coalescing_panda_lti_account_id"
155
+ t.string "nonce"
164
156
  t.datetime "timestamp"
165
157
  end
166
158
 
167
159
  create_table "coalescing_panda_oauth_states", force: :cascade do |t|
168
- t.string "state_key"
169
- t.text "data"
160
+ t.string "state_key"
161
+ t.text "data"
170
162
  t.datetime "created_at"
171
163
  t.datetime "updated_at"
164
+ t.index ["state_key"], name: "index_coalescing_panda_oauth_states_on_state_key", unique: true
172
165
  end
173
166
 
174
- add_index "coalescing_panda_oauth_states", ["state_key"], name: "index_coalescing_panda_oauth_states_on_state_key", unique: true
175
-
176
167
  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
168
+ t.string "session_key"
169
+ t.text "data"
170
+ t.integer "coalescing_panda_lti_account_id"
171
+ t.datetime "created_at", null: false
172
+ t.datetime "updated_at", null: false
173
+ t.index ["coalescing_panda_lti_account_id"], name: "index_persistent_session_on_lti_account_id"
174
+ t.index ["session_key"], name: "index_coalescing_panda_persistent_sessions_on_session_key", unique: true
182
175
  end
183
176
 
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
-
187
177
  create_table "coalescing_panda_sections", force: :cascade do |t|
188
- t.integer "coalescing_panda_course_id", null: false
189
- t.string "name"
190
- t.string "canvas_section_id", null: false
191
- t.string "sis_id"
192
- t.string "workflow_state"
178
+ t.integer "coalescing_panda_course_id", null: false
179
+ t.string "name"
180
+ t.string "canvas_section_id", null: false
181
+ t.string "sis_id"
182
+ t.string "workflow_state"
193
183
  t.datetime "start_at"
194
184
  t.datetime "end_at"
195
185
  t.datetime "created_at"
196
186
  t.datetime "updated_at"
187
+ t.index ["coalescing_panda_course_id", "canvas_section_id"], name: "index_sections_course", unique: true
188
+ t.index ["sis_id"], name: "index_coalescing_panda_sections_on_sis_id"
197
189
  end
198
190
 
199
- add_index "coalescing_panda_sections", ["coalescing_panda_course_id", "canvas_section_id"], name: "index_sections_course", unique: true
200
- add_index "coalescing_panda_sections", ["sis_id"], name: "index_coalescing_panda_sections_on_sis_id"
201
-
202
191
  create_table "coalescing_panda_sessions", force: :cascade do |t|
203
- t.string "token"
204
- t.text "data"
192
+ t.string "token"
193
+ t.text "data"
205
194
  t.datetime "created_at"
206
195
  t.datetime "updated_at"
207
196
  end
208
197
 
209
198
  create_table "coalescing_panda_submissions", force: :cascade do |t|
210
- t.integer "coalescing_panda_user_id", null: false
211
- t.integer "coalescing_panda_assignment_id", null: false
212
- t.string "url"
213
- t.string "grade"
214
- t.string "score"
199
+ t.integer "coalescing_panda_user_id", null: false
200
+ t.integer "coalescing_panda_assignment_id", null: false
201
+ t.string "url"
202
+ t.string "grade"
203
+ t.string "score"
215
204
  t.datetime "submitted_at"
216
- t.string "workflow_state"
217
- t.string "canvas_submission_id", null: false
205
+ t.string "workflow_state"
206
+ t.string "canvas_submission_id", null: false
218
207
  t.datetime "created_at"
219
208
  t.datetime "updated_at"
209
+ t.index ["canvas_submission_id"], name: "index_coalescing_panda_submissions_on_canvas_submission_id"
210
+ t.index ["coalescing_panda_user_id", "coalescing_panda_assignment_id", "canvas_submission_id"], name: "index_submissions_user_and_assignment", unique: true
220
211
  end
221
212
 
222
- add_index "coalescing_panda_submissions", ["canvas_submission_id"], name: "index_coalescing_panda_submissions_on_canvas_submission_id"
223
- add_index "coalescing_panda_submissions", ["coalescing_panda_user_id", "coalescing_panda_assignment_id", "canvas_submission_id"], name: "index_submissions_user_and_assignment", unique: true
224
-
225
213
  create_table "coalescing_panda_terms", force: :cascade do |t|
226
- t.integer "coalescing_panda_lti_account_id", null: false
227
- t.string "name"
228
- t.string "code"
229
- t.string "sis_id"
230
- t.string "canvas_term_id", null: false
214
+ t.integer "coalescing_panda_lti_account_id", null: false
215
+ t.string "name"
216
+ t.string "code"
217
+ t.string "sis_id"
218
+ t.string "canvas_term_id", null: false
231
219
  t.datetime "start_at"
232
220
  t.datetime "end_at"
233
- t.string "workflow_state"
221
+ t.string "workflow_state"
234
222
  t.datetime "created_at"
235
223
  t.datetime "updated_at"
224
+ t.index ["canvas_term_id", "coalescing_panda_lti_account_id"], name: "index_terms_account", unique: true
225
+ t.index ["sis_id"], name: "index_coalescing_panda_terms_on_sis_id"
236
226
  end
237
227
 
238
- add_index "coalescing_panda_terms", ["canvas_term_id", "coalescing_panda_lti_account_id"], name: "index_terms_account", unique: true
239
- add_index "coalescing_panda_terms", ["sis_id"], name: "index_coalescing_panda_terms_on_sis_id"
240
-
241
228
  create_table "coalescing_panda_users", force: :cascade do |t|
242
- t.integer "coalescing_panda_lti_account_id", null: false
243
- t.string "name"
244
- t.string "email"
245
- t.string "roles"
246
- t.string "workflow_state"
247
- t.string "sis_id"
248
- t.string "canvas_user_id", null: false
229
+ t.integer "coalescing_panda_lti_account_id", null: false
230
+ t.string "name"
231
+ t.string "email"
232
+ t.string "roles"
233
+ t.string "workflow_state"
234
+ t.string "sis_id"
235
+ t.string "canvas_user_id", null: false
249
236
  t.datetime "created_at"
250
237
  t.datetime "updated_at"
251
- t.string "login_id"
238
+ t.string "login_id"
239
+ t.index ["coalescing_panda_lti_account_id", "canvas_user_id"], name: "index_users_account", unique: true
240
+ t.index ["sis_id"], name: "index_coalescing_panda_users_on_sis_id"
252
241
  end
253
242
 
254
- add_index "coalescing_panda_users", ["coalescing_panda_lti_account_id", "canvas_user_id"], name: "index_users_account", unique: true
255
- add_index "coalescing_panda_users", ["sis_id"], name: "index_coalescing_panda_users_on_sis_id"
256
-
257
243
  create_table "delayed_jobs", force: :cascade do |t|
258
- t.integer "priority", default: 0, null: false
259
- t.integer "attempts", default: 0, null: false
260
- t.text "handler", null: false
261
- t.text "last_error"
244
+ t.integer "priority", default: 0, null: false
245
+ t.integer "attempts", default: 0, null: false
246
+ t.text "handler", null: false
247
+ t.text "last_error"
262
248
  t.datetime "run_at"
263
249
  t.datetime "locked_at"
264
250
  t.datetime "failed_at"
265
- t.string "locked_by"
266
- t.string "queue"
251
+ t.string "locked_by"
252
+ t.string "queue"
267
253
  t.datetime "created_at"
268
254
  t.datetime "updated_at"
255
+ t.index ["priority", "run_at"], name: "delayed_jobs_priority"
269
256
  end
270
257
 
271
- add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority"
272
-
273
258
  end
Binary file
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coalescing_panda
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.13
4
+ version: 5.2.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Mills
8
8
  - Cody Tanner
9
9
  - Jake Sorce
10
- autorequire:
10
+ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-09-13 00:00:00.000000000 Z
13
+ date: 2021-11-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails
@@ -410,7 +410,7 @@ dependencies:
410
410
  - - ">="
411
411
  - !ruby/object:Gem::Version
412
412
  version: '0'
413
- description:
413
+ description:
414
414
  email:
415
415
  - nathanm@instructure.com
416
416
  - ctanner@instructure.com
@@ -540,7 +540,9 @@ files:
540
540
  - spec/dummy/config/initializers/wrap_parameters.rb
541
541
  - spec/dummy/config/locales/en.yml
542
542
  - spec/dummy/config/routes.rb
543
+ - spec/dummy/db/development.sqlite3
543
544
  - spec/dummy/db/schema.rb
545
+ - spec/dummy/db/test.sqlite3
544
546
  - spec/dummy/public/404.html
545
547
  - spec/dummy/public/422.html
546
548
  - spec/dummy/public/500.html
@@ -577,7 +579,7 @@ files:
577
579
  homepage: http://www.instructure.com
578
580
  licenses: []
579
581
  metadata: {}
580
- post_install_message:
582
+ post_install_message:
581
583
  rdoc_options: []
582
584
  require_paths:
583
585
  - lib
@@ -588,80 +590,81 @@ required_ruby_version: !ruby/object:Gem::Requirement
588
590
  version: '0'
589
591
  required_rubygems_version: !ruby/object:Gem::Requirement
590
592
  requirements:
591
- - - ">="
593
+ - - ">"
592
594
  - !ruby/object:Gem::Version
593
- version: '0'
595
+ version: 1.3.1
594
596
  requirements: []
595
- rubyforge_project:
596
- rubygems_version: 2.6.14.4
597
- signing_key:
597
+ rubygems_version: 3.0.3
598
+ signing_key:
598
599
  specification_version: 4
599
600
  summary: Canvas LTI and OAUTH2 mountable engine
600
601
  test_files:
602
+ - spec/rails_helper.rb
603
+ - spec/models/coalescing_panda/canvas_api_auth_spec.rb
604
+ - spec/models/coalescing_panda/assignment_spec.rb
605
+ - spec/models/coalescing_panda/group_membership_spec.rb
606
+ - spec/models/coalescing_panda/lti_account_spec.rb
607
+ - spec/models/coalescing_panda/section_spec.rb
608
+ - spec/models/coalescing_panda/workers/course_miner_spec.rb
609
+ - spec/models/coalescing_panda/workers/account_miner_spec.rb
610
+ - spec/models/coalescing_panda/group_spec.rb
611
+ - spec/models/coalescing_panda/lti_nonce_spec.rb
612
+ - spec/models/coalescing_panda/submission_spec.rb
613
+ - spec/models/coalescing_panda/term_spec.rb
614
+ - spec/models/coalescing_panda/canvas_batch_spec.rb
615
+ - spec/models/coalescing_panda/enrollment_spec.rb
616
+ - spec/models/coalescing_panda/course_spec.rb
617
+ - spec/models/coalescing_panda/user_spec.rb
618
+ - spec/models/coalescing_panda/assignment_group_spec.rb
619
+ - spec/controllers/coalescing_panda/oauth2_controller_spec.rb
620
+ - spec/controllers/coalescing_panda/lti_controller_spec.rb
621
+ - spec/controllers/coalescing_panda/canvas_batches_controller_spec.rb
601
622
  - spec/spec_helper.rb
623
+ - spec/dummy/db/schema.rb
624
+ - spec/dummy/db/test.sqlite3
625
+ - spec/dummy/db/development.sqlite3
626
+ - spec/dummy/public/422.html
627
+ - spec/dummy/public/favicon.ico
628
+ - spec/dummy/public/404.html
629
+ - spec/dummy/public/500.html
630
+ - spec/dummy/Rakefile
631
+ - spec/dummy/app/views/layouts/application.html.erb
602
632
  - spec/dummy/app/models/account.rb
603
633
  - spec/dummy/app/models/course.rb
604
634
  - spec/dummy/app/controllers/application_controller.rb
605
- - spec/dummy/app/views/layouts/application.html.erb
606
- - spec/dummy/app/assets/javascripts/application.js
607
- - spec/dummy/app/assets/stylesheets/application.css
608
635
  - spec/dummy/app/helpers/application_helper.rb
609
- - spec/dummy/bin/rake
610
- - spec/dummy/bin/bundle
611
- - spec/dummy/bin/rails
612
- - spec/dummy/config/routes.rb
613
- - spec/dummy/config/locales/en.yml
614
- - spec/dummy/config/environments/production.rb
615
- - spec/dummy/config/environments/development.rb
616
- - spec/dummy/config/environments/test.rb
617
- - spec/dummy/config/environment.rb
636
+ - spec/dummy/app/assets/stylesheets/application.css
637
+ - spec/dummy/app/assets/javascripts/application.js
618
638
  - spec/dummy/config/application.rb
619
- - spec/dummy/config/database.yml
620
- - spec/dummy/config/boot.rb
621
639
  - spec/dummy/config/initializers/lti_initializer.rb
622
- - spec/dummy/config/initializers/backtrace_silencers.rb
623
- - spec/dummy/config/initializers/mime_types.rb
624
- - spec/dummy/config/initializers/filter_parameter_logging.rb
625
640
  - spec/dummy/config/initializers/session_store.rb
626
- - spec/dummy/config/initializers/wrap_parameters.rb
627
641
  - spec/dummy/config/initializers/secret_token.rb
642
+ - spec/dummy/config/initializers/wrap_parameters.rb
628
643
  - spec/dummy/config/initializers/inflections.rb
629
- - spec/dummy/config.ru
630
- - spec/dummy/Rakefile
631
- - spec/dummy/public/favicon.ico
632
- - spec/dummy/public/422.html
633
- - spec/dummy/public/500.html
634
- - spec/dummy/public/404.html
635
- - spec/dummy/db/schema.rb
644
+ - spec/dummy/config/initializers/filter_parameter_logging.rb
645
+ - spec/dummy/config/initializers/mime_types.rb
646
+ - spec/dummy/config/initializers/backtrace_silencers.rb
647
+ - spec/dummy/config/environments/development.rb
648
+ - spec/dummy/config/environments/test.rb
649
+ - spec/dummy/config/environments/production.rb
650
+ - spec/dummy/config/database.yml
651
+ - spec/dummy/config/boot.rb
652
+ - spec/dummy/config/routes.rb
653
+ - spec/dummy/config/environment.rb
654
+ - spec/dummy/config/locales/en.yml
636
655
  - spec/dummy/README.rdoc
637
- - spec/models/coalescing_panda/enrollment_spec.rb
638
- - spec/models/coalescing_panda/section_spec.rb
639
- - spec/models/coalescing_panda/lti_nonce_spec.rb
640
- - spec/models/coalescing_panda/lti_account_spec.rb
641
- - spec/models/coalescing_panda/canvas_batch_spec.rb
642
- - spec/models/coalescing_panda/term_spec.rb
643
- - spec/models/coalescing_panda/assignment_spec.rb
644
- - spec/models/coalescing_panda/submission_spec.rb
645
- - spec/models/coalescing_panda/assignment_group_spec.rb
646
- - spec/models/coalescing_panda/group_spec.rb
647
- - spec/models/coalescing_panda/workers/account_miner_spec.rb
648
- - spec/models/coalescing_panda/workers/course_miner_spec.rb
649
- - spec/models/coalescing_panda/canvas_api_auth_spec.rb
650
- - spec/models/coalescing_panda/group_membership_spec.rb
651
- - spec/models/coalescing_panda/user_spec.rb
652
- - spec/models/coalescing_panda/course_spec.rb
653
- - spec/factories/courses.rb
654
- - spec/factories/submissions.rb
655
- - spec/factories/assignment_groups.rb
656
- - spec/factories/assignments.rb
657
- - spec/factories/canvas_api_auths.rb
656
+ - spec/dummy/config.ru
657
+ - spec/dummy/bin/bundle
658
+ - spec/dummy/bin/rake
659
+ - spec/dummy/bin/rails
660
+ - spec/factories/accounts.rb
658
661
  - spec/factories/enrollments.rb
659
- - spec/factories/canvas_batches.rb
662
+ - spec/factories/terms.rb
660
663
  - spec/factories/sections.rb
661
- - spec/factories/accounts.rb
664
+ - spec/factories/canvas_batches.rb
665
+ - spec/factories/assignment_groups.rb
666
+ - spec/factories/submissions.rb
667
+ - spec/factories/courses.rb
668
+ - spec/factories/assignments.rb
662
669
  - spec/factories/users.rb
663
- - spec/factories/terms.rb
664
- - spec/controllers/coalescing_panda/canvas_batches_controller_spec.rb
665
- - spec/controllers/coalescing_panda/oauth2_controller_spec.rb
666
- - spec/controllers/coalescing_panda/lti_controller_spec.rb
667
- - spec/rails_helper.rb
670
+ - spec/factories/canvas_api_auths.rb