adding recaptcha support for comments
parent
5e151f4a77
commit
566516eb46
1
README
1
README
|
@ -12,6 +12,7 @@ Gem Requirements
|
|||
* rmagick
|
||||
* RedCloth
|
||||
* rubyzip (for mass image imports)
|
||||
* libxml-ruby
|
||||
* mysql (recommended -- others may work fine, too)
|
||||
|
||||
Special installation instructions
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
class Comments < Application
|
||||
|
||||
include Ambethia::ReCaptcha::Controller
|
||||
|
||||
def new
|
||||
only_provides :html
|
||||
@page = Page.find_by_name(params[:page_id].gsub(/_/, ' '))
|
||||
|
@ -12,7 +15,7 @@ class Comments < Application
|
|||
raise NotFound unless @page
|
||||
@comment = Comment.new(params[:comment])
|
||||
@comment.page_id = @page.id
|
||||
if @comment.save
|
||||
if (logged_in? or verify_recaptcha(@comment)) and @comment.save
|
||||
flash[:notice] = 'Great success!'
|
||||
redirect url(:page, :id => params[:page_id])
|
||||
else
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module Merb
|
||||
module CommentsHelper
|
||||
|
||||
include Ambethia::ReCaptcha::Helper
|
||||
end
|
||||
end
|
|
@ -18,4 +18,10 @@
|
|||
<p>
|
||||
<%= text_area_control :comment, :label => 'Comment: ', :rows => 8, :cols => 60 %>
|
||||
</p>
|
||||
<% unless logged_in? -%>
|
||||
<p>
|
||||
<strong>Ident</strong>
|
||||
<%= recaptcha_tags %>
|
||||
</p>
|
||||
<% end -%>
|
||||
</fieldset>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
<%= error_messages_for :comment %>
|
||||
|
||||
<% form_for :comment, :action => url(:comment) do %>
|
||||
<% form_for :comment, :action => url(:comments) do %>
|
||||
<%= partial :comment_form %>
|
||||
<p>
|
||||
<%= submit_button 'Create' %>
|
||||
|
|
|
@ -16,6 +16,7 @@ require 'redcloth'
|
|||
require 'RMagick'
|
||||
require 'memcache'
|
||||
require 'memcache_util'
|
||||
require 'recaptcha'
|
||||
|
||||
Merb::BootLoader.after_app_loads do
|
||||
config_path = File.join(Merb.root, 'config', 'memcache.yml')
|
||||
|
@ -28,4 +29,13 @@ Merb::BootLoader.after_app_loads do
|
|||
|
||||
Merb::Mailer.config = { :sendmail_path => '/usr/sbin/sendmail' }
|
||||
Merb::Mailer.delivery_method = :sendmail
|
||||
|
||||
recaptcha_path = File.join(Merb.root, 'config', 'recaptcha.yml')
|
||||
if File.file?(recaptcha_path) and File.readable?(recaptcha_path)
|
||||
rc = YAML::load_file(recaptcha_path)
|
||||
ENV['RECAPTCHA_PUBLIC_KEY'] = rc[:public]
|
||||
ENV['RECAPTCHA_PRIVATE_KEY'] = rc[:private]
|
||||
else
|
||||
raise "ReCaptcha configuration file not found!"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
use Merb::Rack::Static, Merb.dir_for(:public)
|
||||
run Merb::Rack::Application.new
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
:public: PUBKEY
|
||||
:private: PRIVKEY
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2007 Jason L Perry
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,78 @@
|
|||
# ReCAPTCHA
|
||||
module Ambethia
|
||||
module ReCaptcha
|
||||
RECAPTCHA_API_SERVER = 'http://api.recaptcha.net';
|
||||
RECAPTCHA_API_SECURE_SERVER = 'https://api-secure.recaptcha.net';
|
||||
RECAPTCHA_VERIFY_SERVER = 'api-verify.recaptcha.net';
|
||||
|
||||
SKIP_VERIFY_ENV = ['test']
|
||||
|
||||
module Helper
|
||||
# Your public API can be specified in the +options+ hash or preferably the environment
|
||||
# variable +RECAPTCHA_PUBLIC_KEY+.
|
||||
def recaptcha_tags(options = {})
|
||||
# Default options
|
||||
key = options[:public_key] ||= ENV['RECAPTCHA_PUBLIC_KEY']
|
||||
error = options[:error] ||= session[:recaptcha_error]
|
||||
uri = options[:ssl] ? RECAPTCHA_API_SECURE_SERVER : RECAPTCHA_API_SERVER
|
||||
xhtml = Builder::XmlMarkup.new :target => out=(''), :indent => 2 # Because I can.
|
||||
if options[:display]
|
||||
xhtml.script(:type => "text/javascript"){ xhtml.text! "var RecaptchaOptions = #{options[:display].to_json};\n"}
|
||||
end
|
||||
if options[:ajax]
|
||||
xhtml.div(:id => 'dynamic_recaptcha') {}
|
||||
xhtml.script(:type => "text/javascript", :src => "#{uri}/js/recaptcha_ajax.js") {}
|
||||
xhtml.script(:type => "text/javascript") do
|
||||
xhtml.text! "Recaptcha.create('#{key}', document.getElementById('dynamic_recaptcha') );"
|
||||
end
|
||||
else
|
||||
xhtml.script(:type => "text/javascript", :src => "#{uri}/challenge?k=#{key}&error=#{error}") {}
|
||||
unless options[:noscript] == false
|
||||
xhtml.noscript do
|
||||
xhtml.iframe(:src => "#{uri}/noscript?k=#{key}",
|
||||
:height => options[:iframe_height] ||= 300,
|
||||
:width => options[:iframe_width] ||= 500,
|
||||
:frameborder => 0) {}; xhtml.br
|
||||
xhtml.textarea(:name => "recaptcha_challenge_field", :rows => 3, :cols => 40) {}
|
||||
xhtml.input :name => "recaptcha_response_field",
|
||||
:type => "hidden", :value => "manual_challenge"
|
||||
end
|
||||
end
|
||||
end
|
||||
raise ReCaptchaError, "No public key specified." unless key
|
||||
return out
|
||||
end # recaptcha_tags
|
||||
end # Helpers
|
||||
|
||||
module Controller
|
||||
# Your private API key must be specified in the environment variable +RECAPTCHA_PRIVATE_KEY+
|
||||
def verify_recaptcha(model = nil)
|
||||
return true if SKIP_VERIFY_ENV.include? ENV['RAILS_ENV']
|
||||
raise ReCaptchaError, "No private key specified." unless ENV['RECAPTCHA_PRIVATE_KEY']
|
||||
begin
|
||||
recaptcha = Net::HTTP.post_form URI.parse("http://#{RECAPTCHA_VERIFY_SERVER}/verify"), {
|
||||
:privatekey => ENV['RECAPTCHA_PRIVATE_KEY'],
|
||||
:remoteip => request.remote_ip,
|
||||
:challenge => params[:recaptcha_challenge_field],
|
||||
:response => params[:recaptcha_response_field]
|
||||
}
|
||||
answer, error = recaptcha.body.split.map { |s| s.chomp }
|
||||
unless answer == 'true'
|
||||
session[:recaptcha_error] = error
|
||||
model.valid? if model
|
||||
model.errors.add_to_base "Captcha response is incorrect, please try again." if model
|
||||
return false
|
||||
else
|
||||
session[:recaptcha_error] = nil
|
||||
return true
|
||||
end
|
||||
rescue Exception => e
|
||||
raise ReCaptchaError, e
|
||||
end
|
||||
end # verify_recaptcha
|
||||
end # ControllerHelpers
|
||||
|
||||
class ReCaptchaError < StandardError; end
|
||||
|
||||
end # ReCaptcha
|
||||
end # Ambethia
|
Reference in New Issue