panda_pal 5.3.7 → 5.3.9
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 +4 -4
- data/README.md +13 -1
- data/app/controllers/panda_pal/lti_v1_p3_controller.rb +6 -1
- data/app/lib/lti_xml/base_platform.rb +6 -1
- data/app/lib/panda_pal/launch_url_helpers.rb +9 -8
- data/app/models/panda_pal/organization_concerns/task_scheduling.rb +46 -35
- data/config/routes.rb +1 -0
- data/lib/panda_pal/helpers/controller_helper.rb +5 -1
- data/lib/panda_pal/helpers/route_helper.rb +6 -1
- data/lib/panda_pal/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1002e4f3ad5967af145b78fbab0d1baf01463dd106b2516acf8dba0c70374e6a
|
4
|
+
data.tar.gz: 00bd28e3143849e9dbff067ca92bf8b4e8546460b822244af5e7dc311a976bba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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(
|
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(
|
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
|
-
|
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
|
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(:
|
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
@@ -39,7 +39,11 @@ module PandaPal::Helpers
|
|
39
39
|
|
40
40
|
def validate_v1p0_launch
|
41
41
|
authorized = false
|
42
|
-
|
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[:
|
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)
|
data/lib/panda_pal/version.rb
CHANGED
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.
|
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-
|
11
|
+
date: 2021-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|