protect against bots with timeouts
This commit is contained in:
@@ -43,6 +43,8 @@ group :development, :test do
|
|||||||
gem 'byebug'
|
gem 'byebug'
|
||||||
gem 'mongoid-rspec', '3.0.0'
|
gem 'mongoid-rspec', '3.0.0'
|
||||||
gem 'rspec-rails', '~> 3.0'
|
gem 'rspec-rails', '~> 3.0'
|
||||||
|
|
||||||
|
gem 'pry-rails'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ GEM
|
|||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
rack-test (>= 0.5.4)
|
rack-test (>= 0.5.4)
|
||||||
xpath (~> 2.0)
|
xpath (~> 2.0)
|
||||||
|
coderay (1.1.0)
|
||||||
coffee-rails (4.1.0)
|
coffee-rails (4.1.0)
|
||||||
coffee-script (>= 2.2.0)
|
coffee-script (>= 2.2.0)
|
||||||
railties (>= 4.0.0, < 5.0)
|
railties (>= 4.0.0, < 5.0)
|
||||||
@@ -80,6 +81,7 @@ GEM
|
|||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.6.3)
|
mail (2.6.3)
|
||||||
mime-types (>= 1.16, < 3)
|
mime-types (>= 1.16, < 3)
|
||||||
|
method_source (0.8.2)
|
||||||
mime-types (2.6.2)
|
mime-types (2.6.2)
|
||||||
mini_portile (0.6.2)
|
mini_portile (0.6.2)
|
||||||
minitest (5.8.1)
|
minitest (5.8.1)
|
||||||
@@ -98,6 +100,12 @@ GEM
|
|||||||
nokogiri (1.6.6.2)
|
nokogiri (1.6.6.2)
|
||||||
mini_portile (~> 0.6.0)
|
mini_portile (~> 0.6.0)
|
||||||
origin (2.1.1)
|
origin (2.1.1)
|
||||||
|
pry (0.10.2)
|
||||||
|
coderay (~> 1.1.0)
|
||||||
|
method_source (~> 0.8.1)
|
||||||
|
slop (~> 3.4)
|
||||||
|
pry-rails (0.3.4)
|
||||||
|
pry (>= 0.9.10)
|
||||||
puma (2.14.0)
|
puma (2.14.0)
|
||||||
rack (1.6.4)
|
rack (1.6.4)
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
@@ -174,6 +182,7 @@ GEM
|
|||||||
activesupport (>= 3.1, < 5.0)
|
activesupport (>= 3.1, < 5.0)
|
||||||
railties (>= 3.1, < 5.0)
|
railties (>= 3.1, < 5.0)
|
||||||
slim (~> 3.0)
|
slim (~> 3.0)
|
||||||
|
slop (3.6.0)
|
||||||
spring (1.4.0)
|
spring (1.4.0)
|
||||||
sprockets (3.3.5)
|
sprockets (3.3.5)
|
||||||
rack (> 1, < 3)
|
rack (> 1, < 3)
|
||||||
@@ -212,6 +221,7 @@ DEPENDENCIES
|
|||||||
jquery-rails
|
jquery-rails
|
||||||
mongoid (~> 5.0.0)
|
mongoid (~> 5.0.0)
|
||||||
mongoid-rspec (= 3.0.0)
|
mongoid-rspec (= 3.0.0)
|
||||||
|
pry-rails
|
||||||
puma
|
puma
|
||||||
rails (= 4.2.4)
|
rails (= 4.2.4)
|
||||||
rails-i18n
|
rails-i18n
|
||||||
|
|||||||
@@ -15,3 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
@import "bootstrap-sprockets"
|
@import "bootstrap-sprockets"
|
||||||
@import "bootstrap"
|
@import "bootstrap"
|
||||||
|
|
||||||
|
body
|
||||||
|
padding-top: 20px
|
||||||
|
|||||||
@@ -2,4 +2,18 @@ class ApplicationController < ActionController::Base
|
|||||||
# Prevent CSRF attacks by raising an exception.
|
# Prevent CSRF attacks by raising an exception.
|
||||||
# For APIs, you may want to use :null_session instead.
|
# For APIs, you may want to use :null_session instead.
|
||||||
protect_from_forgery with: :exception
|
protect_from_forgery with: :exception
|
||||||
|
|
||||||
|
INPUT_TIMEOUT = 2.seconds # We estimate that a user needs more then x seconds to enter some informations
|
||||||
|
|
||||||
|
# calculate how long a user needed for a form input, ussually we just
|
||||||
|
def input_to_fast?
|
||||||
|
fail 'session[:form_timestamp] not set' unless session[:form_timestamp]
|
||||||
|
duration = Time.now - session[:form_timestamp].to_time
|
||||||
|
duration < INPUT_TIMEOUT
|
||||||
|
end
|
||||||
|
|
||||||
|
# Set the current timestamp that marks entering a form
|
||||||
|
def set_form_timestamp
|
||||||
|
session[:form_timestamp] = Time.now
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
class SupportersController < ApplicationController
|
class SupportersController < ApplicationController
|
||||||
|
before_filter :set_form_timestamp, only: :new
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@supporter = Supporter.new
|
@supporter = Supporter.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@supporter = Supporter.new supporter_form_params
|
@supporter = Supporter.new supporter_form_params
|
||||||
if @supporter.save
|
if !input_to_fast? && @supporter.save
|
||||||
redirect_to thanks_path
|
redirect_to thanks_path
|
||||||
else
|
else
|
||||||
flash.now[:danger] = t 'shared.actions.failed'
|
flash.now[:danger] = t '.timeout' if input_to_fast?
|
||||||
render :new
|
render :new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,5 +5,7 @@ html
|
|||||||
= javascript_include_tag 'application', 'data-turbolinks-track' => true
|
= javascript_include_tag 'application', 'data-turbolinks-track' => true
|
||||||
= csrf_meta_tags
|
= csrf_meta_tags
|
||||||
body
|
body
|
||||||
|
= console if Rails.env.development?
|
||||||
.container
|
.container
|
||||||
|
= render 'shared/flashes'
|
||||||
= yield
|
= yield
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
- if flash.any?
|
||||||
|
#flashes
|
||||||
|
- flash.each do |type, message|
|
||||||
|
div class="alert alert-#{type} fade in"
|
||||||
|
= message
|
||||||
@@ -12,6 +12,8 @@ de:
|
|||||||
form:
|
form:
|
||||||
title: Ja, ich will helfen Cannabis in der Schweiz endlich zu legalisieren
|
title: Ja, ich will helfen Cannabis in der Schweiz endlich zu legalisieren
|
||||||
submit: Unterstützung zusichern
|
submit: Unterstützung zusichern
|
||||||
|
create:
|
||||||
|
timeout: Ihre Eingabe war zu schnell.
|
||||||
|
|
||||||
pages:
|
pages:
|
||||||
thanks:
|
thanks:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ require 'rails_helper'
|
|||||||
|
|
||||||
feature 'Support announcement' do
|
feature 'Support announcement' do
|
||||||
scenario 'User announces support' do
|
scenario 'User announces support' do
|
||||||
|
allow_any_instance_of(SupportersController).to receive(:input_to_fast?).and_return(false)
|
||||||
visit root_path
|
visit root_path
|
||||||
|
|
||||||
fill_in 'Vorname', with: 'Christoph'
|
fill_in 'Vorname', with: 'Christoph'
|
||||||
@@ -18,4 +19,17 @@ feature 'Support announcement' do
|
|||||||
|
|
||||||
expect { click_button 'Unterstützung zusichern' }.to change { Supporter.count }.by(1)
|
expect { click_button 'Unterstützung zusichern' }.to change { Supporter.count }.by(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scenario 'A bot tries to enter data' do
|
||||||
|
visit root_path
|
||||||
|
|
||||||
|
click_button 'Unterstützung zusichern'
|
||||||
|
|
||||||
|
expect(page).to have_content 'Ihre Eingabe war zu schnell.'
|
||||||
|
|
||||||
|
# Test twice just to be sure that it's not become an update action
|
||||||
|
click_button 'Unterstützung zusichern'
|
||||||
|
|
||||||
|
expect(page).to have_content 'Ihre Eingabe war zu schnell.'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user