Merge pull request #137 from AyuntamientoMadrid/captcha-51
uses simple_captcha instead of recaptcha [#51]
This commit is contained in:
2
Gemfile
2
Gemfile
@@ -26,7 +26,7 @@ gem 'acts-as-taggable-on'
|
||||
gem "responders"
|
||||
gem 'foundation-rails'
|
||||
gem 'acts_as_votable'
|
||||
gem "recaptcha", require: "recaptcha/rails"
|
||||
gem 'simple_captcha2', require: 'simple_captcha'
|
||||
gem 'ckeditor'
|
||||
gem 'cancancan'
|
||||
gem 'social-share-button'
|
||||
|
||||
@@ -205,7 +205,6 @@ GEM
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rake (10.4.2)
|
||||
recaptcha (0.4.0)
|
||||
responders (2.1.0)
|
||||
railties (>= 4.2.0, < 5)
|
||||
rest-client (1.8.0)
|
||||
@@ -236,6 +235,8 @@ GEM
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (~> 1.1)
|
||||
simple_captcha2 (0.3.4)
|
||||
rails (>= 4.1)
|
||||
simplecov (0.10.0)
|
||||
docile (~> 1.1.0)
|
||||
json (~> 1.8)
|
||||
@@ -317,10 +318,10 @@ DEPENDENCIES
|
||||
poltergeist
|
||||
quiet_assets
|
||||
rails (= 4.2.3)
|
||||
recaptcha
|
||||
responders
|
||||
rspec-rails (~> 3.0)
|
||||
sass-rails (~> 5.0)
|
||||
simple_captcha2
|
||||
social-share-button
|
||||
spring
|
||||
turbolinks
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
require "application_responder"
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
|
||||
check_authorization unless: :devise_controller?
|
||||
|
||||
include SimpleCaptcha::ControllerHelpers
|
||||
self.responder = ApplicationResponder
|
||||
respond_to :html
|
||||
|
||||
@@ -38,9 +37,4 @@ class ApplicationController < ActionController::Base
|
||||
end
|
||||
end
|
||||
|
||||
def verify_captcha?(resource)
|
||||
return true unless recaptcha_keys?
|
||||
verify_recaptcha(model: resource)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
class DebatesController < ApplicationController
|
||||
include RecaptchaHelper
|
||||
before_action :authenticate_user!, except: [:index, :show]
|
||||
load_and_authorize_resource
|
||||
|
||||
@@ -28,7 +27,7 @@ class DebatesController < ApplicationController
|
||||
def create
|
||||
@debate = Debate.new(debate_params)
|
||||
@debate.author = current_user
|
||||
if verify_captcha?(@debate) and @debate.save
|
||||
if @debate.save_with_captcha
|
||||
redirect_to @debate, notice: t('flash.actions.create.notice', resource_name: 'Debate')
|
||||
else
|
||||
render :new
|
||||
@@ -52,7 +51,7 @@ class DebatesController < ApplicationController
|
||||
end
|
||||
|
||||
def debate_params
|
||||
params.require(:debate).permit(:title, :description, :tag_list, :terms_of_service)
|
||||
params.require(:debate).permit(:title, :description, :tag_list, :terms_of_service, :captcha, :captcha_key)
|
||||
end
|
||||
|
||||
def set_voted_values(debates_ids)
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
class RegistrationsController < Devise::RegistrationsController
|
||||
include RecaptchaHelper
|
||||
|
||||
def create
|
||||
if verify_captcha?(resource)
|
||||
build_resource(sign_up_params)
|
||||
if resource.valid_with_captcha?
|
||||
super
|
||||
else
|
||||
build_resource(sign_up_params)
|
||||
flash.now[:alert] = t('recaptcha.errors.verification_failed')
|
||||
render :new
|
||||
end
|
||||
end
|
||||
@@ -15,7 +13,7 @@ class RegistrationsController < Devise::RegistrationsController
|
||||
private
|
||||
|
||||
def sign_up_params
|
||||
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :use_nickname, :nickname)
|
||||
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation, :use_nickname, :nickname, :captcha, :captcha_key)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
module RecaptchaHelper
|
||||
|
||||
def recaptchable?(resource)
|
||||
resource.new_record?
|
||||
end
|
||||
|
||||
def recaptcha_keys?
|
||||
Recaptcha.configuration.public_key.present? &&
|
||||
Recaptcha.configuration.private_key.present?
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
require 'numeric'
|
||||
class Debate < ActiveRecord::Base
|
||||
|
||||
apply_simple_captcha
|
||||
TITLE_LENGTH = Debate.columns.find{|c| c.name == 'title'}.limit
|
||||
|
||||
acts_as_votable
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class User < ActiveRecord::Base
|
||||
apply_simple_captcha
|
||||
devise :database_authenticatable, :registerable, :confirmable,
|
||||
:recoverable, :rememberable, :trackable, :validatable
|
||||
|
||||
|
||||
@@ -37,10 +37,10 @@
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= render 'shared/captcha', resource: @debate %>
|
||||
<%= f.simple_captcha %>
|
||||
</div>
|
||||
|
||||
<div class="actions small-12 column">
|
||||
<div class="actions small-12 column" style="padding-top:20px">
|
||||
<%= f.submit(class: "button radius") %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= render 'shared/captcha', resource: resource %>
|
||||
<%= f.simple_captcha %>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 columns">
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
<%= javascript_include_tag "vendor/modernizr" %>
|
||||
<%= javascript_include_tag "application", 'data-turbolinks-track' => true %>
|
||||
<%= csrf_meta_tags %>
|
||||
<script src="https://www.google.com/recaptcha/api.js?hl=<%= I18n.locale %>"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
<%= javascript_include_tag "vendor/modernizr" %>
|
||||
<%= javascript_include_tag "application", 'data-turbolinks-track' => true %>
|
||||
<%= csrf_meta_tags %>
|
||||
<script src="https://www.google.com/recaptcha/api.js?hl=<%= I18n.locale %>"></script>
|
||||
</head>
|
||||
|
||||
<body class="auth-page">
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
<% if recaptchable?(resource) and recaptcha_keys? %>
|
||||
<%= recaptcha_tags ajax: true, hl: I18n.locale %>
|
||||
<% end %>
|
||||
41
app/views/simple_captcha/_simple_captcha.erb
Normal file
41
app/views/simple_captcha/_simple_captcha.erb
Normal file
@@ -0,0 +1,41 @@
|
||||
<style type="text/css">
|
||||
.simple_captcha{border: 1px solid #ccc; padding: 5px !important;}
|
||||
.simple_captcha,
|
||||
.simple_captcha div{display: table;}
|
||||
.simple_captcha .simple_captcha_field,
|
||||
.simple_captcha .simple_captcha_image{
|
||||
border: 1px solid #ccc;
|
||||
margin: 0px 0px 2px 0px !important;
|
||||
padding: 0px !important;
|
||||
}
|
||||
.simple_captcha .simple_captcha_image img{
|
||||
margin: 0px !important;
|
||||
padding: 0px !important;
|
||||
width: 110px !important;
|
||||
}
|
||||
.simple_captcha .simple_captcha_label{font-size: 12px;}
|
||||
.simple_captcha .simple_captcha_field input{
|
||||
width: 150px !important;
|
||||
font-size: 16px;
|
||||
border: none;
|
||||
background-color: #efefef;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='simple_captcha'>
|
||||
<div class='simple_captcha_image'>
|
||||
<%= simple_captcha_options[:image] %>
|
||||
</div>
|
||||
|
||||
<div class='simple_captcha_field'>
|
||||
<%= simple_captcha_options[:field] %>
|
||||
</div>
|
||||
|
||||
<div class='simple_captcha_label'>
|
||||
<%= simple_captcha_options[:label] %>
|
||||
</div>
|
||||
|
||||
<div class='simple_captcha_refresh_button'>
|
||||
<%= simple_captcha_options[:refresh_button] %>
|
||||
</div>
|
||||
</div>
|
||||
@@ -99,6 +99,7 @@ ignore_unused:
|
||||
# - 'simple_form.{error_notification,required}.:'
|
||||
ignore_unused:
|
||||
- 'unauthorized.*'
|
||||
- 'simple_captcha.*'
|
||||
|
||||
## Exclude these keys from the `i18n-tasks eq-base' report:
|
||||
# ignore_eq_base:
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
Recaptcha.configure do |config|
|
||||
config.public_key = Rails.application.secrets.recaptcha_public_key
|
||||
config.private_key = Rails.application.secrets.recaptcha_private_key
|
||||
config.api_version = 'v2'
|
||||
end
|
||||
37
config/initializers/simple_captcha.rb
Normal file
37
config/initializers/simple_captcha.rb
Normal file
@@ -0,0 +1,37 @@
|
||||
SimpleCaptcha.always_pass = false
|
||||
|
||||
SimpleCaptcha.setup do |sc|
|
||||
# default: 100x28
|
||||
sc.image_size = '120x40'
|
||||
|
||||
# default: 5
|
||||
sc.length = 6
|
||||
|
||||
# default: simply_blue
|
||||
# possible values:
|
||||
# 'embosed_silver',
|
||||
# 'simply_red',
|
||||
# 'simply_green',
|
||||
# 'simply_blue',
|
||||
# 'distorted_black',
|
||||
# 'all_black',
|
||||
# 'charcoal_grey',
|
||||
# 'almost_invisible'
|
||||
# 'random'
|
||||
sc.image_style = 'simply_green'
|
||||
|
||||
# default: low
|
||||
# possible values: 'low', 'medium', 'high', 'random'
|
||||
sc.distortion = 'random'
|
||||
|
||||
# default: medium
|
||||
# possible values: 'none', 'low', 'medium', 'high'
|
||||
sc.implode = 'medium'
|
||||
|
||||
# sc.image_style = 'mycaptha'
|
||||
# sc.add_image_style('mycaptha', [
|
||||
# "-background '#F4F7F8'",
|
||||
# "-fill '#86818B'",
|
||||
# "-border 1",
|
||||
# "-bordercolor '#E0E2E3'"])
|
||||
end
|
||||
@@ -72,9 +72,12 @@ en:
|
||||
last_name_label: "Last Name"
|
||||
use_nickname_label: "Use nickname"
|
||||
nickname_label: "Nickname"
|
||||
recaptcha:
|
||||
errors:
|
||||
verification_failed: "The captcha verification failed"
|
||||
simple_captcha:
|
||||
placeholder: "Enter the image value"
|
||||
label: "Enter the code in the box:"
|
||||
message:
|
||||
user: "secret code did not match with the image"
|
||||
debate: "secret code did not match with the image"
|
||||
shared:
|
||||
tags_cloud:
|
||||
tags: Tags
|
||||
|
||||
@@ -72,9 +72,12 @@ es:
|
||||
last_name_label: "Apellidos"
|
||||
use_nickname_label: "Usar pseudónimo"
|
||||
nickname_label: "Pseudónimo"
|
||||
recaptcha:
|
||||
errors:
|
||||
verification_failed: "La verificación por captcha falló"
|
||||
simple_captcha:
|
||||
placeholder: "Introduce el texto de la imagen"
|
||||
label: "Introduce el texto en la caja:"
|
||||
message:
|
||||
user: "el código secreto no coincide con la imagen"
|
||||
debate: "el código secreto no coincide con la imagen"
|
||||
shared:
|
||||
tags_cloud:
|
||||
tags: Etiquetas
|
||||
|
||||
@@ -20,7 +20,3 @@
|
||||
# available at http://guides.rubyonrails.org/i18n.html.
|
||||
|
||||
en:
|
||||
recaptcha:
|
||||
errors:
|
||||
verification_failed: "Incorrect Captcha"
|
||||
recaptcha_unreachable: "Internet connecion error. Could not load Captcha"
|
||||
|
||||
@@ -10,7 +10,7 @@ es:
|
||||
- vie
|
||||
- sáb
|
||||
abbr_month_names:
|
||||
-
|
||||
-
|
||||
- ene
|
||||
- feb
|
||||
- mar
|
||||
@@ -36,7 +36,7 @@ es:
|
||||
long: "%d de %B de %Y"
|
||||
short: "%d de %b"
|
||||
month_names:
|
||||
-
|
||||
-
|
||||
- enero
|
||||
- febrero
|
||||
- marzo
|
||||
@@ -195,8 +195,4 @@ es:
|
||||
default: "%A, %d de %B de %Y %H:%M:%S %z"
|
||||
long: "%d de %B de %Y %H:%M"
|
||||
short: "%d de %b %H:%M"
|
||||
pm: pm
|
||||
recaptcha:
|
||||
errors:
|
||||
verification_failed: "El Captcha no es correcto"
|
||||
recaptcha_unreachable: "Fallo de conexión a Internet. No se ha podido cargar el Captcha"
|
||||
pm: pm
|
||||
@@ -11,8 +11,6 @@
|
||||
# if you're sharing your code publicly.
|
||||
|
||||
default: &default
|
||||
recaptcha_public_key: <%= ENV["MADRID_RECAPTCHA_PUBLIC_KEY"] %>
|
||||
recaptcha_private_key: <%= ENV["MADRID_RECAPTCHA_PRIVATE_KEY"] %>
|
||||
|
||||
development:
|
||||
secret_key_base: 56792feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4
|
||||
|
||||
15
db/migrate/20150808141306_create_simple_captcha_data.rb
Normal file
15
db/migrate/20150808141306_create_simple_captcha_data.rb
Normal file
@@ -0,0 +1,15 @@
|
||||
class CreateSimpleCaptchaData < ActiveRecord::Migration
|
||||
def self.up
|
||||
create_table :simple_captcha_data do |t|
|
||||
t.string :key, :limit => 40
|
||||
t.string :value, :limit => 6
|
||||
t.timestamps
|
||||
end
|
||||
|
||||
add_index :simple_captcha_data, :key, :name => "idx_key"
|
||||
end
|
||||
|
||||
def self.down
|
||||
drop_table :simple_captcha_data
|
||||
end
|
||||
end
|
||||
11
db/schema.rb
11
db/schema.rb
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150807140346) do
|
||||
ActiveRecord::Schema.define(version: 20150808141306) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -53,6 +53,15 @@ ActiveRecord::Schema.define(version: 20150807140346) do
|
||||
|
||||
add_index "moderators", ["user_id"], name: "index_moderators_on_user_id", using: :btree
|
||||
|
||||
create_table "simple_captcha_data", force: :cascade do |t|
|
||||
t.string "key", limit: 40
|
||||
t.string "value", limit: 6
|
||||
t.datetime "created_at"
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
add_index "simple_captcha_data", ["key"], name: "idx_key", using: :btree
|
||||
|
||||
create_table "taggings", force: :cascade do |t|
|
||||
t.integer "tag_id"
|
||||
t.integer "taggable_id"
|
||||
|
||||
@@ -47,6 +47,7 @@ feature 'Debates' do
|
||||
visit new_debate_path
|
||||
fill_in 'debate_title', with: 'Acabar con los desahucios'
|
||||
fill_in 'debate_description', with: 'Esto es un tema muy importante porque...'
|
||||
fill_in 'debate_captcha', with: correct_captcha_text
|
||||
check 'debate_terms_of_service'
|
||||
|
||||
click_button 'Create Debate'
|
||||
@@ -65,6 +66,7 @@ feature 'Debates' do
|
||||
visit new_debate_path
|
||||
fill_in 'debate_title', with: 'A test'
|
||||
fill_in 'debate_description', with: '<p>This is <script>alert("an attack");</script></p>'
|
||||
fill_in 'debate_captcha', with: correct_captcha_text
|
||||
check 'debate_terms_of_service'
|
||||
|
||||
click_button 'Create Debate'
|
||||
@@ -86,6 +88,7 @@ feature 'Debates' do
|
||||
fill_in 'debate_title', with: 'A test'
|
||||
fill_in 'debate_description', with: 'A test'
|
||||
fill_in 'debate_tag_list', with: 'user_id=1, &a=3, <script>alert("hey");</script>'
|
||||
fill_in 'debate_captcha', with: SimpleCaptcha::SimpleCaptchaData.first.value
|
||||
check 'debate_terms_of_service'
|
||||
|
||||
click_button 'Create Debate'
|
||||
|
||||
@@ -65,6 +65,7 @@ feature 'Tags' do
|
||||
visit new_debate_path
|
||||
fill_in 'debate_title', with: 'Title'
|
||||
fill_in 'debate_description', with: 'Description'
|
||||
fill_in 'debate_captcha', with: correct_captcha_text
|
||||
check 'debate_terms_of_service'
|
||||
|
||||
fill_in 'debate_tag_list', with: "Impuestos, Economía, Hacienda"
|
||||
|
||||
@@ -11,6 +11,7 @@ feature 'Users' do
|
||||
fill_in 'user_email', with: 'manuela@madrid.es'
|
||||
fill_in 'user_password', with: 'judgementday'
|
||||
fill_in 'user_password_confirmation', with: 'judgementday'
|
||||
fill_in 'user_captcha', with: correct_captcha_text
|
||||
|
||||
click_button 'Sign up'
|
||||
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe RecaptchaHelper do
|
||||
|
||||
describe '#recaptchable?' do
|
||||
|
||||
it 'should be true if new record' do
|
||||
debate = build(:debate)
|
||||
expect(helper.recaptchable?(debate)).to be true
|
||||
end
|
||||
|
||||
it 'should be false if existing record' do
|
||||
debate = create(:debate)
|
||||
expect(helper.recaptchable?(debate)).to be false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "#recaptcha_keys?" do
|
||||
|
||||
it "should be true if Recaptcha keys are configured" do
|
||||
allow(Recaptcha.configuration).to receive(:public_key).and_return("akjasf")
|
||||
allow(Recaptcha.configuration).to receive(:private_key).and_return("akjasf4532")
|
||||
|
||||
expect(helper.recaptcha_keys?).to be true
|
||||
end
|
||||
|
||||
it "should be false if Recaptcha keys are not configured" do
|
||||
allow(Recaptcha.configuration).to receive(:public_key).and_return(nil)
|
||||
allow(Recaptcha.configuration).to receive(:private_key).and_return(nil)
|
||||
|
||||
expect(helper.recaptcha_keys?).to be false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -9,6 +9,7 @@ module CommonActions
|
||||
fill_in 'user_email', with: 'manuela@madrid.es'
|
||||
fill_in 'user_password', with: 'judgementday'
|
||||
fill_in 'user_password_confirmation', with: 'judgementday'
|
||||
fill_in 'user_captcha', with: correct_captcha_text
|
||||
|
||||
click_button 'Sign up'
|
||||
end
|
||||
@@ -51,4 +52,8 @@ module CommonActions
|
||||
expect(page).to have_content 'It will be done next week.'
|
||||
end
|
||||
|
||||
def correct_captcha_text
|
||||
SimpleCaptcha::SimpleCaptchaData.first.value
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user