acts_as_textcaptcha 4.1.3 → 4.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.travis.yml +22 -10
- data/Appraisals +11 -0
- data/CHANGELOG.md +7 -1
- data/README.md +108 -96
- data/Rakefile +6 -4
- data/acts_as_textcaptcha.gemspec +2 -1
- data/gemfiles/rails_3.gemfile +7 -0
- data/gemfiles/rails_4.gemfile +7 -0
- data/gemfiles/rails_5.gemfile +7 -0
- data/lib/acts_as_textcaptcha/textcaptcha.rb +3 -6
- data/lib/acts_as_textcaptcha/version.rb +1 -1
- data/test/test_helper.rb +10 -5
- data/test/test_models.rb +10 -7
- data/test/textcaptcha_api_test.rb +3 -3
- data/test/textcaptcha_cache_test.rb +1 -1
- data/test/textcaptcha_helper_test.rb +4 -4
- data/test/textcaptcha_test.rb +4 -4
- metadata +23 -6
- data/init.rb +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3a465a05115f3c4c3730aaa5e17ff43ce4167dee5ba269c54ea23c45613a7fcf
|
4
|
+
data.tar.gz: 00ab7bf7dadf2c90f623e1a668be1bef30b941bfd67c4abcf54e9a5b5679658e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 476c04ecc39f85a54b8f4dd2f3420579ada995553eb841ad39cdde9b534557b9f61d0d5579ab9db568ce0d8a6aa4e82838741943e1d6551f3b35f5551dc13aa0
|
7
|
+
data.tar.gz: 85fa6bdb42b013190232ed5d970a817e7a6fb142b7a40ab1d4c4ed57f2ee03a6592342097db1c7ccfe9826a8ecc95fed332fe737f5ce3b10b8cc33d99c2f6269
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,13 +1,25 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
|
-
|
4
|
-
-
|
3
|
+
gemfile:
|
4
|
+
- gemfiles/rails_3.gemfile
|
5
|
+
- gemfiles/rails_4.gemfile
|
6
|
+
- gemfiles/rails_5.gemfile
|
5
7
|
rvm:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
- 2.2.9
|
9
|
+
- 2.3.6
|
10
|
+
- 2.4.3
|
11
|
+
- 2.5.0
|
12
|
+
matrix:
|
13
|
+
exclude:
|
14
|
+
- rvm: 2.1.10
|
15
|
+
gemfile: gemfiles/rails_5.gemfile
|
16
|
+
before_install:
|
17
|
+
- gem update --system
|
18
|
+
deploy:
|
19
|
+
provider: rubygems
|
20
|
+
api_key:
|
21
|
+
secure: AUJy9JSNrNcJcZc6JQErh1LtmHrdQBk1W0DYVT0soyBEx5hbKKoIympmrlh9VcZxNpbLfbuCdxl2C0nWMembwx71tLytvM76BqoU2KKTxQQLju8SUAyzGQabkNHr0mzpUDQiC4L16c5k+voCkWtptGkxiVq6eDZExBSzDM8cVMk=
|
22
|
+
gem: acts_as_textcaptcha
|
23
|
+
on:
|
24
|
+
tags: true
|
25
|
+
repo: matthutchinson/acts_as_textcaptcha
|
data/Appraisals
ADDED
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,11 @@ project adheres to [Semantic Versioning][Semver].
|
|
7
7
|
|
8
8
|
* Your contribution here!
|
9
9
|
|
10
|
+
## [4.2.0][] (17 Jan 2018)
|
11
|
+
* Updated Rubies for Travis CI
|
12
|
+
* Update tests to remove MiniTest warnings
|
13
|
+
* Latest Rails (~> 5.1.4) now set in gemspec
|
14
|
+
|
10
15
|
## [4.1.3][] (28 May 2016)
|
11
16
|
* Updated gem dependencies
|
12
17
|
* Switched from FakeWeb to Webmock
|
@@ -35,7 +40,8 @@ project adheres to [Semantic Versioning][Semver].
|
|
35
40
|
|
36
41
|
(further change log details for older releases are unavailable)
|
37
42
|
|
38
|
-
[Unreleased]: https://github.com/matthutchinson/acts_as_textcaptcha/compare/v4.
|
43
|
+
[Unreleased]: https://github.com/matthutchinson/acts_as_textcaptcha/compare/v4.2.0...HEAD
|
44
|
+
[4.1.3]: https://github.com/matthutchinson/acts_as_textcaptcha/compare/v4.1.3...v4.2.0
|
39
45
|
[4.1.3]: https://github.com/matthutchinson/acts_as_textcaptcha/compare/v4.1.2...v4.1.3
|
40
46
|
[4.1.2]: https://github.com/matthutchinson/acts_as_textcaptcha/compare/v4.1.1...v4.1.2
|
41
47
|
[4.1.1]: https://github.com/matthutchinson/acts_as_textcaptcha/compare/v4.1.0...v4.1.1
|
data/README.md
CHANGED
@@ -7,54 +7,61 @@
|
|
7
7
|
[![Gem Dependencies](https://img.shields.io/gemnasium/matthutchinson/acts_as_textcaptcha.svg?style=flat)](https://gemnasium.com/matthutchinson/acts_as_textcaptcha)
|
8
8
|
|
9
9
|
ActsAsTextcaptcha provides spam protection for your Rails models using logic
|
10
|
-
questions from the excellent [
|
11
|
-
(by [Rob Tuley](
|
12
|
-
|
13
|
-
|
10
|
+
questions from the excellent [TextCaptcha](http://textcaptcha.com/) web service
|
11
|
+
(by [Rob Tuley](https://twitter.com/robtuley). It is also possible to configure your
|
12
|
+
own captcha questions (instead, or as a fallback in the event of any API
|
13
|
+
issues).
|
14
14
|
|
15
15
|
This gem is actively maintained, has good test coverage and is compatible with
|
16
|
-
Rails >= 3
|
16
|
+
Rails >= 3 (including Rails 4 & 5) and Ruby >= 2.1. If you have issues
|
17
|
+
please report them
|
17
18
|
[here](https://github.com/matthutchinson/acts_as_textcaptcha/issues/new).
|
18
19
|
|
19
20
|
Logic questions from the web service are aimed at a child's age of 7, so they
|
20
21
|
can be solved easily by even the most cognitively impaired users. As they
|
21
22
|
involve human logic, questions cannot be solved by a robot. There are both
|
22
|
-
advantages and disadvantages
|
23
|
-
captchas, find out more at [
|
23
|
+
advantages and disadvantages in using logic questions over image based
|
24
|
+
captchas, find out more at [TextCaptcha](http://textcaptcha.com/).
|
24
25
|
|
25
26
|
## Demo
|
26
27
|
|
27
|
-
Try a [working demo here](
|
28
|
+
Try a [working demo here](https://acts-as-textcaptcha-demo.herokuapp.com)!
|
28
29
|
|
29
|
-
|
30
|
+
**Or** click below to deploy your own example Rails app to Heroku (already
|
31
|
+
configured with acts_as_textcaptcha). See
|
32
|
+
[here](https://github.com/matthutchinson/acts_as_textcaptcha_demo) for more
|
33
|
+
details.
|
34
|
+
|
35
|
+
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://www.heroku.com/deploy?template=https://github.com/matthutchinson/acts_as_textcaptcha_demo/tree/master)
|
30
36
|
|
31
|
-
|
32
|
-
are having problems please carefully check the steps below or refer to the [upgrade
|
33
|
-
instructions](https://github.com/matthutchinson/acts_as_textcaptcha/wiki/Upgrading-from-3.0.10).
|
37
|
+
## Installing
|
34
38
|
|
35
39
|
First add the following to your Gemfile, then `bundle install`;
|
36
40
|
|
37
41
|
gem 'acts_as_textcaptcha'
|
38
42
|
|
39
|
-
|
40
|
-
the following code to models you would like to protect;
|
43
|
+
Add the following code to models you would like to protect;
|
41
44
|
|
42
|
-
class Comment <
|
43
|
-
# (this is the simplest way to configure the gem
|
44
|
-
acts_as_textcaptcha :api_key => '
|
45
|
+
class Comment < ApplicationRecord
|
46
|
+
# (this is the simplest way to configure the gem)
|
47
|
+
acts_as_textcaptcha :api_key => 'TEXTCAPTCHA_API_IDENTITY'
|
45
48
|
end
|
46
49
|
|
47
|
-
|
48
|
-
|
50
|
+
Your `TEXTCAPTCHA_API_IDENTITY` should be some reference to yourself (e.g. an
|
51
|
+
email address, domain or similar where if there are problems with your usage you
|
52
|
+
can be contacted).
|
53
|
+
|
54
|
+
Next, in your controller's *new* action generate and assign the logic question
|
55
|
+
for the record, like so;
|
49
56
|
|
50
57
|
def new
|
51
58
|
@comment = Comment.new
|
52
59
|
@comment.textcaptcha
|
53
60
|
end
|
54
61
|
|
55
|
-
Finally, in
|
56
|
-
the textcaptcha_fields helper.
|
57
|
-
as you like;
|
62
|
+
Finally, in the view add the textcaptcha question and answer fields to your form
|
63
|
+
using the `textcaptcha_fields` helper. Feel free to arrange the HTML within this
|
64
|
+
block as you like;
|
58
65
|
|
59
66
|
<%= textcaptcha_fields(f) do %>
|
60
67
|
<div class="field">
|
@@ -63,48 +70,56 @@ as you like;
|
|
63
70
|
</div>
|
64
71
|
<% end %>
|
65
72
|
|
66
|
-
*NOTE:* If you'd rather NOT use this helper and
|
67
|
-
|
68
|
-
[
|
69
|
-
code](https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/lib/acts_as_textcaptcha/textcaptcha_helper.rb).
|
73
|
+
*NOTE:* If you'd rather NOT use this helper and prefer to write your own form
|
74
|
+
elements, take a look at the HTML produced from this helper method
|
75
|
+
[here](https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/lib/acts_as_textcaptcha/textcaptcha_helper.rb).
|
70
76
|
|
71
|
-
|
77
|
+
*NOTE:* The defaults for [cache
|
78
|
+
configuration](http://guides.rubyonrails.org/caching_with_rails.html#cache-stores)
|
79
|
+
changed with Rails 5 and this gem **requires** a working Rails.cache store to
|
80
|
+
exist.
|
81
|
+
|
82
|
+
*NOTE:* These installation steps changed with v4.0.0 of this gem. If you are
|
83
|
+
having problems please refer to the 3.0 [upgrade
|
84
|
+
guide](https://github.com/matthutchinson/acts_as_textcaptcha/wiki/Upgrading-from-3.0.10).
|
85
|
+
|
86
|
+
### Toggling TextCaptcha
|
72
87
|
|
73
88
|
You can toggle textcaptcha on/off for your models by overriding the
|
74
89
|
`perform_textcaptcha?` method. If it returns false, no questions will be fetched
|
75
|
-
from the web service and
|
90
|
+
from the web service and captcha validation is disabled.
|
76
91
|
|
77
92
|
This is useful for writing your own custom logic for toggling spam protection
|
78
93
|
on/off e.g. for logged in users. By default the `perform_textcaptcha?` method
|
79
|
-
[checks if the
|
94
|
+
[checks if the object is a new (unsaved)
|
80
95
|
record](https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/lib/acts_as_textcaptcha/textcaptcha.rb#L54).
|
81
96
|
|
82
97
|
So out of the box, spam protection is only enabled for creating new records (not
|
83
|
-
updating).
|
98
|
+
updating). Here is a typical example showing how to overwrite the
|
84
99
|
`perform_textcaptcha?` method, while maintaining the new record check.
|
85
100
|
|
86
|
-
class Comment <
|
87
|
-
acts_as_textcaptcha :api_key => '
|
101
|
+
class Comment < ApplicationRecord
|
102
|
+
acts_as_textcaptcha :api_key => 'TEXTCAPTCHA_API_IDENTITY'
|
88
103
|
|
89
104
|
def perform_textcaptcha?
|
90
105
|
super && user.admin?
|
91
106
|
end
|
92
107
|
end
|
93
108
|
|
94
|
-
|
109
|
+
### Configuration options
|
95
110
|
|
96
111
|
You can configure captchas with the following options;
|
97
112
|
|
98
|
-
* *api_key* (_required_) -
|
99
|
-
* *questions* (_optional_) - array of question and answer hashes (see below) A random question from this array will be asked if the web service fails OR if no
|
113
|
+
* *api_key* (_required_) - reference to yourself (e.g. your email - to identify calls to the textcaptcha.com API)
|
114
|
+
* *questions* (_optional_) - array of question and answer hashes (see below) A random question from this array will be asked if the web service fails OR if no `api_key` has been set. Multiple answers to the same question are comma separated (e.g. 2,two). Don't use commas in your answers!
|
100
115
|
* *cache_expiry_minutes* (_optional_) - minutes for answers to persist in the cache (default 10 minutes), see [below for details](https://github.com/matthutchinson/acts_as_textcaptcha#what-does-the-code-do)
|
101
116
|
* *http_read_timeout* (_optional_) - Net::HTTP option, seconds to wait for one block to be read from the remote API
|
102
117
|
* *http_open_timeout* (_optional_) - Net::HTTP option, seconds to wait for the connection to open to the remote API
|
103
118
|
|
104
119
|
For example;
|
105
120
|
|
106
|
-
class Comment <
|
107
|
-
acts_as_textcaptcha :api_key => '
|
121
|
+
class Comment < ApplicationRecord
|
122
|
+
acts_as_textcaptcha :api_key => 'TEXTCAPTCHA_API_IDENTITY',
|
108
123
|
:http_read_timeout => 60,
|
109
124
|
:http_read_timeout => 10,
|
110
125
|
:cache_expiry_minutes => 10,
|
@@ -112,27 +127,28 @@ For example;
|
|
112
127
|
{ 'question' => 'The green hat is what color?', 'answers' => 'green' }]
|
113
128
|
end
|
114
129
|
|
115
|
-
|
130
|
+
#### YAML config
|
116
131
|
|
117
132
|
The gem can be configured for models individually (as shown above) or with a
|
118
|
-
config/textcaptcha.yml file.
|
119
|
-
|
120
|
-
preference over the configuration in textcaptcha.yml.
|
121
|
-
|
133
|
+
config/textcaptcha.yml file. The config file must have an `api_key` defined
|
134
|
+
and/or an array of questions and answers. Any options defined inline in model
|
135
|
+
classes take preference over the global configuration in textcaptcha.yml.
|
136
|
+
|
137
|
+
The gem comes with a handy rake task to copy over a
|
122
138
|
[textcaptcha.yml](http://github.com/matthutchinson/acts_as_textcaptcha/raw/master/config/textcaptcha.yml)
|
123
139
|
template to your config directory;
|
124
140
|
|
125
141
|
rake textcaptcha:config
|
126
142
|
|
127
|
-
|
143
|
+
#### Configuring _without_ the TextCaptcha web service
|
128
144
|
|
129
|
-
To use only your own logic questions, simply
|
130
|
-
configuration and define at least
|
145
|
+
To use only your own logic questions, simply omit the `api_key` from the
|
146
|
+
configuration and define at least one logic question and answer (see above).
|
131
147
|
|
132
148
|
## Translations
|
133
149
|
|
134
150
|
The gem uses the standard Rails I18n translation approach (with a fall-back to
|
135
|
-
English). Unfortunately at present, the
|
151
|
+
English). Unfortunately at present, the TextCaptcha web service only provides
|
136
152
|
logic questions in English.
|
137
153
|
|
138
154
|
en:
|
@@ -147,109 +163,105 @@ logic questions in English.
|
|
147
163
|
activemodel:
|
148
164
|
attributes:
|
149
165
|
comment:
|
150
|
-
textcaptcha_answer: "
|
166
|
+
textcaptcha_answer: "TextCaptcha answer"
|
151
167
|
|
152
|
-
## Without
|
168
|
+
## Without ActiveRecord
|
153
169
|
|
154
|
-
|
155
|
-
it without ActiveRecord, or Rails. As an example, take a look at the
|
170
|
+
It is possible to use this gem without ActiveRecord. As an example, take a look at the
|
156
171
|
[Contact](https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/test/test_models.rb#L44)
|
157
172
|
model used in the test suite
|
158
173
|
[here](https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/test/test_models.rb#L44).
|
159
174
|
|
160
|
-
Please note that the built-in
|
161
|
-
[TextcaptchaCache](https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/lib/acts_as_textcaptcha/textcaptcha_cache.rb)
|
162
|
-
class directly wraps the
|
163
|
-
[Rails.cache](http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html).
|
164
|
-
An alternative TextcaptchaCache implementation will be necessary if Rails.cache
|
165
|
-
is not available.
|
166
|
-
|
167
175
|
## Testing and docs
|
168
176
|
|
169
177
|
In development you can run the tests and rdoc tasks like so;
|
170
178
|
|
171
|
-
* rake test (all tests)
|
172
|
-
* rake test:coverage (all tests with code coverage)
|
173
|
-
* rake
|
179
|
+
* `rake test` (all tests)
|
180
|
+
* `rake test:coverage` (all tests with code coverage reporting)
|
181
|
+
* `appraisal rake test` (all tests with all gemfile variations)
|
182
|
+
* `appraisal rails-3 rake test` (all tests using a specific gemfile)
|
183
|
+
* `rake rdoc` (generate docs)
|
184
|
+
|
185
|
+
This gem uses [appraisal](https://github.com/thoughtbot/appraisal) to run the
|
186
|
+
test suite with multiple versions of Rails.
|
174
187
|
|
175
188
|
## What does the code do?
|
176
189
|
|
177
190
|
The gem contains two parts, a module for your ActiveRecord models, and a single
|
178
|
-
view helper method.
|
191
|
+
view helper method. The ActiveRecord module makes use of two futher classes,
|
179
192
|
[TextcaptchaApi](https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/lib/acts_as_textcaptcha/textcaptcha_api.rb)
|
180
193
|
and
|
181
194
|
[TextcaptchaCache](https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/lib/acts_as_textcaptcha/textcaptcha_cache.rb).
|
182
195
|
|
183
|
-
A call to
|
184
|
-
service.
|
185
|
-
|
186
|
-
|
187
|
-
TextcaptchaCache with this random key.
|
188
|
-
|
196
|
+
A call to `@model.textcaptcha` in your controller will query the TextCaptcha web
|
197
|
+
service. A GET request is made with Net::HTTP and parsed using the default Rails
|
198
|
+
`ActiveSupport::XMLMini` backend. A textcaptcha_question and a random cache key
|
199
|
+
are assigned to the record. An array of possible answers is also stored in the
|
200
|
+
TextcaptchaCache with this random key. The cached answers have (by default) a 10
|
201
|
+
minute TTL in your cache. If your forms take more than 10 minutes to be
|
189
202
|
completed you can adjust this value setting the `cache_expiry_minutes` option.
|
190
203
|
Internally TextcaptchaCache wraps
|
191
204
|
[Rails.cache](http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html)
|
192
|
-
and all cache keys are
|
205
|
+
and all cache keys are name spaced.
|
193
206
|
|
194
|
-
On saving, validate_textcaptcha is called on @model.validate checking that the
|
195
|
-
|
196
|
-
the cache).
|
197
|
-
i.e. never on
|
207
|
+
On saving, `validate_textcaptcha` is called on @model.validate checking that the
|
208
|
+
`@model.textcaptcha_answer` matches one of the possible answers (retrieved from
|
209
|
+
the cache). By default, this validation is _only_ carried out on new records,
|
210
|
+
i.e. never on update, only on create. All attempted answers are case-insensitive
|
198
211
|
and have trailing/leading white-space removed.
|
199
212
|
|
200
213
|
Regardless of a correct, or incorrect answer the possible answers are cleared
|
201
|
-
from the cache and a new random key is generated and assigned.
|
202
|
-
answer will cause a new question to be prompted.
|
214
|
+
from the cache and a new random key is generated and assigned. An incorrect
|
215
|
+
answer will cause a new question to be prompted. After one correct answer, the
|
203
216
|
answer and a mutating key are sent on further form requests, and no question is
|
204
217
|
presented in the form.
|
205
218
|
|
206
219
|
If an error or timeout occurs during API fetching, ActsAsTextcaptcha will fall
|
207
|
-
back to choose a random logic question defined in your options (see above).
|
220
|
+
back to choose a random logic question defined in your options (see above). If
|
208
221
|
the web service fails or no API key is specified AND no alternate questions are
|
209
222
|
configured, the @model will not require textcaptcha checking and will pass as
|
210
223
|
valid.
|
211
224
|
|
212
225
|
For more details on the code please check the
|
213
226
|
[documentation](http://rdoc.info/projects/matthutchinson/acts_as_textcaptcha).
|
214
|
-
Tests are written with [MiniTest](https://rubygems.org/gems/minitest).
|
227
|
+
Tests are written with [MiniTest](https://rubygems.org/gems/minitest). Pull
|
215
228
|
requests and bug reports are welcome.
|
216
229
|
|
217
230
|
## Requirements
|
218
231
|
|
219
232
|
What do you need?
|
220
233
|
|
221
|
-
* [Rails](http://github.com/rails/rails) >= 3
|
222
|
-
* [Rails.cache](http://
|
223
|
-
* [Ruby](http://ruby-lang.org/) >= 2.
|
224
|
-
* [Text CAPTCHA API key](http://textcaptcha.com/register) (_optional_, since you can define your own logic questions)
|
225
|
-
* [MiniTest](https://rubygems.org/gems/minitest) (_optional_ if you want to run the tests)
|
226
|
-
* [SimpleCov](https://rubygems.org/gems/simplecov) (_optional_ if you want to run the tests with code coverage reporting)
|
234
|
+
* [Rails](http://github.com/rails/rails) >= 3 (including Rails 4 & 5)
|
235
|
+
* [Rails.cache](http://guides.rubyonrails.org/caching_with_rails.html#cache-stores) - a basic cache configuration is necessary
|
236
|
+
* [Ruby](http://ruby-lang.org/) >= 2.1
|
227
237
|
|
228
|
-
*
|
238
|
+
*NOTE:* The built-in
|
229
239
|
[TextcaptchaCache](https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/lib/acts_as_textcaptcha/textcaptcha_cache.rb)
|
230
240
|
class directly wraps the
|
231
|
-
[Rails.cache](http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html)
|
232
|
-
|
241
|
+
[Rails.cache](http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html).
|
242
|
+
An alternative TextcaptchaCache implementation will be necessary if
|
243
|
+
`Rails.cache` is not available.
|
244
|
+
|
233
245
|
|
234
|
-
## Rails 2
|
246
|
+
## Rails 2 Support
|
235
247
|
|
236
|
-
Support for Rails 2 was dropped with the release of v4.1.0
|
237
|
-
continue to use this gem with an older version of Rails (>= 2.3.8), please
|
238
|
-
|
248
|
+
Support for Rails 2 was dropped with the release of `v4.1.0`. If you would like
|
249
|
+
to continue to use this gem with an older version of Rails (>= 2.3.8), please
|
250
|
+
lock your Gemfile with version `4.0.0`. Like so;
|
239
251
|
|
240
252
|
# in your Gemfile
|
241
253
|
gem 'acts_as_textcaptcha', '=4.0.0'
|
242
254
|
|
243
|
-
# or in environment.rb
|
255
|
+
# or in config/environment.rb
|
244
256
|
config.gem 'acts_as_textcaptcha', :version => '=4.0.0'
|
245
257
|
|
246
258
|
Check out the
|
247
259
|
[README](https://github.com/matthutchinson/acts_as_textcaptcha/tree/v4.0.0) for
|
248
|
-
this release for
|
260
|
+
this release for further instructions.
|
249
261
|
|
250
262
|
## Links
|
251
263
|
|
252
|
-
* [Demo](
|
264
|
+
* [Demo](https://acts-as-textcaptcha-demo.herokuapp.com)
|
253
265
|
* [Travis CI](http://travis-ci.org/#!/matthutchinson/acts_as_textcaptcha)
|
254
266
|
* [Test Coverage](https://coveralls.io/r/matthutchinson/acts_as_textcaptcha?branch=master)
|
255
267
|
* [Code Climate](https://codeclimate.com/github/matthutchinson/acts_as_textcaptcha)
|
@@ -263,14 +275,14 @@ this release for more information.
|
|
263
275
|
## Who's who?
|
264
276
|
|
265
277
|
* [ActsAsTextcaptcha](http://github.com/matthutchinson/acts_as_textcaptcha) and [little robot drawing](http://www.flickr.com/photos/hiddenloop/4541195635/) by [Matthew Hutchinson](http://matthewhutchinson.net)
|
266
|
-
* [
|
278
|
+
* [TextCaptcha](http://textcaptcha.com) API and service by [Rob Tuley](https://twitter.com/robtuley)
|
267
279
|
|
268
280
|
## Usage
|
269
281
|
|
270
282
|
This gem is used in a number of production websites and apps. It was originally
|
271
|
-
extracted from code developed for [Bugle](http://bugleblogs.com).
|
272
|
-
happily using acts_as_textcaptcha in production, let me know and I'll add
|
273
|
-
this list!
|
283
|
+
extracted from code developed for [Bugle](http://bugleblogs.com). If you're
|
284
|
+
happily using acts_as_textcaptcha in production, please let me know and I'll add
|
285
|
+
you to this list!
|
274
286
|
|
275
287
|
* [matthewhutchinson.net](http://matthewhutchinson.net)
|
276
288
|
* [pmFAQtory.com](http://pmfaqtory.com)
|
data/Rakefile
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require 'rubygems'
|
3
2
|
require 'bundler/gem_tasks'
|
4
3
|
require 'rake/testtask'
|
4
|
+
|
5
|
+
gem 'rdoc'
|
6
|
+
|
5
7
|
Rake::TestTask.new(:test) do |t|
|
6
8
|
t.libs << "test"
|
7
9
|
t.libs << "lib"
|
@@ -22,9 +24,9 @@ end
|
|
22
24
|
# rdoc tasks
|
23
25
|
require 'rdoc/task'
|
24
26
|
RDoc::Task.new do |rd|
|
25
|
-
rd.main = "README.
|
27
|
+
rd.main = "README.md"
|
26
28
|
rd.title = 'acts_as_textcaptcha'
|
27
29
|
rd.rdoc_dir = 'doc'
|
28
30
|
rd.options << "--all"
|
29
|
-
rd.rdoc_files.include("README.
|
31
|
+
rd.rdoc_files.include("README.md", "LICENSE.txt", "lib/**/*.rb")
|
30
32
|
end
|
data/acts_as_textcaptcha.gemspec
CHANGED
@@ -31,7 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
s.require_paths = ["lib"]
|
32
32
|
|
33
33
|
# always test against latest rails version
|
34
|
-
s.add_development_dependency('rails', '~>
|
34
|
+
s.add_development_dependency('rails', '~> 5.1.4')
|
35
35
|
|
36
36
|
s.add_development_dependency('mime-types')
|
37
37
|
s.add_development_dependency('bundler')
|
@@ -41,4 +41,5 @@ Gem::Specification.new do |s|
|
|
41
41
|
s.add_development_dependency('sqlite3')
|
42
42
|
s.add_development_dependency('webmock')
|
43
43
|
s.add_development_dependency('coveralls')
|
44
|
+
s.add_development_dependency('appraisal')
|
44
45
|
end
|
@@ -12,12 +12,9 @@ module ActsAsTextcaptcha
|
|
12
12
|
cattr_accessor :textcaptcha_config
|
13
13
|
attr_accessor :textcaptcha_question, :textcaptcha_answer, :textcaptcha_key
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
elsif respond_to?(:attr_accessible)
|
19
|
-
attr_accessible :textcaptcha_answer, :textcaptcha_key
|
20
|
-
end
|
15
|
+
# Rails 3, ensure these attrs are accessible
|
16
|
+
if respond_to?(:accessible_attributes) && respond_to?(:attr_accessible)
|
17
|
+
attr_accessible :textcaptcha_answer, :textcaptcha_key
|
21
18
|
end
|
22
19
|
|
23
20
|
validate :validate_textcaptcha, :if => :perform_textcaptcha?
|
data/test/test_helper.rb
CHANGED
@@ -2,6 +2,9 @@ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)+'./../lib/acts_as_tex
|
|
2
2
|
|
3
3
|
ENV['RAILS_ENV'] = 'test'
|
4
4
|
|
5
|
+
# ensure tmp dir exists
|
6
|
+
FileUtils.mkdir_p './tmp'
|
7
|
+
|
5
8
|
# confgure test coverage reporting
|
6
9
|
if ENV['COVERAGE']
|
7
10
|
require 'simplecov'
|
@@ -20,18 +23,20 @@ end
|
|
20
23
|
|
21
24
|
require 'minitest/autorun'
|
22
25
|
require 'webmock/minitest'
|
23
|
-
|
24
26
|
require 'rails/all'
|
25
|
-
|
26
27
|
require 'acts_as_textcaptcha'
|
27
28
|
require './test/test_models'
|
28
29
|
|
29
30
|
# load and initialize test db schema
|
30
|
-
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => 'tmp/
|
31
|
+
ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => 'tmp/acts_as_textcaptcha_test.sqlite3.db')
|
31
32
|
load(File.dirname(__FILE__) + "/schema.rb")
|
32
33
|
|
33
|
-
# initialize
|
34
|
-
Rails.
|
34
|
+
# initialize the Rails cache (use a basic memory store in tests)
|
35
|
+
if Rails.version >= '4'
|
36
|
+
Rails.cache = ActiveSupport::Cache::MemoryStore.new
|
37
|
+
else
|
38
|
+
RAILS_CACHE = ActiveSupport::Cache::MemoryStore.new
|
39
|
+
end
|
35
40
|
|
36
41
|
# additional helper methods for use in tests
|
37
42
|
def find_in_cache(key)
|
data/test/test_models.rb
CHANGED
@@ -1,34 +1,37 @@
|
|
1
1
|
# models for use in tests
|
2
|
+
class ApplicationRecord < ActiveRecord::Base
|
3
|
+
self.abstract_class = true
|
4
|
+
end
|
2
5
|
|
3
|
-
class Widget <
|
6
|
+
class Widget < ApplicationRecord
|
4
7
|
# uses textcaptcha.yml file for configuration
|
5
8
|
acts_as_textcaptcha
|
6
9
|
end
|
7
10
|
|
8
|
-
class Comment <
|
11
|
+
class Comment < ApplicationRecord
|
9
12
|
# inline options (symbol keys) with api_key only
|
10
13
|
acts_as_textcaptcha :api_key => '8u5ixtdnq9csc84cok0owswgo'
|
11
14
|
end
|
12
15
|
|
13
|
-
class FastComment <
|
16
|
+
class FastComment < ApplicationRecord
|
14
17
|
# inline options with super fast (0.006 seconds) cache expiry time
|
15
18
|
acts_as_textcaptcha :cache_expiry_minutes => '0.0001',
|
16
19
|
:questions => [{ :question => '1+1', :answers => '2,two' }]
|
17
20
|
end
|
18
21
|
|
19
|
-
class Review <
|
22
|
+
class Review < ApplicationRecord
|
20
23
|
# inline options with all possible options
|
21
24
|
acts_as_textcaptcha :api_key => '8u5ixtdnq9csc84cok0owswgo',
|
22
25
|
:questions => [{ :question => 'The green hat is what color?', :answers => 'green' }]
|
23
26
|
end
|
24
27
|
|
25
|
-
class MovieReview <
|
28
|
+
class MovieReview < ApplicationRecord
|
26
29
|
# inline options with all possible options
|
27
30
|
acts_as_textcaptcha 'api_key' => '8u5ixtdnq9csc84cok0owswgo',
|
28
31
|
'questions' => [{ 'Question' => 'The green hat is what color?', 'answers' => nil }]
|
29
32
|
end
|
30
33
|
|
31
|
-
class Note <
|
34
|
+
class Note < ApplicationRecord
|
32
35
|
# inline options (string keys) with user defined questions only (no textcaptcha service)
|
33
36
|
acts_as_textcaptcha 'questions' => [{ 'question' => '1+1', 'answers' => '2,two' }]
|
34
37
|
|
@@ -48,7 +51,7 @@ class Contact
|
|
48
51
|
acts_as_textcaptcha :questions => [{ :question => 'one+1', :answers => "2,two,апельсин" }]
|
49
52
|
end
|
50
53
|
|
51
|
-
class StrongAccessibleWidget <
|
54
|
+
class StrongAccessibleWidget < ApplicationRecord
|
52
55
|
|
53
56
|
# stub out attr_accessbile interface for testing
|
54
57
|
def self.accessible_attributes(role = :default); end
|
@@ -30,17 +30,17 @@ describe 'TextcaptchaApi' do
|
|
30
30
|
URI::InvalidURIError
|
31
31
|
].each do |error|
|
32
32
|
stub_request(:get, "http://textcaptcha.com/api/xyz").to_raise(error)
|
33
|
-
ActsAsTextcaptcha::TextcaptchaApi.fetch('xyz')
|
33
|
+
assert_nil ActsAsTextcaptcha::TextcaptchaApi.fetch('xyz')
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
it 'should return nil when body cannot be parsed as XML' do
|
38
38
|
stub_request(:get, "http://textcaptcha.com/api/jibber").to_return(:body => 'here be gibberish')
|
39
|
-
ActsAsTextcaptcha::TextcaptchaApi.fetch('jibber')
|
39
|
+
assert_nil ActsAsTextcaptcha::TextcaptchaApi.fetch('jibber')
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'should return nil when body is empty' do
|
43
43
|
stub_request(:get, "http://textcaptcha.com/api/empty").to_return(:body => '')
|
44
|
-
ActsAsTextcaptcha::TextcaptchaApi.fetch('empty')
|
44
|
+
assert_nil ActsAsTextcaptcha::TextcaptchaApi.fetch('empty')
|
45
45
|
end
|
46
46
|
end
|
@@ -36,8 +36,8 @@ describe 'TextcaptchaHelper' do
|
|
36
36
|
html = render_template
|
37
37
|
|
38
38
|
assert_match(/\<label for\=\"note_textcaptcha_answer\"\>1\+1\<\/label\>/, html)
|
39
|
-
assert_match(/\<input
|
40
|
-
assert_match(/\<input
|
39
|
+
assert_match(/\<input(.*)name\=\"note\[textcaptcha_answer\]\"(.*)\/\>/, html)
|
40
|
+
assert_match(/\<input(.*)name\=\"note\[textcaptcha_key\]\"(.*)\/\>/, html)
|
41
41
|
end
|
42
42
|
|
43
43
|
it 'should render hidden answer and textcaptcha_key when only answer is present' do
|
@@ -46,8 +46,8 @@ describe 'TextcaptchaHelper' do
|
|
46
46
|
html = render_template
|
47
47
|
|
48
48
|
refute_match(/\<label for\=\"note_textcaptcha_answer\"\>1\+1\<\/label\>/, html)
|
49
|
-
assert_match(/\<input
|
50
|
-
assert_match(/\<input
|
49
|
+
assert_match(/\<input(.*)name\=\"note\[textcaptcha_answer\]\"(.*)\/\>/, html)
|
50
|
+
assert_match(/\<input(.*)name\=\"note\[textcaptcha_key\]\"(.*)\/\>/, html)
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'should not render any question or answer when perform_textcaptcha? is false' do
|
data/test/textcaptcha_test.rb
CHANGED
@@ -131,8 +131,8 @@ describe 'Textcaptcha' do
|
|
131
131
|
|
132
132
|
stub_request(:get, %r{http://textcaptcha.com/api/}).to_raise(SocketError)
|
133
133
|
@comment.textcaptcha
|
134
|
-
@comment.textcaptcha_question
|
135
|
-
@comment.textcaptcha_key
|
134
|
+
assert_nil @comment.textcaptcha_question
|
135
|
+
assert_nil @comment.textcaptcha_key
|
136
136
|
end
|
137
137
|
|
138
138
|
it 'should not generate any question or answer when user defined questions set incorrectly' do
|
@@ -140,8 +140,8 @@ describe 'Textcaptcha' do
|
|
140
140
|
|
141
141
|
stub_request(:get, %r{http://textcaptcha.com/api/}).to_raise(SocketError)
|
142
142
|
@comment.textcaptcha
|
143
|
-
@comment.textcaptcha_question
|
144
|
-
@comment.textcaptcha_key
|
143
|
+
assert_nil @comment.textcaptcha_question
|
144
|
+
assert_nil @comment.textcaptcha_key
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_textcaptcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Hutchinson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.1.4
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 5.1.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: mime-types
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,6 +136,20 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: appraisal
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
139
153
|
description: |-
|
140
154
|
Simple question/answer based spam protection for your Rails models.
|
141
155
|
You can define your own logic questions and/or fetch questions from the textcaptcha.com API.
|
@@ -150,6 +164,7 @@ files:
|
|
150
164
|
- ".coveralls.yml"
|
151
165
|
- ".gitignore"
|
152
166
|
- ".travis.yml"
|
167
|
+
- Appraisals
|
153
168
|
- CHANGELOG.md
|
154
169
|
- CODE_OF_CONDUCT.md
|
155
170
|
- CONTRIBUTING.md
|
@@ -160,7 +175,9 @@ files:
|
|
160
175
|
- acts_as_textcaptcha.gemspec
|
161
176
|
- bin/console
|
162
177
|
- config/textcaptcha.yml
|
163
|
-
-
|
178
|
+
- gemfiles/rails_3.gemfile
|
179
|
+
- gemfiles/rails_4.gemfile
|
180
|
+
- gemfiles/rails_5.gemfile
|
164
181
|
- lib/acts_as_textcaptcha.rb
|
165
182
|
- lib/acts_as_textcaptcha/framework/rails.rb
|
166
183
|
- lib/acts_as_textcaptcha/textcaptcha.rb
|
@@ -197,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
214
|
version: '0'
|
198
215
|
requirements: []
|
199
216
|
rubyforge_project:
|
200
|
-
rubygems_version: 2.
|
217
|
+
rubygems_version: 2.7.3
|
201
218
|
signing_key:
|
202
219
|
specification_version: 4
|
203
220
|
summary: Spam protection for your models via logic questions and the textcaptcha.com
|
data/init.rb
DELETED