Commit 97f28847c412196c24e0ee24b0a8a9e482c38f42
Exists in
master
and in
29 other branches
Merge branch 'honeypot'
Showing
5 changed files
with
68 additions
and
1 deletions
Show diff stats
app/controllers/public/account_controller.rb
@@ -4,6 +4,7 @@ class AccountController < ApplicationController | @@ -4,6 +4,7 @@ class AccountController < ApplicationController | ||
4 | 4 | ||
5 | before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise] | 5 | before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise] |
6 | before_filter :redirect_if_logged_in, :only => [:login, :signup] | 6 | before_filter :redirect_if_logged_in, :only => [:login, :signup] |
7 | + before_filter :protect_from_bots, :only => :signup | ||
7 | 8 | ||
8 | # say something nice, you goof! something sweet. | 9 | # say something nice, you goof! something sweet. |
9 | def index | 10 | def index |
app/views/account/_signup_form.rhtml
@@ -9,7 +9,7 @@ | @@ -9,7 +9,7 @@ | ||
9 | 9 | ||
10 | <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %> | 10 | <%= error_messages_for :user, :person, :header_message => _('The account could not be created') %> |
11 | 11 | ||
12 | -<% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form' } do |f| %> | 12 | +<% labelled_form_for :user, @user, :html => { :multipart => true, :id => 'signup-form', :honeypot => true } do |f| %> |
13 | 13 | ||
14 | <input type="hidden" id="signup_time_key" name="signup_time_key" /> | 14 | <input type="hidden" id="signup_time_key" name="signup_time_key" /> |
15 | <script type="text/javascript"> | 15 | <script type="text/javascript"> |
test/functional/account_controller_test.rb
@@ -882,6 +882,18 @@ class AccountControllerTest < ActionController::TestCase | @@ -882,6 +882,18 @@ class AccountControllerTest < ActionController::TestCase | ||
882 | assert_tag :tag => 'strong', :content => 'Plugin2 text' | 882 | assert_tag :tag => 'strong', :content => 'Plugin2 text' |
883 | end | 883 | end |
884 | 884 | ||
885 | + should 'include honeypot in the signup form' do | ||
886 | + get :signup | ||
887 | + assert_tag :tag => /input|textarea/, :attributes => {:id => 'honeypot'} | ||
888 | + end | ||
889 | + | ||
890 | + should 'not sign in if the honeypot field is filled' do | ||
891 | + Person.any_instance.stubs(:required_fields).returns(['organization']) | ||
892 | + assert_no_difference User, :count do | ||
893 | + post :signup, :user => { :login => 'testuser', :password => '123456', :password_confirmation => '123456', :email => 'testuser@example.com' }, :profile_data => { :organization => 'example.com' }, :honeypot => 'something' | ||
894 | + end | ||
895 | + assert @response.body.blank? | ||
896 | + end | ||
885 | 897 | ||
886 | protected | 898 | protected |
887 | def new_user(options = {}, extra_options ={}) | 899 | def new_user(options = {}, extra_options ={}) |
@@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
1 | +# Inpired on https://github.com/curtis/honeypot-captcha | ||
2 | +require File.join(File.dirname(__FILE__), 'lib', 'form_tag_helper') | ||
3 | + | ||
4 | +module Honeypot | ||
5 | + def honeypot_fields | ||
6 | + { :honeypot => _('Do not fill in this field') } | ||
7 | + end | ||
8 | + | ||
9 | + def protect_from_bots | ||
10 | + head :ok if honeypot_fields.any? { |f,l| !params[f].blank? } | ||
11 | + end | ||
12 | + | ||
13 | + def self.included(base) | ||
14 | + base.send :helper_method, :honeypot_fields | ||
15 | + end | ||
16 | +end | ||
17 | + | ||
18 | +ActionController::Base.send(:include, Honeypot) if defined?(ActionController::Base) |
@@ -0,0 +1,36 @@ | @@ -0,0 +1,36 @@ | ||
1 | +module ActionView | ||
2 | + module Helpers | ||
3 | + module FormTagHelper | ||
4 | + def form_tag_with_honeypot(url_for_options = {}, options = {}, *parameters_for_url, &block) | ||
5 | + honeypot = options.delete(:honeypot) | ||
6 | + html = form_tag_without_honeypot(url_for_options, options, *parameters_for_url, &block) | ||
7 | + if honeypot | ||
8 | + captcha = "".respond_to?(:html_safe) ? honey_pot_captcha.html_safe : honey_pot_captcha | ||
9 | + if block_given? | ||
10 | + html.insert(html.index('</form>'), captcha) | ||
11 | + else | ||
12 | + html += captcha | ||
13 | + end | ||
14 | + end | ||
15 | + html | ||
16 | + end | ||
17 | + alias_method_chain :form_tag, :honeypot | ||
18 | + | ||
19 | + private | ||
20 | + | ||
21 | + def honey_pot_captcha | ||
22 | + html_ids = [] | ||
23 | + honeypot_fields.collect do |f, l| | ||
24 | + html_ids << (html_id = "#{f}_hp_#{Time.now.to_i}") | ||
25 | + content_tag :div, :id => html_id do | ||
26 | + content_tag(:style, :type => 'text/css', :media => 'screen', :scoped => "scoped") do | ||
27 | + "#{html_ids.map { |i| "##{i}" }.join(', ')} { display:none; }" | ||
28 | + end + | ||
29 | + label_tag(f, l) + | ||
30 | + send([:text_field_tag, :text_area_tag][rand(2)], f) | ||
31 | + end | ||
32 | + end.join | ||
33 | + end | ||
34 | + end | ||
35 | + end | ||
36 | +end |