roda 3.82.0 → 3.84.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/roda/plugins/assume_ssl.rb +28 -0
- data/lib/roda/plugins/hsts.rb +35 -0
- data/lib/roda/plugins/multi_public.rb +3 -3
- data/lib/roda/plugins/public.rb +1 -1
- data/lib/roda/plugins/timestamp_public.rb +1 -1
- data/lib/roda/plugins/typecast_params.rb +1 -1
- data/lib/roda/response.rb +1 -1
- data/lib/roda/version.rb +1 -1
- metadata +5 -177
- data/CHANGELOG +0 -687
- data/README.rdoc +0 -1136
- data/doc/conventions.rdoc +0 -177
- data/doc/release_notes/3.0.0.txt +0 -84
- data/doc/release_notes/3.1.0.txt +0 -24
- data/doc/release_notes/3.10.0.txt +0 -132
- data/doc/release_notes/3.11.0.txt +0 -54
- data/doc/release_notes/3.12.0.txt +0 -19
- data/doc/release_notes/3.13.0.txt +0 -38
- data/doc/release_notes/3.14.0.txt +0 -36
- data/doc/release_notes/3.14.1.txt +0 -43
- data/doc/release_notes/3.15.0.txt +0 -21
- data/doc/release_notes/3.16.0.txt +0 -52
- data/doc/release_notes/3.17.0.txt +0 -62
- data/doc/release_notes/3.18.0.txt +0 -170
- data/doc/release_notes/3.19.0.txt +0 -229
- data/doc/release_notes/3.2.0.txt +0 -22
- data/doc/release_notes/3.20.0.txt +0 -7
- data/doc/release_notes/3.21.0.txt +0 -5
- data/doc/release_notes/3.22.0.txt +0 -24
- data/doc/release_notes/3.23.0.txt +0 -28
- data/doc/release_notes/3.24.0.txt +0 -14
- data/doc/release_notes/3.25.0.txt +0 -12
- data/doc/release_notes/3.26.0.txt +0 -15
- data/doc/release_notes/3.27.0.txt +0 -15
- data/doc/release_notes/3.28.0.txt +0 -13
- data/doc/release_notes/3.29.0.txt +0 -15
- data/doc/release_notes/3.3.0.txt +0 -291
- data/doc/release_notes/3.30.0.txt +0 -14
- data/doc/release_notes/3.31.0.txt +0 -11
- data/doc/release_notes/3.32.0.txt +0 -42
- data/doc/release_notes/3.33.0.txt +0 -8
- data/doc/release_notes/3.34.0.txt +0 -17
- data/doc/release_notes/3.35.0.txt +0 -12
- data/doc/release_notes/3.36.0.txt +0 -17
- data/doc/release_notes/3.37.0.txt +0 -42
- data/doc/release_notes/3.38.0.txt +0 -5
- data/doc/release_notes/3.39.0.txt +0 -16
- data/doc/release_notes/3.4.0.txt +0 -24
- data/doc/release_notes/3.40.0.txt +0 -24
- data/doc/release_notes/3.41.0.txt +0 -9
- data/doc/release_notes/3.42.0.txt +0 -21
- data/doc/release_notes/3.43.0.txt +0 -34
- data/doc/release_notes/3.44.0.txt +0 -23
- data/doc/release_notes/3.45.0.txt +0 -22
- data/doc/release_notes/3.46.0.txt +0 -19
- data/doc/release_notes/3.47.0.txt +0 -13
- data/doc/release_notes/3.48.0.txt +0 -10
- data/doc/release_notes/3.49.0.txt +0 -18
- data/doc/release_notes/3.5.0.txt +0 -31
- data/doc/release_notes/3.50.0.txt +0 -21
- data/doc/release_notes/3.51.0.txt +0 -20
- data/doc/release_notes/3.52.0.txt +0 -20
- data/doc/release_notes/3.53.0.txt +0 -14
- data/doc/release_notes/3.54.0.txt +0 -48
- data/doc/release_notes/3.55.0.txt +0 -12
- data/doc/release_notes/3.56.0.txt +0 -33
- data/doc/release_notes/3.57.0.txt +0 -34
- data/doc/release_notes/3.58.0.txt +0 -16
- data/doc/release_notes/3.59.0.txt +0 -17
- data/doc/release_notes/3.6.0.txt +0 -21
- data/doc/release_notes/3.60.0.txt +0 -56
- data/doc/release_notes/3.61.0.txt +0 -24
- data/doc/release_notes/3.62.0.txt +0 -41
- data/doc/release_notes/3.63.0.txt +0 -36
- data/doc/release_notes/3.64.0.txt +0 -26
- data/doc/release_notes/3.65.0.txt +0 -12
- data/doc/release_notes/3.66.0.txt +0 -23
- data/doc/release_notes/3.67.0.txt +0 -25
- data/doc/release_notes/3.68.0.txt +0 -21
- data/doc/release_notes/3.69.0.txt +0 -33
- data/doc/release_notes/3.7.0.txt +0 -123
- data/doc/release_notes/3.70.0.txt +0 -19
- data/doc/release_notes/3.71.0.txt +0 -33
- data/doc/release_notes/3.72.0.txt +0 -48
- data/doc/release_notes/3.73.0.txt +0 -33
- data/doc/release_notes/3.74.0.txt +0 -28
- data/doc/release_notes/3.75.0.txt +0 -19
- data/doc/release_notes/3.76.0.txt +0 -18
- data/doc/release_notes/3.77.0.txt +0 -8
- data/doc/release_notes/3.78.0.txt +0 -99
- data/doc/release_notes/3.79.0.txt +0 -148
- data/doc/release_notes/3.8.0.txt +0 -27
- data/doc/release_notes/3.80.0.txt +0 -31
- data/doc/release_notes/3.81.0.txt +0 -24
- data/doc/release_notes/3.82.0.txt +0 -43
- data/doc/release_notes/3.9.0.txt +0 -67
@@ -1,33 +0,0 @@
|
|
1
|
-
= New Feature
|
2
|
-
|
3
|
-
* The symbol_matcher method in the symbol_matchers plugin now
|
4
|
-
supports a block to allow for type conversion of matched
|
5
|
-
segments:
|
6
|
-
|
7
|
-
symbol_matcher(:date, /(\d\d\d\d)-(\d\d)-(\d\d)/) do |y, m, d|
|
8
|
-
[Date.new(y.to_i, m.to_i, d.to_i)]
|
9
|
-
end
|
10
|
-
|
11
|
-
route do |r|
|
12
|
-
r.on :date do |date|
|
13
|
-
# date is an instance of Date
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
As shown above, the block should return an array of objects to yield
|
18
|
-
to the match block.
|
19
|
-
|
20
|
-
If you have a segment match the passed regexp, but decide during block
|
21
|
-
processing that you do not want to treat it as a match, you can have the
|
22
|
-
block return nil or false. This is useful if you want to make sure you
|
23
|
-
are using valid data:
|
24
|
-
|
25
|
-
symbol_matcher(:date, /(\d\d\d\d)-(\d\d)-(\d\d)/) do |y, m, d|
|
26
|
-
y = y.to_i
|
27
|
-
m = m.to_i
|
28
|
-
d = d.to_i
|
29
|
-
[Date.new(y, m, d)] if Date.valid_date?(y, m, d)
|
30
|
-
end
|
31
|
-
|
32
|
-
When providing a block when using the symbol_matchers method, that
|
33
|
-
symbol may not work with the params_capturing plugin.
|
data/doc/release_notes/3.7.0.txt
DELETED
@@ -1,123 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A content_security_policy plugin has been added for setting up an
|
4
|
-
appropriate Content-Security-Policy header. To configure the
|
5
|
-
default policy, load the plugin with a block:
|
6
|
-
|
7
|
-
plugin :content_security_policy do |csp|
|
8
|
-
csp.default_src :none
|
9
|
-
csp.img_src :self
|
10
|
-
csp.style_src :self, 'fonts.googleapis.com'
|
11
|
-
csp.script_src :self
|
12
|
-
csp.font_src :self, 'fonts.gstatic.com'
|
13
|
-
csp.form_action :self
|
14
|
-
csp.base_uri :none
|
15
|
-
csp.frame_ancestors :none
|
16
|
-
csp.block_all_mixed_content
|
17
|
-
end
|
18
|
-
|
19
|
-
It's recommended that use use a default_src of :none at the top
|
20
|
-
of the policy, then explicitly change other settings (e.g. img_src)
|
21
|
-
when you want to allow content.
|
22
|
-
|
23
|
-
Anywhere in the routing tree, you can use the content_security_policy
|
24
|
-
method to override the default policy. You can pass this method a
|
25
|
-
block:
|
26
|
-
|
27
|
-
r.get 'foo' do
|
28
|
-
content_security_policy do |csp|
|
29
|
-
csp.object_src :self
|
30
|
-
csp.add_style_src 'bar.com'
|
31
|
-
end
|
32
|
-
# ...
|
33
|
-
end
|
34
|
-
|
35
|
-
Or just call a method on it:
|
36
|
-
|
37
|
-
r.get 'foo' do
|
38
|
-
content_security_policy.script_src :self, 'example.com', [:nonce, 'foobarbaz']
|
39
|
-
# ...
|
40
|
-
end
|
41
|
-
|
42
|
-
The following methods exist for configuring the content security policy, they set
|
43
|
-
the appropriate directive, with the underscores replaced by a dash.
|
44
|
-
|
45
|
-
* base_uri
|
46
|
-
* child_src
|
47
|
-
* connect_src
|
48
|
-
* default_src
|
49
|
-
* font_src
|
50
|
-
* form_action
|
51
|
-
* frame_ancestors
|
52
|
-
* frame_src
|
53
|
-
* img_src
|
54
|
-
* manifest_src
|
55
|
-
* media_src
|
56
|
-
* object_src
|
57
|
-
* plugin_types
|
58
|
-
* report_uri
|
59
|
-
* require_sri_for
|
60
|
-
* sandbox
|
61
|
-
* script_src
|
62
|
-
* style_src
|
63
|
-
* worker_src
|
64
|
-
|
65
|
-
All of these methods support any number of arguments, and each argument
|
66
|
-
should be one of the following types:
|
67
|
-
|
68
|
-
String :: used verbatim
|
69
|
-
Symbol :: Substitutes underscore with dash and surrounds with single
|
70
|
-
quotes
|
71
|
-
Array :: only accepts 2 element arrays, joins elements with a dash
|
72
|
-
and surrounds them with single quotes
|
73
|
-
|
74
|
-
Example:
|
75
|
-
|
76
|
-
content_security_policy.script_src :self, :unsafe_eval,
|
77
|
-
'example.com', [:nonce, 'foobarbaz']
|
78
|
-
# script-src 'self' 'unsafe-eval' example.com 'nonce-foobarbaz';
|
79
|
-
|
80
|
-
When calling a method with no arguments, the setting is removed from
|
81
|
-
the policy instead of being left empty, since all of these setting
|
82
|
-
require at least one value. Likewise, if the policy does not have
|
83
|
-
any settings, the header will not be added.
|
84
|
-
|
85
|
-
Calling the method overrides any previous setting. Each of the
|
86
|
-
methods has a add_* method (e.g. add_script_src) for appending to the
|
87
|
-
current setting, and a get_* method (e.g. get_script_src) for
|
88
|
-
retrieving the current value of the setting, or nil if it is not
|
89
|
-
defined.
|
90
|
-
|
91
|
-
content_security_policy.script_src :self, :unsafe_eval
|
92
|
-
# script-src 'self' 'unsafe-eval';
|
93
|
-
content_security_policy.add_script_src 'example.com', [:nonce, 'foobarbaz']
|
94
|
-
# script-src 'self' 'unsafe-eval' example.com 'nonce-foobarbaz';
|
95
|
-
|
96
|
-
content_security_policy.get_script_src 'example.com', [:nonce, 'foobarbaz']
|
97
|
-
# => [:self, :unsafe_eval, 'example.com', [:nonce, 'foobarbaz']]
|
98
|
-
|
99
|
-
The clear method can be used to remove all settings from the policy.
|
100
|
-
|
101
|
-
The following methods to set boolean directives are also defined:
|
102
|
-
|
103
|
-
* block_all_mixed_content
|
104
|
-
* upgrade_insecure_requests
|
105
|
-
|
106
|
-
Calling these methods will turn on the related setting. To turn the
|
107
|
-
setting off again, you can call them with a false argument (e.g.
|
108
|
-
block_all_mixed_content(false)). Each method also an *? method
|
109
|
-
(e.g. block_all_mixed_content?) for returning whether the setting is
|
110
|
-
currently enabled.
|
111
|
-
|
112
|
-
Likewise there is also a report_only method for turning on report
|
113
|
-
only mode (the default is enforcement mode), or turning off report
|
114
|
-
only mode if a false argument is given. Also, there is a
|
115
|
-
report_only? method for returning whether report only mode is
|
116
|
-
enabled. In report only mode, the Content-Security-Policy-Report-Only
|
117
|
-
header is used.
|
118
|
-
|
119
|
-
= Other Improvements
|
120
|
-
|
121
|
-
* The response_request plugin now integrates with the error_handler and
|
122
|
-
class_level_routing plugins. Those plugins now reinitialize the
|
123
|
-
current response object instead of creating a new response object.
|
@@ -1,19 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A plain_hash_response_headers plugin has been added. On Rack 3,
|
4
|
-
this changes Roda to use a plain hash for response headers (as it
|
5
|
-
does on Rack 2), instead of using Rack::Headers (the default on
|
6
|
-
Rack 3). For a minimal app, using this plugin can almost double
|
7
|
-
the performance on Rack 3. Before using this plugin, you should
|
8
|
-
make sure that all response headers set explictly in your
|
9
|
-
application are already lower-case.
|
10
|
-
|
11
|
-
= Improvements
|
12
|
-
|
13
|
-
* Roda now natively uses lower-case for all response headers set
|
14
|
-
implicitly when using Rack 3. Previously, Roda used mixed-case
|
15
|
-
response headers and had Rack::Headers handle the conversion to
|
16
|
-
lower-case (Rack 3 requires lower-case response headers). Note
|
17
|
-
that Rack::Headers is still used for response headers by default
|
18
|
-
on Rack 3, as applications may not have converted to using
|
19
|
-
lower-case response headers.
|
@@ -1,33 +0,0 @@
|
|
1
|
-
= New Feature
|
2
|
-
|
3
|
-
* A match_hook_args plugin has been added. This is similar to the
|
4
|
-
existing match_hook plugin, but passes through the matchers and
|
5
|
-
block arguments (values yielded to the match block). Example:
|
6
|
-
|
7
|
-
plugin :match_hook_args
|
8
|
-
|
9
|
-
add_match_hook do |matchers, block_args|
|
10
|
-
logger.debug("matchers: #{matchers.inspect}. #{block_args.inspect} yielded.")
|
11
|
-
end
|
12
|
-
|
13
|
-
# Term is an implicit matcher used for terminating matches, and
|
14
|
-
# will be included in the array of matchers yielded to the match hook
|
15
|
-
# if a terminating match is used.
|
16
|
-
term = self.class::RodaRequest::TERM
|
17
|
-
|
18
|
-
route do |r|
|
19
|
-
r.root do
|
20
|
-
# for a request for /
|
21
|
-
# matchers: nil, block_args: nil
|
22
|
-
end
|
23
|
-
|
24
|
-
r.on 'a', ['b', 'c'], Integer do |segment, id|
|
25
|
-
# for a request for /a/b/1
|
26
|
-
# matchers: ["a", ["b", "c"], Integer], block_args: ["b", 1]
|
27
|
-
end
|
28
|
-
|
29
|
-
r.get 'd' do
|
30
|
-
# for a request for /d
|
31
|
-
# matchers: ["d", term], block_args: []
|
32
|
-
end
|
33
|
-
end
|
@@ -1,48 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* An invalid_request_body plugin has been added for allowing custom
|
4
|
-
handling of invalid request bodies. Roda uses Rack's request body
|
5
|
-
parsing, and by default invalid request bodies can result in
|
6
|
-
different exceptions based on how the body is invalid and which
|
7
|
-
version of Rack is in use.
|
8
|
-
|
9
|
-
If you want to treat an invalid request body as the submission of
|
10
|
-
no parameters, you can use the :empty_hash argument when loading
|
11
|
-
the plugin:
|
12
|
-
|
13
|
-
plugin :invalid_request_body, :empty_hash
|
14
|
-
|
15
|
-
If you want to return a empty 400 (Bad Request) response if an
|
16
|
-
invalid request body is submitted, you can use the :empty_400
|
17
|
-
argument when loading the plugin:
|
18
|
-
|
19
|
-
plugin :invalid_request_body, :empty_400
|
20
|
-
|
21
|
-
If you want to raise a Roda::RodaPlugins::InvalidRequestBody::Error
|
22
|
-
exception if an invalid request body is submitted (which makes it
|
23
|
-
easier to handle these exceptions when using the error_handler
|
24
|
-
plugin), you can use the :raise argument when loading the plugin:
|
25
|
-
|
26
|
-
plugin :invalid_request_body, :raise
|
27
|
-
|
28
|
-
For custom behavior, you can pass a block when loading the plugin
|
29
|
-
The block is called with the exception Rack raised when parsing the
|
30
|
-
body. The block will be used to define a method in the application's
|
31
|
-
RodaRequest class. It can either return a hash of parameters, or
|
32
|
-
you can raise a different exception, or you can halt processing and
|
33
|
-
return a response:
|
34
|
-
|
35
|
-
plugin :invalid_request_body do |exception|
|
36
|
-
# To treat the exception raised as a submitted parameter
|
37
|
-
{body_error: exception}
|
38
|
-
end
|
39
|
-
|
40
|
-
= Other Improvements
|
41
|
-
|
42
|
-
* When using the check_arity: :warn Roda option, Roda now correctly
|
43
|
-
warns when defining a method that expects a single argument when
|
44
|
-
the provided block requires multiple arguments.
|
45
|
-
|
46
|
-
* The match_hooks plugin is now implemented using the match_hook_args
|
47
|
-
plugin, simplifying the implementation. This change should be
|
48
|
-
transparent unless you were reaching into the internals.
|
@@ -1,33 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* The middleware plugin now accepts a :next_if_not_found option.
|
4
|
-
This allows the middleware plugin to pass the request to the next
|
5
|
-
application if the current application handles the request but
|
6
|
-
ends up calling the not_found handler. With the following
|
7
|
-
middleware:
|
8
|
-
|
9
|
-
class Mid < Roda
|
10
|
-
plugin :middleware
|
11
|
-
|
12
|
-
route do |r|
|
13
|
-
r.on "foo" do
|
14
|
-
r.get "bar" do
|
15
|
-
'bar'
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
Requests for /x would be forwarded to the next application, since
|
22
|
-
the application doesn't handle the request, but requests for /foo/x
|
23
|
-
would not be, because the middleware is partially handling the
|
24
|
-
request in the r.on "foo" block. With the :next_if_not_found
|
25
|
-
option, only requests for /foo/bar would be handled by the
|
26
|
-
middleware, and all other requests would be forwarded to the next
|
27
|
-
application.
|
28
|
-
|
29
|
-
= Other Improvements
|
30
|
-
|
31
|
-
* The sessions and route_csrf plugins no longer depend on the base64
|
32
|
-
library. base64 will be removed from Ruby's standard library
|
33
|
-
starting in Ruby 3.4.
|
@@ -1,28 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A redirect_http_to_https plugin has been added, redirecting HTTP
|
4
|
-
requests to the same path on an HTTPS site. Using the routing tree,
|
5
|
-
you can control where to do the redirection, which allows you to
|
6
|
-
easily have part of your site accessible via HTTP, with sensitive
|
7
|
-
sections requiring HTTPS:
|
8
|
-
|
9
|
-
plugin :redirect_http_to_https
|
10
|
-
|
11
|
-
route do |r|
|
12
|
-
# routes available via both HTTP and HTTPS
|
13
|
-
r.redirect_http_to_https
|
14
|
-
# routes available only via HTTPS
|
15
|
-
end
|
16
|
-
|
17
|
-
If you want to redirect to HTTPS for all routes in the routing tree, you
|
18
|
-
can have r.redirect_http_to_https as the very first method call in the
|
19
|
-
routing tree. Note that in Roda it is possible to handle routing before
|
20
|
-
the normal routing tree using before hooks. The static_routing and
|
21
|
-
heartbeat plugins use this feature. If you would like to handle routes
|
22
|
-
before the normal routing tree, you can setup a before hook:
|
23
|
-
|
24
|
-
plugin :hooks
|
25
|
-
|
26
|
-
before do
|
27
|
-
request.redirect_http_to_https
|
28
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A cookie_flags plugin has been added, for overriding, warning, or
|
4
|
-
raising for incorrect cookie flags. The plugin by default checks
|
5
|
-
whether the secure, httponly, and samesite=strict flags are set.
|
6
|
-
The default behavior is to add the appropriate flags if they are
|
7
|
-
not set, and change the samesite flag to strict if it is set to
|
8
|
-
something else. You can configure the flag checking behavior
|
9
|
-
via the :httponly, :same_site, and :secure options.
|
10
|
-
|
11
|
-
You can configure the action the plugin takes via the :action option.
|
12
|
-
The default action is to modify the flags, but the :action option can
|
13
|
-
be set to :raise, :warn, or :warn_and_modify to override the behavior.
|
14
|
-
|
15
|
-
The recommended way to use the plugin is to use it during testing,
|
16
|
-
and specify action: :raise, so you can catch places where cookies
|
17
|
-
are set with the wrong flags. Then you can fix those places to
|
18
|
-
use the correct flags, which is better than relying on the plugin
|
19
|
-
at runtime in production to fix incorrect flags.
|
@@ -1,18 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A break plugin has been added, allowing you to use break from
|
4
|
-
inside a routing block and continue routing after the block. This
|
5
|
-
offers the same feature as the pass plugin, but using the standard
|
6
|
-
break keyword instead of the r.pass method.
|
7
|
-
|
8
|
-
* The error_mail and error_email features now both accept a :filter
|
9
|
-
plugin option. The value should respond to call with two arguments.
|
10
|
-
The first arguments is the key, and the second is the value, and
|
11
|
-
should return a truthy value if the value should be filtered. This
|
12
|
-
will be used for filtering parameter values, ENV values, and session
|
13
|
-
values in the generated emails.
|
14
|
-
|
15
|
-
= Other Improvements
|
16
|
-
|
17
|
-
* On Ruby 3.3+, the middleware plugin sets a temporary class name for
|
18
|
-
the created middleware, based on the class name of the Roda app.
|
@@ -1,8 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* The route_csrf plugin now supports formaction/formmethod attributes
|
4
|
-
in forms. A csrf_formaction_tag method has been added for creating
|
5
|
-
a hidden input for a particular path and method. When a form is
|
6
|
-
submitted, the check_csrf! method will fix check for a path-specific
|
7
|
-
csrf token (set by the hidden tag added by the csrf_formaction_tag
|
8
|
-
method), before checking for the default csrf token.
|
@@ -1,99 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* A permissions_policy plugin has been added that allows you to easily set a
|
4
|
-
Permissions-Policy header for the application, which browsers can use to
|
5
|
-
determine whether to allow specific functionality on the returned page
|
6
|
-
(mainly related to which JavaScript APIs the page is allowed to use).
|
7
|
-
|
8
|
-
You would generally call the plugin with a block to set the default policy:
|
9
|
-
|
10
|
-
plugin :permissions_policy do |pp|
|
11
|
-
pp.camera :none
|
12
|
-
pp.fullscreen :self
|
13
|
-
pp.clipboard_read :self, 'https://example.com'
|
14
|
-
end
|
15
|
-
|
16
|
-
Then, anywhere in the routing tree, you can customize the policy for just that
|
17
|
-
branch or action using the same block syntax:
|
18
|
-
|
19
|
-
r.get 'foo' do
|
20
|
-
permissions_policy do |pp|
|
21
|
-
pp.camera :self
|
22
|
-
end
|
23
|
-
# ...
|
24
|
-
end
|
25
|
-
|
26
|
-
In addition to using a block, you can also call methods on the object returned
|
27
|
-
by the method:
|
28
|
-
|
29
|
-
r.get 'foo' do
|
30
|
-
permissions_policy.camera :self
|
31
|
-
# ...
|
32
|
-
end
|
33
|
-
|
34
|
-
You can use the :default plugin option to set the default for all settings.
|
35
|
-
For example, to disallow all access for each setting by default:
|
36
|
-
|
37
|
-
plugin :permissions_policy, default: :none
|
38
|
-
|
39
|
-
The following methods are available for configuring the permissions policy,
|
40
|
-
which specify the setting (substituting _ with -):
|
41
|
-
|
42
|
-
* accelerometer
|
43
|
-
* ambient_light_sensor
|
44
|
-
* autoplay
|
45
|
-
* bluetooth
|
46
|
-
* camera
|
47
|
-
* clipboard_read
|
48
|
-
* clipboard_write
|
49
|
-
* display_capture
|
50
|
-
* encrypted_media
|
51
|
-
* fullscreen
|
52
|
-
* geolocation
|
53
|
-
* gyroscope
|
54
|
-
* hid
|
55
|
-
* idle_detection
|
56
|
-
* keyboard_map
|
57
|
-
* magnetometer
|
58
|
-
* microphone
|
59
|
-
* midi
|
60
|
-
* payment
|
61
|
-
* picture_in_picture
|
62
|
-
* publickey_credentials_get
|
63
|
-
* screen_wake_lock
|
64
|
-
* serial
|
65
|
-
* sync_xhr
|
66
|
-
* usb
|
67
|
-
* web_share
|
68
|
-
* window_management
|
69
|
-
|
70
|
-
All of these methods support any number of arguments, and each argument should
|
71
|
-
be one of the following values:
|
72
|
-
|
73
|
-
:all :: Grants permission to all domains (must be only argument)
|
74
|
-
:none :: Does not allow permission at all (must be only argument)
|
75
|
-
:self :: Allows feature in current document and any nested browsing contexts
|
76
|
-
that use the same domain as the current document.
|
77
|
-
:src :: Allows feature in current document and any nested browsing contexts
|
78
|
-
that use the same domain as the src of the iframe.
|
79
|
-
String :: Specifies origin domain where access is allowed
|
80
|
-
|
81
|
-
When calling a method with no arguments, the setting is removed from the policy instead
|
82
|
-
of being left empty, since all of these setting require at least one value. Likewise,
|
83
|
-
if the policy does not have any settings, the header will not be added.
|
84
|
-
|
85
|
-
Calling the method overrides any previous setting. Each of the methods has +add_*+ and
|
86
|
-
+get_*+ methods defined. The +add_*+ method appends to any existing setting, and the +get_*+ method
|
87
|
-
returns the current value for the setting (this will be +:all+ if all domains are allowed, or
|
88
|
-
any array of strings/:self/:src).
|
89
|
-
|
90
|
-
permissions_policy.fullscreen :self, 'https://example.com'
|
91
|
-
# fullscreen (self "https://example.com")
|
92
|
-
|
93
|
-
permissions_policy.add_fullscreen 'https://*.example.com'
|
94
|
-
# fullscreen (self "https://example.com" "https://*.example.com")
|
95
|
-
|
96
|
-
permissions_policy.get_fullscreen
|
97
|
-
# => [:self, "https://example.com", "https://*.example.com"]
|
98
|
-
|
99
|
-
The clear method can be used to remove all settings from the policy.
|
@@ -1,148 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* The hmac_paths plugin allows protection of paths using an HMAC. This can be used
|
4
|
-
to prevent users enumerating paths, since only paths with valid HMACs will be
|
5
|
-
respected.
|
6
|
-
|
7
|
-
To use the plugin, you must provide a :secret option. This sets the secret for
|
8
|
-
the HMACs. Make sure to keep this value secret, as this plugin does not provide
|
9
|
-
protection against users who know the secret value. The secret must be at least
|
10
|
-
32 bytes.
|
11
|
-
|
12
|
-
plugin :hmac_paths, secret: 'some-secret-value-with-at-least-32-bytes'
|
13
|
-
|
14
|
-
To generate a valid HMAC path, you call the hmac_path method:
|
15
|
-
|
16
|
-
hmac_path('/widget/1')
|
17
|
-
# => "/0c2feaefdfc80cc73da19b060c713d4193c57022815238c6657ce2d99b5925eb/0/widget/1"
|
18
|
-
|
19
|
-
The first segment in the returned path is the HMAC. The second segment is flags for
|
20
|
-
the type of paths (see below), and the rest of the path is as given.
|
21
|
-
|
22
|
-
To protect a path or any subsection in the routing tree, you wrap the related code
|
23
|
-
in an +r.hmac_path+ block.
|
24
|
-
|
25
|
-
route do |r|
|
26
|
-
r.hmac_path do
|
27
|
-
r.get 'widget', Integer do |widget_id|
|
28
|
-
# ...
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
If first segment of the remaining path contains a valid HMAC for the rest of the path (considering
|
34
|
-
the flags), then r.hmac_path will match and yield to the block, and routing continues inside
|
35
|
-
the block with the HMAC and flags segments removed.
|
36
|
-
|
37
|
-
In the above example, if you provide a user a link for widget with ID 1, there is no way
|
38
|
-
for them to guess the valid path for the widget with ID 2, preventing a user from
|
39
|
-
enumerating widgets, without relying on custom access control. Users can only access
|
40
|
-
paths that have been generated by the application and provided to them, either directly
|
41
|
-
or indirectly.
|
42
|
-
|
43
|
-
In the above example, r.hmac_path is used at the root of the routing tree. If you
|
44
|
-
would like to call it below the root of the routing tree, it works correctly, but you
|
45
|
-
must pass hmac_path the :root option specifying where r.hmac_paths will be called from.
|
46
|
-
Consider this example:
|
47
|
-
|
48
|
-
route do |r|
|
49
|
-
r.on 'widget' do
|
50
|
-
r.hmac_path do
|
51
|
-
r.get Integer do |widget_id|
|
52
|
-
# ...
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
r.on 'foobar' do
|
58
|
-
r.hmac_path do
|
59
|
-
r.get Integer do |foobar_id|
|
60
|
-
# ...
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
For security reasons, the hmac_path plugin does not allow an HMAC path designed for
|
67
|
-
widgets to be a valid match in the r.hmac_path call inside the "r.on 'foobar'"
|
68
|
-
block, preventing users who have a valid HMAC for a widget from looking at the page for
|
69
|
-
a foobar with the same ID. When generating HMAC paths where the matching r.hmac_path
|
70
|
-
call is not at the root of the routing tree, you must pass the :root option:
|
71
|
-
|
72
|
-
hmac_path('/1', root: '/widget')
|
73
|
-
# => "/widget/daccafce3ce0df52e5ce774626779eaa7286085fcbde1e4681c74175ff0bbacd/0/1"
|
74
|
-
|
75
|
-
hmac_path('/1', root: '/foobar')
|
76
|
-
# => "/foobar/c5fdaf482771d4f9f38cc13a1b2832929026a4ceb05e98ed6a0cd5a00bf180b7/0/1"
|
77
|
-
|
78
|
-
Note how the HMAC changes even though the path is the same.
|
79
|
-
|
80
|
-
In addition to the +:root+ option, there are additional options that further constrain
|
81
|
-
use of the generated paths.
|
82
|
-
|
83
|
-
The :method option creates a path that can only be called with a certain request
|
84
|
-
method:
|
85
|
-
|
86
|
-
hmac_path('/widget/1', method: :get)
|
87
|
-
# => "/d38c1e634ecf9a3c0ab9d0832555b035d91b35069efcbf2670b0dfefd4b62fdd/m/widget/1"
|
88
|
-
|
89
|
-
Note how this results in a different HMAC than the original hmac_path('/widget/1')
|
90
|
-
call. This sets the flags segment to "m", which means r.hmac_path will consider the
|
91
|
-
request mehod when checking the HMAC, and will only match if the provided request method
|
92
|
-
is GET. This allows you to provide a user the ability to submit a GET request for the
|
93
|
-
underlying path, without providing them the ability to submit a POST request for the
|
94
|
-
underlying path, with no other access control.
|
95
|
-
|
96
|
-
The :params option accepts a hash of params, converts it into a query string, and
|
97
|
-
includes the query string in the returned path. It sets the flags segment to +p+, which
|
98
|
-
means r.hmac_path will check for that exact query string. Requests with an empty query
|
99
|
-
string or a different string will not match.
|
100
|
-
|
101
|
-
hmac_path('/widget/1', params: {foo: 'bar'})
|
102
|
-
# => "/fe8d03f9572d5af6c2866295bd3c12c2ea11d290b1cbd016c3b68ee36a678139/p/widget/1?foo=bar"
|
103
|
-
|
104
|
-
For GET requests, which cannot have request bodies, that is sufficient to ensure that the
|
105
|
-
submitted params are exactly as specified. However, POST requests can have request bodies,
|
106
|
-
and request body params override query string params in r.params. So if you are using
|
107
|
-
this for POST requests (or other HTTP verbs that can have request bodies), use r.GET
|
108
|
-
instead of r.params to specifically check query string parameters.
|
109
|
-
|
110
|
-
You can use +:root+, +:method+, and +:params+ at the same time:
|
111
|
-
|
112
|
-
hmac_path('/1', root: '/widget', method: :get, params: {foo: 'bar'})
|
113
|
-
# => "/widget/9169af1b8f40c62a1c2bb15b1b377c65bda681b8efded0e613a4176387468c15/mp/1?foo=bar"
|
114
|
-
|
115
|
-
This gives you a path only valid for a GET request with a root of "/widget" and
|
116
|
-
a query string of "foo=bar".
|
117
|
-
|
118
|
-
To handle secret rotation, you can provide an :old_secret option when loading the
|
119
|
-
plugin.
|
120
|
-
|
121
|
-
plugin :hmac_paths, secret: 'some-secret-value-with-at-least-32-bytes',
|
122
|
-
old_secret: 'previous-secret-value-with-at-least-32-bytes'
|
123
|
-
|
124
|
-
This will use :secret for constructing new paths, but will respect paths generated by
|
125
|
-
:old_secret.
|
126
|
-
|
127
|
-
= Other Improvements
|
128
|
-
|
129
|
-
* When not using cached templates in the render plugin, the render plugin
|
130
|
-
now has better handling when a template is modified and results in an
|
131
|
-
error. Previously, the error would be raised on the first request after
|
132
|
-
the template modification, but subsequent requests would use the
|
133
|
-
previous template value. The render plugin will no longer update the
|
134
|
-
last modified time in this case, so if a template is modified and
|
135
|
-
introduces an error (e.g. SyntaxError in an erb template), all future
|
136
|
-
requests that use the template will result in the error being raised,
|
137
|
-
until the template is fixed.
|
138
|
-
|
139
|
-
= Backwards Compatibility
|
140
|
-
|
141
|
-
* The internal TemplateMtimeWrapper API has been modified. As documented,
|
142
|
-
this is an internal class and the API can change in any Roda version.
|
143
|
-
However, if any code was relying on the previous implementation of
|
144
|
-
TemplateMtimeWrapper#modified?, it will need to be modified, as that
|
145
|
-
method has been replaced with TemplateMtimeWrapper#if_modified.
|
146
|
-
|
147
|
-
Additionally, the TemplateMtimeWrapper#compiled_method_lambda API has
|
148
|
-
also changed.
|
data/doc/release_notes/3.8.0.txt
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* The convert_each! method in the typecast_params plugin now
|
4
|
-
accepts a Proc or Method value for the :keys option. The proc
|
5
|
-
or method is called with the current array or hash that
|
6
|
-
typecast params is operating on, and should return an
|
7
|
-
array of keys to use for the conversion.
|
8
|
-
|
9
|
-
* The convert_each! method in the typecast_params plugin will
|
10
|
-
now automatically handle hashes with keys from '0'..'N',
|
11
|
-
without a :keys option being provided.
|
12
|
-
|
13
|
-
This makes it possible to handle parameter names such as
|
14
|
-
foo[0][bar], foo[0][baz], foo[1][bar], and foo[1][baz], if you
|
15
|
-
want to avoid the issues related to rack's issues when parsing
|
16
|
-
array parameters.
|
17
|
-
|
18
|
-
= Other Improvements
|
19
|
-
|
20
|
-
* The Roda::RodaVersionNumber constant has been added for easier
|
21
|
-
version comparisons. It is 30080 for version 3.8.0.
|
22
|
-
|
23
|
-
= Backwards Compatibility
|
24
|
-
|
25
|
-
* When an unsupported type is given as value of the :keys option
|
26
|
-
to the convert_each! method in the typecast_params plugin, a
|
27
|
-
ProgrammerError exception is now raised.
|
@@ -1,31 +0,0 @@
|
|
1
|
-
= New Features
|
2
|
-
|
3
|
-
* The hmac_paths plugin now supports a :namespace option for both hmac_path and
|
4
|
-
r.hmac_path. The :namespace option makes the generated HMAC values unique
|
5
|
-
per namespace, allowing easy use of per user/group HMAC paths. This can
|
6
|
-
be useful if the same path will show different information to different
|
7
|
-
users/groups, and you want to prevent path enumeration for each user/group
|
8
|
-
(not allow paths enumerated by one user/group to be valid for a different
|
9
|
-
user/group). Example:
|
10
|
-
|
11
|
-
hmac_path('/widget/1', namespace: '1')
|
12
|
-
# => "/3793ac2a72ea399c40cbd63f154d19f0fe34cdf8d347772134c506a0b756d590/n/widget/1"
|
13
|
-
|
14
|
-
hmac_path('/widget/1', namespace: '2')
|
15
|
-
# => "/0e1e748860d4fd17fe9b7c8259b1e26996502c38e465f802c2c9a0a13000087c/n/widget/1"
|
16
|
-
|
17
|
-
The HMAC path created with namespace: '1' will only be valid when calling
|
18
|
-
r.hmac_path with namespace: '1' (similar for namespace: '2').
|
19
|
-
|
20
|
-
It is expected that the most common use of the :namespace option is to
|
21
|
-
reference session values, so the value of each path depends on the logged in
|
22
|
-
user. You can use the :namespace_session_key plugin option to set the
|
23
|
-
default namespace for both hmac_path and r.hmac_path:
|
24
|
-
|
25
|
-
plugin :hmac_paths, secret: 'some-secret-value-with-at-least-32-bytes',
|
26
|
-
namespace_session_key: 'account_id'
|
27
|
-
|
28
|
-
This will use <tt>session['account_id']</tt> (converted to a string) as the namespace
|
29
|
-
for both hmac_path and r.hmac_path, unless a specific :namespace option is
|
30
|
-
given, making it simple to implement per user/group HMAC paths across an
|
31
|
-
application.
|