atomic_lti 1.7.0 → 1.8.0

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: 265fc192cec38bb2a8dbac1f8fc4eaf3388f9240de43f5558ea28f52c3272047
4
- data.tar.gz: cd5cbbb67fc5f2bed2cf959421321aae77a0a8a73504c6ff3a1729d7e78bc8e2
3
+ metadata.gz: 9657315417130b6c1e170190e55603fff1aa97f2285518fa47645b6586b63c64
4
+ data.tar.gz: 5cc81825d70b45eb8d2de538b60ead7ac77742bf57f974762e9ab199d9101004
5
5
  SHA512:
6
- metadata.gz: 8b5c6de47055ebad0a7dfb6a8a8bfeb3f5fdf4598799bd0ed6805ae6c665282bf37130a6a8e37c31cacfdfb77bc10fd8971e85592e7eaca5ae9539015decfd05
7
- data.tar.gz: 775b35f941fd47e529c68906fe47541b3c2736c0c4659179485e5e3da2492edcae02bd537d9bcd4cd621a5f99539f3b466d8f91e0584fa0f14b5fa5c381df9f9
6
+ metadata.gz: 32921bce5874ad6e3066c14f2bc984747efc06fcfb229cb43c4e8fe13026823ff42b1d5582e677d27832b3d88735cdc1e0317e7d962020b6a2b380134bbf6802
7
+ data.tar.gz: e0255a4a3671f6ab6d56041179c28592f088d61f67d1c07632f374aba83657bb7831f94e6ba241fc4467ae0c0122885dd8d22a7578365e49714b432fb7ce5b00
@@ -83,7 +83,9 @@ module AtomicLti
83
83
 
84
84
  # Validate that we are at the target_link_uri
85
85
  target_link_uri = decoded_token[AtomicLti::Definitions::TARGET_LINK_URI_CLAIM]
86
- if validate_target_link_url && target_link_uri != requested_target_link_uri
86
+
87
+ if validate_target_link_url &&
88
+ !matching_uri?(target_link_uri, requested_target_link_uri, ignore_host: AtomicLti.update_target_link_host)
87
89
  errors.push(
88
90
  "LTI token target link uri '#{target_link_uri}' doesn't match url '#{requested_target_link_uri}'",
89
91
  )
@@ -123,5 +125,16 @@ module AtomicLti
123
125
  decoded_token["aud"]
124
126
  end
125
127
  end
128
+
129
+ def self.matching_uri?(target, actual, ignore_host:)
130
+ t = URI.parse(target)
131
+ a = URI.parse(actual)
132
+
133
+ t.scheme == a.scheme &&
134
+ t.path == a.path &&
135
+ t.query == a.query &&
136
+ t.fragment == a.fragment &&
137
+ (ignore_host || t.host == a.host)
138
+ end
126
139
  end
127
140
  end
@@ -31,13 +31,17 @@ module AtomicLti
31
31
  headers = { "Content-Type" => "text/html" }
32
32
  Rack::Utils.set_cookie_header!(
33
33
  headers, "#{OPEN_ID_COOKIE_PREFIX}storage",
34
- { value: "1", path: "/", max_age: 365.days, http_only: false, secure: true, same_site: "None" }
34
+ { value: "1", path: "/", max_age: 365.days, http_only: false, secure: true, same_site: "None", partitioned: true }
35
35
  )
36
36
  Rack::Utils.set_cookie_header!(
37
37
  headers, "#{OPEN_ID_COOKIE_PREFIX}#{state}",
38
- { value: 1, path: "/", max_age: 1.minute, http_only: false, secure: true, same_site: "None" }
38
+ { value: 1, path: "/", max_age: 1.minute, http_only: false, secure: true, same_site: "None", partitioned: true }
39
39
  )
40
40
 
41
+ # Ensure our cookies are partitioned. This can be removed once our Rack version
42
+ # understands the partitioned: argument above.
43
+ headers[Rack::SET_COOKIE] = partition_cookies(headers[Rack::SET_COOKIE])
44
+
41
45
  redirect_uri = [request.base_url, AtomicLti.oidc_redirect_path].join
42
46
  response_url = build_oidc_response(request, state, nonce, redirect_uri)
43
47
 
@@ -111,6 +115,13 @@ module AtomicLti
111
115
  target_link_uri = id_token_decoded[AtomicLti::Definitions::TARGET_LINK_URI_CLAIM] ||
112
116
  File.join("#{uri.scheme}://#{uri.host}", AtomicLti.default_deep_link_path)
113
117
 
118
+ target = URI.parse(target_link_uri)
119
+
120
+ # Optionally update the target link host to match the redirect host
121
+ if AtomicLti.update_target_link_host && target.host != uri.host
122
+ target.host = uri.host
123
+ end
124
+
114
125
  # We want to strip out the redirect path params from the request params
115
126
  # so that we can support having the redirect path be the same as the
116
127
  # launch path, only differentiated by a query parameter. This is needed
@@ -131,7 +142,7 @@ module AtomicLti
131
142
  template: "atomic_lti/shared/redirect",
132
143
  assigns: {
133
144
  launch_params: launch_params,
134
- launch_url: target_link_uri,
145
+ launch_url: target,
135
146
  },
136
147
  )
137
148
 
@@ -363,5 +374,30 @@ module AtomicLti
363
374
  platformOIDCUrl: platform.oidc_url,
364
375
  }.compact
365
376
  end
377
+
378
+ def partition_cookies(header)
379
+ # Some versions of rack add multiple cookies as a newline-separated string, and others
380
+ # as an array of strings.
381
+ case header
382
+ when String
383
+ header.split("\n").map do |cookie|
384
+ if !cookie.match? /partitioned/i
385
+ "#{cookie}; partitioned"
386
+ else
387
+ cookie
388
+ end
389
+ end.join("\n")
390
+ when Array
391
+ header.map do |cookie|
392
+ if !cookie.match? /partitioned/i
393
+ "#{cookie}; partitioned"
394
+ else
395
+ cookie
396
+ end
397
+ end
398
+ else
399
+ header
400
+ end
401
+ end
366
402
  end
367
403
  end
@@ -1,3 +1,3 @@
1
1
  module AtomicLti
2
- VERSION = "1.7.0".freeze
2
+ VERSION = "1.8.0".freeze
3
3
  end
data/lib/atomic_lti.rb CHANGED
@@ -32,6 +32,12 @@ module AtomicLti
32
32
  # requires this, but Canvas doesn't currently support it.
33
33
  mattr_accessor :set_post_message_origin, default: false
34
34
 
35
+ # Set to true to update the target link uri host to match the oidc redirect host.
36
+ # Enable this when a single LTI install needs to support launches across multiple hosts.
37
+ # Setting this avoids state validation problems on launch since state cookies and
38
+ # postMessage storage won't work across different hosts.
39
+ mattr_accessor :update_target_link_host, default: false
40
+
35
41
  mattr_accessor :privacy_policy_url, default: "#"
36
42
  mattr_accessor :privacy_policy_message, default: nil
37
43
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: atomic_lti
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 1.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Petro
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-12-26 00:00:00.000000000 Z
13
+ date: 2024-01-26 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: pg
@@ -133,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
133
133
  - !ruby/object:Gem::Version
134
134
  version: '0'
135
135
  requirements: []
136
- rubygems_version: 3.4.19
136
+ rubygems_version: 3.4.10
137
137
  signing_key:
138
138
  specification_version: 4
139
139
  summary: AtomicLti implements the LTI Advantage specification.