rack_csrf 1.1.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog.md ADDED
@@ -0,0 +1,57 @@
1
+ # v2.0.0 (2010-01-11)
2
+
3
+ * Added a changelog and a Rake task to help.
4
+ * Removed Jeweler's support for Rubyforge.
5
+ * Fixed a couple of typos.
6
+ * Removed the :browser_only option.
7
+ * Tweaked the copyright notice.
8
+ * Cleaned up a bit some step definitions.
9
+ * Switched to use Rack::Test in the Cucumber's scenarios.
10
+ * Removed redundant require in Cucumber's support files.
11
+
12
+
13
+
14
+ # v1.1.1 (2009-10-15)
15
+
16
+ * Tweaked the default HTTP response code.
17
+ * Moving to Jeweler.
18
+ * Innate example.
19
+ * Little tweak to the plain Rack example.
20
+ * Plain Rack example.
21
+ * Extended the main README.rdoc.
22
+ * Fixed loading Rack::Csrf in the Sinatra example. New README.
23
+ * Moved the Sinatra example in its own directory.
24
+ * Fixed RSpec support file.
25
+ * Tweaked Cucumber's task definition.
26
+ * Fixed grammar; added some fragments of code.
27
+ * Tweaked a bit the Cucumber and RSpec support files.
28
+ * Reworded and fixed the spec. It should be clearer.
29
+
30
+
31
+
32
+ # 1.1.0 (2009-05-22)
33
+
34
+ * Tweaks to the examples to run smoothly with future Sinatra release.
35
+ * Moved some code into #initialize.
36
+ * More generic step checking response code.
37
+ * Added the :browser_only option.
38
+ * Tweaked Cucumber's profile to follow new Cucumber release.
39
+ * Shortened steps' names.
40
+ * Tweak to spec to ensure use of csrf_field in csrf_tag.
41
+ * Clarification on options' default values.
42
+ * :skip now accept an array of regexps.
43
+
44
+
45
+
46
+ # 1.0.1 (2009-05-02)
47
+
48
+ * Changed env key to satisfy Rack specification.
49
+ * Auto-fill session with token upon receiving first request.
50
+ * Added missing scenarios for :field option.
51
+ * Fixed a typo.
52
+
53
+
54
+
55
+ # 1.0.0 (2009-04-22 17:14:45 +0200)
56
+
57
+ * First release
data/LICENSE.rdoc CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  (The MIT License)
4
4
 
5
- Copyright (c) 2009 Emanuele Vicentini
5
+ Copyright (c) 2009, 2010 Emanuele Vicentini
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  of this software and associated documentation files (the 'Software'), to deal
data/README.rdoc CHANGED
@@ -55,14 +55,16 @@ The following options allow you to tweak Rack::Csrf.
55
55
 
56
56
  Default value: _csrf
57
57
 
58
- [<tt>:browser_only</tt>]
59
- Set it to true to inspect only requests with Content-Type typically produced
60
- only by web browsers. This means that curl, Active Resource, etc. can send
61
- any request without worring about the token.
58
+ The <tt>:browser_only</tt> option has been removed; you do not need to edit
59
+ any rackup file because Rack::Csrf simply ignores unknown options. Changes
60
+ introduced in Rack version 1.1.0 tightened the parsing of POST params, so
61
+ requests need to have the right Content-Type (or none at all); these
62
+ Content-Types are exactly those used also by browsers and so there is no use
63
+ for <tt>:browser_only</tt> anymore.
62
64
 
63
- use Rack::Csrf, :browser_only => true
64
-
65
- Default value: false.
65
+ The ill devised <tt>:browser_only</tt> option could have been used to
66
+ "protect" an API, but I think it might be better to use a combination of
67
+ <tt>:skip</tt> and formatted URLs.
66
68
 
67
69
  == Helpers
68
70
 
@@ -107,3 +109,7 @@ list}[http://github.com/baldowl/rack_csrf] on GitHub.
107
109
  I cannot stress enough that this middleware is not a bulletproof vest or a
108
110
  panacea for the CSRF plague; it is just an *aid* and by using it you cannot
109
111
  forgo responsibilities for keeping your application as safe as possible.
112
+
113
+ == Copyright
114
+
115
+ Copyright (c) 2009, 2010 Emanuele Vicentini. See LICENSE.rdoc for details.
data/Rakefile CHANGED
@@ -37,11 +37,26 @@ Jeweler::Tasks.new do |gem|
37
37
  gem.rubyforge_project = 'rackcsrf'
38
38
  gem.add_dependency 'rack', '>= 0.9'
39
39
  gem.add_development_dependency 'cucumber', '>= 0.1.13'
40
+ gem.add_development_dependency 'rack-test'
40
41
  gem.add_development_dependency 'rspec'
41
42
  gem.rdoc_options << '--line-numbers' << '--inline-source' << '--title' <<
42
43
  "Rack::Csrf #{version}" << '--main' << 'README.rdoc'
43
44
  gem.test_files.clear
44
45
  end
45
46
 
46
- Jeweler::RubyforgeTasks.new
47
47
  Jeweler::GemcutterTasks.new
48
+
49
+ desc <<-EOD
50
+ Shows the changelog in Git between the given points.
51
+
52
+ start -- defaults to the current version tag
53
+ end -- defaults to HEAD
54
+ EOD
55
+ task :changes, [:start, :end] do |t, args|
56
+ args.with_defaults :start => "v#{Rake.application.jeweler.version}",
57
+ :end => 'HEAD'
58
+ repo = Git.open Rake.application.jeweler.git_base_dir
59
+ repo.log(nil).between(args.start, args.end).each do |c|
60
+ puts c.message.split($/).first
61
+ end
62
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.1
1
+ 2.0.0
@@ -27,8 +27,3 @@ Feature: Setup of the middleware
27
27
  Given a rack with the session middleware
28
28
  When I insert the anti-CSRF middleware with the :field option
29
29
  Then I get a fully functional rack
30
-
31
- Scenario: Setup with the :browser_only option
32
- Given a rack with the session middleware
33
- When I insert the anti-CSRF middleware with the :browser_only option
34
- Then I get a fully functional rack
@@ -1,55 +1,37 @@
1
1
  When /^it receives a GET request (with|without) the CSRF token$/ do |prep|
2
- if prep == 'with'
3
- url = "/?#{Rack::Utils.build_query(Rack::Csrf.csrf_field => 'whatever')}"
4
- else
5
- url = '/'
6
- end
7
- @response = Rack::MockRequest.new(@app).get(url)
2
+ params = prep == 'with' ? {Rack::Csrf.csrf_field => 'whatever'} : {}
3
+ @browser.get '/', :params => params
8
4
  end
9
5
 
10
6
  # Yes, they're not as DRY as possible, but I think they're more readable than
11
7
  # a single step definition with a few captures and more complex checkings.
12
8
 
13
9
  When /^it receives a (POST|PUT|DELETE) request without the CSRF token$/ do |http_method|
14
- http_method.downcase!
15
10
  begin
16
- @response = Rack::MockRequest.new(@app).send http_method.to_sym, '/'
11
+ @browser.request '/', :method => http_method
17
12
  rescue Exception => e
18
13
  @exception = e
19
14
  end
20
15
  end
21
16
 
22
17
  When /^it receives a (POST|PUT|DELETE) request for (.+) without the CSRF token$/ do |http_method, path|
23
- http_method.downcase!
24
- begin
25
- @response = Rack::MockRequest.new(@app).send http_method.to_sym, path
26
- rescue Exception => e
27
- @exception = e
28
- end
29
- end
30
-
31
- When /^it receives a (POST|PUT|DELETE) request without the CSRF token from a browser$/ do |http_method|
32
- http_method.downcase!
33
18
  begin
34
- @response = Rack::MockRequest.new(@app).send http_method.to_sym, '/',
35
- 'CONTENT_TYPE' => 'text/html'
19
+ @browser.request path, :method => http_method
36
20
  rescue Exception => e
37
21
  @exception = e
38
22
  end
39
23
  end
40
24
 
41
25
  When /^it receives a (POST|PUT|DELETE) request with the right CSRF token$/ do |http_method|
42
- http_method.downcase!
43
- @response = Rack::MockRequest.new(@app).send http_method.to_sym, '/',
44
- :input => "#{Rack::Csrf.csrf_field}=right_token",
45
- 'rack.session' => {'csrf.token' => 'right_token'}
26
+ @browser.request '/', :method => http_method,
27
+ 'rack.session' => {'csrf.token' => 'right_token'},
28
+ :params => {Rack::Csrf.csrf_field => 'right_token'}
46
29
  end
47
30
 
48
31
  When /^it receives a (POST|PUT|DELETE) request with the wrong CSRF token$/ do |http_method|
49
- http_method.downcase!
50
32
  begin
51
- @response = Rack::MockRequest.new(@app).send http_method.to_sym, '/',
52
- :input => "#{Rack::Csrf.csrf_field}=whatever"
33
+ @browser.request '/', :method => http_method,
34
+ :params => {Rack::Csrf.csrf_field => 'whatever'}
53
35
  rescue Exception => e
54
36
  @exception = e
55
37
  end
@@ -1,18 +1,18 @@
1
1
  Then /^it lets it pass untouched$/ do
2
- @response.should be_ok
3
- @response.should =~ /Hello world!/
2
+ @browser.last_response.should be_ok
3
+ @browser.last_response.should =~ /Hello world!/
4
4
  end
5
5
 
6
6
  Then /^it responds with (\d\d\d)$/ do |code|
7
- @response.status.should == code.to_i
7
+ @browser.last_response.status.should == code.to_i
8
8
  end
9
9
 
10
10
  Then /^the response body is empty$/ do
11
- @response.body.should be_empty
11
+ @browser.last_response.body.should be_empty
12
12
  end
13
13
 
14
14
  Then /^there is no response$/ do
15
- @response.should be_nil
15
+ lambda {@browser.last_response}.should raise_error(Rack::Test::Error)
16
16
  end
17
17
 
18
18
  Then /^an exception is climbing up the stack$/ do
@@ -1,5 +1,6 @@
1
1
  Given /^a rack (with|without) the session middleware$/ do |prep|
2
2
  @rack_builder = Rack::Builder.new
3
+ @rack_builder.use Rack::Lint
3
4
  @rack_builder.use FakeSession if prep == 'with'
4
5
  end
5
6
 
@@ -26,48 +27,32 @@ Given /^a rack with the anti\-CSRF middleware and the :field option$/ do
26
27
  When 'I insert the anti-CSRF middleware with the :field option'
27
28
  end
28
29
 
29
- Given /^a rack with the anti\-CSRF middleware and the :browser_only option$/ do
30
- Given 'a rack with the session middleware'
31
- When 'I insert the anti-CSRF middleware with the :browser_only option'
32
- end
33
-
34
30
  # Yes, they're not as DRY as possible, but I think they're more readable than
35
31
  # a single step definition with a few captures and more complex checkings.
36
32
 
37
33
  When /^I insert the anti\-CSRF middleware$/ do
38
- @rack_builder.use Rack::Lint
39
34
  @rack_builder.use Rack::Csrf
40
- @rack_builder.run(lambda {|env| Rack::Response.new('Hello world!').finish})
41
- @app = @rack_builder.to_app
35
+ toy_app
36
+ @browser = Rack::Test::Session.new(Rack::MockSession.new(@app))
42
37
  end
43
38
 
44
39
  When /^I insert the anti\-CSRF middleware with the :raise option$/ do
45
- @rack_builder.use Rack::Lint
46
40
  @rack_builder.use Rack::Csrf, :raise => true
47
- @rack_builder.run(lambda {|env| Rack::Response.new('Hello world!').finish})
48
- @app = @rack_builder.to_app
41
+ toy_app
42
+ @browser = Rack::Test::Session.new(Rack::MockSession.new(@app))
49
43
  end
50
44
 
51
45
  When /^I insert the anti\-CSRF middleware with the :skip option$/ do |table|
52
46
  skippable = table.hashes.collect {|t| t.values}.flatten
53
- @rack_builder.use Rack::Lint
54
47
  @rack_builder.use Rack::Csrf, :skip => skippable
55
- @rack_builder.run(lambda {|env| Rack::Response.new('Hello world!').finish})
56
- @app = @rack_builder.to_app
48
+ toy_app
49
+ @browser = Rack::Test::Session.new(Rack::MockSession.new(@app))
57
50
  end
58
51
 
59
52
  When /^I insert the anti\-CSRF middleware with the :field option$/ do
60
- @rack_builder.use Rack::Lint
61
53
  @rack_builder.use Rack::Csrf, :field => 'fantasy_name'
62
- @rack_builder.run(lambda {|env| Rack::Response.new('Hello world!').finish})
63
- @app = @rack_builder.to_app
64
- end
65
-
66
- When /^I insert the anti\-CSRF middleware with the :browser_only option$/ do
67
- @rack_builder.use Rack::Lint
68
- @rack_builder.use Rack::Csrf, :browser_only => true
69
- @rack_builder.run(lambda {|env| Rack::Response.new('Hello world!').finish})
70
- @app = @rack_builder.to_app
54
+ toy_app
55
+ @browser = Rack::Test::Session.new(Rack::MockSession.new(@app))
71
56
  end
72
57
 
73
58
  Then /^I get a fully functional rack$/ do
@@ -77,3 +62,8 @@ end
77
62
  Then /^I get an error message$/ do
78
63
  lambda {Rack::MockRequest.new(@app).get('/')}.should raise_error(Rack::Csrf::SessionUnavailable, 'Rack::Csrf depends on session middleware')
79
64
  end
65
+
66
+ def toy_app
67
+ @rack_builder.run(lambda {|env| Rack::Response.new('Hello world!').finish})
68
+ @app = @rack_builder.to_app
69
+ end
@@ -1,9 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'spec/expectations'
3
+ require 'rack/test'
3
4
 
4
5
  $: << File.join(File.dirname(__FILE__), '../../lib')
5
- $: << File.join(File.dirname(__FILE__))
6
6
 
7
7
  require 'rack/csrf'
8
-
9
- require 'fake_session'
data/lib/rack/csrf.rb CHANGED
@@ -18,13 +18,8 @@ module Rack
18
18
  @raisable = opts[:raise] || false
19
19
  @skippable = (opts[:skip] || []).map {|r| /\A#{r}\Z/i}
20
20
  @@field = opts[:field] if opts[:field]
21
- @browser_only = opts[:browser_only] || false
22
21
 
23
22
  @http_verbs = %w(POST PUT DELETE)
24
- @browser_content_types = ['text/html', 'application/xhtml+xml', 'xhtml',
25
- 'application/x-www-form-urlencoded',
26
- 'multipart/form-data',
27
- 'text/plain', 'txt']
28
23
  end
29
24
 
30
25
  def call(env)
@@ -35,7 +30,7 @@ module Rack
35
30
  req = Rack::Request.new(env)
36
31
  untouchable = !@http_verbs.include?(req.request_method) ||
37
32
  req.POST[self.class.csrf_field] == env['rack.session']['csrf.token'] ||
38
- skip_checking(req) || (@browser_only && !from_a_browser(req))
33
+ skip_checking(req)
39
34
  if untouchable
40
35
  @app.call(env)
41
36
  else
@@ -63,9 +58,5 @@ module Rack
63
58
  route =~ (request.request_method + ':' + request.path_info)
64
59
  end
65
60
  end
66
-
67
- def from_a_browser request
68
- @browser_content_types.include?(request.media_type)
69
- end
70
61
  end
71
62
  end
data/rack_csrf.gemspec CHANGED
@@ -1,15 +1,15 @@
1
1
  # Generated by jeweler
2
- # DO NOT EDIT THIS FILE
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rack_csrf}
8
- s.version = "1.1.1"
8
+ s.version = "2.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Emanuele Vicentini"]
12
- s.date = %q{2009-10-15}
12
+ s.date = %q{2010-01-11}
13
13
  s.description = %q{Anti-CSRF Rack middleware}
14
14
  s.email = %q{emanuele.vicentini@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -17,7 +17,8 @@ Gem::Specification.new do |s|
17
17
  "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
- "LICENSE.rdoc",
20
+ "Changelog.md",
21
+ "LICENSE.rdoc",
21
22
  "README.rdoc",
22
23
  "Rakefile",
23
24
  "VERSION",
@@ -40,7 +41,6 @@ Gem::Specification.new do |s|
40
41
  "examples/sinatra/views/form.erb",
41
42
  "examples/sinatra/views/form_not_working.erb",
42
43
  "examples/sinatra/views/response.erb",
43
- "features/browser_only.feature",
44
44
  "features/empty_responses.feature",
45
45
  "features/raising_exception.feature",
46
46
  "features/setup.feature",
@@ -59,7 +59,7 @@ Gem::Specification.new do |s|
59
59
  "spec/spec_helper.rb"
60
60
  ]
61
61
  s.homepage = %q{http://github.com/baldowl/rack_csrf}
62
- s.rdoc_options = ["--charset=UTF-8", "--line-numbers", "--inline-source", "--title", "Rack::Csrf 1.1.1", "--main", "README.rdoc"]
62
+ s.rdoc_options = ["--charset=UTF-8", "--line-numbers", "--inline-source", "--title", "Rack::Csrf 2.0.0", "--main", "README.rdoc"]
63
63
  s.require_paths = ["lib"]
64
64
  s.rubyforge_project = %q{rackcsrf}
65
65
  s.rubygems_version = %q{1.3.5}
@@ -72,15 +72,19 @@ Gem::Specification.new do |s|
72
72
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
73
73
  s.add_runtime_dependency(%q<rack>, [">= 0.9"])
74
74
  s.add_development_dependency(%q<cucumber>, [">= 0.1.13"])
75
+ s.add_development_dependency(%q<rack-test>, [">= 0"])
75
76
  s.add_development_dependency(%q<rspec>, [">= 0"])
76
77
  else
77
78
  s.add_dependency(%q<rack>, [">= 0.9"])
78
79
  s.add_dependency(%q<cucumber>, [">= 0.1.13"])
80
+ s.add_dependency(%q<rack-test>, [">= 0"])
79
81
  s.add_dependency(%q<rspec>, [">= 0"])
80
82
  end
81
83
  else
82
84
  s.add_dependency(%q<rack>, [">= 0.9"])
83
85
  s.add_dependency(%q<cucumber>, [">= 0.1.13"])
86
+ s.add_dependency(%q<rack-test>, [">= 0"])
84
87
  s.add_dependency(%q<rspec>, [">= 0"])
85
88
  end
86
89
  end
90
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack_csrf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emanuele Vicentini
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-15 00:00:00 +02:00
12
+ date: 2010-01-11 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -32,6 +32,16 @@ dependencies:
32
32
  - !ruby/object:Gem::Version
33
33
  version: 0.1.13
34
34
  version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: rack-test
37
+ type: :development
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
35
45
  - !ruby/object:Gem::Dependency
36
46
  name: rspec
37
47
  type: :development
@@ -52,6 +62,7 @@ extra_rdoc_files:
52
62
  - LICENSE.rdoc
53
63
  - README.rdoc
54
64
  files:
65
+ - Changelog.md
55
66
  - LICENSE.rdoc
56
67
  - README.rdoc
57
68
  - Rakefile
@@ -75,7 +86,6 @@ files:
75
86
  - examples/sinatra/views/form.erb
76
87
  - examples/sinatra/views/form_not_working.erb
77
88
  - examples/sinatra/views/response.erb
78
- - features/browser_only.feature
79
89
  - features/empty_responses.feature
80
90
  - features/raising_exception.feature
81
91
  - features/setup.feature
@@ -102,7 +112,7 @@ rdoc_options:
102
112
  - --line-numbers
103
113
  - --inline-source
104
114
  - --title
105
- - Rack::Csrf 1.1.1
115
+ - Rack::Csrf 2.0.0
106
116
  - --main
107
117
  - README.rdoc
108
118
  require_paths:
@@ -1,24 +0,0 @@
1
- Feature: Filtering only browser generated requests
2
-
3
- Scenario Outline: Handling request without CSRF token
4
- Given a rack with the anti-CSRF middleware and the :browser_only option
5
- When it receives a <method> request without the CSRF token
6
- Then it lets it pass untouched
7
-
8
- Examples:
9
- | method |
10
- | POST |
11
- | PUT |
12
- | DELETE |
13
-
14
- Scenario Outline: Handling request without CSRF token
15
- Given a rack with the anti-CSRF middleware and the :browser_only option
16
- When it receives a <method> request without the CSRF token from a browser
17
- Then it responds with 403
18
- And the response body is empty
19
-
20
- Examples:
21
- | method |
22
- | POST |
23
- | PUT |
24
- | DELETE |