padrino-core 0.16.0.pre3 → 0.16.0
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.rdoc +8 -8
- data/Rakefile +1 -1
- data/bin/padrino +1 -1
- data/lib/padrino-core/application/application_setup.rb +28 -26
- data/lib/padrino-core/application/authenticity_token.rb +3 -2
- data/lib/padrino-core/application/flash.rb +4 -5
- data/lib/padrino-core/application/params_protection.rb +34 -37
- data/lib/padrino-core/application/routing.rb +165 -164
- data/lib/padrino-core/application/show_exceptions.rb +5 -7
- data/lib/padrino-core/application.rb +4 -4
- data/lib/padrino-core/caller.rb +28 -30
- data/lib/padrino-core/cli/adapter.rb +4 -4
- data/lib/padrino-core/cli/base.rb +31 -32
- data/lib/padrino-core/cli/binstub.rb +9 -8
- data/lib/padrino-core/cli/console.rb +1 -1
- data/lib/padrino-core/cli/launcher.rb +45 -42
- data/lib/padrino-core/cli/rake.rb +16 -14
- data/lib/padrino-core/cli/rake_tasks.rb +18 -20
- data/lib/padrino-core/command.rb +1 -1
- data/lib/padrino-core/ext/sinatra.rb +3 -2
- data/lib/padrino-core/filter.rb +3 -3
- data/lib/padrino-core/loader.rb +10 -12
- data/lib/padrino-core/logger.rb +87 -78
- data/lib/padrino-core/mounter/application_extension.rb +2 -2
- data/lib/padrino-core/mounter.rb +33 -34
- data/lib/padrino-core/path_router/compiler.rb +8 -8
- data/lib/padrino-core/path_router/matcher.rb +11 -11
- data/lib/padrino-core/path_router/route.rb +15 -15
- data/lib/padrino-core/path_router.rb +4 -3
- data/lib/padrino-core/reloader/rack.rb +1 -1
- data/lib/padrino-core/reloader/storage.rb +12 -11
- data/lib/padrino-core/reloader.rb +18 -19
- data/lib/padrino-core/router.rb +14 -14
- data/lib/padrino-core/server.rb +20 -24
- data/lib/padrino-core/tasks.rb +0 -1
- data/lib/padrino-core/version.rb +1 -1
- data/lib/padrino-core.rb +9 -10
- data/padrino-core.gemspec +18 -17
- data/test/fixtures/app_gem/app_gem.gemspec +8 -7
- data/test/fixtures/app_gem/lib/app_gem/version.rb +1 -1
- data/test/fixtures/apps/complex.rb +6 -6
- data/test/fixtures/apps/concerned/app.rb +1 -1
- data/test/fixtures/apps/custom_dependencies/custom_dependencies.rb +3 -3
- data/test/fixtures/apps/demo_app.rb +1 -1
- data/test/fixtures/apps/demo_demo.rb +1 -1
- data/test/fixtures/apps/demo_project/api/app.rb +1 -1
- data/test/fixtures/apps/demo_project/app.rb +1 -1
- data/test/fixtures/apps/helpers/class_methods_helpers.rb +1 -0
- data/test/fixtures/apps/helpers/instance_methods_helpers.rb +1 -0
- data/test/fixtures/apps/helpers/system_helpers.rb +0 -1
- data/test/fixtures/apps/lib/myklass/mysubklass.rb +2 -2
- data/test/fixtures/apps/mountable_apps/rack_apps.rb +7 -7
- data/test/fixtures/apps/precompiled_app.rb +6 -5
- data/test/fixtures/apps/simple.rb +5 -5
- data/test/fixtures/apps/static.rb +2 -2
- data/test/fixtures/apps/stealthy/app.rb +1 -1
- data/test/fixtures/apps/stealthy/helpers/stealthy_class_helpers.rb +1 -1
- data/test/fixtures/apps/system.rb +1 -1
- data/test/fixtures/apps/system_class_methods_demo.rb +1 -1
- data/test/fixtures/apps/system_instance_methods_demo.rb +1 -1
- data/test/fixtures/dependencies/a.rb +1 -1
- data/test/fixtures/dependencies/b.rb +1 -1
- data/test/fixtures/dependencies/c.rb +1 -1
- data/test/fixtures/dependencies/circular/e.rb +2 -1
- data/test/fixtures/dependencies/d.rb +1 -1
- data/test/fixtures/dependencies/linear/i.rb +1 -1
- data/test/fixtures/dependencies/nested/l.rb +2 -2
- data/test/fixtures/dependencies/nested/m.rb +1 -1
- data/test/fixtures/dependencies/nested/qqq.rb +2 -2
- data/test/fixtures/dependencies/nested/rrr.rb +1 -1
- data/test/fixtures/dependencies/nested/sss.rb +1 -1
- data/test/fixtures/reloadable_apps/external/app/app.rb +0 -1
- data/test/fixtures/reloadable_apps/external/app/controllers/base.rb +1 -2
- data/test/fixtures/reloadable_apps/main/app.rb +2 -2
- data/test/helper.rb +2 -2
- data/test/test_application.rb +59 -60
- data/test/test_configuration.rb +2 -2
- data/test/test_core.rb +13 -13
- data/test/test_csrf_protection.rb +67 -63
- data/test/test_dependencies.rb +33 -34
- data/test/test_filters.rb +52 -53
- data/test/test_flash.rb +18 -18
- data/test/test_locale.rb +2 -2
- data/test/test_logger.rb +65 -65
- data/test/test_mounter.rb +133 -123
- data/test/test_params_protection.rb +40 -40
- data/test/test_reloader_complex.rb +24 -24
- data/test/test_reloader_external.rb +10 -10
- data/test/test_reloader_simple.rb +26 -23
- data/test/test_reloader_storage.rb +9 -12
- data/test/test_reloader_system.rb +29 -29
- data/test/test_restful_routing.rb +19 -19
- data/test/test_router.rb +126 -145
- data/test/test_routing.rb +897 -909
- metadata +7 -7
data/test/test_application.rb
CHANGED
|
@@ -1,61 +1,60 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative 'helper'
|
|
2
2
|
|
|
3
3
|
class PadrinoPristine < Padrino::Application; end
|
|
4
4
|
class PadrinoTestApp < Padrino::Application; end
|
|
5
5
|
class PadrinoTestApp2 < Padrino::Application; end
|
|
6
6
|
|
|
7
|
-
describe
|
|
7
|
+
describe 'Application' do
|
|
8
8
|
before { Padrino.clear! }
|
|
9
9
|
|
|
10
10
|
describe 'for application functionality' do
|
|
11
|
-
|
|
12
11
|
it 'should check default options' do
|
|
13
12
|
assert File.identical?(__FILE__, PadrinoPristine.app_file)
|
|
14
13
|
assert_equal :padrino_pristine, PadrinoPristine.app_name
|
|
15
14
|
assert_equal :test, PadrinoPristine.environment
|
|
16
15
|
assert_equal Padrino.root('views'), PadrinoPristine.views
|
|
17
|
-
assert
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
assert
|
|
23
|
-
|
|
16
|
+
assert PadrinoPristine.raise_errors
|
|
17
|
+
refute PadrinoPristine.logging
|
|
18
|
+
refute PadrinoPristine.sessions
|
|
19
|
+
refute PadrinoPristine.dump_errors
|
|
20
|
+
refute PadrinoPristine.show_exceptions
|
|
21
|
+
assert PadrinoPristine.raise_errors
|
|
22
|
+
refute Padrino.configure_apps
|
|
24
23
|
end
|
|
25
24
|
|
|
26
25
|
it 'should check padrino specific options' do
|
|
27
|
-
|
|
26
|
+
refute PadrinoPristine.instance_variable_get(:@_configured)
|
|
28
27
|
PadrinoPristine.send(:setup_application!)
|
|
29
28
|
assert_equal :padrino_pristine, PadrinoPristine.app_name
|
|
30
29
|
assert_equal 'StandardFormBuilder', PadrinoPristine.default_builder
|
|
31
|
-
assert
|
|
32
|
-
|
|
30
|
+
assert PadrinoPristine.instance_variable_get(:@_configured)
|
|
31
|
+
refute PadrinoPristine.reload?
|
|
33
32
|
end
|
|
34
33
|
|
|
35
34
|
it 'should set global project settings' do
|
|
36
|
-
Padrino.configure_apps { enable :sessions; set :foo,
|
|
35
|
+
Padrino.configure_apps { enable :sessions; set :foo, 'bar' }
|
|
37
36
|
PadrinoTestApp.send(:default_configuration!)
|
|
38
37
|
PadrinoTestApp2.send(:default_configuration!)
|
|
39
|
-
assert PadrinoTestApp.sessions,
|
|
40
|
-
assert_equal
|
|
38
|
+
assert PadrinoTestApp.sessions, 'should have sessions enabled'
|
|
39
|
+
assert_equal 'bar', PadrinoTestApp.settings.foo, 'should have foo assigned'
|
|
41
40
|
assert_equal PadrinoTestApp.session_secret, PadrinoTestApp2.session_secret
|
|
42
41
|
end
|
|
43
42
|
|
|
44
43
|
it 'should be able to configure_apps multiple times' do
|
|
45
|
-
Padrino.configure_apps { set :foo1,
|
|
46
|
-
Padrino.configure_apps { set :foo1,
|
|
47
|
-
Padrino.configure_apps { set :foo2,
|
|
44
|
+
Padrino.configure_apps { set :foo1, 'bar' }
|
|
45
|
+
Padrino.configure_apps { set :foo1, 'bam' }
|
|
46
|
+
Padrino.configure_apps { set :foo2, 'baz' }
|
|
48
47
|
PadrinoTestApp.send(:default_configuration!)
|
|
49
|
-
assert_equal
|
|
50
|
-
assert_equal
|
|
48
|
+
assert_equal 'bam', PadrinoTestApp.settings.foo1, 'should have foo1 assigned to bam'
|
|
49
|
+
assert_equal 'baz', PadrinoTestApp.settings.foo2, 'should have foo2 assigned to baz'
|
|
51
50
|
end
|
|
52
51
|
|
|
53
52
|
it 'should have shared sessions accessible in project' do
|
|
54
53
|
Padrino.configure_apps { enable :sessions; set :session_secret, PadrinoTestApp2.session_secret }
|
|
55
|
-
Padrino.mount(
|
|
56
|
-
Padrino.mount(
|
|
54
|
+
Padrino.mount('PadrinoTestApp').to('/write')
|
|
55
|
+
Padrino.mount('PadrinoTestApp2').to('/read')
|
|
57
56
|
PadrinoTestApp.send :default_configuration!
|
|
58
|
-
PadrinoTestApp.get('/') { session[:foo] =
|
|
57
|
+
PadrinoTestApp.get('/') { session[:foo] = 'shared' }
|
|
59
58
|
PadrinoTestApp2.send(:default_configuration!)
|
|
60
59
|
PadrinoTestApp2.get('/') { session[:foo] }
|
|
61
60
|
@app = Padrino.application
|
|
@@ -73,10 +72,10 @@ describe "Application" do
|
|
|
73
72
|
|
|
74
73
|
it 'should able to set custome session management' do
|
|
75
74
|
class PadrinoTestApp3 < Padrino::Application
|
|
76
|
-
set :sessions, :
|
|
75
|
+
set :sessions, use: Rack::Session::Pool
|
|
77
76
|
end
|
|
78
|
-
Padrino.mount(
|
|
79
|
-
PadrinoTestApp3.get('/write') { session[:foo] =
|
|
77
|
+
Padrino.mount('PadrinoTestApp3').to('/')
|
|
78
|
+
PadrinoTestApp3.get('/write') { session[:foo] = 'pool' }
|
|
80
79
|
PadrinoTestApp3.get('/read') { session[:foo] }
|
|
81
80
|
@app = Padrino.application
|
|
82
81
|
get '/write'
|
|
@@ -88,12 +87,14 @@ describe "Application" do
|
|
|
88
87
|
class PadrinoTestApp4 < Padrino::Application
|
|
89
88
|
enable :sessions
|
|
90
89
|
end
|
|
90
|
+
|
|
91
91
|
class PadrinoTestApp5 < Padrino::Application
|
|
92
|
-
set :sessions, :
|
|
92
|
+
set :sessions, use: Rack::Session::Pool
|
|
93
93
|
end
|
|
94
|
-
|
|
95
|
-
Padrino.mount(
|
|
96
|
-
|
|
94
|
+
|
|
95
|
+
Padrino.mount('PadrinoTestApp4').to('/write')
|
|
96
|
+
Padrino.mount('PadrinoTestApp5').to('/read')
|
|
97
|
+
PadrinoTestApp4.get('/') { session[:foo] = 'cookie' }
|
|
97
98
|
PadrinoTestApp5.get('/') { session[:foo] }
|
|
98
99
|
@app = Padrino.application
|
|
99
100
|
get '/write'
|
|
@@ -106,8 +107,8 @@ describe "Application" do
|
|
|
106
107
|
mock_app do
|
|
107
108
|
provides :xml
|
|
108
109
|
|
|
109
|
-
get(
|
|
110
|
-
get(
|
|
110
|
+
get('/foo') { "Foo in #{content_type.inspect}" }
|
|
111
|
+
get('/bar') { "Foo in #{content_type.inspect}" }
|
|
111
112
|
end
|
|
112
113
|
|
|
113
114
|
get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
|
@@ -116,61 +117,59 @@ describe "Application" do
|
|
|
116
117
|
assert_equal 'Foo in :xml', body
|
|
117
118
|
|
|
118
119
|
get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
|
|
119
|
-
assert_equal
|
|
120
|
+
assert_equal 'Foo in nil', body
|
|
120
121
|
end
|
|
121
122
|
|
|
122
123
|
it 'should resolve views and layouts paths' do
|
|
123
|
-
assert_equal Padrino.root('views')
|
|
124
|
-
assert_equal Padrino.root('views')
|
|
124
|
+
assert_equal "#{Padrino.root('views')}/users/index", PadrinoPristine.view_path('users/index')
|
|
125
|
+
assert_equal "#{Padrino.root('views')}/layouts/app", PadrinoPristine.layout_path(:app)
|
|
125
126
|
end
|
|
126
127
|
|
|
127
|
-
describe
|
|
128
|
+
describe 'errors' do
|
|
128
129
|
it 'should have not mapped errors on development' do
|
|
129
|
-
mock_app { get('/'){ 'HI' } }
|
|
130
|
-
get
|
|
130
|
+
mock_app { get('/') { 'HI' } }
|
|
131
|
+
get '/'
|
|
131
132
|
assert_empty @app.errors
|
|
132
133
|
end
|
|
133
134
|
|
|
134
135
|
it 'should have mapped errors on production' do
|
|
135
|
-
mock_app { set :environment, :production; get('/'){ 'HI' } }
|
|
136
|
-
get
|
|
136
|
+
mock_app { set :environment, :production; get('/') { 'HI' } }
|
|
137
|
+
get '/'
|
|
137
138
|
assert_equal 1, @app.errors.size
|
|
138
139
|
end
|
|
139
140
|
|
|
140
141
|
it 'should overide errors' do
|
|
141
142
|
mock_app do
|
|
142
143
|
set :environment, :production
|
|
143
|
-
get('/'){ raise }
|
|
144
|
-
error(::Exception){ 'custom error' }
|
|
144
|
+
get('/') { raise }
|
|
145
|
+
error(::Exception) { 'custom error' }
|
|
145
146
|
end
|
|
146
|
-
get
|
|
147
|
+
get '/'
|
|
147
148
|
assert_equal 1, @app.errors.size
|
|
148
149
|
assert_equal 'custom error', body
|
|
149
150
|
end
|
|
150
151
|
|
|
152
|
+
# see naming collision in issue #1814
|
|
151
153
|
it 'should pass Routing#parent to Module#parent' do
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
def parent
|
|
157
|
-
:dirty
|
|
158
|
-
end
|
|
154
|
+
ConstTest = Class.new(Padrino::Application)
|
|
155
|
+
class Module
|
|
156
|
+
def parent
|
|
157
|
+
:dirty
|
|
159
158
|
end
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
159
|
+
end
|
|
160
|
+
assert_equal :dirty, ConstTest.parent
|
|
161
|
+
ensure
|
|
162
|
+
Module.instance_eval { undef :parent }
|
|
164
163
|
end
|
|
165
164
|
end
|
|
166
165
|
|
|
167
|
-
describe
|
|
168
|
-
it
|
|
169
|
-
require File.expand_path(
|
|
166
|
+
describe 'pre-compile routes' do
|
|
167
|
+
it 'should compile routes before first request if enabled the :precompile_routes option' do
|
|
168
|
+
require File.expand_path("#{__dir__}/fixtures/apps/precompiled_app")
|
|
170
169
|
assert_instance_of Padrino::PathRouter::Compiler, PrecompiledApp::App.compiled_router.engine
|
|
171
170
|
assert_instance_of Padrino::PathRouter::Compiler, PrecompiledApp::SubApp.compiled_router.engine
|
|
172
|
-
|
|
173
|
-
|
|
171
|
+
assert PrecompiledApp::App.compiled_router.engine.compiled?
|
|
172
|
+
assert PrecompiledApp::SubApp.compiled_router.engine.compiled?
|
|
174
173
|
assert_equal 20, PrecompiledApp::App.compiled_router.engine.routes.length
|
|
175
174
|
assert_equal 20, PrecompiledApp::SubApp.compiled_router.engine.routes.length
|
|
176
175
|
end
|
data/test/test_configuration.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative 'helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
3
|
+
describe 'PadrinoConfiguration' do
|
|
4
4
|
it 'should be able to store values' do
|
|
5
5
|
Padrino.config.val1 = 12_345
|
|
6
6
|
assert_equal 12_345, Padrino.config.val1
|
data/test/test_core.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative 'helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
3
|
+
describe 'Core' do
|
|
4
4
|
def setup
|
|
5
5
|
Padrino.clear!
|
|
6
6
|
end
|
|
@@ -19,7 +19,7 @@ describe "Core" do
|
|
|
19
19
|
|
|
20
20
|
it 'should validate global helpers' do
|
|
21
21
|
assert_equal :test, Padrino.env
|
|
22
|
-
assert_match(
|
|
22
|
+
assert_match(%r{/test}, Padrino.root)
|
|
23
23
|
assert Padrino.version
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -38,25 +38,25 @@ describe "Core" do
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it 'should add middlewares in front if specified' do
|
|
41
|
-
test = Class.new
|
|
41
|
+
test = Class.new do
|
|
42
42
|
def initialize(app)
|
|
43
43
|
@app = app
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def call(env)
|
|
47
47
|
status, headers, body = @app.call(env)
|
|
48
|
-
headers[
|
|
48
|
+
headers['Middleware-Called'] = 'yes'
|
|
49
49
|
[status, headers, body]
|
|
50
50
|
end
|
|
51
|
-
|
|
51
|
+
end
|
|
52
52
|
|
|
53
53
|
class Foo < Padrino::Application; end
|
|
54
54
|
|
|
55
55
|
Padrino.use(test)
|
|
56
|
-
Padrino.mount(Foo).to(
|
|
56
|
+
Padrino.mount(Foo).to('/')
|
|
57
57
|
|
|
58
|
-
res = Rack::MockRequest.new(Padrino.application).get(
|
|
59
|
-
assert_equal
|
|
58
|
+
res = Rack::MockRequest.new(Padrino.application).get('/')
|
|
59
|
+
assert_equal 'yes', res['Middleware-Called']
|
|
60
60
|
end
|
|
61
61
|
|
|
62
62
|
it 'should properly set default options' do
|
|
@@ -75,13 +75,13 @@ describe "Core" do
|
|
|
75
75
|
it 'should return a friendly 500' do
|
|
76
76
|
mock_app do
|
|
77
77
|
enable :show_exceptions
|
|
78
|
-
get(:index){ raise StandardError }
|
|
78
|
+
get(:index) { raise StandardError }
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
-
get
|
|
81
|
+
get '/'
|
|
82
82
|
assert_equal 500, status
|
|
83
|
-
assert_includes body,
|
|
84
|
-
assert_includes body,
|
|
83
|
+
assert_includes body, 'StandardError'
|
|
84
|
+
assert_includes body, '<code>show_exceptions</code> setting'
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
87
|
end
|
|
@@ -1,206 +1,210 @@
|
|
|
1
|
-
|
|
1
|
+
require_relative 'helper'
|
|
2
2
|
|
|
3
|
-
describe
|
|
3
|
+
describe 'Application' do
|
|
4
4
|
before { Padrino.clear! }
|
|
5
5
|
|
|
6
6
|
describe 'CSRF protection' do
|
|
7
|
-
describe
|
|
7
|
+
describe 'with CSRF protection on' do
|
|
8
8
|
before do
|
|
9
|
-
@token =
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
@token =
|
|
10
|
+
begin
|
|
11
|
+
Rack::Protection::AuthenticityToken.random_token
|
|
12
|
+
rescue StandardError
|
|
13
|
+
'a_token'
|
|
14
|
+
end
|
|
15
|
+
|
|
14
16
|
mock_app do
|
|
15
17
|
enable :sessions
|
|
16
18
|
enable :protect_from_csrf
|
|
17
|
-
post('/'){ 'HI' }
|
|
19
|
+
post('/') { 'HI' }
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
|
|
21
23
|
it 'should not allow requests without tokens' do
|
|
22
|
-
post
|
|
24
|
+
post '/'
|
|
23
25
|
assert_equal 403, status
|
|
24
26
|
end
|
|
25
27
|
|
|
26
28
|
it 'should allow requests with correct tokens' do
|
|
27
|
-
post
|
|
29
|
+
post '/', { 'authenticity_token' => @token }, 'rack.session' => { csrf: @token }
|
|
28
30
|
assert_equal 200, status
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
it 'should not allow requests with incorrect tokens' do
|
|
32
|
-
post
|
|
34
|
+
post '/', { 'authenticity_token' => 'b' }, 'rack.session' => { csrf: @token }
|
|
33
35
|
assert_equal 403, status
|
|
34
36
|
end
|
|
35
37
|
|
|
36
38
|
it 'should allow requests with correct X-CSRF-TOKEN' do
|
|
37
|
-
post
|
|
39
|
+
post '/', {}, 'rack.session' => { csrf: @token }, 'HTTP_X_CSRF_TOKEN' => @token
|
|
38
40
|
assert_equal 200, status
|
|
39
41
|
end
|
|
40
42
|
|
|
41
43
|
it 'should not allow requests with incorrect X-CSRF-TOKEN' do
|
|
42
|
-
post
|
|
44
|
+
post '/', {}, 'rack.session' => { csrf: @token }, 'HTTP_X_CSRF_TOKEN' => 'b'
|
|
43
45
|
assert_equal 403, status
|
|
44
46
|
end
|
|
45
47
|
end
|
|
46
48
|
|
|
47
|
-
describe
|
|
49
|
+
describe 'without CSRF protection on' do
|
|
48
50
|
before do
|
|
49
51
|
mock_app do
|
|
50
52
|
enable :sessions
|
|
51
53
|
disable :protect_from_csrf
|
|
52
|
-
post('/'){ 'HI' }
|
|
54
|
+
post('/') { 'HI' }
|
|
53
55
|
end
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
it 'should allows requests without tokens' do
|
|
57
|
-
post
|
|
59
|
+
post '/'
|
|
58
60
|
assert_equal 200, status
|
|
59
61
|
end
|
|
60
62
|
|
|
61
63
|
it 'should allow requests with correct tokens' do
|
|
62
|
-
post
|
|
64
|
+
post '/', { 'authenticity_token' => 'a' }, 'rack.session' => { csrf: 'a' }
|
|
63
65
|
assert_equal 200, status
|
|
64
66
|
end
|
|
65
67
|
|
|
66
68
|
it 'should allow requests with incorrect tokens' do
|
|
67
|
-
post
|
|
69
|
+
post '/', { 'authenticity_token' => 'a' }, 'rack.session' => { csrf: 'b' }
|
|
68
70
|
assert_equal 200, status
|
|
69
71
|
end
|
|
70
72
|
|
|
71
73
|
it 'should allow requests with correct X-CSRF-TOKEN' do
|
|
72
|
-
post
|
|
74
|
+
post '/', {}, 'rack.session' => { csrf: 'a' }, 'HTTP_X_CSRF_TOKEN' => 'a'
|
|
73
75
|
assert_equal 200, status
|
|
74
76
|
end
|
|
75
77
|
|
|
76
78
|
it 'should allow requests with incorrect X-CSRF-TOKEN' do
|
|
77
|
-
post
|
|
79
|
+
post '/', {}, 'rack.session' => { csrf: 'a' }, 'HTTP_X_CSRF_TOKEN' => 'b'
|
|
78
80
|
assert_equal 200, status
|
|
79
81
|
end
|
|
80
82
|
end
|
|
81
83
|
|
|
82
|
-
describe
|
|
84
|
+
describe 'with optional CSRF protection' do
|
|
83
85
|
before do
|
|
84
86
|
mock_app do
|
|
85
87
|
enable :sessions
|
|
86
88
|
enable :protect_from_csrf
|
|
87
89
|
enable :allow_disabled_csrf
|
|
88
90
|
post('/on') { 'HI' }
|
|
89
|
-
post('/off', :
|
|
91
|
+
post('/off', csrf_protection: false) { 'HI' }
|
|
90
92
|
end
|
|
91
93
|
end
|
|
92
94
|
|
|
93
95
|
it 'should allow access to routes with csrf_protection off' do
|
|
94
|
-
post
|
|
96
|
+
post '/off'
|
|
95
97
|
assert_equal 200, status
|
|
96
98
|
end
|
|
97
99
|
|
|
98
100
|
it 'should not allow access to routes with csrf_protection on' do
|
|
99
|
-
post
|
|
101
|
+
post '/on'
|
|
100
102
|
assert_equal 403, status
|
|
101
103
|
assert_equal 'Forbidden', body
|
|
102
104
|
end
|
|
103
105
|
end
|
|
104
106
|
|
|
105
|
-
describe
|
|
107
|
+
describe 'with :except option that is using Proc' do
|
|
106
108
|
before do
|
|
107
109
|
mock_app do
|
|
108
110
|
enable :sessions
|
|
109
|
-
set :protect_from_csrf, :
|
|
110
|
-
post(
|
|
111
|
-
post(
|
|
112
|
-
post(
|
|
111
|
+
set :protect_from_csrf, except: proc { |env| ['/', '/foo'].any? { |path| path == env['PATH_INFO'] } }
|
|
112
|
+
post('/') { 'Hello' }
|
|
113
|
+
post('/foo') { 'Hello, foo' }
|
|
114
|
+
post('/bar') { 'Hello, bar' }
|
|
113
115
|
end
|
|
114
116
|
end
|
|
115
117
|
|
|
116
118
|
it 'should allow ignoring CSRF protection on specific routes' do
|
|
117
|
-
post
|
|
119
|
+
post '/'
|
|
118
120
|
assert_equal 200, status
|
|
119
|
-
post
|
|
121
|
+
post '/foo'
|
|
120
122
|
assert_equal 200, status
|
|
121
|
-
post
|
|
123
|
+
post '/bar'
|
|
122
124
|
assert_equal 403, status
|
|
123
125
|
end
|
|
124
126
|
end
|
|
125
127
|
|
|
126
|
-
describe
|
|
128
|
+
describe 'with :except option that is using String and Regexp' do
|
|
127
129
|
before do
|
|
128
130
|
mock_app do
|
|
129
131
|
enable :sessions
|
|
130
|
-
set :protect_from_csrf, :
|
|
131
|
-
post(
|
|
132
|
-
post(
|
|
133
|
-
post(
|
|
132
|
+
set :protect_from_csrf, except: ['/a', %r{^/a.c$}]
|
|
133
|
+
post('/a') { 'a' }
|
|
134
|
+
post('/abc') { 'abc' }
|
|
135
|
+
post('/foo') { 'foo' }
|
|
134
136
|
end
|
|
135
137
|
end
|
|
136
138
|
|
|
137
139
|
it 'should allow ignoring CSRF protection on specific routes' do
|
|
138
|
-
post
|
|
140
|
+
post '/a'
|
|
139
141
|
assert_equal 200, status
|
|
140
|
-
post
|
|
142
|
+
post '/abc'
|
|
141
143
|
assert_equal 200, status
|
|
142
|
-
post
|
|
144
|
+
post '/foo'
|
|
143
145
|
assert_equal 403, status
|
|
144
146
|
end
|
|
145
147
|
end
|
|
146
148
|
|
|
147
|
-
describe
|
|
149
|
+
describe 'with custom protection options' do
|
|
148
150
|
before do
|
|
149
|
-
@token =
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
@token =
|
|
152
|
+
begin
|
|
153
|
+
Rack::Protection::AuthenticityToken.random_token
|
|
154
|
+
rescue StandardError
|
|
155
|
+
'a_token'
|
|
156
|
+
end
|
|
157
|
+
|
|
154
158
|
mock_app do
|
|
155
159
|
enable :sessions
|
|
156
|
-
set :protect_from_csrf, :
|
|
157
|
-
post(
|
|
160
|
+
set :protect_from_csrf, authenticity_param: 'foobar', message: 'sucker!'
|
|
161
|
+
post('/a') { 'a' }
|
|
158
162
|
end
|
|
159
163
|
end
|
|
160
164
|
|
|
161
165
|
it 'should allow configuring protection options' do
|
|
162
|
-
post
|
|
166
|
+
post '/a', { 'foobar' => @token }, 'rack.session' => { csrf: @token }
|
|
163
167
|
assert_equal 200, status
|
|
164
168
|
end
|
|
165
169
|
|
|
166
170
|
it 'should allow configuring message' do
|
|
167
|
-
post
|
|
171
|
+
post '/a'
|
|
168
172
|
assert_equal 403, status
|
|
169
173
|
assert_equal 'sucker!', body
|
|
170
174
|
end
|
|
171
175
|
end
|
|
172
176
|
|
|
173
|
-
describe
|
|
177
|
+
describe 'with middleware' do
|
|
174
178
|
before do
|
|
175
179
|
class Middleware < Sinatra::Base
|
|
176
|
-
post(
|
|
177
|
-
post(
|
|
180
|
+
post('/middleware') { 'Hello, middleware' }
|
|
181
|
+
post('/dummy') { 'Hello, dummy' }
|
|
178
182
|
end
|
|
179
183
|
mock_app do
|
|
180
184
|
enable :sessions
|
|
181
|
-
set :protect_from_csrf, :
|
|
185
|
+
set :protect_from_csrf, except: proc { |env| ['/', '/middleware'].any? { |path| path == env['PATH_INFO'] } }
|
|
182
186
|
use Middleware
|
|
183
|
-
post(
|
|
187
|
+
post('/') { 'Hello' }
|
|
184
188
|
end
|
|
185
189
|
end
|
|
186
190
|
|
|
187
191
|
it 'should allow ignoring CSRF protection on specific routes of middleware' do
|
|
188
|
-
post
|
|
192
|
+
post '/'
|
|
189
193
|
assert_equal 200, status
|
|
190
|
-
post
|
|
194
|
+
post '/middleware'
|
|
191
195
|
assert_equal 200, status
|
|
192
|
-
post
|
|
196
|
+
post '/dummy'
|
|
193
197
|
assert_equal 403, status
|
|
194
198
|
end
|
|
195
199
|
end
|
|
196
200
|
|
|
197
|
-
describe
|
|
201
|
+
describe 'with standard report layout' do
|
|
198
202
|
before do
|
|
199
203
|
mock_app do
|
|
200
204
|
enable :sessions
|
|
201
|
-
set :protect_from_csrf, :
|
|
205
|
+
set :protect_from_csrf, message: 'sucker!'
|
|
202
206
|
enable :report_csrf_failure
|
|
203
|
-
post(
|
|
207
|
+
post('/a') { 'a' }
|
|
204
208
|
error 403 do
|
|
205
209
|
halt 406, 'please, do not hack'
|
|
206
210
|
end
|
|
@@ -208,7 +212,7 @@ describe "Application" do
|
|
|
208
212
|
end
|
|
209
213
|
|
|
210
214
|
it 'should allow configuring protection options' do
|
|
211
|
-
post
|
|
215
|
+
post '/a'
|
|
212
216
|
assert_equal 406, status
|
|
213
217
|
assert_equal 'please, do not hack', body
|
|
214
218
|
end
|