acts_as_textcaptcha 2.1.5 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +2 -2
- data/lib/acts_as_textcaptcha/textcaptcha.rb +12 -12
- data/spec/acts_as_textcaptcha_spec.rb +16 -13
- data/spec/spec_helper.rb +1 -3
- metadata +5 -5
data/README.rdoc
CHANGED
@@ -24,7 +24,7 @@ What do you need?
|
|
24
24
|
* {Ruby}[http://ruby-lang.org/] >= 1.8.7 (also tested with REE and Ruby 1.9.2)
|
25
25
|
* {bcrypt-ruby}[http://bcrypt-ruby.rubyforge.org/] gem (to securely encrypt the spam answers in your session)
|
26
26
|
* {Text CAPTCHA api key}[http://textcaptcha.com/register] (_optional_, since you can define your own logic questions, see below for details)
|
27
|
-
* {
|
27
|
+
* {Rspec2}[http://rspec.info/] (_optional_ if you want to run the tests, requires >= rspec2)
|
28
28
|
|
29
29
|
== Installing
|
30
30
|
|
@@ -136,7 +136,7 @@ For more details on the code please check the {documentation}[http://rdoc.info/p
|
|
136
136
|
|
137
137
|
== Rake Tasks
|
138
138
|
|
139
|
-
* rake
|
139
|
+
* rake rspec (run the rspec2 tests)
|
140
140
|
* rake rcov (run tests showing coverage)
|
141
141
|
* rake rdoc (generate docs)
|
142
142
|
|
@@ -30,10 +30,10 @@ module ActsAsTextcaptcha
|
|
30
30
|
validate :validate_textcaptcha
|
31
31
|
|
32
32
|
if options.is_a?(Hash)
|
33
|
-
self.textcaptcha_config = options
|
33
|
+
self.textcaptcha_config = options.symbolize_keys!
|
34
34
|
else
|
35
35
|
begin
|
36
|
-
self.textcaptcha_config = YAML.load(File.read("#{Rails.root ? Rails.root.to_s : '.'}/config/textcaptcha.yml"))[Rails.env]
|
36
|
+
self.textcaptcha_config = YAML.load(File.read("#{Rails.root ? Rails.root.to_s : '.'}/config/textcaptcha.yml"))[Rails.env].symbolize_keys!
|
37
37
|
rescue Errno::ENOENT
|
38
38
|
raise('./config/textcaptcha.yml not found')
|
39
39
|
end
|
@@ -77,14 +77,14 @@ module ActsAsTextcaptcha
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def encrypt_answer(answer)
|
80
|
-
return answer unless(textcaptcha_config[
|
81
|
-
BCrypt::Engine.hash_secret(answer, textcaptcha_config[
|
80
|
+
return answer unless(textcaptcha_config[:bcrypt_salt])
|
81
|
+
BCrypt::Engine.hash_secret(answer, textcaptcha_config[:bcrypt_salt], (textcaptcha_config[:bcrypt_cost].to_i || 10))
|
82
82
|
end
|
83
83
|
|
84
84
|
def generate_spam_question(use_textcaptcha = true)
|
85
|
-
if use_textcaptcha && textcaptcha_config && textcaptcha_config[
|
85
|
+
if use_textcaptcha && textcaptcha_config && textcaptcha_config[:api_key]
|
86
86
|
begin
|
87
|
-
resp = Net::HTTP.get(URI.parse('http://textcaptcha.com/api/'+textcaptcha_config[
|
87
|
+
resp = Net::HTTP.get(URI.parse('http://textcaptcha.com/api/'+textcaptcha_config[:api_key]))
|
88
88
|
return [] if resp.empty?
|
89
89
|
|
90
90
|
if defined?(ActiveSupport::XmlMini)
|
@@ -103,16 +103,16 @@ module ActsAsTextcaptcha
|
|
103
103
|
return possible_answers if spam_question && !possible_answers.empty?
|
104
104
|
rescue SocketError, Timeout::Error, Errno::EINVAL, Errno::ECONNRESET, EOFError, Errno::ECONNREFUSED,
|
105
105
|
Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, URI::InvalidURIError => e
|
106
|
-
log_textcaptcha("failed to load or parse textcaptcha with key '#{textcaptcha_config[
|
106
|
+
log_textcaptcha("failed to load or parse textcaptcha with key '#{textcaptcha_config[:api_key]}'; #{e}")
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
110
|
# fall back to textcaptcha_config questions
|
111
|
-
if textcaptcha_config && textcaptcha_config[
|
112
|
-
log_textcaptcha('falling back to random logic question from config') if textcaptcha_config[
|
113
|
-
random_question = textcaptcha_config[
|
114
|
-
self.spam_question = random_question[
|
115
|
-
self.possible_answers = encrypt_answers(random_question[
|
111
|
+
if textcaptcha_config && textcaptcha_config[:questions]
|
112
|
+
log_textcaptcha('falling back to random logic question from config') if textcaptcha_config[:api_key]
|
113
|
+
random_question = textcaptcha_config[:questions][rand(textcaptcha_config[:questions].size)].symbolize_keys!
|
114
|
+
self.spam_question = random_question[:question]
|
115
|
+
self.possible_answers = encrypt_answers(random_question[:answers].split(',').map!{|ans| Digest::MD5.hexdigest(ans)})
|
116
116
|
end
|
117
117
|
possible_answers
|
118
118
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require 'rspec/core'
|
2
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
3
|
|
3
4
|
class Widget < ActiveRecord::Base
|
4
5
|
# uses textcaptcha.yml file for configuration
|
@@ -30,7 +31,7 @@ class Contact
|
|
30
31
|
include ActiveModel::Validations
|
31
32
|
include ActiveModel::Conversion
|
32
33
|
extend ActsAsTextcaptcha::Textcaptcha
|
33
|
-
acts_as_textcaptcha(
|
34
|
+
acts_as_textcaptcha(:questions => [{:question => '1+1', :answers => '2,two'}])
|
34
35
|
end
|
35
36
|
|
36
37
|
|
@@ -138,13 +139,15 @@ describe 'ActsAsTextcaptcha' do
|
|
138
139
|
|
139
140
|
describe 'with inline options hash' do
|
140
141
|
|
141
|
-
it 'should be configurable from inline options' do
|
142
|
-
@comment.textcaptcha_config.should eql({
|
143
|
-
@review.textcaptcha_config.should eql({
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
142
|
+
it 'should be configurable from inline options with keys as symbols' do
|
143
|
+
@comment.textcaptcha_config.should eql({:api_key => '8u5ixtdnq9csc84cok0owswgo'})
|
144
|
+
@review.textcaptcha_config.should eql({:bcrypt_cost =>'3', :questions => [{'question' => '1+1', 'answers' => '2,two'},
|
145
|
+
{'question' => 'The green hat is what color?', 'answers' => 'green'},
|
146
|
+
{'question' => 'Which is bigger: 67, 14 or 6', 'answers' => '67,sixtyseven,sixty seven,sixty-seven'}],
|
147
|
+
:bcrypt_salt => '$2a$10$j0bmycH.SVfD1b5mpEGPpe',
|
148
|
+
:api_key => '8u5ixtdnq9csc84cok0owswgo'})
|
149
|
+
@note.textcaptcha_config.should eql({:questions => [{:question => '1+1', :answers => '2,two'}]})
|
150
|
+
@contact.textcaptcha_config.should eql({:questions => [{:question => '1+1', :answers => '2,two'}]})
|
148
151
|
end
|
149
152
|
|
150
153
|
it 'should generate spam question from textcaptcha service' do
|
@@ -190,10 +193,10 @@ describe 'ActsAsTextcaptcha' do
|
|
190
193
|
end
|
191
194
|
|
192
195
|
it 'should be configurable from config/textcaptcha.yml file' do
|
193
|
-
@widget.textcaptcha_config[
|
194
|
-
@widget.textcaptcha_config[
|
195
|
-
@widget.textcaptcha_config[
|
196
|
-
@widget.textcaptcha_config[
|
196
|
+
@widget.textcaptcha_config[:api_key].should eql('8u5ixtdnq9csc84cok0owswgo')
|
197
|
+
@widget.textcaptcha_config[:bcrypt_salt].should eql('$2a$10$j0bmycH.SVfD1b5mpEGPpe')
|
198
|
+
@widget.textcaptcha_config[:bcrypt_cost].should eql(10)
|
199
|
+
@widget.textcaptcha_config[:questions].length.should eql(10)
|
197
200
|
end
|
198
201
|
|
199
202
|
it 'should generate spam question' do
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_textcaptcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 7
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 2.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 2.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matthew Hutchinson
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-12-01 00:00:00 +00:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|