panda_pal 5.3.7 → 5.3.9

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: 2e3454f04c4cbf7a07dc7a041118bb3b60db681c531ebf228115de69f1114d50
4
- data.tar.gz: bc600d9940213278b6a0b9e908df51c24012a75ac120746758719faa91e8abbc
3
+ metadata.gz: 1002e4f3ad5967af145b78fbab0d1baf01463dd106b2516acf8dba0c70374e6a
4
+ data.tar.gz: 00bd28e3143849e9dbff067ca92bf8b4e8546460b822244af5e7dc311a976bba
5
5
  SHA512:
6
- metadata.gz: 507728d1f3dbe751125f4bd7fbda5a2245c20eee20ea8d446f12d5b701007ab1fbee5cfe81d741d400966db2f526d484e4f8ffde1c82f5db43a1e685f96362cc
7
- data.tar.gz: c97afd8ec0a896f46a5b63a6eb8d9b9f13d31d995d448d29800f88f23c6fd4897877e7958e54d5d47e23dab04277c1eba7c73b852dc61704d197f3ec47ed27aa
6
+ metadata.gz: 2778d5d235d572716e43596a694968cf06ce07cd5e085edc73e08146ad8e1f10ac3cd0866fd134f88fb867cf7f04586dba46d4c8fd87673b333b659c9776c986
7
+ data.tar.gz: 5432aa9d9531c19ce5b4f08cd619507f0597a365d585cd482de1917aae538cf21c33d03f25be19431e0b40b7cc19f6f260091c5e377b6e428513c1c06f06265e
data/README.md CHANGED
@@ -93,10 +93,22 @@ The following routes should be added to the routes.rb file of the implementing L
93
93
  ```ruby
94
94
  # config/routes.rb
95
95
  mount PandaPal::Engine, at: '/lti'
96
- lti_nav account_navigation: 'accounts#launch' # Use lti_nav to provide a custom Launch implementation, otherwise use the url: param of stage_navigation to let PandaPal handle launch.
97
96
  root to: 'panda_pal/lti#launch'
97
+
98
+ # Add Launch Endpoints:
99
+ lti_nav account_navigation: 'accounts#launch', auto_launch: false # (LTI <1.3 Default)
100
+ # -- OR --
101
+ scope '/organizations/:organization_id' do
102
+ lti_nav account_navigation: 'accounts#launch_landing', auto_launch: true # (LTI 1.3 Default)
103
+ lti_nav account_navigation: 'accounts#launch_landing' # Automatically sets auto_launch to true because :organization_id is part of the path
104
+ # ...
105
+ end
98
106
  ```
99
107
 
108
+ `auto_launch`: Setting to `true` will tell PandaPal to handle all of the launch details and session creation, and then pass off to
109
+ the defined action. Setting it to `false` indicates that the defined action handles launch validation and setup itself (this has been the legacy approach).
110
+ Because `auto_launch: false` is most similar to the previous behavior, it is the default for LTI 1.0/1.1 LTIs. For LTI 1.3 LTIs, `auto_launch: true` is the default. If not specified and `:organization_id` is detected in the Route Path, `auto_launch` will be set to `true`
111
+
100
112
  ## Implementating data segregation
101
113
  This engine uses Apartment to keep data segregated between installations of the implementing LTI tool.
102
114
  By default, it does this by inspecting the path of the request, and matching URLs containing `orgs` or `organizations`,
@@ -58,7 +58,12 @@ module PandaPal
58
58
  opts = LaunchUrlHelpers.normalize_lti_launch_desc(opts)
59
59
  opts.merge!({
60
60
  placement: k,
61
- target_link_uri: LaunchUrlHelpers.absolute_launch_url(k.to_sym, host: parsed_request_url, launch_handler: v1p3_resource_link_request_path),
61
+ target_link_uri: LaunchUrlHelpers.absolute_launch_url(
62
+ k.to_sym,
63
+ host: parsed_request_url,
64
+ launch_handler: v1p3_resource_link_request_path,
65
+ default_auto_launch: true
66
+ ),
62
67
  })
63
68
  opts
64
69
  end
@@ -86,7 +86,12 @@ module LtiXml
86
86
 
87
87
  def ext_params(options, k)
88
88
  options = PandaPal::LaunchUrlHelpers.normalize_lti_launch_desc(options)
89
- options[:url] = PandaPal::LaunchUrlHelpers.absolute_launch_url(k.to_sym, host: parsed_request_url, launch_handler: nil)
89
+ options[:url] = PandaPal::LaunchUrlHelpers.absolute_launch_url(
90
+ k.to_sym,
91
+ host: parsed_request_url,
92
+ launch_handler: :v1p0_launch_path,
93
+ default_auto_launch: false
94
+ )
90
95
  options
91
96
  end
92
97
  end
@@ -1,25 +1,26 @@
1
1
  module PandaPal
2
2
  module LaunchUrlHelpers
3
- def self.absolute_launch_url(launch_type, host:, launch_handler: nil)
3
+ def self.absolute_launch_url(launch_type, host:, launch_handler: nil, default_auto_launch: false)
4
4
  opts = PandaPal.lti_paths[launch_type]
5
- is_direct = opts[:no_redirect] || !launch_handler.present?
5
+ auto_launch = opts[:auto_launch] != nil ? opts[:auto_launch] : default_auto_launch
6
+ auto_launch = auto_launch && launch_handler.present?
6
7
 
7
- if is_direct
8
- final_url = launch_url(opts, launch_type: launch_type)
9
- return final_url if URI.parse(final_url).absolute?
10
- return [host.to_s, final_url].join
11
- else
8
+ if auto_launch
12
9
  launch_handler = resolve_route(launch_handler) if launch_handler.is_a?(Symbol)
13
10
  return add_url_params([host.to_s, launch_handler].join, {
14
11
  launch_type: launch_type,
15
12
  })
13
+ else
14
+ final_url = launch_url(opts, launch_type: launch_type)
15
+ return final_url if URI.parse(final_url).absolute?
16
+ return [host.to_s, final_url].join
16
17
  end
17
18
  end
18
19
 
19
20
  def self.normalize_lti_launch_desc(opts)
20
21
  opts = opts.dup
21
22
  opts.delete(:route_helper_key)
22
- opts.delete(:no_redirect)
23
+ opts.delete(:auto_launch)
23
24
  opts
24
25
  end
25
26
 
@@ -40,41 +40,7 @@ module PandaPal
40
40
 
41
41
  hash.tap do |hash|
42
42
  kl = ' ' * (k.to_s.length - 4)
43
- hash[k.to_sym] = hash[k.to_s] = {
44
- required: false,
45
- description: <<~MARKDOWN,
46
- Override schedule for '#{k.to_s}' task.
47
-
48
- **Default**: #{desc[:schedule].is_a?(String) ? desc[:schedule] : '<Computed>'}
49
-
50
- Set to `false` to disable or supply a Cron string:
51
- ```yaml
52
- #{k.to_s}: 0 0 0 * * * America/Denver
53
- ##{kl} │ │ │ │ │ │ └── Timezone (Optional)
54
- ##{kl} │ │ │ │ │ └── Day of Week
55
- ##{kl} │ │ │ │ └── Month
56
- ##{kl} │ │ │ └── Day of Month
57
- ##{kl} │ │ └── Hour
58
- ##{kl} │ └── Minute
59
- ##{kl} └── Second (Optional)
60
- ````
61
- MARKDOWN
62
- json_schema: {
63
- oneOf: [
64
- { type: 'string', pattern: '^((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,6})(\w+\/\w+)?$' },
65
- { enum: [false] },
66
- ],
67
- default: desc[:schedule].is_a?(String) ? desc[:schedule] : '0 0 3 * * * America/Denver',
68
- },
69
- validate: ->(value, *args, errors:, **kwargs) {
70
- begin
71
- Rufus::Scheduler.parse(value) if value
72
- nil
73
- rescue ArgumentError
74
- errors << "<path> must be false or a Crontab string"
75
- end
76
- }
77
- }
43
+ hash[k.to_sym] = hash[k.to_s] = PandaPal::OrganizationConcerns::TaskScheduling.build_settings_entry(desc)
78
44
  end
79
45
  end,
80
46
  }
@@ -137,6 +103,51 @@ module PandaPal
137
103
  end
138
104
  end
139
105
 
106
+ def self.build_settings_entry(desc)
107
+ k = desc[:key]
108
+ kl = ' ' * (k.to_s.length - 4)
109
+
110
+ default_schedule = '<Computed>'
111
+ default_schedule = desc[:schedule] if desc[:schedule].is_a?(String)
112
+ default_schedule = '<Disabled>' unless desc[:schedule].present?
113
+
114
+ {
115
+ required: false,
116
+ description: <<~MARKDOWN,
117
+ Override schedule for '#{k.to_s}' task.
118
+
119
+ **Default**: #{default_schedule}
120
+
121
+ Set to `false` to disable or supply a Cron string:
122
+ ```yaml
123
+ #{k.to_s}: 0 0 0 * * * America/Denver
124
+ ##{kl} │ │ │ │ │ │ └── Timezone (Optional)
125
+ ##{kl} │ │ │ │ │ └── Day of Week
126
+ ##{kl} │ │ │ │ └── Month
127
+ ##{kl} │ │ │ └── Day of Month
128
+ ##{kl} │ │ └── Hour
129
+ ##{kl} │ └── Minute
130
+ ##{kl} └── Second (Optional)
131
+ ````
132
+ MARKDOWN
133
+ json_schema: {
134
+ oneOf: [
135
+ { type: 'string', pattern: '^((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,6})(\w+\/\w+)?$' },
136
+ { enum: [false] },
137
+ ],
138
+ default: desc[:schedule].is_a?(String) ? desc[:schedule] : '0 0 3 * * * America/Denver',
139
+ },
140
+ validate: ->(value, *args, errors:, **kwargs) {
141
+ begin
142
+ Rufus::Scheduler.parse(value) if value
143
+ nil
144
+ rescue ArgumentError
145
+ errors << "<path> must be false or a Crontab string"
146
+ end
147
+ }
148
+ }
149
+ end
150
+
140
151
  private
141
152
 
142
153
  def unschedule_tasks(new_task_keys = nil)
data/config/routes.rb CHANGED
@@ -3,6 +3,7 @@ PandaPal::Engine.routes.draw do
3
3
 
4
4
  scope '/v1p0', as: 'v1p0' do
5
5
  get '/config' => 'lti_v1_p0#tool_config'
6
+ post '/launch' => 'lti_v1_p0#launch'
6
7
  end
7
8
 
8
9
  scope '/v1p3', as: 'v1p3' do
@@ -39,7 +39,11 @@ module PandaPal::Helpers
39
39
 
40
40
  def validate_v1p0_launch
41
41
  authorized = false
42
- if @organization = params['oauth_consumer_key'] && PandaPal::Organization.find_by_key(params['oauth_consumer_key'])
42
+ # We should verify the timestamp is recent (within 5 minutes). The approved timestamp is part of the signature,
43
+ # so we don't need to worry about malicious users messing with it. We should deny requests that come too long
44
+ # after the approved timestamp.
45
+ good_timestamp = params['oauth_timestamp'] && params['oauth_timestamp'].to_i > Time.now.to_i - 300
46
+ if @organization = good_timestamp && params['oauth_consumer_key'] && PandaPal::Organization.find_by_key(params['oauth_consumer_key'])
43
47
  sanitized_params = request.request_parameters
44
48
  # These params come over with a safari-workaround launch. The authenticator doesn't like them, so clean them out.
45
49
  safe_unexpected_params = ["full_win_launch_requested", "platform_redirect_url", "dummy_param"]
@@ -9,7 +9,12 @@ module PandaPal::Helpers::RouteHelper
9
9
  path = "#{base_path}/#{nav.to_s}"
10
10
 
11
11
  lti_options = options.delete(:lti_options) || {}
12
- lti_options[:no_redirect] = options.delete(:no_redirect)
12
+ lti_options[:auto_launch] = options.delete(:auto_launch)
13
+
14
+ if lti_options[:auto_launch].nil?
15
+ lti_options[:auto_launch] = (@scope[:path] || '').include?(':organization_id')
16
+ end
17
+
13
18
  lti_options[:route_helper_key] = path.split('/').reject(&:empty?).join('_')
14
19
  post(path, options.dup, &block)
15
20
  get(path, options.dup, &block)
@@ -1,3 +1,3 @@
1
1
  module PandaPal
2
- VERSION = "5.3.7"
2
+ VERSION = "5.3.9"
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.3.7
4
+ version: 5.3.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Instructure ProServe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-01 00:00:00.000000000 Z
11
+ date: 2021-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails