coalescing_panda 5.1.13 → 5.2.0.beta1

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: 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