Commit 4fe87ea2452f92429c2f7af9d9bc1b54a9928792

Authored by Caio SBA
Committed by Joenio Costa
1 parent fd5c2e61

Adding recaptcha to comments and article suggestion

(ActionItem2075)
Showing 65 changed files with 792 additions and 452 deletions   Show diff stats
app/controllers/my_profile/cms_controller.rb
@@ -285,7 +285,7 @@ class CmsController < MyProfileController @@ -285,7 +285,7 @@ class CmsController < MyProfileController
285 @task = SuggestArticle.new(params[:task]) 285 @task = SuggestArticle.new(params[:task])
286 if request.post? 286 if request.post?
287 @task.target = profile 287 @task.target = profile
288 - if @task.save 288 + if verify_recaptcha(:model => @task, :message => _('Please type the words correctly')) && @task.save
289 session[:notice] = _('Thanks for your suggestion. The community administrators were notified.') 289 session[:notice] = _('Thanks for your suggestion. The community administrators were notified.')
290 redirect_to @back_to 290 redirect_to @back_to
291 end 291 end
app/controllers/public/account_controller.rb
@@ -2,8 +2,6 @@ class AccountController < ApplicationController @@ -2,8 +2,6 @@ class AccountController < ApplicationController
2 2
3 no_design_blocks 3 no_design_blocks
4 4
5 - inverse_captcha :field => 'e_mail'  
6 -  
7 require_ssl :except => [ :login_popup, :logout_popup, :profile_details ] 5 require_ssl :except => [ :login_popup, :logout_popup, :profile_details ]
8 6
9 before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise] 7 before_filter :login_required, :only => [:activation_question, :accept_terms, :activate_enterprise]
@@ -69,7 +67,7 @@ class AccountController < ApplicationController @@ -69,7 +67,7 @@ class AccountController < ApplicationController
69 @user.person_data = params[:profile_data] 67 @user.person_data = params[:profile_data]
70 @person = Person.new(params[:profile_data]) 68 @person = Person.new(params[:profile_data])
71 @person.environment = @user.environment 69 @person.environment = @user.environment
72 - if request.post? && params[self.icaptcha_field].blank? 70 + if request.post?
73 @user.signup! 71 @user.signup!
74 owner_role = Role.find_by_name('owner') 72 owner_role = Role.find_by_name('owner')
75 @user.person.affiliate(@user.person, [owner_role]) if owner_role 73 @user.person.affiliate(@user.person, [owner_role]) if owner_role
app/controllers/public/contact_controller.rb
@@ -4,10 +4,9 @@ class ContactController < PublicController @@ -4,10 +4,9 @@ class ContactController < PublicController
4 4
5 needs_profile 5 needs_profile
6 6
7 - inverse_captcha :field => 'e_mail'  
8 def new 7 def new
9 @contact 8 @contact
10 - if request.post? && params[self.icaptcha_field].blank? && params[:confirm] == 'true' 9 + if request.post? && params[:confirm] == 'true'
11 @contact = user.build_contact(profile, params[:contact]) 10 @contact = user.build_contact(profile, params[:contact])
12 @contact.city = (!params[:city].blank? && City.exists?(params[:city])) ? City.find(params[:city]).name : nil 11 @contact.city = (!params[:city].blank? && City.exists?(params[:city])) ? City.find(params[:city]).name : nil
13 @contact.state = (!params[:state].blank? && State.exists?(params[:state])) ? State.find(params[:state]).name : nil 12 @contact.state = (!params[:state].blank? && State.exists?(params[:state])) ? State.find(params[:state]).name : nil
app/controllers/public/content_viewer_controller.rb
@@ -2,8 +2,6 @@ class ContentViewerController < ApplicationController @@ -2,8 +2,6 @@ class ContentViewerController < ApplicationController
2 2
3 needs_profile 3 needs_profile
4 4
5 - inverse_captcha :field => 'e_mail'  
6 -  
7 helper ProfileHelper 5 helper ProfileHelper
8 helper TagsHelper 6 helper TagsHelper
9 7
@@ -76,7 +74,7 @@ class ContentViewerController < ApplicationController @@ -76,7 +74,7 @@ class ContentViewerController < ApplicationController
76 74
77 @form_div = params[:form] 75 @form_div = params[:form]
78 76
79 - if params[:comment] && params[self.icaptcha_field].blank? && params[:confirm] == 'true' 77 + if params[:comment] && params[:confirm] == 'true'
80 @comment = Comment.new(params[:comment]) 78 @comment = Comment.new(params[:comment])
81 if request.post? && @page.accept_comments? 79 if request.post? && @page.accept_comments?
82 add_comment 80 add_comment
@@ -121,7 +119,7 @@ class ContentViewerController < ApplicationController @@ -121,7 +119,7 @@ class ContentViewerController < ApplicationController
121 def add_comment 119 def add_comment
122 @comment.author = user if logged_in? 120 @comment.author = user if logged_in?
123 @comment.article = @page 121 @comment.article = @page
124 - if @comment.save 122 + if (@comment.reply_of_id || verify_recaptcha(:model => @comment, :message => _('Please type the words correctly'))) && @comment.save
125 @page.touch 123 @page.touch
126 @comment = nil # clear the comment form 124 @comment = nil # clear the comment form
127 redirect_to :action => 'view_page', :profile => params[:profile], :page => @page.explode_path, :view => params[:view] 125 redirect_to :action => 'view_page', :profile => params[:profile], :page => @page.explode_path, :view => params[:view]
app/models/comment.rb
1 class Comment < ActiveRecord::Base 1 class Comment < ActiveRecord::Base
2 2
3 - has_captcha  
4 -  
5 track_actions :leave_comment, :after_create, :keep_params => ["article.title", "article.url", "title", "url", "body"], :custom_target => :action_tracker_target 3 track_actions :leave_comment, :after_create, :keep_params => ["article.title", "article.url", "title", "url", "body"], :custom_target => :action_tracker_target
6 4
7 validates_presence_of :title, :body 5 validates_presence_of :title, :body
app/models/suggest_article.rb
1 class SuggestArticle < Task 1 class SuggestArticle < Task
2 2
3 - has_captcha  
4 -  
5 validates_presence_of :target_id, :article_name, :email, :name, :article_body 3 validates_presence_of :target_id, :article_name, :email, :name, :article_body
6 4
7 settings_items :email, :type => String 5 settings_items :email, :type => String
app/views/account/_signup_form.rhtml
@@ -7,8 +7,7 @@ @@ -7,8 +7,7 @@
7 </div> 7 </div>
8 <% end %> 8 <% end %>
9 9
10 -<% labelled_form_for :user, @user do |f| %>  
11 -<%= icaptcha_field() %> 10 +<% labelled_form_for :user, @user, :html => { :multipart => true } do |f| %>
12 11
13 <%= hidden_field_tag :invitation_code, @invitation_code %> 12 <%= hidden_field_tag :invitation_code, @invitation_code %>
14 13
app/views/cms/suggest_an_article.rhtml
@@ -18,13 +18,10 @@ @@ -18,13 +18,10 @@
18 18
19 <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :object => :task, :abstract_method => 'article_abstract', :body_method => 'article_body'} %> 19 <%= render :partial => 'shared/lead_and_body', :locals => {:tiny_mce => true, :object => :task, :abstract_method => 'article_abstract', :body_method => 'article_body'} %>
20 20
21 - <div id="captcha">  
22 - <%= labelled_form_field(_("What is the result of '%s = ?'") % @task.captcha.task, text_field(:task, 'captcha_solution')) %>  
23 - <%= hidden_field :task, :captcha_secret %>  
24 - <br style="clear: both;">  
25 - </div>  
26 -  
27 <%= hidden_field_tag('back_to', @back_to) %> 21 <%= hidden_field_tag('back_to', @back_to) %>
  22 +
  23 + <%= recaptcha_tags(:display => { :theme => 'clean' }, :ajax => true) %>
  24 +
28 <% button_bar do %> 25 <% button_bar do %>
29 <%= submit_button :save, _('Save') %> 26 <%= submit_button :save, _('Save') %>
30 <%= button :cancel, _('Cancel'), @back_to %> 27 <%= button :cancel, _('Cancel'), @back_to %>
app/views/contact/new.rhtml
@@ -4,7 +4,6 @@ @@ -4,7 +4,6 @@
4 4
5 5
6 <% labelled_form_for :contact, @contact do |f| %> 6 <% labelled_form_for :contact, @contact do |f| %>
7 - <%= icaptcha_field() %>  
8 <%= hidden_field_tag(:confirm, 'false') %> 7 <%= hidden_field_tag(:confirm, 'false') %>
9 8
10 <%= required_fields_message %> 9 <%= required_fields_message %>
app/views/content_viewer/_comment_form.rhtml
@@ -20,7 +20,6 @@ @@ -20,7 +20,6 @@
20 </h4> 20 </h4>
21 21
22 <% form_tag( url_for(@page.view_url.merge({:only_path => true})), { :class => 'comment_form' } ) do %> 22 <% form_tag( url_for(@page.view_url.merge({:only_path => true})), { :class => 'comment_form' } ) do %>
23 - <%= icaptcha_field() %>  
24 <%= hidden_field_tag(:confirm, 'false') %> 23 <%= hidden_field_tag(:confirm, 'false') %>
25 24
26 <%= required_fields_message %> 25 <%= required_fields_message %>
@@ -29,7 +28,6 @@ @@ -29,7 +28,6 @@
29 28
30 <%= required labelled_form_field(_('Name'), text_field(:comment, :name)) %> 29 <%= required labelled_form_field(_('Name'), text_field(:comment, :name)) %>
31 <%= required labelled_form_field(_('e-mail'), text_field(:comment, :email)) %> 30 <%= required labelled_form_field(_('e-mail'), text_field(:comment, :email)) %>
32 -  
33 <p> 31 <p>
34 <%= _('If you are a registered user, you can login and be automatically recognized.') %> 32 <%= _('If you are a registered user, you can login and be automatically recognized.') %>
35 </p> 33 </p>
@@ -39,8 +37,7 @@ @@ -39,8 +37,7 @@
39 <%= required labelled_form_field(_('Title'), text_field(:comment, :title)) %> 37 <%= required labelled_form_field(_('Title'), text_field(:comment, :title)) %>
40 <%= required labelled_form_field(_('Enter your comment'), text_area(:comment, :body, :rows => 5)) %> 38 <%= required labelled_form_field(_('Enter your comment'), text_area(:comment, :body, :rows => 5)) %>
41 39
42 - <%= required labelled_form_field(_("What is the result of '%s = ?'") % @comment.captcha.task, text_field(:comment, :captcha_solution)) %>  
43 - <%= hidden_field(:comment, :captcha_secret) %> 40 + <%= recaptcha_tags(:display => { :theme => 'clean' }, :ajax => true) unless logged_in? %>
44 41
45 <% button_bar do %> 42 <% button_bar do %>
46 <%= submit_button('add', _('Post comment'), :onclick => "this.form.confirm.value = 'true'; this.disabled = true; this.form.submit(); return true;") %> 43 <%= submit_button('add', _('Post comment'), :onclick => "this.form.confirm.value = 'true'; this.disabled = true; this.form.submit(); return true;") %>
app/views/profile_editor/edit.rhtml
@@ -13,7 +13,6 @@ @@ -13,7 +13,6 @@
13 <% end %> 13 <% end %>
14 </div> 14 </div>
15 15
16 -  
17 <h2><%= _('Privacy options') %></h2> 16 <h2><%= _('Privacy options') %></h2>
18 17
19 <% if profile.person? %> 18 <% if profile.person? %>
config/initializers/recaptcha.rb 0 → 100644
@@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
  1 +Recaptcha.configure do |config|
  2 + config.public_key = '6LdLTsgSAAAAACYr0rHdF2sVqt3sMaoz_h6uN4k7'
  3 + config.private_key = '6LdLTsgSAAAAADM9Mxg-EFjXc4tCe6zpKiPOEMs8'
  4 +end
features/comment.feature
@@ -82,11 +82,6 @@ Feature: comment @@ -82,11 +82,6 @@ Feature: comment
82 And I should be exactly on /booking/article-with-comment 82 And I should be exactly on /booking/article-with-comment
83 And I should be moved to anchor "comment_form" 83 And I should be moved to anchor "comment_form"
84 84
85 - Scenario: ask captcha question  
86 - Given I am on /booking/article-with-comment  
87 - When I follow "Post a comment" within ".post-comment-button"  
88 - Then I should see "What is the result of "  
89 -  
90 @selenium 85 @selenium
91 Scenario: keep comments field filled while trying to do a comment 86 Scenario: keep comments field filled while trying to do a comment
92 Given I am on /booking/article-with-comment 87 Given I am on /booking/article-with-comment
features/comment_reply.feature
@@ -64,8 +64,7 @@ Feature: comment @@ -64,8 +64,7 @@ Feature: comment
64 64
65 @selenium 65 @selenium
66 Scenario: reply a comment 66 Scenario: reply a comment
67 - Given skip comments captcha  
68 - And I go to /booking/another-article 67 + Given I go to /booking/another-article
69 And I follow "Reply" within ".comment-balloon" 68 And I follow "Reply" within ".comment-balloon"
70 And I fill in "Name" within "comment-balloon" with "Joey" 69 And I fill in "Name" within "comment-balloon" with "Joey"
71 And I fill in "e-mail" within "comment-balloon" with "joey@ramones.com" 70 And I fill in "e-mail" within "comment-balloon" with "joey@ramones.com"
features/step_definitions/noosfero_steps.rb
@@ -368,7 +368,6 @@ Given /^the articles of &quot;(.+)&quot; are moderated$/ do |organization| @@ -368,7 +368,6 @@ Given /^the articles of &quot;(.+)&quot; are moderated$/ do |organization|
368 end 368 end
369 369
370 Given /^the following comments?$/ do |table| 370 Given /^the following comments?$/ do |table|
371 - Comment.skip_captcha!  
372 table.hashes.each do |item| 371 table.hashes.each do |item|
373 data = item.dup 372 data = item.dup
374 article = Article.find_by_name(data.delete("article")) 373 article = Article.find_by_name(data.delete("article"))
@@ -388,7 +387,6 @@ Given /^the community &quot;(.+)&quot; is closed$/ do |community| @@ -388,7 +387,6 @@ Given /^the community &quot;(.+)&quot; is closed$/ do |community|
388 end 387 end
389 388
390 Given /^someone suggested the following article to be published$/ do |table| 389 Given /^someone suggested the following article to be published$/ do |table|
391 - SuggestArticle.skip_captcha!  
392 table.hashes.map{|item| item.dup}.each do |item| 390 table.hashes.map{|item| item.dup}.each do |item|
393 target = Community[item.delete('target')] 391 target = Community[item.delete('target')]
394 task = SuggestArticle.create!(:target => target, :data => item) 392 task = SuggestArticle.create!(:target => target, :data => item)
@@ -422,10 +420,6 @@ Given /^the environment domain is &quot;([^\&quot;]*)&quot;$/ do |domain| @@ -422,10 +420,6 @@ Given /^the environment domain is &quot;([^\&quot;]*)&quot;$/ do |domain|
422 d.save(false) 420 d.save(false)
423 end 421 end
424 422
425 -Given /^skip comments captcha$/ do  
426 - Comment.any_instance.stubs(:skip_captcha?).returns(true)  
427 -end  
428 -  
429 When /^([^\']*)'s account is activated$/ do |person| 423 When /^([^\']*)'s account is activated$/ do |person|
430 Person.find_by_name(person).user.activate 424 Person.find_by_name(person).user.activate
431 end 425 end
features/step_definitions/selenium_steps.rb
@@ -93,12 +93,6 @@ When /^I type &quot;([^\&quot;]*)&quot; in TinyMCE field &quot;([^\&quot;]*)&quot;$/ do |value, field_id| @@ -93,12 +93,6 @@ When /^I type &quot;([^\&quot;]*)&quot; in TinyMCE field &quot;([^\&quot;]*)&quot;$/ do |value, field_id|
93 response.selenium.type("dom=document.getElementById('#{field_id}_ifr').contentDocument.body", value) 93 response.selenium.type("dom=document.getElementById('#{field_id}_ifr').contentDocument.body", value)
94 end 94 end
95 95
96 -When /^I answer the captcha$/ do  
97 - question = response.selenium.get_text("//label[@for='task_captcha_solution']").match(/What is the result of '(.+) = \?'/)[1]  
98 - answer = eval(question)  
99 - response.selenium.type("id=task_captcha_solution", answer)  
100 -end  
101 -  
102 When /^I refresh the page$/ do 96 When /^I refresh the page$/ do
103 response.selenium.refresh 97 response.selenium.refresh
104 end 98 end
features/suggest_article.feature
@@ -31,7 +31,6 @@ Feature: suggest article @@ -31,7 +31,6 @@ Feature: suggest article
31 And I fill in "Email" with "someguy@somewhere.com" 31 And I fill in "Email" with "someguy@somewhere.com"
32 And I type "This is my suggestion's lead" in TinyMCE field "task_article_abstract" 32 And I type "This is my suggestion's lead" in TinyMCE field "task_article_abstract"
33 And I type "I like free software" in TinyMCE field "task_article_body" 33 And I type "I like free software" in TinyMCE field "task_article_body"
34 - And I answer the captcha  
35 And I press "Save" 34 And I press "Save"
36 And I am logged in as "joaosilva" 35 And I am logged in as "joaosilva"
37 And I go to Sample Community's control panel 36 And I go to Sample Community's control panel
public/javascripts/application.js
@@ -662,6 +662,7 @@ function add_comment_reply_form(button, comment_id) { @@ -662,6 +662,7 @@ function add_comment_reply_form(button, comment_id) {
662 var f = container.find('.comment_form'); 662 var f = container.find('.comment_form');
663 if (f.length == 0) { 663 if (f.length == 0) {
664 f = jQuery('#page-comment-form .comment_form').clone(); 664 f = jQuery('#page-comment-form .comment_form').clone();
  665 + f.find('#dynamic_recaptcha').remove();
665 f.find('.fieldWithErrors').map(function() { jQuery(this).replaceWith(jQuery(this).contents()); }); 666 f.find('.fieldWithErrors').map(function() { jQuery(this).replaceWith(jQuery(this).contents()); });
666 f.prepend('<input type="hidden" name="comment[reply_of_id]" value="' + comment_id + '" />'); 667 f.prepend('<input type="hidden" name="comment[reply_of_id]" value="' + comment_id + '" />');
667 container.append(f); 668 container.append(f);
public/stylesheets/application.css
@@ -6136,3 +6136,30 @@ h1#agenda-title { @@ -6136,3 +6136,30 @@ h1#agenda-title {
6136 #user a#pending-tasks-count { 6136 #user a#pending-tasks-count {
6137 color: #FFFFFF; 6137 color: #FFFFFF;
6138 } 6138 }
  6139 +
  6140 +/* Captcha */
  6141 +
  6142 +.comment_reply #recaptcha_area {
  6143 + margin-bottom: 3px !important;
  6144 +}
  6145 +
  6146 +.comment_reply .recaptchatable tr td + td + td {
  6147 + display: none !important;
  6148 +}
  6149 +
  6150 +.comment_reply .recaptcha-container {
  6151 + width: 100%;
  6152 + overflow: hidden;
  6153 +}
  6154 +
  6155 +.comment_reply .recaptcha-container:hover {
  6156 + overflow: visible;
  6157 +}
  6158 +
  6159 +.comment_reply .recaptcha-container tr:hover td {
  6160 + background: transparent;
  6161 +}
  6162 +
  6163 +.comment_reply .recaptcha_image_cell {
  6164 + background: transparent !important;
  6165 +}
test/functional/account_controller_test.rb
@@ -571,17 +571,6 @@ class AccountControllerTest &lt; Test::Unit::TestCase @@ -571,17 +571,6 @@ class AccountControllerTest &lt; Test::Unit::TestCase
571 571
572 # end of enterprise activation tests 572 # end of enterprise activation tests
573 573
574 - should 'not be able to signup while inverse captcha field filled' do  
575 - assert_no_difference User, :count do  
576 - new_user({}, @controller.icaptcha_field => 'bli@bla.email.foo')  
577 - end  
578 - end  
579 -  
580 - should 'render inverse captcha field' do  
581 - get :signup  
582 - assert_tag :tag => 'input', :attributes => { :type => 'text', :name => @controller.icaptcha_field }  
583 - end  
584 -  
585 should 'use the current environment for the template of user' do 574 should 'use the current environment for the template of user' do
586 template = create_user('test_template', :email => 'test@bli.com', :password => 'pass', :password_confirmation => 'pass').person 575 template = create_user('test_template', :email => 'test@bli.com', :password => 'pass', :password_confirmation => 'pass').person
587 template.boxes.destroy_all 576 template.boxes.destroy_all
test/functional/cms_controller_test.rb
@@ -1320,7 +1320,6 @@ class CmsControllerTest &lt; Test::Unit::TestCase @@ -1320,7 +1320,6 @@ class CmsControllerTest &lt; Test::Unit::TestCase
1320 should 'create a task suggest task to a profile' do 1320 should 'create a task suggest task to a profile' do
1321 c = Community.create!(:name => 'test comm', :identifier => 'test_comm', :moderated_articles => true) 1321 c = Community.create!(:name => 'test comm', :identifier => 'test_comm', :moderated_articles => true)
1322 1322
1323 - SuggestArticle.any_instance.stubs(:skip_captcha?).returns(true)  
1324 assert_difference SuggestArticle, :count do 1323 assert_difference SuggestArticle, :count do
1325 post :suggest_an_article, :profile => c.identifier, :back_to => 'action_view', :task => {:article_name => 'some name', :article_body => 'some body', :email => 'some@localhost.com', :name => 'some name'} 1324 post :suggest_an_article, :profile => c.identifier, :back_to => 'action_view', :task => {:article_name => 'some name', :article_body => 'some body', :email => 'some@localhost.com', :name => 'some name'}
1326 end 1325 end
test/functional/contact_controller_test.rb
@@ -74,13 +74,6 @@ class ContactControllerTest &lt; Test::Unit::TestCase @@ -74,13 +74,6 @@ class ContactControllerTest &lt; Test::Unit::TestCase
74 assert_no_tag :tag => 'select', :attributes => {:name => 'state'} 74 assert_no_tag :tag => 'select', :attributes => {:name => 'state'}
75 end 75 end
76 76
77 - should 'not be able to post contact while inverse captcha field filled' do  
78 - post :new, :profile => enterprise.identifier, @controller.icaptcha_field => 'filled', :contact => {:subject => 'Hi', :message => 'Hi, all', :state => '', :city => ''}  
79 -  
80 - assert_response :success  
81 - assert_template 'new'  
82 - end  
83 -  
84 should 'not allow if not logged' do 77 should 'not allow if not logged' do
85 logout 78 logout
86 get :new, :profile => profile.identifier 79 get :new, :profile => profile.identifier
@@ -93,12 +86,6 @@ class ContactControllerTest &lt; Test::Unit::TestCase @@ -93,12 +86,6 @@ class ContactControllerTest &lt; Test::Unit::TestCase
93 assert_equal Person['contact_test_user'], assigns(:contact).sender 86 assert_equal Person['contact_test_user'], assigns(:contact).sender
94 end 87 end
95 88
96 - should 'send contact while inverse captcha field not filled' do  
97 - post :new, :profile => enterprise.identifier, :contact => {:subject => 'Hi', :message => 'Hi, all', :state => '', :city => ''}, :confirm => 'true'  
98 - assert_response :redirect  
99 - assert_redirected_to :action => 'new'  
100 - end  
101 -  
102 should 'deliver contact if subject and message are filled' do 89 should 'deliver contact if subject and message are filled' do
103 post :new, :profile => enterprise.identifier, :contact => {:subject => 'Hi', :message => 'Hi, all'}, :confirm => 'true' 90 post :new, :profile => enterprise.identifier, :contact => {:subject => 'Hi', :message => 'Hi, all'}, :confirm => 'true'
104 assert_response :redirect 91 assert_response :redirect
test/functional/content_viewer_controller_test.rb
@@ -15,7 +15,6 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -15,7 +15,6 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
15 15
16 @profile = create_user('testinguser').person 16 @profile = create_user('testinguser').person
17 @environment = @profile.environment 17 @environment = @profile.environment
18 - Comment.skip_captcha!  
19 end 18 end
20 attr_reader :profile, :environment 19 attr_reader :profile, :environment
21 20
@@ -188,17 +187,6 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -188,17 +187,6 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
188 end 187 end
189 end 188 end
190 189
191 - should 'not be able to post comment while inverse captcha field filled' do  
192 - profile = create_user('popstar').person  
193 - page = profile.articles.build(:name => 'myarticle', :body => 'the body of the text')  
194 - page.save!  
195 - profile.home_page = page; profile.save!  
196 -  
197 - assert_no_difference Comment, :count do  
198 - post :view_page, :profile => profile.identifier, :page => [ 'myarticle' ], @controller.icaptcha_field => 'filled', :comment => { :title => 'crap!', :body => 'I think that this article is crap', :name => 'Anonymous coward', :email => 'coward@anonymous.com' }  
199 - end  
200 - end  
201 -  
202 should 'be able to remove comments if is moderator' do 190 should 'be able to remove comments if is moderator' do
203 commenter = create_user('commenter_user').person 191 commenter = create_user('commenter_user').person
204 community = Community.create!(:name => 'Community test', :identifier => 'community-test') 192 community = Community.create!(:name => 'Community test', :identifier => 'community-test')
@@ -212,15 +200,6 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase @@ -212,15 +200,6 @@ class ContentViewerControllerTest &lt; Test::Unit::TestCase
212 end 200 end
213 end 201 end
214 202
215 - should 'render inverse captcha field' do  
216 - profile = create_user('popstar').person  
217 - page = profile.articles.build(:name => 'myarticle', :body => 'the body of the text')  
218 - page.save!  
219 - profile.home_page = page; profile.save!  
220 - get :view_page, :profile => profile.identifier, :page => [ 'myarticle' ]  
221 - assert_tag :tag => 'input', :attributes => { :type => 'text', :name => @controller.icaptcha_field }  
222 - end  
223 -  
224 should 'filter html content from body' do 203 should 'filter html content from body' do
225 login_as @profile.identifier 204 login_as @profile.identifier
226 page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text') 205 page = profile.articles.create!(:name => 'myarticle', :body => 'the body of the text')
test/functional/search_controller_test.rb
@@ -17,7 +17,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -17,7 +17,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase
17 domain.save! 17 domain.save!
18 18
19 @product_category = fast_create(ProductCategory) 19 @product_category = fast_create(ProductCategory)
20 - Comment.skip_captcha!  
21 end 20 end
22 21
23 def create_article_with_optional_category(name, profile, category = nil) 22 def create_article_with_optional_category(name, profile, category = nil)
test/functional/tasks_controller_test.rb
@@ -238,7 +238,6 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -238,7 +238,6 @@ class TasksControllerTest &lt; Test::Unit::TestCase
238 c = fast_create(Community) 238 c = fast_create(Community)
239 c.add_admin profile 239 c.add_admin profile
240 @controller.stubs(:profile).returns(c) 240 @controller.stubs(:profile).returns(c)
241 - SuggestArticle.skip_captcha!  
242 t = SuggestArticle.create!(:article_name => 'test name', :article_abstract => 'test abstract', :article_body => 'test body', :name => 'some name', :email => 'test@localhost.com', :target => c) 241 t = SuggestArticle.create!(:article_name => 'test name', :article_abstract => 'test abstract', :article_body => 'test body', :name => 'some name', :email => 'test@localhost.com', :target => c)
243 242
244 get :index 243 get :index
@@ -251,7 +250,6 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -251,7 +250,6 @@ class TasksControllerTest &lt; Test::Unit::TestCase
251 c = fast_create(Community) 250 c = fast_create(Community)
252 c.affiliate(profile, Profile::Roles.all_roles(profile.environment.id)) 251 c.affiliate(profile, Profile::Roles.all_roles(profile.environment.id))
253 @controller.stubs(:profile).returns(c) 252 @controller.stubs(:profile).returns(c)
254 - SuggestArticle.skip_captcha!  
255 t = SuggestArticle.create!(:article_name => 'test name', :article_body => 'test body', :name => 'some name', :email => 'test@localhost.com', :target => c) 253 t = SuggestArticle.create!(:article_name => 'test name', :article_body => 'test body', :name => 'some name', :email => 'test@localhost.com', :target => c)
256 254
257 post :close, :tasks => {t.id => { :task => {}, :decision => "finish"}} 255 post :close, :tasks => {t.id => { :task => {}, :decision => "finish"}}
@@ -263,7 +261,6 @@ class TasksControllerTest &lt; Test::Unit::TestCase @@ -263,7 +261,6 @@ class TasksControllerTest &lt; Test::Unit::TestCase
263 c = fast_create(Community) 261 c = fast_create(Community)
264 c.affiliate(profile, Profile::Roles.all_roles(profile.environment.id)) 262 c.affiliate(profile, Profile::Roles.all_roles(profile.environment.id))
265 @controller.stubs(:profile).returns(c) 263 @controller.stubs(:profile).returns(c)
266 - SuggestArticle.skip_captcha!  
267 t = SuggestArticle.new 264 t = SuggestArticle.new
268 t.article_name = 'test name' 265 t.article_name = 'test name'
269 t.article_body = 'test body' 266 t.article_body = 'test body'
test/unit/article_test.rb
@@ -6,7 +6,6 @@ class ArticleTest &lt; Test::Unit::TestCase @@ -6,7 +6,6 @@ class ArticleTest &lt; Test::Unit::TestCase
6 6
7 def setup 7 def setup
8 @profile = create_user('testing').person 8 @profile = create_user('testing').person
9 - Comment.skip_captcha!  
10 end 9 end
11 attr_reader :profile 10 attr_reader :profile
12 11
test/unit/category_finder_test.rb
@@ -7,7 +7,6 @@ class CategoryFinderTest &lt; ActiveSupport::TestCase @@ -7,7 +7,6 @@ class CategoryFinderTest &lt; ActiveSupport::TestCase
7 @finder = CategoryFinder.new(@category) 7 @finder = CategoryFinder.new(@category)
8 @product_category = fast_create(ProductCategory, :name => 'Products') 8 @product_category = fast_create(ProductCategory, :name => 'Products')
9 9
10 - Comment.skip_captcha!  
11 end 10 end
12 11
13 should 'search for articles in a specific category' do 12 should 'search for articles in a specific category' do
test/unit/category_test.rb
@@ -5,7 +5,6 @@ class CategoryTest &lt; Test::Unit::TestCase @@ -5,7 +5,6 @@ class CategoryTest &lt; Test::Unit::TestCase
5 5
6 def setup 6 def setup
7 @env = fast_create(Environment) 7 @env = fast_create(Environment)
8 - Comment.skip_captcha!  
9 end 8 end
10 9
11 def test_mandatory_field_name 10 def test_mandatory_field_name
test/unit/comment_notifier_test.rb
@@ -10,7 +10,6 @@ class CommentNotifierTest &lt; Test::Unit::TestCase @@ -10,7 +10,6 @@ class CommentNotifierTest &lt; Test::Unit::TestCase
10 ActionMailer::Base.deliveries = [] 10 ActionMailer::Base.deliveries = []
11 @profile = create_user('user_comment_test').person 11 @profile = create_user('user_comment_test').person
12 @article = fast_create(Article, :name => 'Article test', :profile_id => @profile.id, :notify_comments => true) 12 @article = fast_create(Article, :name => 'Article test', :profile_id => @profile.id, :notify_comments => true)
13 - Comment.skip_captcha!  
14 end 13 end
15 14
16 should 'deliver mail after make aarticle commment' do 15 should 'deliver mail after make aarticle commment' do
test/unit/comment_test.rb
@@ -3,7 +3,6 @@ require File.dirname(__FILE__) + &#39;/../test_helper&#39; @@ -3,7 +3,6 @@ require File.dirname(__FILE__) + &#39;/../test_helper&#39;
3 class CommentTest < Test::Unit::TestCase 3 class CommentTest < Test::Unit::TestCase
4 4
5 def setup 5 def setup
6 - Comment.skip_captcha!  
7 end 6 end
8 7
9 should 'have a name and require it' do 8 should 'have a name and require it' do
@@ -331,12 +330,4 @@ class CommentTest &lt; Test::Unit::TestCase @@ -331,12 +330,4 @@ class CommentTest &lt; Test::Unit::TestCase
331 assert_nil Comment.new(:email => 'my@email.com').author_url 330 assert_nil Comment.new(:email => 'my@email.com').author_url
332 end 331 end
333 332
334 - should 'have the captcha_solution be solved' do  
335 - Comment.dont_skip_captcha!  
336 - c = Comment.new  
337 - assert !c.valid? && c.errors.invalid?(:captcha_solution)  
338 - c.skip_captcha!  
339 - assert !c.valid? && !c.errors.invalid?(:captcha_solution)  
340 - end  
341 -  
342 end 333 end
test/unit/community_test.rb
@@ -4,7 +4,6 @@ class CommunityTest &lt; Test::Unit::TestCase @@ -4,7 +4,6 @@ class CommunityTest &lt; Test::Unit::TestCase
4 4
5 def setup 5 def setup
6 @person = fast_create(Person) 6 @person = fast_create(Person)
7 - Comment.skip_captcha!  
8 end 7 end
9 8
10 attr_reader :person 9 attr_reader :person
test/unit/forum_helper_test.rb
@@ -12,7 +12,6 @@ class ForumHelperTest &lt; Test::Unit::TestCase @@ -12,7 +12,6 @@ class ForumHelperTest &lt; Test::Unit::TestCase
12 @environment = Environment.default 12 @environment = Environment.default
13 @profile = create_user('forum_helper_test').person 13 @profile = create_user('forum_helper_test').person
14 @forum = fast_create(Forum, :profile_id => profile.id, :name => 'Forum test') 14 @forum = fast_create(Forum, :profile_id => profile.id, :name => 'Forum test')
15 - Comment.skip_captcha!  
16 end 15 end
17 16
18 attr :profile 17 attr :profile
test/unit/suggest_article_test.rb
@@ -45,18 +45,6 @@ class SuggestArticleTest &lt; ActiveSupport::TestCase @@ -45,18 +45,6 @@ class SuggestArticleTest &lt; ActiveSupport::TestCase
45 assert t.errors.invalid?(:target_id) 45 assert t.errors.invalid?(:target_id)
46 end 46 end
47 47
48 - should 'have the captcha_solution be solved' do  
49 - t = SuggestArticle.new  
50 - assert !t.errors.invalid?(:captcha_solution)  
51 - t.valid?  
52 - assert t.errors.invalid?(:captcha_solution)  
53 -  
54 - t.skip_captcha!  
55 - assert t.skip_captcha?  
56 - t.valid?  
57 - assert !t.errors.invalid?(:captcha_solution)  
58 - end  
59 -  
60 should 'have the article_abstract' do 48 should 'have the article_abstract' do
61 t = SuggestArticle.new 49 t = SuggestArticle.new
62 assert t.respond_to?(:article_abstract) 50 assert t.respond_to?(:article_abstract)
vendor/plugins/inverse_captcha/README
@@ -1,29 +0,0 @@ @@ -1,29 +0,0 @@
1 -InverseCaptcha  
2 -==============  
3 -  
4 -Implement simple Anti-Comment-Spam Technique.  
5 -  
6 -Basic Usage  
7 -===========  
8 -  
9 -Add method inverse_captcha on controller:  
10 -  
11 -ps.: dont use this method more than once time on same controller.  
12 -  
13 - inverse_captcha :field => 'e-mail'[, class => 'ghost']  
14 -  
15 -Add the field in view form:  
16 -  
17 - <%= icaptcha_field() %>  
18 -  
19 -Check if field is blank in your controller:  
20 -  
21 - if params[controller.icaptcha_field].blank?  
22 - do...  
23 - else  
24 - dont...  
25 - end  
26 -  
27 ----  
28 -Joenio Costa <joenio@colivre.coop.br>  
29 -Qui Mar 27 15:48:12 BRT 2008  
vendor/plugins/inverse_captcha/init.rb
@@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
1 -ActionController::Base.extend(InverseCaptcha::ClassMethods)  
2 -ActionController::Base.send(:include, InverseCaptcha::InstanceMethods)  
3 -ActionView::Base.send(:include, InverseCaptchaHelper)  
vendor/plugins/inverse_captcha/lib/inverse_captcha.rb
@@ -1,18 +0,0 @@ @@ -1,18 +0,0 @@
1 -module InverseCaptcha  
2 -  
3 - module ClassMethods  
4 - def inverse_captcha(opt = {})  
5 - InverseCaptcha.const_set("ICAPTCHA_FIELD", opt[:field]) unless InverseCaptcha.const_defined? "ICAPTCHA_FIELD"  
6 - InverseCaptcha.const_set("ICAPTCHA_LABEL", opt[:label] || N_("Don't fill this field")) unless InverseCaptcha.const_defined? "ICAPTCHA_LABEL"  
7 - InverseCaptcha.const_set("ICAPTCHA_STYLECLASS", opt[:class] || 'ghost') unless InverseCaptcha.const_defined? "ICAPTCHA_STYLECLASS"  
8 - self.send(:include, InverseCaptcha)  
9 - end  
10 - end  
11 -  
12 - module InstanceMethods  
13 - def icaptcha_field  
14 - ICAPTCHA_FIELD  
15 - end  
16 - end  
17 -  
18 -end  
vendor/plugins/inverse_captcha/lib/inverse_captcha_helper.rb
@@ -1,11 +0,0 @@ @@ -1,11 +0,0 @@
1 -module InverseCaptchaHelper  
2 -  
3 - def icaptcha_field(opt = {})  
4 - label = controller.class::ICAPTCHA_LABEL  
5 - field = controller.class::ICAPTCHA_FIELD  
6 - opt.merge!({:class => controller.class::ICAPTCHA_STYLECLASS})  
7 - stylesheet = "<style type='text/css'> span.#{opt[:class]} { display: none; } </style>"  
8 - stylesheet + content_tag('span', labelled_form_field(_(label), text_field_tag(field, nil)), opt)  
9 - end  
10 -  
11 -end  
vendor/plugins/rails-math-captcha/MIT-LICENSE
@@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
1 -Copyright (c) 2007 [name of plugin creator]  
2 -  
3 -Permission is hereby granted, free of charge, to any person obtaining  
4 -a copy of this software and associated documentation files (the  
5 -"Software"), to deal in the Software without restriction, including  
6 -without limitation the rights to use, copy, modify, merge, publish,  
7 -distribute, sublicense, and/or sell copies of the Software, and to  
8 -permit persons to whom the Software is furnished to do so, subject to  
9 -the following conditions:  
10 -  
11 -The above copyright notice and this permission notice shall be  
12 -included in all copies or substantial portions of the Software.  
13 -  
14 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  
15 -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF  
16 -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  
17 -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE  
18 -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION  
19 -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION  
20 -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  
vendor/plugins/rails-math-captcha/README
@@ -1,45 +0,0 @@ @@ -1,45 +0,0 @@
1 -MathCaptcha  
2 -===========  
3 -  
4 -TODO: Create form helpers  
5 -  
6 -Validates your Model to be saved by a human (or very clever script) by asking  
7 -the user to solve a very basic mathematical equation.  
8 -  
9 -It does not use the session to store the secret, but uses AES from EzCrypto.  
10 -  
11 -  
12 -Requirements  
13 -============  
14 - * gem ezcrypto  
15 - * users who can calculate  
16 -  
17 -Usage  
18 -=====  
19 -  
20 -In your Model < ActiveRecord::Base  
21 -  
22 - has_captcha  
23 -  
24 -  
25 -In your form view:  
26 -  
27 - <%= @model.captcha.task %> = ?  
28 - <%= form.text_field :captcha_solution %>  
29 - <%= form.hidden_field :captcha_secret %>  
30 -  
31 -  
32 -If you want to skip the validation (in tests/specs), you can  
33 -  
34 - Model.skip_captcha! # or  
35 - @model.skip_captcha!  
36 -  
37 -and turn that off by  
38 -  
39 - Model.dont_skip_captcha! # or  
40 - @model.dont_skip_captcha!  
41 -  
42 -  
43 -  
44 -Copyright (c) 2007 Pat Nakajima, released under the MIT license  
45 -Copyright (c) 2009 Niklas Hofer, released under the MIT license  
vendor/plugins/rails-math-captcha/Rakefile
@@ -1,22 +0,0 @@ @@ -1,22 +0,0 @@
1 -require 'rake'  
2 -require 'rake/testtask'  
3 -require 'rake/rdoctask'  
4 -  
5 -desc 'Default: run unit tests.'  
6 -task :default => :test  
7 -  
8 -desc 'Test the math_captcha plugin.'  
9 -Rake::TestTask.new(:test) do |t|  
10 - t.libs << 'lib'  
11 - t.pattern = 'test/**/*_test.rb'  
12 - t.verbose = true  
13 -end  
14 -  
15 -desc 'Generate documentation for the math_captcha plugin.'  
16 -Rake::RDocTask.new(:rdoc) do |rdoc|  
17 - rdoc.rdoc_dir = 'rdoc'  
18 - rdoc.title = 'MathCaptcha'  
19 - rdoc.options << '--line-numbers' << '--inline-source'  
20 - rdoc.rdoc_files.include('README')  
21 - rdoc.rdoc_files.include('lib/**/*.rb')  
22 -end  
vendor/plugins/rails-math-captcha/init.rb
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -require 'math_captcha'  
2 \ No newline at end of file 0 \ No newline at end of file
vendor/plugins/rails-math-captcha/install.rb
@@ -1 +0,0 @@ @@ -1 +0,0 @@
1 -# Install hook code here  
vendor/plugins/rails-math-captcha/lib/math_captcha.rb
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -require 'math_captcha/captcha'  
2 -require 'math_captcha/has_captcha'  
vendor/plugins/rails-math-captcha/lib/math_captcha/captcha.rb
@@ -1,68 +0,0 @@ @@ -1,68 +0,0 @@
1 -require 'rubygems'  
2 -require 'ezcrypto'  
3 -class Captcha  
4 - NUMBERS = (1..9).to_a  
5 - OPERATORS = [:+, :-, :*]  
6 -  
7 - attr_reader :x, :y, :operator  
8 -  
9 - def initialize(x=nil, y=nil, operator=nil)  
10 - @x = x || NUMBERS.sort_by{rand}.first  
11 - @y = y || NUMBERS.sort_by{rand}.first  
12 - @operator = operator || OPERATORS.sort_by{rand}.first  
13 - end  
14 -  
15 - # Only the #to_secret is shared with the client.  
16 - # It can be reused here to create the Captcha again  
17 - def self.from_secret(secret)  
18 - yml = cipher.decrypt64 secret  
19 - args = YAML.load(yml)  
20 - new(args[:x], args[:y], args[:operator])  
21 - end  
22 -  
23 - def self.cipher  
24 - EzCrypto::Key.with_password key, 'bad_fixed_salt'  
25 - end  
26 -  
27 - def self.key  
28 - 'ultrasecret'  
29 - end  
30 -  
31 -  
32 - def check(answer)  
33 - answer == solution  
34 - end  
35 -  
36 - def task  
37 - "#{@x} #{@operator.to_s} #{@y}"  
38 - end  
39 - def task_with_questionmark  
40 - "#{@x} #{@operator.to_s} #{@y} = ?"  
41 - end  
42 - alias_method :to_s, :task  
43 -  
44 - def solution  
45 - @x.send @operator, @y  
46 - end  
47 -  
48 - def to_secret  
49 - cipher.encrypt64(to_yaml)  
50 - end  
51 -  
52 - def to_yaml  
53 - YAML::dump({  
54 - :x => x,  
55 - :y => y,  
56 - :operator => operator  
57 - })  
58 - end  
59 -  
60 - private  
61 - def cipher  
62 - @cipher ||= self.class.cipher  
63 - end  
64 - def reset_cipher  
65 - @cipher = nil  
66 - end  
67 -  
68 -end  
vendor/plugins/rails-math-captcha/lib/math_captcha/has_captcha.rb
@@ -1,54 +0,0 @@ @@ -1,54 +0,0 @@
1 -module MathCaptcha  
2 - module HasCaptcha  
3 - module InstanceMethods  
4 - def must_solve_captcha  
5 - self.errors.add(:captcha_solution, "wrong answer.") unless self.captcha.check(self.captcha_solution.to_i)  
6 - end  
7 - def skip_captcha!  
8 - self.class.skip_captcha!  
9 - end  
10 - def skip_captcha?  
11 - self.class.skip_captcha?  
12 - end  
13 - def captcha  
14 - @captcha ||= Captcha.new  
15 - end  
16 - def captcha_secret=(secret)  
17 - @captcha = Captcha.from_secret(secret)  
18 - end  
19 - def captcha_secret  
20 - captcha.to_secret  
21 - end  
22 - end  
23 -  
24 - module ClassMethods  
25 - def has_captcha  
26 - include InstanceMethods  
27 - attr_accessor :captcha_solution  
28 - dont_skip_captcha!  
29 - validates_presence_of :captcha_solution,  
30 - :on => :create, :message => "can't be blank",  
31 - :unless => Proc.new {|record| record.skip_captcha? }  
32 - validate_on_create :must_solve_captcha,  
33 - :unless => Proc.new {|record| record.skip_captcha? }  
34 - end  
35 - def skip_captcha!  
36 - @@skip_captcha = true  
37 - end  
38 - def dont_skip_captcha!  
39 - @@skip_captcha = false  
40 - end  
41 - def skip_captcha?  
42 - @@skip_captcha  
43 - end  
44 - def skipping_captcha(&block)  
45 - skipping_before = skip_captcha?  
46 - skip_captcha!  
47 - yield  
48 - dont_skip_captcha! if skipping_before  
49 - end  
50 - end  
51 - end  
52 -end  
53 -  
54 -ActiveRecord::Base.send(:extend, MathCaptcha::HasCaptcha::ClassMethods)  
vendor/plugins/rails-math-captcha/spec/captcha_spec.rb
@@ -1,49 +0,0 @@ @@ -1,49 +0,0 @@
1 -require 'lib/math_captcha/captcha'  
2 -require 'base64'  
3 -  
4 -describe Captcha do  
5 - describe "with a random task" do  
6 - before(:each) do  
7 - @captcha = Captcha.new  
8 - end  
9 - it "should have arguments and an operator" do  
10 - @captcha.x.should_not be_nil  
11 - @captcha.y.should_not be_nil  
12 - @captcha.operator.should_not be_nil  
13 - end  
14 - it "should use numbers bigger than zero" do  
15 - @captcha.x.should > 0  
16 - @captcha.y.should > 0  
17 - end  
18 - it "should offer a human readable task" do  
19 - @captcha.task.should =~ /^\d+\s*[\+\-\*]\s*\d+$/  
20 - end  
21 - it "should have a secret to use in forms" do  
22 - @captcha.to_secret.should_not be_nil  
23 - @captcha.to_secret.should_not be_empty  
24 - end  
25 -  
26 - it "should re-use its cipher" do  
27 - @captcha.send(:cipher).should == @captcha.send(:cipher)  
28 - end  
29 -  
30 - it "should have a base64 encoded secret" do  
31 - lambda { Base64.decode64(@captcha.to_secret).should_not be_nil }.should_not raise_error  
32 - end  
33 -  
34 - describe "re-creating another from secret" do  
35 - before(:each) do  
36 - @secret = @captcha.to_secret  
37 - @new_captcha = Captcha.from_secret(@secret)  
38 - end  
39 - it "should have the same arguments and operator" do  
40 - @new_captcha.x.should == @captcha.x  
41 - @new_captcha.y.should == @captcha.y  
42 - @new_captcha.operator.should == @captcha.operator  
43 - end  
44 - it "should have the same string" do  
45 - @new_captcha.task.should == @captcha.task  
46 - end  
47 - end  
48 - end  
49 -end  
vendor/plugins/rails-math-captcha/spec/spec.opts
@@ -1,4 +0,0 @@ @@ -1,4 +0,0 @@
1 ---colour  
2 ---format progress  
3 ---loadby mtime  
4 ---reverse  
vendor/plugins/recaptcha/CHANGELOG 0 → 100644
@@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
  1 +== 0.2.2 / 2009-09-14
  2 +
  3 +* Add a timeout to the validator
  4 +* Give the documentation some love
  5 +
  6 +== 0.2.1 / 2009-09-14
  7 +
  8 +* Removed Ambethia namespace, and restructured classes a bit
  9 +* Added an example rails app in the example-rails branch
  10 +
  11 +== 0.2.0 / 2009-09-12
  12 +
  13 +* RecaptchaOptions AJAX API Fix
  14 +* Added 'cucumber' as a test environment to skip
  15 +* Ruby 1.9 compat fixes
  16 +* Added option :message => 'Custom error message' to verify_recaptcha
  17 +* Removed dependency on ActiveRecord constant
  18 +* Add I18n
  19 +
  20 +== 0.1.0 / 2008-2-8
  21 +
  22 +* 1 major enhancement
  23 + * Initial Gem Release
0 \ No newline at end of file 24 \ No newline at end of file
vendor/plugins/recaptcha/Gemfile 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +source 'http://rubygems.org'
  2 +
  3 +gemspec
vendor/plugins/recaptcha/LICENSE 0 → 100644
@@ -0,0 +1,19 @@ @@ -0,0 +1,19 @@
  1 +Copyright (c) 2007 Jason L Perry
  2 +
  3 +Permission is hereby granted, free of charge, to any person obtaining a copy
  4 +of this software and associated documentation files (the "Software"), to deal
  5 +in the Software without restriction, including without limitation the rights
  6 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7 +copies of the Software, and to permit persons to whom the Software is
  8 +furnished to do so, subject to the following conditions:
  9 +
  10 +The above copyright notice and this permission notice shall be included in
  11 +all copies or substantial portions of the Software.
  12 +
  13 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19 +THE SOFTWARE.
0 \ No newline at end of file 20 \ No newline at end of file
vendor/plugins/recaptcha/README.rdoc 0 → 100644
@@ -0,0 +1,150 @@ @@ -0,0 +1,150 @@
  1 += reCAPTCHA
  2 +
  3 +Author:: Jason L Perry (http://ambethia.com)
  4 +Copyright:: Copyright (c) 2007 Jason L Perry
  5 +License:: {MIT}[http://creativecommons.org/licenses/MIT/]
  6 +Info:: http://ambethia.com/recaptcha
  7 +Git:: http://github.com/ambethia/recaptcha/tree/master
  8 +Bugs:: http://github.com/ambethia/recaptcha/issues
  9 +
  10 +This plugin adds helpers for the {reCAPTCHA API}[http://recaptcha.net]. In your
  11 +views you can use the +recaptcha_tags+ method to embed the needed javascript,
  12 +and you can validate in your controllers with +verify_recaptcha+.
  13 +
  14 +Beforehand you need to configure Recaptcha with your custom private and public
  15 +key. You may find detailed examples below. Exceptions will be raised if you
  16 +call these methods and the keys can't be found.
  17 +
  18 +== About this fork
  19 +
  20 +This fork tries to introduces a more convenient way to configure recaptcha's
  21 +settings. The API will be inspired by {Thoughtbot's
  22 +Hoptoad}[http://robots.thoughtbot.com/post/344833329/mygem-configure-block].
  23 +
  24 +== Rails Installation
  25 +
  26 +reCAPTCHA for Rails, add this to your Gemfile:
  27 +
  28 + gem "recaptcha", :require => "recaptcha/rails"
  29 +
  30 +Or, it can be installed as a gem:
  31 +
  32 + config.gem "recaptcha", :lib => "recaptcha/rails"
  33 +
  34 +Or, as a standard rails plugin:
  35 +
  36 + script/plugin install git://github.com/ambethia/recaptcha.git
  37 +
  38 +== Merb Installation
  39 +
  40 +reCAPTCHA can also be used in a Merb application when installed as a gem:
  41 +
  42 + dependency "alm-recaptcha", ">=0.2.2.1", :require_as => "recaptcha/merb"
  43 +
  44 +Initial Merb compatability funded by ALM Labs.
  45 +
  46 +== Setting up your API Keys
  47 +
  48 +There are multiple ways to setup your reCAPTCHA API key once you
  49 +{obtain}[http://recaptcha.net/whyrecaptcha.html] a pair.
  50 +
  51 +=== Recaptcha.configure
  52 +
  53 +You may use the block style configuration. The following code could be placed
  54 +into a +config/initializers/recaptcha.rb+ when used in a Rails project.
  55 +
  56 + Recaptcha.configure do |config|
  57 + config.public_key = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
  58 + config.private_key = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
  59 + config.proxy = 'http://myrpoxy.com.au:8080'
  60 + end
  61 +
  62 +This way, you may also set additional options to fit recaptcha into your
  63 +deployment environment.
  64 +
  65 +== Recaptcha#with_configuration
  66 +
  67 +If you want to temporarily overwrite the configuration you set with `Recaptcha.configure` (when testing, for example), you can use a `Recaptcha#with_configuration` block:
  68 +
  69 + Recaptcha.configure(:public_key => '12345') do
  70 + # Do stuff with the overwritten public_key.
  71 + end
  72 +
  73 +=== Shell environment
  74 +
  75 +Or, you can keep your keys out of your code base by exporting the following
  76 +environment variables. You might do this in the .profile/rc, or equivalent for
  77 +the user running your application:
  78 +
  79 + export RECAPTCHA_PUBLIC_KEY = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
  80 + export RECAPTCHA_PRIVATE_KEY = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
  81 +
  82 +=== Per call
  83 +
  84 +You can also pass in your keys as options at runtime, for example:
  85 +
  86 + recaptcha_tags :public_key => '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
  87 +
  88 +and later,
  89 +
  90 + verify_recaptcha :private_key => '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
  91 +
  92 +This option might be useful, if the same code base is used for multiple
  93 +reCAPTCHA setups.
  94 +
  95 +== To use 'recaptcha'
  96 +
  97 +Add +recaptcha_tags+ to each form you want to protect.
  98 +
  99 +And, add +verify_recaptcha+ logic to each form action that you've protected.
  100 +
  101 +=== +recaptcha_tags+
  102 +
  103 +Some of the options available:
  104 +
  105 +<tt>:ssl</tt>:: Uses secure http for captcha widget (default +false+)
  106 +<tt>:noscript</tt>:: Include <noscript> content (default +true+)
  107 +<tt>:display</tt>:: Takes a hash containing the +theme+ and +tabindex+ options per the API. (default +nil+)
  108 +<tt>:ajax</tt>:: Render the dynamic AJAX captcha per the API. (default +false+)
  109 +<tt>:public_key</tt>:: Your public API key, takes precedence over the ENV variable (default +nil+)
  110 +<tt>:error</tt>:: Override the error code returned from the reCAPTCHA API (default +nil+)
  111 +
  112 +You can also override the html attributes for the sizes of the generated +textarea+ and +iframe+
  113 +elements, if CSS isn't your thing. Inspect the source of +recaptcha_tags+ to see these options.
  114 +
  115 +=== +verify_recaptcha+
  116 +
  117 +This method returns +true+ or +false+ after processing the parameters from the reCAPTCHA widget. Why
  118 +isn't this a model validation? Because that violates MVC. You can use it like this, or how ever you
  119 +like. Passing in the ActiveRecord object is optional, if you do--and the captcha fails to verify--an
  120 +error will be added to the object for you to use.
  121 +
  122 +Some of the options available:
  123 +
  124 +<tt>:model</tt>:: Model to set errors
  125 +<tt>:attribute</tt>:: Model attribute to receive errors (default :base)
  126 +<tt>:message</tt>:: Custom error message
  127 +<tt>:private_key</tt>:: Your private API key, takes precedence over the ENV variable (default +nil+).
  128 +<tt>:timeout</tt>:: The number of seconds to wait for reCAPTCHA servers before give up. (default +3+)
  129 +
  130 + respond_to do |format|
  131 + if verify_recaptcha(:model => @post, :message => "Oh! It's error with reCAPTCHA!") && @post.save
  132 + # ...
  133 + else
  134 + # ...
  135 + end
  136 + end
  137 +
  138 +== I18n support
  139 +reCAPTCHA passes two types of error explanation to a linked model. It will use the I18n gem
  140 +to translate the default error message if I18n is available. To customize the messages to your locale,
  141 +add these keys to your I18n backend:
  142 +
  143 +<tt>recaptcha.errors.verification_failed</tt>:: error message displayed if the captcha words didn't match
  144 +<tt>recaptcha.errors.recaptcha_unavailable</tt>:: displayed if a timout error occured while attempting to verify the captcha
  145 +
  146 +== TODO
  147 +* Remove Rails/ActionController dependencies
  148 +* Framework agnostic
  149 +* Add some helpers to use in before_filter and what not
  150 +* Better documentation
vendor/plugins/recaptcha/Rakefile 0 → 100644
@@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
  1 +require 'rake'
  2 +
  3 +begin
  4 + require 'jeweler'
  5 + Jeweler::Tasks.new do |gem|
  6 + gem.name = "recaptcha"
  7 + gem.description = "This plugin adds helpers for the reCAPTCHA API "
  8 + gem.summary = "Helpers for the reCAPTCHA API"
  9 + gem.homepage = "http://ambethia.com/recaptcha"
  10 + gem.authors = ["Jason L. Perry"]
  11 + gem.email = "jasper@ambethia.com"
  12 + gem.files.reject! { |fn| fn.include? ".gitignore" }
  13 + gem.add_development_dependency "mocha"
  14 + gem.add_development_dependency "activesupport"
  15 + end
  16 + Jeweler::GemcutterTasks.new
  17 +rescue LoadError
  18 + puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
  19 +end
  20 +
  21 +require 'rake/rdoctask'
  22 +Rake::RDocTask.new do |rd|
  23 + if File.exist?('VERSION.yml')
  24 + config = YAML.load(File.read('VERSION.yml'))
  25 + version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
  26 + else
  27 + version = ""
  28 + end
  29 +
  30 + rd.main = "README.rdoc"
  31 + rd.rdoc_files.include "README.rdoc", "LICENSE", "lib/**/*.rb"
  32 + rd.rdoc_dir = 'rdoc'
  33 + rd.options << '-N' # line numbers
  34 + rd.options << '-S' # inline source
  35 +end
  36 +
  37 +require 'rake/testtask'
  38 +Rake::TestTask.new(:test) do |test|
  39 + test.libs << 'test'
  40 + test.pattern = 'test/**/*_test.rb'
  41 + # test.verbose = true
  42 +end
  43 +
  44 +begin
  45 + require 'rcov/rcovtask'
  46 + Rcov::RcovTask.new do |test|
  47 + test.libs << 'test'
  48 + test.pattern = 'test/**/*_test.rb'
  49 + test.verbose = true
  50 + end
  51 +rescue LoadError
  52 + task :rcov do
  53 + abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
  54 + end
  55 +end
  56 +
  57 +task :default => :test
  58 +
  59 +
  60 +
vendor/plugins/recaptcha/VERSION 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +0.3.2
vendor/plugins/recaptcha/init.rb 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +# Rails plugin initialization.
  2 +# You can also install it as a gem:
  3 +# config.gem "ambethia-recaptcha", :lib => "recaptcha/rails", :source => "http://gems.github.com"
  4 +
  5 +require 'recaptcha/rails'
0 \ No newline at end of file 6 \ No newline at end of file
vendor/plugins/recaptcha/lib/recaptcha.rb 0 → 100644
@@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
  1 +require 'recaptcha/configuration'
  2 +require 'recaptcha/client_helper'
  3 +require 'recaptcha/verify'
  4 +
  5 +module Recaptcha
  6 + module VERSION #:nodoc:
  7 + MAJOR = 0
  8 + MINOR = 2
  9 + TINY = 2
  10 + PATCH = 1
  11 +
  12 + STRING = [MAJOR, MINOR, TINY, PATCH].join('.')
  13 + end
  14 +
  15 +
  16 + RECAPTCHA_API_SERVER_URL = 'http://www.google.com/recaptcha/api'
  17 + RECAPTCHA_API_SECURE_SERVER_URL = 'https://www.google.com/recaptcha/api'
  18 + RECAPTCHA_VERIFY_URL = 'http://www.google.com/recaptcha/api/verify'
  19 +
  20 + SKIP_VERIFY_ENV = ['test', 'cucumber']
  21 +
  22 + # Gives access to the current Configuration.
  23 + def self.configuration
  24 + @configuration ||= Configuration.new
  25 + end
  26 +
  27 + # Allows easy setting of multiple configuration options. See Configuration
  28 + # for all available options.
  29 + #--
  30 + # The temp assignment is only used to get a nicer rdoc. Feel free to remove
  31 + # this hack.
  32 + #++
  33 + def self.configure
  34 + config = configuration
  35 + yield(config)
  36 + end
  37 +
  38 + def self.with_configuration(config)
  39 + original_config = {}
  40 +
  41 + config.each do |key, value|
  42 + original_config[key] = configuration.send(key)
  43 + configuration.send("#{key}=", value)
  44 + end
  45 +
  46 + result = yield if block_given?
  47 +
  48 + original_config.each { |key, value| configuration.send("#{key}=", value) }
  49 + result
  50 + end
  51 +
  52 + class RecaptchaError < StandardError
  53 + end
  54 +end
  55 +
  56 +if defined?(Rails)
  57 + require 'recaptcha/rails'
  58 +end
vendor/plugins/recaptcha/lib/recaptcha/client_helper.rb 0 → 100644
@@ -0,0 +1,51 @@ @@ -0,0 +1,51 @@
  1 +module Recaptcha
  2 + module ClientHelper
  3 + # Your public API can be specified in the +options+ hash or preferably
  4 + # using the Configuration.
  5 + def recaptcha_tags(options = {})
  6 + # Default options
  7 + key = options[:public_key] ||= Recaptcha.configuration.public_key
  8 + raise RecaptchaError, "No public key specified." unless key
  9 + error = options[:error] ||= (defined? flash ? flash[:recaptcha_error] : "")
  10 + uri = Recaptcha.configuration.api_server_url(options[:ssl])
  11 + html = ""
  12 + if options[:display]
  13 + html << %{<script type="text/javascript">\n}
  14 + html << %{ var RecaptchaOptions = #{options[:display].to_json};\n}
  15 + html << %{</script>\n}
  16 + end
  17 + if options[:ajax]
  18 + html << <<-EOS
  19 + <div id="dynamic_recaptcha"></div>
  20 + <script type="text/javascript">
  21 + var rc_script_tag = document.createElement('script'),
  22 + rc_init_func = function(){Recaptcha.create("#{key}", document.getElementById("dynamic_recaptcha")#{',RecaptchaOptions' if options[:display]});}
  23 + rc_script_tag.src = "#{uri}/js/recaptcha_ajax.js";
  24 + rc_script_tag.type = 'text/javascript';
  25 + rc_script_tag.onload = function(){rc_init_func.call();};
  26 + rc_script_tag.onreadystatechange = function(){
  27 + if (rc_script_tag.readyState == 'loaded' || rc_script_tag.readyState == 'complete') {rc_init_func.call();}
  28 + };
  29 + (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(rc_script_tag);
  30 + </script>
  31 + EOS
  32 + else
  33 + html << %{<script type="text/javascript" src="#{uri}/challenge?k=#{key}}
  34 + html << %{#{error ? "&amp;error=#{CGI::escape(error)}" : ""}"></script>\n}
  35 + unless options[:noscript] == false
  36 + html << %{<noscript>\n }
  37 + html << %{<iframe src="#{uri}/noscript?k=#{key}" }
  38 + html << %{height="#{options[:iframe_height] ||= 300}" }
  39 + html << %{width="#{options[:iframe_width] ||= 500}" }
  40 + html << %{style="border:none;"></iframe><br/>\n }
  41 + html << %{<textarea name="recaptcha_challenge_field" }
  42 + html << %{rows="#{options[:textarea_rows] ||= 3}" }
  43 + html << %{cols="#{options[:textarea_cols] ||= 40}"></textarea>\n }
  44 + html << %{<input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>}
  45 + html << %{</noscript>\n}
  46 + end
  47 + end
  48 + return (html.respond_to?(:html_safe) && html.html_safe) || html
  49 + end # recaptcha_tags
  50 + end # ClientHelper
  51 +end # Recaptcha
vendor/plugins/recaptcha/lib/recaptcha/configuration.rb 0 → 100644
@@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
  1 +module Recaptcha
  2 + # This class enables detailed configuration of the recaptcha services.
  3 + #
  4 + # By calling
  5 + #
  6 + # Recaptcha.configuration # => instance of Recaptcha::Configuration
  7 + #
  8 + # or
  9 + # Recaptcha.configure do |config|
  10 + # config # => instance of Recaptcha::Configuration
  11 + # end
  12 + #
  13 + # you are able to perform configuration updates.
  14 + #
  15 + # Your are able to customize all attributes listed below. All values have
  16 + # sensitive default and will very likely not need to be changed.
  17 + #
  18 + # Please note that the public and private key for the reCAPTCHA API Access
  19 + # have no useful default value. The keys may be set via the Shell enviroment
  20 + # or using this configuration. Settings within this configuration always take
  21 + # precedence.
  22 + #
  23 + # Setting the keys with this Configuration
  24 + #
  25 + # Recaptcha.configure do |config|
  26 + # config.public_key = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
  27 + # config.private_key = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
  28 + # end
  29 + #
  30 + class Configuration
  31 + attr_accessor :nonssl_api_server_url,
  32 + :ssl_api_server_url,
  33 + :verify_url,
  34 + :skip_verify_env,
  35 + :private_key,
  36 + :public_key,
  37 + :proxy
  38 +
  39 + def initialize #:nodoc:
  40 + @nonssl_api_server_url = RECAPTCHA_API_SERVER_URL
  41 + @ssl_api_server_url = RECAPTCHA_API_SECURE_SERVER_URL
  42 + @verify_url = RECAPTCHA_VERIFY_URL
  43 + @skip_verify_env = SKIP_VERIFY_ENV
  44 +
  45 + @private_key = ENV['RECAPTCHA_PRIVATE_KEY']
  46 + @public_key = ENV['RECAPTCHA_PUBLIC_KEY']
  47 + end
  48 +
  49 + def api_server_url(ssl = false) #:nodoc:
  50 + ssl ? ssl_api_server_url : nonssl_api_server_url
  51 + end
  52 + end
  53 +end
vendor/plugins/recaptcha/lib/recaptcha/merb.rb 0 → 100644
@@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
  1 +require 'recaptcha'
  2 +
  3 +Merb::GlobalHelpers.send(:include, Recaptcha::ClientHelper)
  4 +Merb::Controller.send(:include, Recaptcha::Verify)
vendor/plugins/recaptcha/lib/recaptcha/rails.rb 0 → 100644
@@ -0,0 +1,5 @@ @@ -0,0 +1,5 @@
  1 +require 'net/http'
  2 +require 'recaptcha'
  3 +
  4 +ActionView::Base.send(:include, Recaptcha::ClientHelper)
  5 +ActionController::Base.send(:include, Recaptcha::Verify)
0 \ No newline at end of file 6 \ No newline at end of file
vendor/plugins/recaptcha/lib/recaptcha/railtie.rb 0 → 100644
@@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
  1 +require 'net/http'
  2 +require 'recaptcha'
  3 +module Rails
  4 + module Recaptcha
  5 + class Railtie < Rails::Railtie
  6 + initializer "setup config" do
  7 + begin
  8 + ActionView::Base.send(:include, ::Recaptcha::ClientHelper)
  9 + ActionController::Base.send(:include, ::Recaptcha::Verify)
  10 + end
  11 + end
  12 + end
  13 + end
  14 +end
  15 +
vendor/plugins/recaptcha/lib/recaptcha/verify.rb 0 → 100644
@@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
  1 +require "uri"
  2 +module Recaptcha
  3 + module Verify
  4 + # Your private API can be specified in the +options+ hash or preferably
  5 + # using the Configuration.
  6 + def verify_recaptcha(options = {})
  7 + if !options.is_a? Hash
  8 + options = {:model => options}
  9 + end
  10 +
  11 + env = options[:env] || ENV['RAILS_ENV']
  12 + return true if Recaptcha.configuration.skip_verify_env.include? env
  13 + model = options[:model]
  14 + attribute = options[:attribute] || :base
  15 + private_key = options[:private_key] || Recaptcha.configuration.private_key
  16 + raise RecaptchaError, "No private key specified." unless private_key
  17 +
  18 + begin
  19 + recaptcha = nil
  20 + if(Recaptcha.configuration.proxy)
  21 + proxy_server = URI.parse(Recaptcha.configuration.proxy)
  22 + http = Net::HTTP::Proxy(proxy_server.host, proxy_server.port)
  23 + else
  24 + http = Net::HTTP
  25 + end
  26 +
  27 + Timeout::timeout(options[:timeout] || 3) do
  28 + recaptcha = http.post_form(URI.parse(Recaptcha.configuration.verify_url), {
  29 + "privatekey" => private_key,
  30 + "remoteip" => request.remote_ip,
  31 + "challenge" => params[:recaptcha_challenge_field],
  32 + "response" => params[:recaptcha_response_field]
  33 + })
  34 + end
  35 + answer, error = recaptcha.body.split.map { |s| s.chomp }
  36 + unless answer == 'true'
  37 + flash[:recaptcha_error] = error
  38 + if model
  39 + message = "Word verification response is incorrect, please try again."
  40 + message = I18n.translate(:'recaptcha.errors.verification_failed', {:default => message}) if defined?(I18n)
  41 + model.errors.add attribute, options[:message] || message
  42 + end
  43 + return false
  44 + else
  45 + flash[:recaptcha_error] = nil
  46 + return true
  47 + end
  48 + rescue Timeout::Error
  49 + flash[:recaptcha_error] = "recaptcha-not-reachable"
  50 + if model
  51 + message = "Oops, we failed to validate your word verification response. Please try again."
  52 + message = I18n.translate(:'recaptcha.errors.recaptcha_unreachable', :default => message) if defined?(I18n)
  53 + model.errors.add attribute, options[:message] || message
  54 + end
  55 + return false
  56 + rescue Exception => e
  57 + raise RecaptchaError, e.message, e.backtrace
  58 + end
  59 + end # verify_recaptcha
  60 + end # Verify
  61 +end # Recaptcha
vendor/plugins/recaptcha/recaptcha.gemspec 0 → 100644
@@ -0,0 +1,65 @@ @@ -0,0 +1,65 @@
  1 +# Generated by jeweler
  2 +# DO NOT EDIT THIS FILE DIRECTLY
  3 +# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
  4 +# -*- encoding: utf-8 -*-
  5 +
  6 +Gem::Specification.new do |s|
  7 + s.name = %q{recaptcha}
  8 + s.version = "0.3.2"
  9 +
  10 + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
  11 + s.authors = ["Jason L. Perry"]
  12 + s.date = %q{2010-12-20}
  13 + s.description = %q{This plugin adds helpers for the reCAPTCHA API }
  14 + s.email = %q{jasper@ambethia.com}
  15 + s.extra_rdoc_files = [
  16 + "LICENSE",
  17 + "README.rdoc"
  18 + ]
  19 + s.files = [
  20 + "CHANGELOG",
  21 + "LICENSE",
  22 + "README.rdoc",
  23 + "Rakefile",
  24 + "VERSION",
  25 + "init.rb",
  26 + "lib/recaptcha.rb",
  27 + "lib/recaptcha/client_helper.rb",
  28 + "lib/recaptcha/configuration.rb",
  29 + "lib/recaptcha/merb.rb",
  30 + "lib/recaptcha/rails.rb",
  31 + "lib/recaptcha/verify.rb",
  32 + "recaptcha.gemspec",
  33 + "tasks/recaptcha_tasks.rake",
  34 + "test/recaptcha_test.rb",
  35 + "test/verify_recaptcha_test.rb"
  36 + ]
  37 + s.homepage = %q{http://ambethia.com/recaptcha}
  38 + s.require_paths = ["lib"]
  39 + s.rubygems_version = %q{1.3.7}
  40 + s.summary = %q{Helpers for the reCAPTCHA API}
  41 + s.test_files = [
  42 + "test/recaptcha_test.rb",
  43 + "test/verify_recaptcha_test.rb"
  44 + ]
  45 +
  46 + if s.respond_to? :specification_version then
  47 + current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
  48 + s.specification_version = 3
  49 +
  50 + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
  51 + s.add_development_dependency(%q<mocha>, [">= 0"])
  52 + s.add_development_dependency(%q<activesupport>, [">= 0"])
  53 + s.add_dependency(%q<i18n>, [">= 0"])
  54 + else
  55 + s.add_dependency(%q<mocha>, [">= 0"])
  56 + s.add_dependency(%q<activesupport>, [">= 0"])
  57 + s.add_dependency(%q<i18n>, [">= 0"])
  58 + end
  59 + else
  60 + s.add_dependency(%q<mocha>, [">= 0"])
  61 + s.add_dependency(%q<activesupport>, [">= 0"])
  62 + s.add_dependency(%q<i18n>, [">= 0"])
  63 + end
  64 +end
  65 +
vendor/plugins/recaptcha/tasks/recaptcha_tasks.rake 0 → 100644
@@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
  1 +# desc "Explaining what the task does"
  2 +# task :recaptcha do
  3 +# # Task goes here
  4 +# end
0 \ No newline at end of file 5 \ No newline at end of file
vendor/plugins/recaptcha/test/recaptcha_test.rb 0 → 100644
@@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
  1 +require 'test/unit'
  2 +require 'cgi'
  3 +require File.dirname(File.expand_path(__FILE__)) + '/../lib/recaptcha'
  4 +
  5 +class RecaptchaClientHelperTest < Test::Unit::TestCase
  6 + include Recaptcha
  7 + include Recaptcha::ClientHelper
  8 + include Recaptcha::Verify
  9 +
  10 + attr_accessor :session
  11 +
  12 + def setup
  13 + @session = {}
  14 + Recaptcha.configure do |config|
  15 + config.public_key = '0000000000000000000000000000000000000000'
  16 + config.private_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  17 + end
  18 + end
  19 +
  20 + def test_recaptcha_tags
  21 + # Might as well match something...
  22 + assert_match /http:\/\/www.google.com\/recaptcha\/api\/challenge/, recaptcha_tags
  23 + end
  24 +
  25 + def test_recaptcha_tags_with_ssl
  26 + assert_match /https:\/\/www.google.com\/recaptcha\/api\/challenge/, recaptcha_tags(:ssl => true)
  27 + end
  28 +
  29 + def test_recaptcha_tags_without_noscript
  30 + assert_no_match /noscript/, recaptcha_tags(:noscript => false)
  31 + end
  32 +
  33 + def test_should_raise_exception_without_public_key
  34 + assert_raise RecaptchaError do
  35 + Recaptcha.configuration.public_key = nil
  36 + recaptcha_tags
  37 + end
  38 + end
  39 +
  40 + def test_different_configuration_within_with_configuration_block
  41 + key = Recaptcha.with_configuration(:public_key => '12345') do
  42 + Recaptcha.configuration.public_key
  43 + end
  44 +
  45 + assert_equal('12345', key)
  46 + end
  47 +
  48 + def test_reset_configuration_after_with_configuration_block
  49 + Recaptcha.with_configuration(:public_key => '12345')
  50 + assert_equal('0000000000000000000000000000000000000000', Recaptcha.configuration.public_key)
  51 + end
  52 +end
vendor/plugins/recaptcha/test/verify_recaptcha_test.rb 0 → 100644
@@ -0,0 +1,120 @@ @@ -0,0 +1,120 @@
  1 +# coding: utf-8
  2 +
  3 +require 'test/unit'
  4 +require 'rubygems'
  5 +require 'active_support/core_ext/string'
  6 +require 'mocha'
  7 +require 'i18n'
  8 +require 'net/http'
  9 +require File.dirname(File.expand_path(__FILE__)) + '/../lib/recaptcha'
  10 +
  11 +class RecaptchaVerifyTest < Test::Unit::TestCase
  12 + def setup
  13 + Recaptcha.configuration.private_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
  14 + @controller = TestController.new
  15 + @controller.request = stub(:remote_ip => "1.1.1.1")
  16 + @controller.params = {:recaptcha_challenge_field => "challenge", :recaptcha_response_field => "response"}
  17 +
  18 + @expected_post_data = {}
  19 + @expected_post_data["privatekey"] = Recaptcha.configuration.private_key
  20 + @expected_post_data["remoteip"] = @controller.request.remote_ip
  21 + @expected_post_data["challenge"] = "challenge"
  22 + @expected_post_data["response"] = "response"
  23 +
  24 + @expected_uri = URI.parse(Recaptcha.configuration.verify_url)
  25 + end
  26 +
  27 + def test_should_raise_exception_without_private_key
  28 + assert_raise Recaptcha::RecaptchaError do
  29 + Recaptcha.configuration.private_key = nil
  30 + @controller.verify_recaptcha
  31 + end
  32 + end
  33 +
  34 + def test_should_return_false_when_key_is_invalid
  35 + expect_http_post(response_with_body("false\ninvalid-site-private-key"))
  36 +
  37 + assert !@controller.verify_recaptcha
  38 + assert_equal "invalid-site-private-key", @controller.flash[:recaptcha_error]
  39 + end
  40 +
  41 + def test_returns_true_on_success
  42 + @controller.flash[:recaptcha_error] = "previous error that should be cleared"
  43 + expect_http_post(response_with_body("true\n"))
  44 +
  45 + assert @controller.verify_recaptcha
  46 + assert_nil @controller.flash[:recaptcha_error]
  47 + end
  48 +
  49 + def test_errors_should_be_added_to_model
  50 + expect_http_post(response_with_body("false\nbad-news"))
  51 +
  52 + errors = mock
  53 + errors.expects(:add).with(:base, "Word verification response is incorrect, please try again.")
  54 + model = mock(:errors => errors)
  55 +
  56 + assert !@controller.verify_recaptcha(:model => model)
  57 + assert_equal "bad-news", @controller.flash[:recaptcha_error]
  58 + end
  59 +
  60 + def test_returns_true_on_success_with_optional_key
  61 + @controller.flash[:recaptcha_error] = "previous error that should be cleared"
  62 + # reset private key
  63 + @expected_post_data["privatekey"] = 'ADIFFERENTPRIVATEKEYXXXXXXXXXXXXXX'
  64 + expect_http_post(response_with_body("true\n"))
  65 +
  66 + assert @controller.verify_recaptcha(:private_key => 'ADIFFERENTPRIVATEKEYXXXXXXXXXXXXXX')
  67 + assert_nil @controller.flash[:recaptcha_error]
  68 + end
  69 +
  70 + def test_timeout
  71 + expect_http_post(Timeout::Error, :exception => true)
  72 + assert !@controller.verify_recaptcha()
  73 + assert_equal "recaptcha-not-reachable", @controller.flash[:recaptcha_error]
  74 + end
  75 +
  76 + def test_message_should_use_i18n
  77 + I18n.locale = :de
  78 + verification_failed_translated = "Sicherheitscode konnte nicht verifiziert werden."
  79 + verification_failed_default = "Word verification response is incorrect, please try again."
  80 + recaptcha_unreachable_translated = "Netzwerkfehler, bitte versuchen Sie es später erneut."
  81 + recaptcha_unreachable_default = "Oops, we failed to validate your word verification response. Please try again."
  82 + I18n.expects(:translate).with(:'recaptcha.errors.verification_failed', :default => verification_failed_default).returns(verification_failed_translated)
  83 + I18n.expects(:translate).with(:'recaptcha.errors.recaptcha_unreachable', :default => recaptcha_unreachable_default).returns(recaptcha_unreachable_translated)
  84 +
  85 + errors = mock
  86 + errors.expects(:add).with(:base, verification_failed_translated)
  87 + errors.expects(:add).with(:base, recaptcha_unreachable_translated)
  88 + model = mock; model.stubs(:errors => errors)
  89 +
  90 + expect_http_post(response_with_body("false\nbad-news"))
  91 + @controller.verify_recaptcha(:model => model)
  92 +
  93 + expect_http_post(Timeout::Error, :exception => true)
  94 + @controller.verify_recaptcha(:model => model)
  95 +
  96 + end
  97 +
  98 + private
  99 +
  100 + class TestController
  101 + include Recaptcha::Verify
  102 + attr_accessor :request, :params, :flash
  103 +
  104 + def initialize
  105 + @flash = {}
  106 + end
  107 + end
  108 +
  109 + def expect_http_post(response, options = {})
  110 + unless options[:exception]
  111 + Net::HTTP.expects(:post_form).with(@expected_uri, @expected_post_data).returns(response)
  112 + else
  113 + Net::HTTP.expects(:post_form).raises response
  114 + end
  115 + end
  116 +
  117 + def response_with_body(body)
  118 + stub(:body => body)
  119 + end
  120 +end