bot-away 1.2.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.travis.yml +14 -0
  2. data/History.txt +20 -0
  3. data/README.md +198 -0
  4. data/Rakefile +14 -94
  5. data/bot-away.gemspec +20 -87
  6. data/gemfiles/Gemfile.rails-3.0.x +8 -0
  7. data/gemfiles/Gemfile.rails-3.0.x.lock +121 -0
  8. data/gemfiles/Gemfile.rails-3.1.x +8 -0
  9. data/gemfiles/Gemfile.rails-3.1.x.lock +133 -0
  10. data/lib/bot-away.rb +15 -13
  11. data/lib/bot-away/action_dispatch/params_parser.rb +22 -0
  12. data/lib/bot-away/action_view/helpers/instance_tag.rb +36 -12
  13. data/lib/bot-away/param_parser.rb +2 -2
  14. data/lib/bot-away/railtie.rb +10 -0
  15. data/lib/bot-away/test_case.rb +58 -0
  16. data/lib/bot-away/test_case/controller_test_case.rb +11 -0
  17. data/lib/bot-away/test_case/instance_tag_test_case.rb +15 -0
  18. data/lib/bot-away/test_case/matchers.rb +20 -0
  19. data/lib/bot-away/test_case/matchers/honeypot_matcher.rb +30 -0
  20. data/lib/bot-away/test_case/matchers/obfuscation_matcher.rb +30 -0
  21. data/lib/bot-away/test_case/mock_object.rb +16 -0
  22. data/lib/bot-away/version.rb +12 -0
  23. data/lib/locale/honeypots.yml +6 -0
  24. data/spec/controllers/basic_form_view_spec.rb +112 -0
  25. data/spec/controllers/{test_controller_spec.rb → tests_controller_spec.rb} +29 -80
  26. data/spec/integration/params_post_spec.rb +42 -0
  27. data/spec/lib/action_view/helpers/instance_tag_spec.rb +94 -0
  28. data/spec/{views/lib → lib/action_view}/param_parser_spec.rb +10 -10
  29. data/spec/spec_helper.rb +37 -105
  30. data/spec/test_rails_app/app/controllers/tests_controller.rb +11 -0
  31. data/spec/test_rails_app/app/models/post.rb +13 -0
  32. data/spec/test_rails_app/app/views/tests/basic_form.html.erb +5 -0
  33. data/spec/test_rails_app/app/views/tests/model_form.html.erb +12 -0
  34. data/spec/test_rails_app/config/locales/bot-away-overrides.yml +6 -0
  35. data/spec/views/form_builder_spec.rb +118 -0
  36. metadata +94 -137
  37. data/Manifest.txt +0 -23
  38. data/README.rdoc +0 -179
  39. data/VERSION +0 -1
  40. data/lib/bot-away/action_dispatch/request.rb +0 -20
  41. data/spec/rspec_version.rb +0 -19
  42. data/spec/support/honeypot_matcher.rb +0 -30
  43. data/spec/support/obfuscation_helper.rb +0 -123
  44. data/spec/support/obfuscation_matcher.rb +0 -28
  45. data/spec/support/rails/mock_logger.rb +0 -21
  46. data/spec/support/test_controller.rb +0 -28
  47. data/spec/support/views/test/index.html.erb +0 -4
  48. data/spec/support/views/test/model_form.html.erb +0 -6
  49. data/spec/views/lib/action_view/helpers/instance_tag_spec.rb +0 -75
  50. data/spec/views/lib/disabled_for_spec.rb +0 -101
  51. data/spec/views/lib/form_builder_spec.rb +0 -56
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.2.0
@@ -1,20 +0,0 @@
1
- request = (defined?(Rails::VERSION) && Rails::VERSION::STRING >= "3.0") ?
2
- ActionDispatch::Request : # Rails 3.0
3
- ActionController::Request # Rails 2.3
4
-
5
- request.module_eval do
6
- def parameters_with_deobfuscation
7
- # NFC what is happening behind the scenes but Rails 2.3 croaks when we memoize; Rails 3 croaks when we don't.
8
- if defined?(Rails::VERSION) && Rails::VERSION::STRING >= "3.0"
9
- @deobfuscated_parameters ||= begin
10
- BotAway::ParamParser.new(ip, parameters_without_deobfuscation.dup).params
11
- end
12
- else
13
- Rails.logger.info parameters_without_deobfuscation.inspect
14
- BotAway::ParamParser.new(ip, parameters_without_deobfuscation.dup).params
15
- end
16
- end
17
-
18
- alias_method_chain :parameters, :deobfuscation
19
- alias_method :params, :parameters
20
- end
@@ -1,19 +0,0 @@
1
- unless defined?(RSPEC_VERSION)
2
- begin
3
- # RSpec 1.3.0
4
- require 'spec/rake/spectask'
5
- require 'spec/version'
6
-
7
- RSPEC_VERSION = Spec::VERSION::STRING
8
- rescue LoadError
9
- # RSpec 2.0
10
- begin
11
- require 'rspec/core/rake_task'
12
- require 'rspec/core/version'
13
-
14
- RSPEC_VERSION = RSpec::Core::Version::STRING
15
- rescue LoadError
16
- raise "RSpec does not seem to be installed. You must install rspec to test this gem."
17
- end
18
- end
19
- end
@@ -1,30 +0,0 @@
1
- class HoneypotMatcher
2
- def initialize(object_name, method_name)
3
- @object_name, @method_name = object_name, method_name
4
- end
5
-
6
- def matches?(target)
7
- target = target.call if target.kind_of?(Proc)
8
- @target = target
9
- if @method_name.nil?
10
- @rx = /name="#{Regexp::escape @object_name}/m
11
- else
12
- @rx = /name="#{Regexp::escape @object_name}\[#{Regexp::escape @method_name}/m
13
- end
14
- @target[@rx]
15
- end
16
-
17
- def failure_message
18
- "expected #{@target.inspect}\n to match #{@rx.to_s}"
19
- end
20
-
21
- def negative_failure_message
22
- "expected #{@target.inspect}\n to not match #{@rx.to_s}"
23
- end
24
- end
25
-
26
- def include_honeypot(object_name, method_name)
27
- HoneypotMatcher.new(object_name, method_name)
28
- end
29
-
30
- alias contain_honeypot include_honeypot
@@ -1,123 +0,0 @@
1
- module ObfuscationHelper
2
- def controller_class
3
- TestController
4
- end
5
-
6
- def dump
7
- result = yield
8
- puts result if ENV['DUMP']
9
- result
10
- end
11
-
12
- if RAILS_VERSION >= "3.0"
13
- def self.included(base)
14
- base.before(:each) do
15
- session[:_csrf_token] = '1234'
16
- controller.stub!(:protect_from_forgery?).and_return(true)
17
- if respond_to?(:view)
18
- controller.request.path_parameters["action"] ||= "index"
19
- controller.action_name ||= "index"
20
- view.stub!(:request_forgery_protection_token).and_return(:authenticity_token)
21
- view.stub!(:form_authenticity_token).and_return('1234')
22
- else
23
- # response.stub!(:request_forgery_protection_token).and_return(:authenticity_token)
24
- # response.stub!(:form_authenticity_token).and_return('1234')
25
- end
26
- end
27
- end
28
- end
29
-
30
- def builder
31
- return @builder if @builder
32
- if RAILS_VERSION < "3.0"
33
- response = TestController.call(Rack::MockRequest.env_for('/').merge({'REQUEST_URI' => '/',
34
- 'REMOTE_ADDR' => '127.0.0.1'}))
35
- response.template.controller.request_forgery_protection_token = :authenticity_token
36
- response.template.controller.session[:_csrf_token] = '1234'
37
- @builder = ActionView::Helpers::FormBuilder.new(:object_name, MockObject.new, response.template, {}, proc {})
38
- else
39
- @builder = ActionView::Base.default_form_builder.new(:object_name, MockObject.new, view, {}, proc {})
40
- end
41
- end
42
-
43
- # this is the obfuscated version of the string "object_name_method_name"
44
- def obfuscated_id
45
- self.class.obfuscated_id
46
- end
47
-
48
- # this is the obfuscated version of the string "object_name[method_name]"
49
- def obfuscated_name
50
- self.class.obfuscated_name
51
- end
52
-
53
- def object_name
54
- self.class.object_name
55
- end
56
-
57
- def method_name
58
- self.class.method_name
59
- end
60
-
61
- module ClassMethods
62
- def includes_honeypot(object_name, method_name)
63
- it "includes a honeypot called #{object_name}[#{method_name}]" do
64
- subject.should include_honeypot(object_name, method_name)
65
- end
66
- end
67
-
68
- def is_obfuscated_as(id, name)
69
- it "is obfuscated as #{id}, #{name}" do
70
- subject.should be_obfuscated_as(id, name)
71
- end
72
- end
73
-
74
- def obfuscates(method, options = {}, unused = nil, &block)
75
- if !options.kind_of?(Hash)
76
- options = { :obfuscated_id => options, :obfuscated_name => unused }
77
- end
78
-
79
- obfuscated_id = options[:obfuscated_id] || self.obfuscated_id
80
- obfuscated_name = options[:obfuscatd_name] || self.obfuscated_name
81
-
82
- context "##{method}" do
83
- before(:each) { @obfuscates_value = instance_eval(&block) }
84
- subject { proc { dump { @obfuscates_value } } }
85
-
86
- if options[:name]
87
- includes_honeypot(options[:name], nil)
88
- else
89
- includes_honeypot(options[:object_name] || object_name, options[:method_name] || method_name)
90
- end
91
- is_obfuscated_as(obfuscated_id, obfuscated_name)
92
- end
93
- end
94
-
95
- def obfuscated_id
96
- RAILS_VERSION >= "3.0" ? "f51a02a636f507f1bd64722451b71297" : "e21372563297c728093bf74c3cb6b96c"
97
- end
98
-
99
- def obfuscated_name
100
- RAILS_VERSION >= "3.0" ? "cd538a9170613d6dedbcc54a0aa24881" : "a0844d45bf150668ff1d86a6eb491969"
101
- end
102
-
103
- def object_name
104
- "object_name"
105
- end
106
-
107
- def method_name
108
- "method_name"
109
- end
110
- end
111
- end
112
-
113
- if RSPEC_VERSION < "2.0"
114
- Spec::Runner.configure do |config|
115
- config.extend ObfuscationHelper::ClassMethods
116
- config.include ObfuscationHelper
117
- end
118
- else
119
- RSpec.configure do |config|
120
- config.extend ObfuscationHelper::ClassMethods
121
- config.include ObfuscationHelper
122
- end
123
- end
@@ -1,28 +0,0 @@
1
- class ObfuscationMatcher
2
- def initialize(id, name)
3
- @id, @name = id, name
4
- end
5
-
6
- def matches?(target)
7
- target = target.call if target.kind_of?(Proc)
8
- @target = target
9
- match(:id) && match(:name)
10
- end
11
-
12
- def match(which)
13
- @rx = /#{which}=['"]#{Regexp::escape instance_variable_get("@#{which}")}/
14
- @target[@rx]
15
- end
16
-
17
- def failure_message
18
- "expected #{@target.inspect}\n to match #{@rx.inspect}"
19
- end
20
-
21
- def negative_failure_message
22
- "expected #{@target.inspect}\n to not match #{@rx.inspect}"
23
- end
24
- end
25
-
26
- def be_obfuscated_as(id, name)
27
- ObfuscationMatcher.new(id, name)
28
- end
@@ -1,21 +0,0 @@
1
- require 'spec/mocks'
2
-
3
- module Rails
4
- class << self
5
- def logger
6
- return @logger if @logger
7
- @logger = Object.new
8
- klass = class << @logger; self; end
9
- if RSPEC_VERSION < "2.0"
10
- klass.send(:include, Spec::Mocks::Methods)
11
- else
12
- end
13
-
14
- def @logger.debug(message); end
15
- def @logger.info(message); end
16
- def @logger.error(message); end
17
- def @logger.warn(message); end
18
- @logger
19
- end
20
- end
21
- end
@@ -1,28 +0,0 @@
1
- class Post
2
- attr_reader :subject, :body, :subscribers
3
-
4
- if defined?(ActiveModel)
5
- extend ActiveModel::Naming
6
-
7
- def to_key
8
- [1]
9
- end
10
- end
11
- end
12
-
13
- class ApplicationController < ActionController::Base
14
-
15
- end
16
-
17
- class TestController < ApplicationController
18
- def index
19
- end
20
-
21
- def model_form
22
- @post = Post.new
23
- end
24
-
25
- def proc_form
26
- render :text => params.to_yaml
27
- end
28
- end
@@ -1,4 +0,0 @@
1
- <%form_for :test, :url => {:action => 'post_to'} do |f|%>
2
- <%=f.text_field :name%>
3
- <%end%>
4
-
@@ -1,6 +0,0 @@
1
- <%form_for @post, :url => url_for('proc_form') do |f|%>
2
- <p>
3
- <%=f.label :subject%><br/>
4
- <%=f.text_field :subject%>
5
- </p>
6
- <%end%>
@@ -1,75 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActionView::Helpers::InstanceTag do
4
- if method_defined?(:controller)
5
- def template
6
- view
7
- end
8
- else
9
- def template
10
- return @response if @response
11
- @response = TestController.call(Rack::MockRequest.env_for('/').merge({'REQUEST_URI' => '/',
12
- 'REMOTE_ADDR' => '127.0.0.1'}))
13
- @response.template.controller.request_forgery_protection_token = :authenticity_token
14
- @response.template.controller.session[:_csrf_token] = '1234'
15
- @response.template
16
- end
17
- end
18
-
19
- def mock_object
20
- @mock_object ||= MockObject.new
21
- end
22
-
23
- def default_instance_tag
24
- ActionView::Helpers::InstanceTag.new("object_name", "method_name", template, mock_object)
25
- end
26
-
27
- subject { default_instance_tag }
28
-
29
- context "with a valid text area tag" do
30
- subject do
31
- dump { default_instance_tag.to_text_area_tag }
32
- end
33
-
34
- it "should produce blank honeypot value" do
35
- subject.should_not =~ /name="object_name\[method_name\]"[^>]+>method_value<\/textarea>/
36
- end
37
- end
38
-
39
- context "with a valid input type=text tag" do
40
- before(:each) { @tag_options = ["input", {:type => 'text', 'name' => 'object_name[method_name]', 'id' => 'object_name_method_name', 'value' => 'method_value'}] }
41
- #subject { dump { default_instance_tag.tag(*@tag_options) } }
42
-
43
- it "should turn off autocomplete for honeypots" do
44
- subject.honeypot_tag(*@tag_options).should =~ /autocomplete="off"/
45
- end
46
-
47
- it "should obfuscate tag name" do
48
- subject.obfuscated_tag(*@tag_options).should =~ /name="#{obfuscated_name}"/
49
- end
50
-
51
- it "should obfuscate tag id" do
52
- subject.obfuscated_tag(*@tag_options).should =~ /id="#{obfuscated_id}"/
53
- end
54
-
55
- # it "should not obfuscate tag value" do
56
- # subject.obfuscated_tag(*@tag_options).should =~ /value="@tag_options"/
57
- # end
58
- #
59
- it "should include unobfuscated tag value" do
60
- subject.obfuscated_tag(*@tag_options).should =~ /value="method_value"/
61
- end
62
-
63
- it "should create honeypot name" do
64
- subject.honeypot_tag(*@tag_options).should =~ /name="object_name\[method_name\]"/
65
- end
66
-
67
- it "should create honeypot id" do
68
- subject.honeypot_tag(*@tag_options).should =~ /id="object_name_method_name"/
69
- end
70
-
71
- it "should create empty honeypot tag value" do
72
- subject.honeypot_tag(*@tag_options).should =~ /value=""/
73
- end
74
- end
75
- end
@@ -1,101 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Bot-Away" do
4
- # Basically we're just switching BA on and off, so we only need 2 sets of tests: what to expect when it's on, and
5
- # what to expect when it's off. The rest of this file just flips the switches.
6
-
7
- def test_params
8
- {"model"=>"User", "commit"=>"Sign in",
9
- "authenticity_token"=>"XBQEDkXrm4E8U9slBX45TWNx7TPcx8ww2FSJRy/XXg4=",
10
- "action"=>"index", "controller"=>"test", "user"=>{"username"=>"admin", "password"=>"Admin01"}
11
- }
12
- end
13
-
14
- def self.it_should_be_disabled
15
- it "should not obfuscate the field, because it should be disabled" do
16
- builder.text_field('method_name').should_not match(/name="#{obfuscated_name}/)
17
- end
18
-
19
- it "should not drop invalid params, because it should be disabled" do
20
- parms = BotAway::ParamParser.new('127.0.0.1', test_params).params
21
- parms.should == test_params
22
- end
23
-
24
- it "should be disabled" do
25
- BotAway.disabled_for?(:controller => 'test', :action => "index").should == true
26
- end
27
- end
28
-
29
- def self.it_should_be_enabled
30
- it "should obfuscate the field, because it should be enabled" do
31
- builder.text_field('method_name').should be_obfuscated_as(obfuscated_id, obfuscated_name)
32
- end
33
-
34
- it "should drop invalid params, because it should be enabled" do
35
- parms = BotAway::ParamParser.new('127.0.0.1', test_params).params
36
- parms.should_not == test_params
37
- end
38
-
39
- it "should be disabled" do
40
- BotAway.disabled_for?(:controller => 'test', :action => "index").should == false
41
- end
42
- end
43
-
44
- # flip-switching begins
45
-
46
- context "with matching controller name" do
47
- context "and no action" do
48
- before(:each) { BotAway.disabled_for :controller => 'test' }
49
- it_should_be_disabled
50
- end
51
-
52
- context "and matching action" do
53
- before(:each) { BotAway.disabled_for :controller => 'test', :action => 'index' }
54
- it_should_be_disabled
55
- end
56
-
57
- context "and not matching action" do
58
- before(:each) { BotAway.disabled_for :controller => 'test', :action => 'create' }
59
- it_should_be_enabled
60
- end
61
- end
62
-
63
- context "with not matching controller name" do
64
- context "and no action" do
65
- before(:each) { BotAway.disabled_for :controller => 'users' }
66
- it_should_be_enabled
67
- end
68
-
69
- context "and matching action" do
70
- before(:each) { BotAway.disabled_for :controller => 'users', :action => 'index' }
71
- it_should_be_enabled
72
- end
73
-
74
- context "and not matching action" do
75
- before(:each) { BotAway.disabled_for :controller => 'users', :action => 'create' }
76
- it_should_be_enabled
77
- end
78
- end
79
-
80
- context "with no controller name" do
81
- context "and matching action" do
82
- before(:each) { BotAway.disabled_for :action => 'index' }
83
- it_should_be_disabled
84
- end
85
-
86
- context "and not matching action" do
87
- before(:each) { BotAway.disabled_for :action => 'create' }
88
- it_should_be_enabled
89
- end
90
- end
91
-
92
- context "with matching mode" do
93
- before(:each) { BotAway.disabled_for :mode => ENV['RAILS_ENV'] }
94
- it_should_be_disabled
95
- end
96
-
97
- context "with not matching mode" do
98
- before(:each) { BotAway.disabled_for :mode => "this_is_not_#{ENV['RAILS_ENV']}" }
99
- it_should_be_enabled
100
- end
101
- end