padrino-csrf 0.1.0 → 0.1.1
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.
- data/.rspec +2 -0
- data/Rakefile +28 -5
- data/lib/padrino-csrf.rb +1 -2
- data/lib/padrino-csrf/routing.rb +4 -2
- data/lib/padrino-csrf/version.rb +1 -1
- data/padrino-csrf.gemspec +3 -2
- data/spec/csrf_spec.rb +86 -0
- data/spec/helpers_spec.rb +82 -0
- data/spec/spec.rb +21 -0
- metadata +27 -12
data/.rspec
ADDED
data/Rakefile
CHANGED
@@ -1,7 +1,30 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
require 'padrino-csrf/version'
|
3
|
+
|
1
4
|
require 'rake'
|
2
|
-
require '
|
5
|
+
require 'yard'
|
6
|
+
require 'rspec'
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
|
9
|
+
RSpec::Core::RakeTask.new do |task|
|
10
|
+
task.pattern = 'spec/**/*_spec.rb'
|
11
|
+
end
|
12
|
+
|
13
|
+
YARD::Rake::YardocTask.new
|
14
|
+
|
15
|
+
task :build do
|
16
|
+
`gem build padrino-csrf.gemspec`
|
17
|
+
end
|
18
|
+
|
19
|
+
task :install => :build do
|
20
|
+
`gem install padrino-csrf-#{Padrino::CSRF::VERSION}.gem`
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'Releases the current version into the wild'
|
24
|
+
task :release => :build do
|
25
|
+
`git tag -a v#{Padrino::CSRF::VERSION} -m "Version #{Padrino::CSRF::VERSION}"`
|
26
|
+
`gem push padrino-csrf-#{Padrino::CSRF::VERSION}.gem`
|
27
|
+
`git push --tags`
|
28
|
+
end
|
3
29
|
|
4
|
-
|
5
|
-
test.test_files = FileList['test/**/test_*.rb']
|
6
|
-
test.verbose = true
|
7
|
-
end
|
30
|
+
task :default => :spec
|
data/lib/padrino-csrf.rb
CHANGED
data/lib/padrino-csrf/routing.rb
CHANGED
@@ -46,9 +46,11 @@ module Padrino
|
|
46
46
|
# @private
|
47
47
|
def route(verb, path, options = {}, &block)
|
48
48
|
if REQUEST_BLACKLIST.include?(verb)
|
49
|
-
|
49
|
+
if options[:protect].nil?
|
50
|
+
options[:protect] = settings.prevent_request_forgery if settings.prevent_request_forgery?
|
51
|
+
end
|
50
52
|
else
|
51
|
-
options.delete
|
53
|
+
options.delete :protect
|
52
54
|
end
|
53
55
|
|
54
56
|
super(verb, path, options, &block)
|
data/lib/padrino-csrf/version.rb
CHANGED
data/padrino-csrf.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_dependency 'padrino-core'
|
20
20
|
s.add_dependency 'padrino-helpers'
|
21
21
|
|
22
|
-
s.add_development_dependency '
|
23
|
-
s.add_development_dependency '
|
22
|
+
s.add_development_dependency 'rspec', '>= 2.0.0'
|
23
|
+
s.add_development_dependency 'rspec-html-matchers'
|
24
|
+
s.add_development_dependency 'rack-test'
|
24
25
|
end
|
data/spec/csrf_spec.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require_relative 'spec'
|
2
|
+
|
3
|
+
describe Padrino::CSRF do
|
4
|
+
let :random_string do
|
5
|
+
SecureRandom.hex(32)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should validate CSRF tokens for POST requests' do
|
9
|
+
app.post :test do
|
10
|
+
# ...
|
11
|
+
end
|
12
|
+
|
13
|
+
post '/test', { _csrf_token: random_string }, 'rack.session' => { _csrf_token: random_string }
|
14
|
+
last_response.should be_ok
|
15
|
+
|
16
|
+
expect do
|
17
|
+
post '/test', { _csrf_token: 'haaaax' }, 'rack.session' => { _csrf_token: random_string }
|
18
|
+
end.to raise_error(Padrino::CSRF::InvalidToken)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should validate CSRF tokens for PUT requests' do
|
22
|
+
app.put :test do
|
23
|
+
# ...
|
24
|
+
end
|
25
|
+
|
26
|
+
put '/test', { _csrf_token: random_string }, 'rack.session' => { _csrf_token: random_string }
|
27
|
+
last_response.should be_ok
|
28
|
+
|
29
|
+
expect do
|
30
|
+
put '/test', { _csrf_token: 'haaaax' }, 'rack.session' => { _csrf_token: random_string }
|
31
|
+
end.to raise_error(Padrino::CSRF::InvalidToken)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should validate CSRF tokens for DELETE requests' do
|
35
|
+
app.delete :test do
|
36
|
+
# ...
|
37
|
+
end
|
38
|
+
|
39
|
+
delete '/test', { _csrf_token: random_string }, 'rack.session' => { _csrf_token: random_string }
|
40
|
+
last_response.should be_ok
|
41
|
+
|
42
|
+
expect do
|
43
|
+
delete '/test', { _csrf_token: 'haaaax' }, 'rack.session' => { _csrf_token: random_string }
|
44
|
+
end.to raise_error(Padrino::CSRF::InvalidToken)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should not validate CSRF tokens for GET requests' do
|
48
|
+
app.get :test do
|
49
|
+
# ...
|
50
|
+
end
|
51
|
+
|
52
|
+
get '/test', {}, 'rack.session' => { _csrf_token: random_string }
|
53
|
+
last_response.should be_ok
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'can disable validation on a request by request basis when enabled globally' do
|
57
|
+
app.enable :prevent_request_forgery
|
58
|
+
app.post :test, protect: false do
|
59
|
+
# ...
|
60
|
+
end
|
61
|
+
|
62
|
+
post '/test', {}, 'rack.session' => { _csrf_token: random_string }
|
63
|
+
last_response.should be_ok
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'can enable validation on a request by request basis when disabled globally' do
|
67
|
+
app.disable :prevent_request_forgery
|
68
|
+
app.post :test do
|
69
|
+
# ...
|
70
|
+
end
|
71
|
+
|
72
|
+
post '/test', {}, 'rack.session' => { _csrf_token: random_string }
|
73
|
+
last_response.should be_ok
|
74
|
+
|
75
|
+
app.post :another_test, protect: true do
|
76
|
+
# ...
|
77
|
+
end
|
78
|
+
|
79
|
+
post '/another_test', { _csrf_token: random_string }, 'rack.session' => { _csrf_token: random_string }
|
80
|
+
last_response.should be_ok
|
81
|
+
|
82
|
+
expect do
|
83
|
+
post '/another_test', { _csrf_token: 'haaaax' }, 'rack.session' => { _csrf_token: random_string }
|
84
|
+
end.to raise_error(Padrino::CSRF::InvalidToken)
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require_relative 'spec'
|
2
|
+
|
3
|
+
describe Padrino::CSRF::Helpers do
|
4
|
+
include Padrino::Helpers::AssetTagHelpers
|
5
|
+
include Padrino::Helpers::OutputHelpers
|
6
|
+
include Padrino::Helpers::FormHelpers
|
7
|
+
include Padrino::Helpers::TagHelpers
|
8
|
+
include Padrino::CSRF::FormHelpers
|
9
|
+
include Padrino::CSRF::Helpers
|
10
|
+
|
11
|
+
let :params do
|
12
|
+
{}
|
13
|
+
end
|
14
|
+
|
15
|
+
let :session do
|
16
|
+
{ _csrf_token: SecureRandom.hex(32) }
|
17
|
+
end
|
18
|
+
|
19
|
+
let :request do
|
20
|
+
Sinatra::Request.new('HTTP_X_CSRF_TOKEN' => nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
context '#csrf_valid?' do
|
24
|
+
it 'should return false when the CSRF param is invalid' do
|
25
|
+
params[csrf_param] = csrf_token[0..-2]
|
26
|
+
csrf_valid?.should be_false
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should return true when the CSRF param is valid' do
|
30
|
+
params[csrf_param] = csrf_token
|
31
|
+
csrf_valid?.should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should return false when the CSRF header is invalid' do
|
35
|
+
request.stub(:env).and_return('HTTP_X_CSRF_TOKEN' => csrf_token[0..-2])
|
36
|
+
csrf_valid?.should be_false
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should return true when the CSRF header is valid' do
|
40
|
+
request.stub(:env).and_return('HTTP_X_CSRF_TOKEN' => csrf_token)
|
41
|
+
csrf_valid?.should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context '#csrf_meta_tags' do
|
46
|
+
it 'should return meta tags with the current token and parameter' do
|
47
|
+
meta_tags = csrf_meta_tags
|
48
|
+
meta_tags.should have_tag(:meta, count: 1, with: { name: 'csrf-param', content: csrf_param })
|
49
|
+
meta_tags.should have_tag(:meta, count: 1, with: { name: 'csrf-token', content: csrf_token })
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context '#csrf_token' do
|
54
|
+
it 'should return the current sessions CSRF token' do
|
55
|
+
csrf_token.should == session[csrf_param]
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should set the sessions CSRF token when one is not present' do
|
59
|
+
session.clear
|
60
|
+
session[csrf_param].should be_nil
|
61
|
+
csrf_token.should_not be_nil
|
62
|
+
session[csrf_param].should_not be_nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context '#form_tag' do
|
67
|
+
it 'should prepend the CSRF authenticity token to the form' do
|
68
|
+
form = form_tag('/register') { text_field_tag :user_name, value: 'test' }
|
69
|
+
form.should have_tag(:form, count: 1, with: { method: 'post', action: '/register' }) do
|
70
|
+
with_tag(:input, count: 1, with: { type: 'hidden', name: csrf_param, value: csrf_token })
|
71
|
+
with_tag(:input, count: 1, with: { type: 'text', name: 'user_name', value: 'test' })
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context '#token_field_tag' do
|
77
|
+
it 'should return a hidden input with the current CSRF token' do
|
78
|
+
input = token_field_tag
|
79
|
+
input.should have_tag(:input, count: 1, with: { type: 'hidden', name: csrf_param, value: csrf_token })
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/spec/spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
PADRINO_ENV = 'test'
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'rspec-html-matchers'
|
5
|
+
require 'rack/test'
|
6
|
+
require 'padrino-csrf'
|
7
|
+
|
8
|
+
module TestHelpers
|
9
|
+
def app
|
10
|
+
@app ||= Sinatra.new(Padrino::Application) do
|
11
|
+
register Padrino::CSRF
|
12
|
+
set :prevent_request_forgery, true
|
13
|
+
set :logging, false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
RSpec.configure do |configuration|
|
19
|
+
configuration.include TestHelpers
|
20
|
+
configuration.include Rack::Test::Methods
|
21
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: padrino-csrf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: padrino-core
|
16
|
-
requirement: &
|
16
|
+
requirement: &15518448 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *15518448
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: padrino-helpers
|
27
|
-
requirement: &
|
27
|
+
requirement: &15517608 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,21 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *15517608
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
-
requirement: &
|
37
|
+
name: rspec
|
38
|
+
requirement: &15517176 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.0.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *15517176
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec-html-matchers
|
49
|
+
requirement: &15516288 !ruby/object:Gem::Requirement
|
39
50
|
none: false
|
40
51
|
requirements:
|
41
52
|
- - ! '>='
|
@@ -43,10 +54,10 @@ dependencies:
|
|
43
54
|
version: '0'
|
44
55
|
type: :development
|
45
56
|
prerelease: false
|
46
|
-
version_requirements: *
|
57
|
+
version_requirements: *15516288
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
49
|
-
requirement: &
|
59
|
+
name: rack-test
|
60
|
+
requirement: &15515712 !ruby/object:Gem::Requirement
|
50
61
|
none: false
|
51
62
|
requirements:
|
52
63
|
- - ! '>='
|
@@ -54,7 +65,7 @@ dependencies:
|
|
54
65
|
version: '0'
|
55
66
|
type: :development
|
56
67
|
prerelease: false
|
57
|
-
version_requirements: *
|
68
|
+
version_requirements: *15515712
|
58
69
|
description: A plugin for the Padrino web framework which adds CSRF protection
|
59
70
|
email:
|
60
71
|
- cirex@gamesol.org
|
@@ -63,6 +74,7 @@ extensions: []
|
|
63
74
|
extra_rdoc_files: []
|
64
75
|
files:
|
65
76
|
- .gitignore
|
77
|
+
- .rspec
|
66
78
|
- .yardopts
|
67
79
|
- Gemfile
|
68
80
|
- LICENSE
|
@@ -74,6 +86,9 @@ files:
|
|
74
86
|
- lib/padrino-csrf/routing.rb
|
75
87
|
- lib/padrino-csrf/version.rb
|
76
88
|
- padrino-csrf.gemspec
|
89
|
+
- spec/csrf_spec.rb
|
90
|
+
- spec/helpers_spec.rb
|
91
|
+
- spec/spec.rb
|
77
92
|
- vendor/assets/jquery.unobtrusive.js
|
78
93
|
homepage: https://github.com/Cirex/padrino-csrf
|
79
94
|
licenses: []
|