panda_pal 5.14.0.beta4 → 5.14.0.beta5

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: 2d4a90a987ce86beeffae59c66c350d8c1c3f4e4d0f18c63379a9f7e7014bc26
4
- data.tar.gz: ea34c39f969a62ba8ce313fb316b6ae54dc6db3c6027dd683ad67191708484c6
3
+ metadata.gz: 3ca8324d890b7a0caa25e8b31216b21b441e1dd23003903c873ff34545b482bc
4
+ data.tar.gz: 4fbf36729ddb999aadad92c6b887ff9c731b81bbf97cb4eca434bfbae54d7c0f
5
5
  SHA512:
6
- metadata.gz: 61f3853d04463655267c9107c07f819858daf4f21f06724a2e4d1a84623c74be983f9f69040f9cd7dc9231efef51f3b806e2390028fe7fcab7feb2ae0d4ef469
7
- data.tar.gz: d68ed40aac052cecf6d972f201c949fc8766e365eecfb5ea7c0dbb835d477ee81ba26f0756e048250edd36ef029b83203a2fab6e57738dee9ff03b3aa23520bc
6
+ metadata.gz: dff58f780e6b55d11447d2844735c211380db9a9932b924e4cdd570a4f67c29a12d5b7f6097eac4df2792faa4bdc6ef23f4c18521348b0be1fdab65081076903
7
+ data.tar.gz: 2e6fba74bc5d48f2a32b316045ee070046704dfc81838762a43484a042b9cde1183cff6531041813dcd8787ae9db3dbf52775e3730e4b3f6ec830e9a9a8ad510
@@ -9,7 +9,6 @@ module PandaPal
9
9
  end
10
10
 
11
11
  before_action ->{ validate_launch!(version: :v1p3) }, only: [:resource_link_request]
12
- around_action :switch_tenant, only: [:resource_link_request]
13
12
  before_action :enforce_environment!, only: [:resource_link_request]
14
13
 
15
14
  # Redirect to beta/test as necessary
@@ -58,15 +58,16 @@ module PandaPal
58
58
  class ::Object
59
59
  unless defined?(switch_tenant)
60
60
  def switch_tenant(tenant, &block)
61
- if tenant.to_s.include?(":")
61
+ if tenant.is_a?(PandaPal::Organization)
62
+ org.switch_tenant(&block)
63
+ elsif (org = PandaPal::Organization.find_by(name: tenant)).present?
64
+ org.switch_tenant(&block)
65
+ else
62
66
  if block_given?
63
67
  Apartment::Tenant.switch(tenant, &block)
64
68
  else
65
69
  Apartment::Tenant.switch!(tenant)
66
70
  end
67
- else
68
- org = PandaPal::Organization.find_by(name: tenant)
69
- org.switch_tenant(&block)
70
71
  end
71
72
  end
72
73
  end
@@ -69,39 +69,41 @@ module PandaPal::Helpers
69
69
  def validate_v1p3_launch
70
70
  require "json/jwt"
71
71
 
72
- decoded_jwt = JSON::JWT.decode(params.require(:id_token), :skip_verification)
73
- raise JSON::JWT::VerificationFailed, 'error decoding id_token' if decoded_jwt.blank?
72
+ switch_tenant("public") do
73
+ decoded_jwt = JSON::JWT.decode(params.require(:id_token), :skip_verification)
74
+ raise JSON::JWT::VerificationFailed, 'error decoding id_token' if decoded_jwt.blank?
74
75
 
75
- client_id = decoded_jwt['aud']
76
- deployment_id = decoded_jwt['https://purl.imsglobal.org/spec/lti/claim/deployment_id']
76
+ client_id = decoded_jwt['aud']
77
+ deployment_id = decoded_jwt['https://purl.imsglobal.org/spec/lti/claim/deployment_id']
77
78
 
78
- if deployment_id.present?
79
- @organization ||= PandaPal::Organization.find_by(key: "#{client_id}/#{deployment_id}")
80
- @organization ||= PandaPal::Organization.find_by(key: deployment_id)
81
- end
79
+ if deployment_id.present?
80
+ @organization ||= PandaPal::Organization.find_by(key: "#{client_id}/#{deployment_id}")
81
+ @organization ||= PandaPal::Organization.find_by(key: deployment_id)
82
+ end
82
83
 
83
- @organization ||= PandaPal::Organization.find_by(key: client_id)
84
+ @organization ||= PandaPal::Organization.find_by(key: client_id)
84
85
 
85
- params[:session_key] = params[:state]
86
+ params[:session_key] = params[:state]
86
87
 
87
- raise JSON::JWT::VerificationFailed, 'Unrecognized Organization' unless @organization.present?
88
- raise JSON::JWT::VerificationFailed, 'Organization does not trust platform' unless @organization.trusted_platform?(current_lti_platform)
88
+ raise JSON::JWT::VerificationFailed, 'Unrecognized Organization' unless @organization.present?
89
+ raise JSON::JWT::VerificationFailed, 'Organization does not trust platform' unless @organization.trusted_platform?(current_lti_platform)
89
90
 
90
- begin
91
- decoded_jwt.verify!(current_lti_platform.public_jwks)
92
- rescue JSON::JWK::Set::KidNotFound
93
- decoded_jwt.verify!(current_lti_platform.public_jwks(force: true))
94
- end
91
+ begin
92
+ decoded_jwt.verify!(current_lti_platform.public_jwks)
93
+ rescue JSON::JWK::Set::KidNotFound
94
+ decoded_jwt.verify!(current_lti_platform.public_jwks(force: true))
95
+ end
95
96
 
96
- raise JSON::JWT::VerificationFailed, 'State is invalid' unless current_panda_session.panda_pal_organization_id == 0
97
- raise JSON::JWT::VerificationFailed, 'State is invalid' unless current_panda_session[:lti_oauth_nonce] == decoded_jwt['nonce']
97
+ raise JSON::JWT::VerificationFailed, 'State is invalid' unless current_panda_session.panda_pal_organization_id == 0
98
+ raise JSON::JWT::VerificationFailed, 'State is invalid' unless current_panda_session[:lti_oauth_nonce] == decoded_jwt['nonce']
98
99
 
99
- jwt_verifier = PandaPal::LtiJwtValidator.new(decoded_jwt, client_id)
100
- raise JSON::JWT::VerificationFailed, jwt_verifier.errors unless jwt_verifier.valid?
100
+ jwt_verifier = PandaPal::LtiJwtValidator.new(decoded_jwt, client_id)
101
+ raise JSON::JWT::VerificationFailed, jwt_verifier.errors unless jwt_verifier.valid?
101
102
 
102
- # Migrate the session to the correct tenant
103
- login_session = current_panda_session
104
- login_session.delete
103
+ # Migrate the session to the correct tenant
104
+ login_session = current_panda_session
105
+ login_session.delete
106
+ end
105
107
 
106
108
  @organization.switch_tenant
107
109
 
@@ -126,8 +128,7 @@ module PandaPal::Helpers
126
128
  def switch_tenant(organization = current_organization, &block)
127
129
  return unless organization
128
130
  raise 'This method should be called in an around_action callback' unless block_given?
129
-
130
- organization.switch_tenant(&block)
131
+ super
131
132
  end
132
133
 
133
134
  def forbid_access_if_lacking_session
@@ -58,6 +58,7 @@ module PandaPal::Helpers
58
58
 
59
59
  if type == 'KEY'
60
60
  @current_session = PandaPal::Session.find_by(session_secret: sig)
61
+ raise SessionNonceMismatch, "Session Not Found" unless @current_session.present?
61
62
  raise SessionNonceMismatch, "Session Not Found" if session_id && @current_session.id != session_id
62
63
  else
63
64
  session_record = PandaPal::Session.find_by(id: session_id)
@@ -76,6 +77,9 @@ module PandaPal::Helpers
76
77
  raise SessionNonceMismatch, "Invalid Method" unless request.method == :get
77
78
 
78
79
  # Verify the signature against the request URL
80
+ # The usig doesn't _need_ to be signed (since it's part of the payload that is already signed),
81
+ # but this was an easy way to make the value a constant length. Any basic hashing function could solve this,
82
+ # but the HMAC implementation was already available.
79
83
  resigned = generate_signed_url(session_record.signing_key, request.url)
80
84
  raise SessionNonceMismatch, "Invalid Signature" unless resigned == decoded_header['usig']
81
85
 
@@ -85,6 +89,7 @@ module PandaPal::Helpers
85
89
  elsif type == "T-NONCE"
86
90
  raise SessionNonceMismatch, "Invalid Nonce" unless session_record.data[:link_nonce] == decoded_header['nnc']
87
91
  @current_session = session_record
92
+ @current_session.data[:link_nonce] = nil
88
93
  elsif type == "T-IP"
89
94
  raise SessionNonceMismatch, "Invalid IP" unless decoded_header["ip"] == request.remote_ip
90
95
  @current_session = session_record
@@ -1,3 +1,3 @@
1
1
  module PandaPal
2
- VERSION = "5.14.0.beta4"
2
+ VERSION = "5.14.0.beta5"
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.14.0.beta4
4
+ version: 5.14.0.beta5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Instructure CustomDev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-18 00:00:00.000000000 Z
11
+ date: 2025-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails