rack_csrf 2.4.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,8 +4,9 @@ class FakeSession
4
4
  def initialize(app)
5
5
  @app = app
6
6
  end
7
+
7
8
  def call(env)
8
- env['rack.session'] ||= Hash.new
9
+ env['rack.session'] ||= {}
9
10
  @app.call(env)
10
11
  end
11
12
  end
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class Csrf
3
+ VERSION = '2.7.0'
4
+ end
5
+ end
data/lib/rack/csrf.rb CHANGED
@@ -1,12 +1,22 @@
1
- require 'rack'
2
1
  begin
3
- require 'securerandom'
2
+ require 'rack/version'
4
3
  rescue LoadError
5
- require File.dirname(__FILE__) + '/vendor/securerandom'
4
+ require 'rack'
5
+ else
6
+ if Rack.release >= '2.3'
7
+ require 'rack/request'
8
+ require 'rack/utils'
9
+ else
10
+ require 'rack'
11
+ end
6
12
  end
13
+ require 'securerandom'
7
14
 
8
15
  module Rack
9
16
  class Csrf
17
+ CONTENT_TYPE = (Rack.release >= '2.3' ? 'content-type' : 'Content-Type').freeze
18
+ CONTENT_LENGTH = (Rack.release >= '2.3' ? 'content-length' : 'Content-Length').freeze
19
+
10
20
  class SessionUnavailable < StandardError; end
11
21
  class InvalidCsrfToken < StandardError; end
12
22
 
@@ -17,34 +27,32 @@ module Rack
17
27
  def initialize(app, opts = {})
18
28
  @app = app
19
29
 
20
- @raisable = opts[:raise] || false
21
- @skip_list = (opts[:skip] || []).map {|r| /\A#{r}\Z/i}
22
- @skip_if = opts[:skip_if] if opts[:skip_if]
23
- @check_only_list = (opts[:check_only] || []).map {|r| /\A#{r}\Z/i}
24
- @@field = opts[:field] if opts[:field]
25
- @@header = opts[:header] if opts[:header]
26
- @@key = opts[:key] if opts[:key]
30
+ @raise_if_invalid = opts.fetch(:raise, false)
31
+ @skip_list = opts.fetch(:skip, []).map {|r| /\A#{r}\Z/i}
32
+ @skip_if = opts[:skip_if]
33
+ @check_only_list = opts.fetch(:check_only, []).map {|r| /\A#{r}\Z/i}
34
+ @@field = opts[:field] if opts[:field]
35
+ @@header = opts[:header] if opts[:header]
36
+ @@key = opts[:key] if opts[:key]
27
37
 
28
38
  standard_http_methods = %w(POST PUT DELETE PATCH)
29
- check_also = opts[:check_also] || []
39
+ check_also = opts.fetch(:check_also, [])
30
40
  @http_methods = (standard_http_methods + check_also).flatten.uniq
31
41
  end
32
42
 
33
43
  def call(env)
34
44
  unless env['rack.session']
35
- raise SessionUnavailable.new('Rack::Csrf depends on session middleware')
45
+ fail SessionUnavailable, 'Rack::Csrf depends on session middleware'
36
46
  end
37
- self.class.token(env)
38
47
  req = Rack::Request.new(env)
39
- untouchable = skip_checking(req) ||
48
+ let_it_pass = skip_checking(req) ||
40
49
  !@http_methods.include?(req.request_method) ||
41
- req.params[self.class.field] == env['rack.session'][self.class.key] ||
42
- req.env[self.class.rackified_header] == env['rack.session'][self.class.key]
43
- if untouchable
50
+ found_a_valid_token?(req)
51
+ if let_it_pass
44
52
  @app.call(env)
45
53
  else
46
- raise InvalidCsrfToken if @raisable
47
- [403, {'Content-Type' => 'text/html', 'Content-Length' => '0'}, []]
54
+ fail InvalidCsrfToken if @raise_if_invalid
55
+ [403, {CONTENT_TYPE => 'text/html', CONTENT_LENGTH => '0'}, []]
48
56
  end
49
57
  end
50
58
 
@@ -61,7 +69,7 @@ module Rack
61
69
  end
62
70
 
63
71
  def self.token(env)
64
- env['rack.session'][key] ||= SecureRandom.base64(32)
72
+ env['rack.session'][key] ||= SecureRandom.urlsafe_base64(32)
65
73
  end
66
74
 
67
75
  def self.tag(env)
@@ -69,7 +77,7 @@ module Rack
69
77
  end
70
78
 
71
79
  def self.metatag(env, options = {})
72
- name = options.delete(:name) || '_csrf'
80
+ name = options.fetch(:name, '_csrf')
73
81
  %Q(<meta name="#{name}" content="#{token(env)}" />)
74
82
  end
75
83
 
@@ -86,7 +94,7 @@ module Rack
86
94
 
87
95
  # Returns the custom header's name adapted to current standards.
88
96
  def self.rackified_header
89
- "HTTP_#{@@header.gsub('-','_').upcase}"
97
+ "HTTP_#{@@header.gsub('-', '_').upcase}"
90
98
  end
91
99
 
92
100
  # Returns +true+ if the given request appears in the <b>skip list</b> or
@@ -108,5 +116,11 @@ module Rack
108
116
  route =~ (request.request_method + ':' + pi)
109
117
  end
110
118
  end
119
+
120
+ def found_a_valid_token? request
121
+ token = self.class.token(request.env)
122
+ Rack::Utils.secure_compare(request.params[self.class.field].to_s, token) ||
123
+ Rack::Utils.secure_compare(request.env[self.class.rackified_header].to_s, token)
124
+ end
111
125
  end
112
126
  end
data/rack_csrf.gemspec CHANGED
@@ -1,121 +1,48 @@
1
- # Generated by jeweler
2
- # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
- # -*- encoding: utf-8 -*-
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rack/csrf/version'
5
5
 
6
- Gem::Specification.new do |s|
7
- s.name = "rack_csrf"
8
- s.version = "2.4.0"
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'rack_csrf'
8
+ spec.version = Rack::Csrf::VERSION
9
+ spec.authors = ['Emanuele Vicentini']
10
+ spec.email = ['emanuele.vicentini@gmail.com']
11
+ spec.description = 'Anti-CSRF Rack middleware'
12
+ spec.summary = 'Anti-CSRF Rack middleware'
13
+ spec.homepage = 'https://github.com/baldowl/rack_csrf'
14
+ spec.license = 'MIT'
9
15
 
10
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Emanuele Vicentini"]
12
- s.date = "2012-02-28"
13
- s.description = "Anti-CSRF Rack middleware"
14
- s.email = "emanuele.vicentini@gmail.com"
15
- s.extra_rdoc_files = [
16
- "LICENSE.rdoc",
17
- "README.rdoc"
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.rdoc_options = [
21
+ '--line-numbers',
22
+ '--inline-source',
23
+ '--title',
24
+ "Rack::Csrf #{Rack::Csrf::VERSION}",
25
+ '--main',
26
+ 'README.rdoc'
18
27
  ]
19
- s.files = [
20
- ".rspec",
21
- "Changelog.md",
22
- "Gemfile",
23
- "LICENSE.rdoc",
24
- "README.rdoc",
25
- "Rakefile",
26
- "VERSION",
27
- "cucumber.yml",
28
- "examples/camping/Gemfile",
29
- "examples/camping/README.rdoc",
30
- "examples/camping/app.rb",
31
- "examples/camping/config.ru",
32
- "examples/cuba/Gemfile",
33
- "examples/cuba/README.rdoc",
34
- "examples/cuba/app.rb",
35
- "examples/cuba/config-with-raise.ru",
36
- "examples/cuba/config.ru",
37
- "examples/cuba/views/form.erb",
38
- "examples/cuba/views/form_not_working.erb",
39
- "examples/cuba/views/response.erb",
40
- "examples/innate/Gemfile",
41
- "examples/innate/README.rdoc",
42
- "examples/innate/app.rb",
43
- "examples/innate/start-with-raise.rb",
44
- "examples/innate/start.rb",
45
- "examples/innate/view/index.erb",
46
- "examples/innate/view/notworking.erb",
47
- "examples/innate/view/response.erb",
48
- "examples/rack/Gemfile",
49
- "examples/rack/README.rdoc",
50
- "examples/rack/app.rb",
51
- "examples/rack/config-with-raise.ru",
52
- "examples/rack/config.ru",
53
- "examples/sinatra/Gemfile",
54
- "examples/sinatra/README.rdoc",
55
- "examples/sinatra/app.rb",
56
- "examples/sinatra/config-with-raise.ru",
57
- "examples/sinatra/config.ru",
58
- "examples/sinatra/views/form.erb",
59
- "examples/sinatra/views/form_not_working.erb",
60
- "examples/sinatra/views/response.erb",
61
- "features/check_only_some_specific_requests.feature",
62
- "features/custom_http_methods.feature",
63
- "features/empty_responses.feature",
64
- "features/inspecting_also_get_requests.feature",
65
- "features/raising_exception.feature",
66
- "features/setup.feature",
67
- "features/skip_if_block_passes.feature",
68
- "features/skip_some_routes.feature",
69
- "features/step_definitions/request_steps.rb",
70
- "features/step_definitions/response_steps.rb",
71
- "features/step_definitions/setup_steps.rb",
72
- "features/support/env.rb",
73
- "features/support/fake_session.rb",
74
- "features/variation_on_field_name.feature",
75
- "features/variation_on_header_name.feature",
76
- "features/variation_on_key_name.feature",
77
- "lib/rack/csrf.rb",
78
- "lib/rack/vendor/securerandom.rb",
79
- "rack_csrf.gemspec",
80
- "spec/csrf_spec.rb",
81
- "spec/spec_helper.rb"
28
+ spec.extra_rdoc_files = [
29
+ 'LICENSE.rdoc',
30
+ 'README.rdoc'
82
31
  ]
83
- s.homepage = "https://github.com/baldowl/rack_csrf"
84
- s.licenses = ["MIT"]
85
- s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Rack::Csrf 2.4.0", "--main", "README.rdoc"]
86
- s.require_paths = ["lib"]
87
- s.rubyforge_project = "rackcsrf"
88
- s.rubygems_version = "1.8.17"
89
- s.summary = "Anti-CSRF Rack middleware"
90
32
 
91
- if s.respond_to? :specification_version then
92
- s.specification_version = 3
33
+ spec.required_ruby_version = '>= 1.9.2'
93
34
 
94
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
95
- s.add_runtime_dependency(%q<rack>, [">= 0.9"])
96
- s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
97
- s.add_development_dependency(%q<cucumber>, [">= 1.1.1"])
98
- s.add_development_dependency(%q<rack-test>, [">= 0"])
99
- s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
100
- s.add_development_dependency(%q<rdoc>, [">= 2.4.2"])
101
- s.add_development_dependency(%q<jeweler>, [">= 0"])
102
- else
103
- s.add_dependency(%q<rack>, [">= 0.9"])
104
- s.add_dependency(%q<bundler>, [">= 1.0.0"])
105
- s.add_dependency(%q<cucumber>, [">= 1.1.1"])
106
- s.add_dependency(%q<rack-test>, [">= 0"])
107
- s.add_dependency(%q<rspec>, [">= 2.0.0"])
108
- s.add_dependency(%q<rdoc>, [">= 2.4.2"])
109
- s.add_dependency(%q<jeweler>, [">= 0"])
110
- end
35
+ if ENV['TEST_WITH_RACK']
36
+ spec.add_runtime_dependency 'rack', "~> #{ENV['TEST_WITH_RACK']}"
111
37
  else
112
- s.add_dependency(%q<rack>, [">= 0.9"])
113
- s.add_dependency(%q<bundler>, [">= 1.0.0"])
114
- s.add_dependency(%q<cucumber>, [">= 1.1.1"])
115
- s.add_dependency(%q<rack-test>, [">= 0"])
116
- s.add_dependency(%q<rspec>, [">= 2.0.0"])
117
- s.add_dependency(%q<rdoc>, [">= 2.4.2"])
118
- s.add_dependency(%q<jeweler>, [">= 0"])
38
+ spec.add_runtime_dependency 'rack', '>= 1.1.0'
119
39
  end
120
- end
121
40
 
41
+ spec.add_development_dependency 'bundler', '>= 1.0.0'
42
+ spec.add_development_dependency 'rake'
43
+ spec.add_development_dependency 'cucumber', '~> 3.0'
44
+ spec.add_development_dependency 'rack-test', '>= 0'
45
+ spec.add_development_dependency 'rspec', '~> 3.0'
46
+ spec.add_development_dependency 'rdoc', '>= 2.4.2'
47
+ spec.add_development_dependency 'git', '>= 1.2.5'
48
+ end
data/spec/csrf_spec.rb CHANGED
@@ -3,58 +3,67 @@ require 'spec_helper'
3
3
  describe Rack::Csrf do
4
4
  describe 'key' do
5
5
  it "should be 'csrf.token' by default" do
6
- Rack::Csrf.key.should == 'csrf.token'
6
+ expect(Rack::Csrf.key).to eq('csrf.token')
7
7
  end
8
8
 
9
- it "should be the value of the :key option" do
9
+ it 'should be the value of the :key option' do
10
10
  Rack::Csrf.new nil, :key => 'whatever'
11
- Rack::Csrf.key.should == 'whatever'
11
+ expect(Rack::Csrf.key).to eq('whatever')
12
12
  end
13
13
  end
14
14
 
15
15
  describe 'csrf_key' do
16
16
  it 'should be the same as method key' do
17
- Rack::Csrf.method(:csrf_key).should == Rack::Csrf.method(:key)
17
+ expect(Rack::Csrf.method(:csrf_key)).to eq(Rack::Csrf.method(:key))
18
18
  end
19
19
  end
20
20
 
21
21
  describe 'field' do
22
22
  it "should be '_csrf' by default" do
23
- Rack::Csrf.field.should == '_csrf'
23
+ expect(Rack::Csrf.field).to eq('_csrf')
24
24
  end
25
25
 
26
- it "should be the value of :field option" do
26
+ it 'should be the value of :field option' do
27
27
  Rack::Csrf.new nil, :field => 'whatever'
28
- Rack::Csrf.field.should == 'whatever'
28
+ expect(Rack::Csrf.field).to eq('whatever')
29
29
  end
30
30
  end
31
31
 
32
32
  describe 'csrf_field' do
33
33
  it 'should be the same as method field' do
34
- Rack::Csrf.method(:csrf_field).should == Rack::Csrf.method(:field)
34
+ expect(Rack::Csrf.method(:csrf_field)).to eq(Rack::Csrf.method(:field))
35
35
  end
36
36
  end
37
37
 
38
38
  describe 'header' do
39
39
  subject { Rack::Csrf.header }
40
- it { should == 'X_CSRF_TOKEN' }
40
+ it { is_expected.to be == 'X_CSRF_TOKEN' }
41
41
 
42
- context "when set to something" do
42
+ context 'when set to something' do
43
43
  before { Rack::Csrf.new nil, :header => 'something' }
44
44
  subject { Rack::Csrf.header }
45
- it { should == 'something' }
45
+ it { is_expected.to be == 'something' }
46
46
  end
47
47
  end
48
48
 
49
49
  describe 'csrf_header' do
50
- subject { Rack::Csrf.method(:csrf_header) }
51
- it { should == Rack::Csrf.method(:header) }
50
+ it 'should be the same as method header' do
51
+ expect(Rack::Csrf.method(:csrf_header)).to eq(Rack::Csrf.method(:header))
52
+ end
52
53
  end
53
54
 
54
55
  describe 'token(env)' do
55
56
  let(:env) { {'rack.session' => {}} }
56
57
 
57
- specify {Rack::Csrf.token(env).should have_at_least(32).characters}
58
+ context 'should produce a token' do
59
+ specify 'with at least 32 characters' do
60
+ expect(Rack::Csrf.token(env).length).to be >= 32
61
+ end
62
+
63
+ specify 'without +, / or =' do
64
+ expect(Rack::Csrf.token(env)).not_to match(/\+|\/|=/)
65
+ end
66
+ end
58
67
 
59
68
  context 'when accessing/manipulating the session' do
60
69
  before do
@@ -62,17 +71,17 @@ describe Rack::Csrf do
62
71
  end
63
72
 
64
73
  it 'should use the key provided by method key' do
65
- env['rack.session'].should be_empty
74
+ expect(env['rack.session']).to be_empty
66
75
  Rack::Csrf.token env
67
- env['rack.session'][Rack::Csrf.key].should_not be_nil
76
+ expect(env['rack.session'][Rack::Csrf.key]).not_to be_nil
68
77
  end
69
78
  end
70
79
 
71
80
  context 'when the session does not already contain the token' do
72
81
  it 'should store the token inside the session' do
73
- env['rack.session'].should be_empty
82
+ expect(env['rack.session']).to be_empty
74
83
  token = Rack::Csrf.token(env)
75
- token.should == env['rack.session'][Rack::Csrf.key]
84
+ expect(token).to eq(env['rack.session'][Rack::Csrf.key])
76
85
  end
77
86
  end
78
87
 
@@ -82,14 +91,14 @@ describe Rack::Csrf do
82
91
  end
83
92
 
84
93
  it 'should get the token from the session' do
85
- env['rack.session'][Rack::Csrf.key].should == Rack::Csrf.token(env)
94
+ expect(env['rack.session'][Rack::Csrf.key]).to eq(Rack::Csrf.token(env))
86
95
  end
87
96
  end
88
97
  end
89
98
 
90
99
  describe 'csrf_token(env)' do
91
100
  it 'should be the same as method token(env)' do
92
- Rack::Csrf.method(:csrf_token).should == Rack::Csrf.method(:token)
101
+ expect(Rack::Csrf.method(:csrf_token)).to eq(Rack::Csrf.method(:token))
93
102
  end
94
103
  end
95
104
 
@@ -102,26 +111,26 @@ describe Rack::Csrf do
102
111
  end
103
112
 
104
113
  it 'should be an input field' do
105
- tag.should =~ /^<input/
114
+ expect(tag).to match(/^<input/)
106
115
  end
107
116
 
108
117
  it 'should be an hidden input field' do
109
- tag.should =~ /type="hidden"/
118
+ expect(tag).to match(/type="hidden"/)
110
119
  end
111
120
 
112
- it "should have the name provided by method field" do
113
- tag.should =~ /name="#{Rack::Csrf.field}"/
121
+ it 'should have the name provided by method field' do
122
+ expect(tag).to match(/name="#{Rack::Csrf.field}"/)
114
123
  end
115
124
 
116
- it "should have the value provided by method token(env)" do
125
+ it 'should have the value provided by method token(env)' do
117
126
  quoted_value = Regexp.quote %Q(value="#{Rack::Csrf.token(env)}")
118
- tag.should =~ /#{quoted_value}/
127
+ expect(tag).to match(/#{quoted_value}/)
119
128
  end
120
129
  end
121
130
 
122
131
  describe 'csrf_tag(env)' do
123
132
  it 'should be the same as method tag(env)' do
124
- Rack::Csrf.method(:csrf_tag).should == Rack::Csrf.method(:tag)
133
+ expect(Rack::Csrf.method(:csrf_tag)).to eq(Rack::Csrf.method(:tag))
125
134
  end
126
135
  end
127
136
 
@@ -135,11 +144,11 @@ describe Rack::Csrf do
135
144
  end
136
145
 
137
146
  subject { metatag }
138
- it { should =~ /^<meta/ }
139
- it { should =~ /name="_csrf"/ }
140
- it "should have the content provided by method token(env)" do
147
+ it { is_expected.to match(/^<meta/) }
148
+ it { is_expected.to match(/name="_csrf"/) }
149
+ it 'should have the content provided by method token(env)' do
141
150
  quoted_value = Regexp.quote %Q(content="#{Rack::Csrf.token(env)}")
142
- metatag.should =~ /#{quoted_value}/
151
+ expect(metatag).to match(/#{quoted_value}/)
143
152
  end
144
153
  end
145
154
 
@@ -150,18 +159,18 @@ describe Rack::Csrf do
150
159
  end
151
160
 
152
161
  subject { metatag }
153
- it { should =~ /^<meta/ }
154
- it { should =~ /name="custom_name"/ }
155
- it "should have the content provided by method token(env)" do
162
+ it { is_expected.to match(/^<meta/) }
163
+ it { is_expected.to match(/name="custom_name"/) }
164
+ it 'should have the content provided by method token(env)' do
156
165
  quoted_value = Regexp.quote %Q(content="#{Rack::Csrf.token(env)}")
157
- metatag.should =~ /#{quoted_value}/
166
+ expect(metatag).to match(/#{quoted_value}/)
158
167
  end
159
168
  end
160
169
  end
161
170
 
162
171
  describe 'csrf_metatag(env)' do
163
172
  it 'should be the same as method metatag(env)' do
164
- Rack::Csrf.method(:csrf_metatag).should == Rack::Csrf.method(:metatag)
173
+ expect(Rack::Csrf.method(:csrf_metatag)).to eq(Rack::Csrf.method(:metatag))
165
174
  end
166
175
  end
167
176
 
@@ -170,7 +179,7 @@ describe Rack::Csrf do
170
179
  describe 'rackified_header' do
171
180
  before { Rack::Csrf.new nil, :header => 'my-header' }
172
181
  subject { Rack::Csrf.rackified_header }
173
- it { should == 'HTTP_MY_HEADER'}
182
+ it { is_expected.to be == 'HTTP_MY_HEADER'}
174
183
  end
175
184
 
176
185
  describe 'skip_checking' do
@@ -185,7 +194,7 @@ describe Rack::Csrf do
185
194
  let(:csrf) { Rack::Csrf.new nil }
186
195
 
187
196
  it 'should run the check' do
188
- csrf.send(:skip_checking, request).should be_false
197
+ expect(csrf.send(:skip_checking, request)).to be false
189
198
  end
190
199
  end
191
200
 
@@ -193,7 +202,7 @@ describe Rack::Csrf do
193
202
  let(:csrf) { Rack::Csrf.new nil, :skip => ['POST:/hello'] }
194
203
 
195
204
  it 'should not run the check' do
196
- csrf.send(:skip_checking, request).should be_true
205
+ expect(csrf.send(:skip_checking, request)).to be true
197
206
  end
198
207
  end
199
208
 
@@ -202,7 +211,7 @@ describe Rack::Csrf do
202
211
  let(:csrf) { Rack::Csrf.new nil, :skip_if => lambda { |req| req.env.key?('HTTP_X_VERY_SPECIAL_HEADER') } }
203
212
 
204
213
  it 'should not run the check' do
205
- csrf.send(:skip_checking, request).should be_true
214
+ expect(csrf.send(:skip_checking, request)).to be true
206
215
  end
207
216
  end
208
217
 
@@ -211,7 +220,7 @@ describe Rack::Csrf do
211
220
  let(:csrf) { Rack::Csrf.new nil, :check_only => [] }
212
221
 
213
222
  it 'should run the check' do
214
- csrf.send(:skip_checking, request).should be_false
223
+ expect(csrf.send(:skip_checking, request)).to be false
215
224
  end
216
225
  end
217
226
 
@@ -220,7 +229,7 @@ describe Rack::Csrf do
220
229
  let(:csrf) { Rack::Csrf.new nil, :check_only => ['POST:/hello'] }
221
230
 
222
231
  it 'should run the check' do
223
- csrf.send(:skip_checking, request).should be_false
232
+ expect(csrf.send(:skip_checking, request)).to be false
224
233
  end
225
234
  end
226
235
 
@@ -228,11 +237,49 @@ describe Rack::Csrf do
228
237
  let(:csrf) { Rack::Csrf.new nil, :check_only => ['POST:/ciao'] }
229
238
 
230
239
  it 'should not run the check' do
231
- csrf.send(:skip_checking, request).should be_true
240
+ expect(csrf.send(:skip_checking, request)).to be true
232
241
  end
233
242
  end
234
243
  end
235
244
  end
236
245
  end
237
246
  end
247
+
248
+ describe 'found_a_valid_token?' do
249
+ let(:env) { {'rack.session' => {}} }
250
+
251
+ let(:csrf) { Rack::Csrf.new nil }
252
+
253
+ let(:mock_request_env) do
254
+ Rack::MockRequest.env_for '/hello',
255
+ :method => 'POST',
256
+ :input => 'foo=bar'
257
+ end
258
+
259
+ before do
260
+ Rack::Csrf.token env
261
+ mock_request_env['rack.session'] = env['rack.session']
262
+ end
263
+
264
+ context 'should be true' do
265
+ specify "if a valid token can be found in the request's paramaters" do
266
+ mock_request_env['rack.input'] = StringIO.new("#{Rack::Csrf.field}=#{Rack::Csrf.token(env)}")
267
+ request = Rack::Request.new(mock_request_env)
268
+ expect(csrf.send(:found_a_valid_token?, request)).to be true
269
+ end
270
+
271
+ specify "if a valid token can be found in the request's headers" do
272
+ mock_request_env[Rack::Csrf.rackified_header] = Rack::Csrf.token(env)
273
+ request = Rack::Request.new(mock_request_env)
274
+ expect(csrf.send(:found_a_valid_token?, request)).to be true
275
+ end
276
+ end
277
+
278
+ context 'should be false' do
279
+ specify 'if no valid token can be found anywhere' do
280
+ request = Rack::Request.new(mock_request_env)
281
+ expect(csrf.send(:found_a_valid_token?, request)).to be false
282
+ end
283
+ end
284
+ end
238
285
  end
data/spec/spec_helper.rb CHANGED
@@ -2,3 +2,4 @@ require 'rubygems'
2
2
  require 'rspec'
3
3
 
4
4
  require 'rack/csrf'
5
+ require 'rack/mock'