rack_csrf 1.1.1 → 2.0.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.
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 |