panda_pal 5.6.7 → 5.6.8

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
2
  SHA256:
3
- metadata.gz: c335f4ab51dec72916a2a630af60dbbed1f681bcd220cbf4585f5291127ca8ac
4
- data.tar.gz: 3031b40de1ba6899077609843b1ed57d30cec38867f68f3c9c45281affea54c2
3
+ metadata.gz: 868d32b3e1b91a944db8d066378cdf2a130945e321679f72e8f3b126b11082b7
4
+ data.tar.gz: 73bce1c742d141276429bec08538ae1dc61785f43ea211da53389e3305f3072b
5
5
  SHA512:
6
- metadata.gz: 7c225b256e06497ddc5ca6faf9604a28cb9290d0b37911ad39ac00e88beb2d3041541d758e55e992608db79ca9b5249c8aaf0ca69310b651f6635095fc7a2650
7
- data.tar.gz: 7d2e7c371bd4bab83ee8c2e001d8affc48d0f5e88b2c21476b181c134a37de9db535c527b41812759eef0d0b96cc7d6bb3a427ef7187f5bc9d3efca145f59838
6
+ metadata.gz: 919ee52b9e3038f9f44141dbba685fd2051a6ce4b1e81ddba5f5ab90063e2979c8471f1e24714b961454f86589a282d645c6ad6628829b97494a8620c3619ca4
7
+ data.tar.gz: 7a3b5a810c65a57fd5ce42d9b805dbb58469972cfb94f54a93c5f74bce3a87fe40c3c76fa0fd63fc008e1effb791086c559e4fe59bec537b21c6baac13e614f8
@@ -50,7 +50,10 @@ module PandaPal
50
50
  api_call_id: id,
51
51
  organization_id: Organization.current&.id,
52
52
  }
53
- payload[:exp] = expiration.iso8601 if expiration.present?
53
+ if expiration.present?
54
+ expiration = DateTime.parse(expiration) if expiration.is_a?(String)
55
+ payload[:exp] = expiration.iso8601
56
+ end
54
57
  ::JWT.encode(payload, Rails.application.secret_key_base, 'HS256')
55
58
  end
56
59
 
@@ -74,8 +74,6 @@ module PandaPal
74
74
  end
75
75
 
76
76
  def validate_settings
77
- return unless defined?(Rails::Console)
78
-
79
77
  validate_settings_level(settings || {}, settings_structure).each do |err|
80
78
  errors[:settings] << err
81
79
  end
@@ -28,7 +28,7 @@ module PandaPal
28
28
  module OrgExtension
29
29
  extend ActiveSupport::Concern
30
30
 
31
- def install_lti(host: nil, context: :root_account, version: 'v1p1', exists: :error)
31
+ def install_lti(host: nil, context: :root_account, version: 'v1p3', exists: :error, dedicated_deployment: false)
32
32
  raise "Automatically installing this LTI requires Bearcat." unless defined?(Bearcat)
33
33
 
34
34
  context = context.to_s
@@ -36,8 +36,101 @@ module PandaPal
36
36
  cid, ctype = context.split(/[\.\/]/).reverse
37
37
  ctype ||= 'account'
38
38
 
39
+ if version == 'v1p0'
40
+ existing_installs = _find_existing_installs(exists: exists) do |lti|
41
+ lti[:consumer_key] == self.key
42
+ end
43
+
44
+ conf = {
45
+ name: PandaPal.lti_options[:title],
46
+ description: PandaPal.lti_options[:description],
47
+ consumer_key: self.key,
48
+ shared_secret: self.secret,
49
+ privacy_level: "public",
50
+ config_type: 'by_url',
51
+ config_url: PandaPal::LaunchUrlHelpers.resolve_route(:v1p0_config_url, host: host),
52
+ }
53
+
54
+ bearcat_client.send(:"create_#{ctype}_external_tool", cid, conf)
55
+ elsif version == 'v1p3'
56
+ ekey = _ensure_lti_v1p3_key(exists: exists)
57
+
58
+ existing_installs = _find_existing_installs(exists: exists) do |lti|
59
+ lti[:developer_key_id] == (ekey[:id] % 10_000_000_000_000)
60
+ end
61
+
62
+ scope_tool = bearcat_client.send(:"create_#{ctype}_external_tool", cid, {
63
+ client_id: ekey[:id],
64
+ })
65
+
66
+ new_client_id = "#{ekey[:id]}"
67
+ new_client_id += "/#{scope_tool[:deployment_id]}" if dedicated_deployment
68
+
69
+ self.key = new_client_id
70
+ self.secret = ekey[:api_key]
71
+
72
+ save! if changed!
73
+ else
74
+ raise "Unrecognized LTI Version #{version}"
75
+ end
76
+ end
77
+
78
+ def _ensure_lti_v1p3_key(exists:)
79
+ current_client_id = self.key.split('/')[0]
80
+
81
+ existing_keys = []
82
+ existing_keys += bearcat_client.get("api/v1/accounts/self/developer_keys?per_page=100").filter do |devkey|
83
+ devkey[:id].to_s == current_client_id
84
+ end
85
+ existing_keys += bearcat_client.get("api/v1/accounts/self/developer_keys?per_page=100", inherited: true).filter do |devkey|
86
+ devkey[:id].to_s == current_client_id
87
+ end
88
+
89
+ ekey = existing_keys[0]
90
+ # if ekey && exists == :error
91
+ # raise "Tool with key #{self.key} already installed"
92
+ # end
93
+
94
+ lti_json_url = PandaPal::LaunchUrlHelpers.resolve_route(:v1p3_config_url, host: host)
95
+ lti_json = JSON.parse(HTTParty.get(lti_json_url, format: :plain).body)
96
+
97
+ if !ekey
98
+ # Create New
99
+ ekey = bearcat_client.post("api/lti/accounts/self/developer_keys/tool_configuration", {
100
+ developer_key: {
101
+ name: PandaPal.lti_options[:title],
102
+ redirect_uris: [
103
+ lti_json["target_link_uri"],
104
+ ].join("\n")
105
+ },
106
+ tool_configuration: {
107
+ settings: lti_json,
108
+ },
109
+ })
110
+ elsif exists == :replace || exists == :update
111
+ # Update Existing
112
+ ekey = bearcat_client.put("api/lti/developer_keys/#{ekey[:id]}/tool_configuration", {
113
+ developer_key: ekey[:developer_key],
114
+ tool_configuration: lti_json,
115
+ })
116
+ end
117
+
118
+ ekey = ekey[:developer_key] || ekey
119
+
120
+ if ekey[:developer_key_account_binding][:workflow_state] == "off"
121
+ bearcat_client.post("api/v1/accounts/self/developer_keys/#{ekey[:id]}/developer_key_account_bindings", {
122
+ developer_key_account_binding: {
123
+ workflow_state: "on",
124
+ },
125
+ })
126
+ end
127
+
128
+ ekey
129
+ end
130
+
131
+ def _find_existing_installs(exists:, &matcher)
39
132
  existing_installs = bearcat_client.send(:"#{ctype}_external_tools", cid).all_pages_each.filter do |cet|
40
- cet[:consumer_key] == self.key
133
+ matcher.call(cet)
41
134
  end
42
135
 
43
136
  if existing_installs.present?
@@ -54,19 +147,7 @@ module PandaPal
54
147
  end
55
148
  end
56
149
 
57
- # TODO LTI 1.3 Support
58
-
59
- conf = {
60
- name: PandaPal.lti_options[:title],
61
- description: PandaPal.lti_options[:description],
62
- consumer_key: self.key,
63
- shared_secret: self.secret,
64
- privacy_level: "public",
65
- config_type: 'by_url',
66
- config_url: PandaPal::LaunchUrlHelpers.resolve_route(:v1p0_config_url, host: host),
67
- }
68
-
69
- bearcat_client.send(:"create_#{ctype}_external_tool", cid, conf)
150
+ existing_installs
70
151
  end
71
152
 
72
153
  def reinstall_lti!(*args, **kwargs)
@@ -49,6 +49,58 @@ module PandaPal
49
49
  end
50
50
  end
51
51
 
52
+ initializer "panda_pal.globals" do |app|
53
+ class ::Object
54
+ unless defined?(switch_tenant)
55
+ def switch_tenant(tenant, &block)
56
+ if block_given?
57
+ Apartment::Tenant.switch(tenant, &block)
58
+ else
59
+ Apartment::Tenant.switch!(tenant)
60
+ end
61
+ end
62
+ end
63
+
64
+ unless defined?(current_organization)
65
+ def current_organization
66
+ PandaPal::Organization.find_by_name(Apartment::Tenant.current)
67
+ end
68
+ end
69
+ end
70
+ end
71
+
72
+ initializer "panda_pal.autoswitch" do |app|
73
+ class ::Object
74
+ def _panda_pal_console_autoswitch_tenant
75
+ org = nil
76
+ if Rails.env.development?
77
+ org = PandaPal::Organization.find_by(name: 'local') || PandaPal::Organization.first
78
+ elsif PandaPal::Organization.count == 1
79
+ org = PandaPal::Organization.first
80
+ end
81
+
82
+ if org
83
+ org.switch_tenant
84
+ puts "PandaPal: Auto Switched to tenant '#{org.name}'"
85
+ end
86
+ rescue => err
87
+ puts "PadaPal: Error occurred auto-switching tenant: #{err}"
88
+ end
89
+ end
90
+
91
+ module Rails::ConsoleMethods
92
+ def self.included(base)
93
+ _panda_pal_console_autoswitch_tenant
94
+ end
95
+ end
96
+
97
+ if defined?(Pry)
98
+ Pry.hooks.add_hook(:before_session, "switch PandaPal tenant") do |output, binding, pry|
99
+ _panda_pal_console_autoswitch_tenant
100
+ end
101
+ end
102
+ end
103
+
52
104
  initializer "panda_pal.serialze_symbols" do |app|
53
105
  app.config.active_record.yaml_column_permitted_classes ||= []
54
106
  app.config.active_record.yaml_column_permitted_classes |= [Symbol]
@@ -1,4 +1,5 @@
1
1
  module PandaPal::Helpers
2
+ require_relative 'helpers/misc_helper'
2
3
  require_relative 'helpers/controller_helper'
3
4
  require_relative 'helpers/route_helper'
4
5
  require_relative 'helpers/secure_headers'
@@ -1,3 +1,3 @@
1
1
  module PandaPal
2
- VERSION = "5.6.7"
2
+ VERSION = "5.6.8"
3
3
  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.6.7
4
+ version: 5.6.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Instructure ProServe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-27 00:00:00.000000000 Z
11
+ date: 2023-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -309,7 +309,6 @@ files:
309
309
  - app/lib/lti_xml/canvas_platform.rb
310
310
  - app/lib/panda_pal/launch_url_helpers.rb
311
311
  - app/lib/panda_pal/lti_jwt_validator.rb
312
- - app/lib/panda_pal/misc_helper.rb
313
312
  - app/models/panda_pal/api_call.rb
314
313
  - app/models/panda_pal/organization.rb
315
314
  - app/models/panda_pal/organization_concerns/settings_validation.rb
@@ -335,6 +334,7 @@ files:
335
334
  - lib/panda_pal/engine.rb
336
335
  - lib/panda_pal/helpers.rb
337
336
  - lib/panda_pal/helpers/controller_helper.rb
337
+ - lib/panda_pal/helpers/misc_helper.rb
338
338
  - lib/panda_pal/helpers/route_helper.rb
339
339
  - lib/panda_pal/helpers/secure_headers.rb
340
340
  - lib/panda_pal/helpers/session_replacement.rb