acts_as_textcaptcha 4.1.3 → 4.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.
- 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
|
[](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
|
+
[](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