panda_pal 5.9.7 → 5.9.8.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
2
  SHA256:
3
- metadata.gz: 799fa888cac92c1bdd0f8db04306a6ca3eac462f8cf545fa28aa1fee2cd8d2e2
4
- data.tar.gz: c52ec2f608302a2c646634691bbe05730455fcec5716493e400f3c2066be2830
3
+ metadata.gz: 0d130670af8eb3c98ac19c8cf001e4fc69b09d4a0c2c2774537213a3b02f935d
4
+ data.tar.gz: f2294052c154c0aa7adb89ac5506c028822dc42c90e6167b77799ba9662468a7
5
5
  SHA512:
6
- metadata.gz: 9c76429c86e9a999aaa90d953175988b86c5af85de9c8021608cd34d911af3bc299f31fe22729c9b91a622749fd2665801de21e34a1076bf11f0be9ec2690090
7
- data.tar.gz: 3c0a7d8aab01ebcdc6eb70fcf89a6936cf138fb661634194417ac55961645e0654d65bf2a9264dac7b53652a6eb67afdc1edf0bc83d7611ac7f5781b337cf79d
6
+ metadata.gz: ca636402af5eb76e8588a9815c3ccd6488096fb8a25f2097663386c2ab5181eb73668a97ffa108589f1760f5e1f7f44531f121f895f171b459fc54cd421e01a2
7
+ data.tar.gz: 975028818d776f606acd2a599e238229ba19292019549583b506b8a3c4bb930f61a44356a065dd52274eaa8dc5b53d7bf0112fbd53265d2a6b4bc1ddb671cf05
@@ -6,15 +6,26 @@ module PandaPal
6
6
  self.session_key ||= SecureRandom.urlsafe_base64(60)
7
7
  end
8
8
 
9
+ def cache(key, &blk)
10
+ panda_pal_session[:cache] ||= {}
11
+ panda_pal_session[:cache][key] ||= blk.call
12
+ end
13
+
14
+ def launch_params
15
+ data[:launch_params] || {}
16
+ end
17
+
9
18
  def lti_platform
10
19
  return nil unless data[:lti_platform].present?
11
20
 
12
21
  @lti_platform ||= Platform.from_serialized(data[:lti_platform])
13
22
  end
14
23
 
15
- def custom_lti_params
16
- launch_params = data[:launch_params] || {}
24
+ def lti_launch_placement
25
+ launch_params['https://www.instructure.com/placement'] || launch_params[:launch_type]
26
+ end
17
27
 
28
+ def custom_lti_params
18
29
  # LT 1.3
19
30
  custom_params = launch_params["https://purl.imsglobal.org/spec/lti/claim/custom"]
20
31
  return custom_params if custom_params.present?
@@ -29,6 +40,113 @@ module PandaPal
29
40
  custom_params.with_indifferent_access
30
41
  end
31
42
 
43
+ def get_lti_cust_param(key)
44
+ nkey = key.to_s.gsub(/^custom_/, '')
45
+
46
+ launch_params.dig("https://purl.imsglobal.org/spec/lti/claim/custom", nkey) || launch_params[nkey] || launch_params["custom_#{nkey}"]
47
+ end
48
+
49
+ def canvas_role_labels
50
+ labels = get_lti_cust_param('custom_canvas_role')
51
+ labels.is_a?(String) ? labels.split(',') : []
52
+ end
53
+
54
+ def canvas_account_role_labels(account = 'self')
55
+ account = 'self' if account.to_s == "root"
56
+ account = account.canvas_id if account.respond_to?(:canvas_id)
57
+
58
+ if "::Admin".safe_constantize && ::Admin < ::ActiveRecord::Base
59
+ account = current_organization.canvas_account_id if account == 'self'
60
+ adm_query = ::Admin.where(canvas_account_id: account, workflow_state: "active")
61
+ adm_query.pluck(:role_name)
62
+ else
63
+ Rails.cache.fetch([self.class.name, "AccountAdminLinks", account, canvas_user_id], expires_in: 1.hour) do
64
+ admin_entries = canvas_sync_client.account_admins(account, user_id: [canvas_user_id])
65
+ admin_entries = admin_entries.select{|ent| ent[:workflow_state] == 'active' }
66
+ admin_entries.map{|ent| ent[:role] }
67
+ end
68
+ end
69
+ end
70
+
71
+ def lti_roles
72
+ @lti_roles ||= RoleStore.new(launch_params["https://purl.imsglobal.org/spec/lti/claim/roles"] || launch_params['ext_roles'] || '')
73
+ end
74
+
75
+ def canvas_site_admin?
76
+ lti_roles.system_roles.include?("sys_admin")
77
+ end
78
+
79
+ class RoleStore
80
+ ContextTypeURN = 'urn:lti:context-type:ims/lis/'.freeze
81
+
82
+ ROLE_TYPES = [
83
+ { type: "system", urn: "urn:lti:sysrole:ims/lis/", url: "http://purl.imsglobal.org/vocab/lis/v2/system/person#" },
84
+ { type: "institution", urn: "urn:lti:instrole:ims/lis/", url: "http://purl.imsglobal.org/vocab/lis/v2/institution/person#" },
85
+ { type: "context", urn: "urn:lti:role:ims/lis/", url: "http://purl.imsglobal.org/vocab/lis/v2/membership#" },
86
+ ]
87
+
88
+ attr_accessor :roles, :context_types, :other_roles
89
+
90
+ def initialize(roles = '')
91
+ roles = roles.split(',') if roles.is_a?(String)
92
+ @roles = roles || []
93
+
94
+ @context_types = []
95
+ @other_roles = []
96
+ @parsed_roles = HashWithIndifferentAccess.new
97
+
98
+ map_roles
99
+ end
100
+
101
+ def system_roles; @parsed_roles[:system] || []; end
102
+ def institution_roles; @parsed_roles[:institution] || []; end
103
+ def context_roles; @parsed_roles[:context] || []; end
104
+
105
+ def to_h
106
+ {
107
+ 'roles' => roles,
108
+ 'context_type' => context_types,
109
+ 'system_roles' => system_roles,
110
+ 'institution_roles' => institution_roles,
111
+ 'context_roles' => context_roles
112
+ }
113
+ end
114
+
115
+ protected
116
+
117
+ def map_roles
118
+ roles.each do |role|
119
+ if role.downcase.include?(ContextTypeURN)
120
+ context_types << clean_role(ContextTypeURN, role)
121
+ elsif (simple_role, type = match_role(role)).present?
122
+ (@parsed_roles[type[:type]] ||= []) << simple_role
123
+ else
124
+ other_roles << role
125
+ end
126
+ end
127
+ end
128
+
129
+ def match_role(role)
130
+ ROLE_TYPES.each do |rt|
131
+ # LIS V1
132
+ if role.downcase.start_with?(rt[:urn])
133
+ return clean_role(ContextTypeURN, role), rt
134
+ end
135
+
136
+ # LIS V2
137
+ if role.downcase.start_with?(rt[:url])
138
+ return role.split('#')[1].underscore, rt
139
+ end
140
+ end
141
+
142
+ nil
143
+ end
144
+
145
+ def clean_role(urn_prefix, role)
146
+ role.gsub(/#{Regexp.quote(urn_prefix)}/i, '').gsub('/', '').underscore
147
+ end
148
+ end
149
+
32
150
  class DataSerializer
33
151
  def self.load(str)
34
152
  return {} unless str.present?
@@ -2,8 +2,10 @@
2
2
  <html>
3
3
  <head>
4
4
  <title>PandaPal</title>
5
- <%= stylesheet_link_tag "panda_pal/application", media: "all" %>
6
- <%= javascript_include_tag "panda_pal/application" %>
5
+ <% if defined? Sprockets%>
6
+ <%= stylesheet_link_tag "panda_pal/application", media: "all" %>
7
+ <%= javascript_include_tag "panda_pal/application" %>
8
+ <% end %>
7
9
  <%= csrf_meta_tags %>
8
10
  </head>
9
11
  <body>
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PandaPal::Concerns
4
+ module AbilityHelper
5
+ extend ActiveSupport::Concern
6
+
7
+ # @return PandaPal::Session
8
+ def panda_pal_session
9
+ @panda_pal_session ||= begin
10
+ raise "Ability class needs to set @panda_pal_session or @controller to use this feature" unless @controller.present?
11
+ @controller.current_session
12
+ end
13
+ end
14
+
15
+ def rails_session
16
+ @rails_session ||= begin
17
+ raise "Ability class needs to set @rails_session or @controller to use this feature" unless @controller.present?
18
+ @controller.session
19
+ end
20
+ end
21
+
22
+ def is_lti_launch?
23
+ panda_pal_session.present?
24
+ end
25
+
26
+ def launch_params
27
+ @launch_params ||= panda_pal_session[:launch_params] || {}
28
+ end
29
+
30
+ def canvas_site_admin?
31
+ panda_pal_session.canvas_site_admin?
32
+ end
33
+ end
34
+ end
@@ -210,6 +210,7 @@ module PandaPal
210
210
  OAUTH_10_SUPPORT = true
211
211
  ActiveSupport.on_load(:action_controller) do
212
212
  include PandaPal::Helpers::ControllerHelper
213
+ include PandaPal::Concerns::AbilityHelper
213
214
  end
214
215
  end
215
216
 
@@ -1,3 +1,3 @@
1
1
  module PandaPal
2
- VERSION = "5.9.7"
2
+ VERSION = "5.9.8.beta1"
3
3
  end
data/lib/panda_pal.rb CHANGED
@@ -4,6 +4,8 @@ require 'panda_pal/helpers'
4
4
  require 'oauth/request_proxy/rack_request'
5
5
  require 'oauth/request_proxy/action_dispatch_request'
6
6
 
7
+ Dir[File.dirname(__FILE__) + "/panda_pal/concerns/**/*.rb"].each { |file| require file }
8
+
7
9
  module PandaPal
8
10
  class LtiNavigationInUse < StandardError;end
9
11
  class NotMounted < StandardError;end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: panda_pal
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.9.7
4
+ version: 5.9.8.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Instructure CustomDev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-21 00:00:00.000000000 Z
11
+ date: 2024-04-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -282,7 +282,7 @@ dependencies:
282
282
  - - '='
283
283
  - !ruby/object:Gem::Version
284
284
  version: 2.7.1
285
- description:
285
+ description:
286
286
  email:
287
287
  - pseng@instructure.com
288
288
  executables: []
@@ -333,6 +333,7 @@ files:
333
333
  - db/migrate/20171205194657_remove_old_organization_settings.rb
334
334
  - db/migrate/20220721095653_create_panda_pal_api_calls.rb
335
335
  - lib/panda_pal.rb
336
+ - lib/panda_pal/concerns/ability_helper.rb
336
337
  - lib/panda_pal/engine.rb
337
338
  - lib/panda_pal/helpers.rb
338
339
  - lib/panda_pal/helpers/console_helpers.rb
@@ -393,7 +394,7 @@ homepage: http://instructure.com
393
394
  licenses:
394
395
  - MIT
395
396
  metadata: {}
396
- post_install_message:
397
+ post_install_message:
397
398
  rdoc_options: []
398
399
  require_paths:
399
400
  - lib
@@ -408,52 +409,52 @@ required_rubygems_version: !ruby/object:Gem::Requirement
408
409
  - !ruby/object:Gem::Version
409
410
  version: '0'
410
411
  requirements: []
411
- rubygems_version: 3.1.6
412
- signing_key:
412
+ rubygems_version: 3.5.4
413
+ signing_key:
413
414
  specification_version: 4
414
415
  summary: LTI mountable engine
415
416
  test_files:
416
- - spec/rails_helper.rb
417
- - spec/models/panda_pal/api_call_spec.rb
418
- - spec/models/panda_pal/organization_spec.rb
419
- - spec/models/panda_pal/session_spec.rb
420
- - spec/models/panda_pal/organization/settings_validation_spec.rb
421
- - spec/models/panda_pal/organization/task_scheduling_spec.rb
422
417
  - spec/controllers/panda_pal/api_call_controller_spec.rb
423
- - spec/spec_helper.rb
424
- - spec/dummy/db/schema.rb
425
- - spec/dummy/public/422.html
426
- - spec/dummy/public/favicon.ico
427
- - spec/dummy/public/404.html
428
- - spec/dummy/public/500.html
418
+ - spec/dummy/README.rdoc
429
419
  - spec/dummy/Rakefile
430
- - spec/dummy/app/views/layouts/application.html.erb
420
+ - spec/dummy/app/assets/javascripts/application.js
421
+ - spec/dummy/app/assets/stylesheets/application.css
431
422
  - spec/dummy/app/controllers/application_controller.rb
432
423
  - spec/dummy/app/helpers/application_helper.rb
433
- - spec/dummy/app/assets/stylesheets/application.css
434
- - spec/dummy/app/assets/javascripts/application.js
435
- - spec/dummy/config/secrets.yml
424
+ - spec/dummy/app/views/layouts/application.html.erb
425
+ - spec/dummy/bin/bundle
426
+ - spec/dummy/bin/rails
427
+ - spec/dummy/bin/rake
428
+ - spec/dummy/bin/setup
436
429
  - spec/dummy/config/application.rb
437
- - spec/dummy/config/initializers/session_store.rb
438
- - spec/dummy/config/initializers/wrap_parameters.rb
439
- - spec/dummy/config/initializers/inflections.rb
440
- - spec/dummy/config/initializers/filter_parameter_logging.rb
441
- - spec/dummy/config/initializers/mime_types.rb
442
- - spec/dummy/config/initializers/backtrace_silencers.rb
443
- - spec/dummy/config/initializers/cookies_serializer.rb
444
- - spec/dummy/config/environments/development.rb
445
- - spec/dummy/config/environments/test.rb
446
- - spec/dummy/config/environments/production.rb
447
- - spec/dummy/config/database.yml
448
430
  - spec/dummy/config/boot.rb
449
- - spec/dummy/config/routes.rb
431
+ - spec/dummy/config/database.yml
450
432
  - spec/dummy/config/environment.rb
433
+ - spec/dummy/config/environments/development.rb
434
+ - spec/dummy/config/environments/production.rb
435
+ - spec/dummy/config/environments/test.rb
436
+ - spec/dummy/config/initializers/backtrace_silencers.rb
437
+ - spec/dummy/config/initializers/cookies_serializer.rb
438
+ - spec/dummy/config/initializers/filter_parameter_logging.rb
439
+ - spec/dummy/config/initializers/inflections.rb
440
+ - spec/dummy/config/initializers/mime_types.rb
441
+ - spec/dummy/config/initializers/session_store.rb
442
+ - spec/dummy/config/initializers/wrap_parameters.rb
451
443
  - spec/dummy/config/locales/en.yml
452
- - spec/dummy/README.rdoc
444
+ - spec/dummy/config/routes.rb
445
+ - spec/dummy/config/secrets.yml
453
446
  - spec/dummy/config.ru
454
- - spec/dummy/bin/bundle
455
- - spec/dummy/bin/rake
456
- - spec/dummy/bin/setup
457
- - spec/dummy/bin/rails
447
+ - spec/dummy/db/schema.rb
448
+ - spec/dummy/public/404.html
449
+ - spec/dummy/public/422.html
450
+ - spec/dummy/public/500.html
451
+ - spec/dummy/public/favicon.ico
458
452
  - spec/factories/panda_pal_organizations.rb
459
453
  - spec/factories/panda_pal_sessions.rb
454
+ - spec/models/panda_pal/api_call_spec.rb
455
+ - spec/models/panda_pal/organization/settings_validation_spec.rb
456
+ - spec/models/panda_pal/organization/task_scheduling_spec.rb
457
+ - spec/models/panda_pal/organization_spec.rb
458
+ - spec/models/panda_pal/session_spec.rb
459
+ - spec/rails_helper.rb
460
+ - spec/spec_helper.rb