canvas_lti_third_party_cookies 0.2.0 → 0.3.3

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: 18685ffb4c05fd45f61a6e2e739fe93b4b2e9e8573e72eb07bb8d026cdb7889d
4
- data.tar.gz: 1cf0160c9d86c39975abb6b64f24ca518ea052625738c904876103ad565a6e01
3
+ metadata.gz: 8d622f96431568706549721c48a8cab10edd7f21790f739d612f2af1e649a686
4
+ data.tar.gz: b0a008358a161f117a9c828975ac40e642a93af253cbd34b4ae3f2abf4890efb
5
5
  SHA512:
6
- metadata.gz: e770cba91ab52316550435e6f1bac4708b292b834f73ea5028da56ec92f6d86d7107f7f0f77c6c0e8da9bc8624b59cc40c837ca32cf0cc19e4215ff164dad249
7
- data.tar.gz: 3a3f448a4ed8ff5e401d913c913207943576c5335c10299d29aad5c08859f581f5e58f2e42bb98cc0aa44ad080f5f41b99d58971ba0546e41c70ba0eeb8653b3
6
+ metadata.gz: 076670fa98327844ceee397d68e346179d326839b831454b80c94e68a1866c43a58873d9b1c1d6032258c21e0be38d44164bd831f7a4287d7a8d9daf519688ee
7
+ data.tar.gz: 4d70af2daa01fc4fb262c01c186f581c81db4fe32c3bf7c025050fe4d9e149bd70c3430e7ce1f8f05cfaab245e3a4df4adae7a09b5b42ba6a13370dca237ed74
data/README.md CHANGED
@@ -25,19 +25,29 @@ below to run on that action, and pass the data needed.
25
25
  Usually, only query parameters *or* form data is needed, not both.
26
26
 
27
27
  ```ruby
28
- include LtiThirdPartyCookies::SafariLaunch
28
+ include CanvasLtiThirdPartyCookies::SafariLaunch
29
29
  #...
30
30
  before_action -> {
31
31
  handle_safari_launch(launch_url: action_url, launch_params: { foo: bar }, launch_data: { foo: baz })
32
32
  }
33
33
  ```
34
34
 
35
+ This will launch the tool multiple times, and also redirect the user back to Canvas when needed. For more information on the detailed tool
36
+ launches, see the comments in `app/controllers/concerns/canvas_lti_third_party_cookies/safari_launch.rb`.
37
+
38
+ Note that the tool will be relaunched from within this method once Storage Access is granted and pass all parameters from the previous
39
+ Canvas launch, which will break JWT nonce verification since it will detect the nonce has already been used.
40
+
41
+ To combat this, this gem provides the `should_ignore_nonce?` method so that your tool can ignore the nonce verification for that
42
+ specific launch. Normally, ignoring a duplicate nonce can lead to replay attacks. This method will only return true if the request's
43
+ `Referer` header matches the tool's domain, which only happens in this last internal redirect.
44
+
35
45
  ## Installation
36
46
  Add this line to your application's Gemfile:
37
47
 
38
48
  ```ruby
39
49
  # Set 3rd party cookies in Safari
40
- gem 'canvas_lti_third_party_cookies', '~> 0.2.0'
50
+ gem 'canvas_lti_third_party_cookies'
41
51
  ```
42
52
 
43
53
  And then execute:
@@ -49,4 +59,12 @@ $ bundle install
49
59
 
50
60
  ```bash
51
61
  $ rails test
52
- ```
62
+ ```
63
+
64
+ ## Publishing New Versions
65
+
66
+ 1. Bump the version in `lib/canvas_lti_third_party_cookies/version.rb`.
67
+ 2. Commit, push, and merge that change.
68
+ 3. `rake install`
69
+ 4. `gem push pkg/canvas_lti_third_party_cookies-<version>.gem`
70
+ - note that this will only work if you have access
@@ -1,6 +1,6 @@
1
1
  require 'browser'
2
2
 
3
- module LtiThirdPartyCookies::SafariLaunch
3
+ module CanvasLtiThirdPartyCookies::SafariLaunch
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  # this needs to be called as a before_action on the route that launches the tool
@@ -12,31 +12,25 @@ module LtiThirdPartyCookies::SafariLaunch
12
12
  # the `launch_data` parameter is optional, and should contain
13
13
  # all needed form data that the tool requires to launch.
14
14
  # example:
15
- # include LtiThirdPartyCookies::SafariLaunch
15
+ # include CanvasLtiThirdPartyCookies::SafariLaunch
16
16
  # ...
17
17
  # before_action -> {
18
18
  # handle_safari_launch(launch_url: action_url, launch_params: { foo: bar }, launch_data: { foo: baz })
19
19
  # }
20
20
  def handle_safari_launch(launch_url:, launch_params: {}, launch_data: {})
21
- browser = Browser.new(request.headers["User-Agent"])
22
- # detect both MacOS and iOS Safari
23
- return unless browser.safari? || (browser.webkit? && browser.platform.ios?)
21
+ return unless is_safari?
24
22
 
25
23
  # Safari launch #4: Storage Access has been granted,
26
- # so launch the app normally.
27
- if params[:storage_access_status].present?
28
- # remove from request directly instead of only from `params` so that
29
- # the tool *really* doesn't have to worry about this being present
30
- request.request_parameters.delete(:storage_access_status)
31
- return
32
- end
24
+ # so launch the app normally. Note that this is not an actual LTI launch, but
25
+ # just opaquely passing on the data from launch #3.
26
+ return if params[:storage_access_status].present?
33
27
 
34
28
  # Safari launch #2: Full-window launch, solely for first-party user interaction.
35
29
  # During a full-window launch, Canvas provides a :platform_redirect_url that
36
30
  # will launch the tool again within an iframe in Canvas. (#3)
37
31
  if params[:platform_redirect_url].present?
38
32
  return render(
39
- 'lti_third_party_cookies/full_window_launch',
33
+ 'canvas_lti_third_party_cookies/full_window_launch',
40
34
  locals: { platform_redirect_url: params[:platform_redirect_url] }
41
35
  )
42
36
  end
@@ -48,7 +42,7 @@ module LtiThirdPartyCookies::SafariLaunch
48
42
  # Pass along any parameters provided by the tool that are needed to launch correctly,
49
43
  # and tell the tool that it has Storage Access.
50
44
  render(
51
- 'lti_third_party_cookies/request_storage_access',
45
+ 'canvas_lti_third_party_cookies/request_storage_access',
52
46
  locals: {
53
47
  launch_url: launch_url,
54
48
  relaunch_url: relaunch_url(launch_url, launch_params),
@@ -57,8 +51,24 @@ module LtiThirdPartyCookies::SafariLaunch
57
51
  )
58
52
  end
59
53
 
54
+ # Safari launch #4 (described above) is actually an internal opaque redirect of launch #3
55
+ # and not a real Canvas LTI launch, so the id_token (and specifically the nonce inside)
56
+ # is exactly the same. Normally, ignoring the nonce is a Bad Idea since it can allow
57
+ # replay attacks, but for this specific situation (the request is an internal redirect)
58
+ # it's a sufficient hack.
59
+ def should_ignore_nonce?
60
+ referer = URI.parse(request.referer)
61
+ is_safari? && params[:storage_access_status] == "granted" && referer.host == request.host && referer.port == request.port
62
+ end
63
+
60
64
  private
61
65
 
66
+ def is_safari?
67
+ browser = Browser.new(request.headers["User-Agent"])
68
+ # detect both MacOS and iOS Safari
69
+ browser.safari? || (browser.webkit? && browser.platform.ios?)
70
+ end
71
+
62
72
  def relaunch_url(launch_url, launch_params)
63
73
  return launch_url if launch_params.empty?
64
74
  "#{launch_url}?#{launch_params.to_query}"
@@ -70,6 +70,7 @@
70
70
  <div class="flex-item">
71
71
  <p>Occasionally, Safari requires you to launch this app outside of Canvas before logging in.</p>
72
72
  <p>This setup is now complete, and Canvas can now relaunch this app.</p>
73
+ <p>In some cases, you may need to relaunch this app yourself.</p>
73
74
  </div>
74
75
 
75
76
  <div class="flex-item">
@@ -99,6 +99,8 @@
99
99
  <p>Safari requires your interaction with this app before logging you in.</p>
100
100
  <p>A dialog may appear asking you to allow this app to use cookies while browsing Canvas.</p>
101
101
  <p>For the best experience, click Allow.</p>
102
+ <p>A dialog may also appear asking you to navigate somewhere else.</p>
103
+ <p>If it does, save your work first and then click Leave Page.</p>
102
104
  </div>
103
105
 
104
106
  <div class="flex-item">
@@ -0,0 +1,4 @@
1
+ require "canvas_lti_third_party_cookies/engine"
2
+
3
+ module CanvasLtiThirdPartyCookies
4
+ end
@@ -0,0 +1,5 @@
1
+ module CanvasLtiThirdPartyCookies
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace CanvasLtiThirdPartyCookies
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module CanvasLtiThirdPartyCookies
2
+ VERSION = '0.3.3'
3
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canvas_lti_third_party_cookies
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Xander Moffatt
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-15 00:00:00.000000000 Z
11
+ date: 2021-03-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -75,19 +75,18 @@ files:
75
75
  - LICENSE
76
76
  - README.md
77
77
  - Rakefile
78
- - app/controllers/concerns/lti_third_party_cookies/safari_launch.rb
78
+ - app/controllers/concerns/canvas_lti_third_party_cookies/safari_launch.rb
79
+ - app/views/canvas_lti_third_party_cookies/full_window_launch.erb
80
+ - app/views/canvas_lti_third_party_cookies/request_storage_access.erb
79
81
  - app/views/layouts/application.html.erb
80
- - app/views/lti_third_party_cookies/full_window_launch.erb
81
- - app/views/lti_third_party_cookies/request_storage_access.erb
82
- - config/routes.rb
83
- - lib/lti_third_party_cookies.rb
84
- - lib/lti_third_party_cookies/engine.rb
85
- - lib/lti_third_party_cookies/version.rb
82
+ - lib/canvas_lti_third_party_cookies.rb
83
+ - lib/canvas_lti_third_party_cookies/engine.rb
84
+ - lib/canvas_lti_third_party_cookies/version.rb
86
85
  homepage: https://gerrit.instructure.com/#/admin/projects/lti_third_party_cookies
87
86
  licenses:
88
87
  - MIT
89
88
  metadata: {}
90
- post_install_message:
89
+ post_install_message:
91
90
  rdoc_options: []
92
91
  require_paths:
93
92
  - lib
@@ -103,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
102
  version: '0'
104
103
  requirements: []
105
104
  rubygems_version: 3.0.1
106
- signing_key:
105
+ signing_key:
107
106
  specification_version: 4
108
107
  summary: Allow LTI tools launched by Canvas to set 3rd party cookies in Safari 13.1+
109
108
  test_files: []
data/config/routes.rb DELETED
@@ -1,2 +0,0 @@
1
- Rails.application.routes.draw do
2
- end
@@ -1,4 +0,0 @@
1
- require "lti_third_party_cookies/engine"
2
-
3
- module LtiThirdPartyCookies
4
- end
@@ -1,5 +0,0 @@
1
- module LtiThirdPartyCookies
2
- class Engine < ::Rails::Engine
3
- isolate_namespace LtiThirdPartyCookies
4
- end
5
- end
@@ -1,3 +0,0 @@
1
- module LtiThirdPartyCookies
2
- VERSION = '0.2.0'
3
- end