acts_as_textcaptcha 4.3.0 → 4.4.1

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.
@@ -1,34 +1,31 @@
1
- # A simple cache for storing Textcaptcha answers
2
- # by default the underlying cache implementation is
3
- # the standard Rails.cache (ActiveSupport::Cache)
1
+ # A simple cache for storing Textcaptcha answers, Rails.cache is used as the
2
+ # backend (ActiveSupport::Cache)
4
3
 
5
4
  module ActsAsTextcaptcha
6
5
  class TextcaptchaCache
7
6
 
8
- CACHE_KEY_PREFIX = 'acts_as_textcaptcha-'
9
- DEFAULT_CACHE_EXPIRY_MINUTES = 10
7
+ KEY_PREFIX = 'acts_as_textcaptcha-'
8
+ DEFAULT_EXPIRY_MINUTES = 10
10
9
 
11
10
  def write(key, value, options = {})
12
11
  unless options.has_key?(:expires_in)
13
- options[:expires_in] = DEFAULT_CACHE_EXPIRY_MINUTES.minutes
12
+ options[:expires_in] = DEFAULT_EXPIRY_MINUTES.minutes
14
13
  end
15
14
  Rails.cache.write(cache_key(key), value, options)
16
15
  end
17
16
 
18
- def read(key, options = nil)
19
- Rails.cache.read(cache_key(key), options)
17
+ def read(key)
18
+ Rails.cache.read(cache_key(key))
20
19
  end
21
20
 
22
- def delete(key, options = nil)
23
- Rails.cache.delete(cache_key(key), options)
21
+ def delete(key)
22
+ Rails.cache.delete(cache_key(key))
24
23
  end
25
24
 
26
25
  private
27
26
 
28
- # since this cache may be shared with other objects
29
- # a prefix is used in all cache keys
30
- def cache_key(key)
31
- "#{CACHE_KEY_PREFIX}#{key}"
32
- end
27
+ def cache_key(key)
28
+ "#{KEY_PREFIX}#{key}"
29
+ end
33
30
  end
34
31
  end
@@ -1,7 +1,11 @@
1
+ module ActsAsTextcaptcha
2
+ class TextcaptchaConfig
3
+
4
+ YAML = <<-CONFIG
1
5
  development: &common_settings
2
- api_key: PASTE_YOUR_TEXTCAPCHA_API_KEY_HERE # grab one from http://textcaptcha.com/api
3
- http_read_timeout: 60 # Optional seconds to wait for one block to be read from http://textcaptcha.com/api
4
- # http_open_timeout: 10 # Optional seconds to wait for the connection to open
6
+ api_key: 'TEXTCAPTCHA_API_IDENT' # see http://textcaptcha.com for details
7
+ # api_endpoint: nil # Optional API URL to fetch questions and answers from
8
+ # raise_errors: false # Optional flag, if true errors will be raised if the API endpoint fails
5
9
  # cache_expiry_minutes: 10 # Optional minutes for captcha answers to persist in the cache (default 10 minutes)
6
10
 
7
11
  questions:
@@ -28,7 +32,15 @@ development: &common_settings
28
32
 
29
33
  test:
30
34
  <<: *common_settings
31
- api_key: 6eh1co0j12mi2ogcoggkkok4o
35
+ api_key: 'TEST_TEXTCAPTCHA_API_IDENT'
32
36
 
33
37
  production:
34
38
  <<: *common_settings
39
+ CONFIG
40
+
41
+ def self.create(path: './config/textcaptcha.yml')
42
+ FileUtils.mkdir_p(File.dirname(path))
43
+ File.open(path, 'w') { |f| f.write(YAML) }
44
+ end
45
+ end
46
+ end
@@ -1,22 +1,22 @@
1
1
  module ActsAsTextcaptcha
2
2
  module TextcaptchaHelper
3
3
 
4
- # builds html form fields for the textcaptcha
5
4
  def textcaptcha_fields(f, &block)
6
- model = f.object
7
- captcha_html = ''
8
- if model.perform_textcaptcha?
9
- if model.textcaptcha_key
10
- captcha_html += f.hidden_field(:textcaptcha_key)
11
- if model.textcaptcha_question
12
- captcha_html += capture(&block)
13
- elsif model.textcaptcha_answer
14
- captcha_html += f.hidden_field(:textcaptcha_answer)
15
- end
16
- end
5
+ if f.object.perform_textcaptcha? && f.object.textcaptcha_key
6
+ build_textcaptcha_form_elements(f, &block)
17
7
  end
18
-
19
- captcha_html.html_safe
20
8
  end
9
+
10
+ private
11
+
12
+ def build_textcaptcha_form_elements(f, &block)
13
+ captcha_html = f.hidden_field(:textcaptcha_key)
14
+ if f.object.textcaptcha_question
15
+ captcha_html += capture(&block)
16
+ elsif f.object.textcaptcha_answer
17
+ captcha_html += f.hidden_field(:textcaptcha_answer)
18
+ end
19
+ captcha_html.html_safe
20
+ end
21
21
  end
22
22
  end
@@ -1,3 +1,3 @@
1
1
  module ActsAsTextcaptcha
2
- VERSION = "4.3.0"
2
+ VERSION = '4.4.1'
3
3
  end
@@ -1,21 +1,16 @@
1
+ require 'rails'
2
+ require 'acts_as_textcaptcha/textcaptcha_config'
3
+
1
4
  namespace :textcaptcha do
2
5
 
3
- desc "Creates a template config file in config/textcaptcha.yml"
6
+ desc "Creates an example textcaptcha config at config/textcaptcha.yml"
4
7
  task :config do
5
- src = File.join(File.dirname(__FILE__), '../..', 'config', 'textcaptcha.yml')
6
- dest = File.join(Rails.root, 'config', 'textcaptcha.yml')
7
- if File.exist?(dest)
8
- puts "\nOoops, a textcaptcha config file at #{dest} already exists ... aborting.\n\n"
8
+ path = File.join((Rails.root ? Rails.root : '.'), 'config', 'textcaptcha.yml')
9
+ if File.exist?(path)
10
+ puts "Ooops, a textcaptcha config file at #{path} already exists ... aborting."
9
11
  else
10
- config = ''
11
- f = File.open(src, 'r')
12
- f.each_line { |line| config += line }
13
- config.gsub!(/ api_key:(.*)# for gem test purposes only$/, " api_key: PASTE_YOUR_TEXTCAPCHA_API_KEY_HERE")
14
-
15
- f = File.new(dest, 'w')
16
- f.write(config)
17
- f.close
18
- puts "\ntextcaptcha.yml generated at #{dest}\nNOTE: edit this file and add your textcaptcha api key, grab one from http://textcaptcha.com/api\n\n"
12
+ ActsAsTextcaptcha::TextcaptchaConfig.create(path: path)
13
+ puts "Done, config generated at #{path}\nEdit this file to add your TextCaptcha API key (see http://textcaptcha.com)."
19
14
  end
20
15
  end
21
16
  end
metadata CHANGED
@@ -1,31 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_textcaptcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Hutchinson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-18 00:00:00.000000000 Z
11
+ date: 2018-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rails
14
+ name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 5.1.4
19
+ version: '0'
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: 5.1.4
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: mime-types
28
+ name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: bundler
42
+ name: pry-byebug
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: minitest
56
+ name: rdoc
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rdoc
70
+ name: minitest
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 5.2.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 5.2.0
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: sqlite3
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +122,20 @@ dependencies:
108
122
  - - ">="
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
111
139
  - !ruby/object:Gem::Dependency
112
140
  name: appraisal
113
141
  requirement: !ruby/object:Gem::Requirement
@@ -122,56 +150,62 @@ dependencies:
122
150
  - - ">="
123
151
  - !ruby/object:Gem::Version
124
152
  version: '0'
125
- description: |-
126
- Simple question/answer based spam protection for your Rails models.
127
- You can define your own logic questions and/or fetch questions from the textcaptcha.com API.
128
- The questions involve human logic and are tough for spam bots to crack.
129
- For more reasons on why logic questions are a good idea visit; http://textcaptcha.com/why
153
+ description: |2
154
+ ActsAsTextcaptcha provides spam protection for Rails models with a text-based
155
+ logic question captcha. Questions are fetched from Rob Tuley's textcaptcha.com
156
+ They can be solved easily by humans but are tough for robots to crack. For
157
+ reasons on why logic based captchas are a good idea visit textcaptcha.com
130
158
  email:
131
159
  - matt@hiddenloop.com
132
160
  executables: []
133
161
  extensions: []
134
- extra_rdoc_files: []
162
+ extra_rdoc_files:
163
+ - README.md
164
+ - LICENSE
135
165
  files:
136
- - ".coveralls.yml"
137
166
  - ".gitignore"
167
+ - ".simplecov"
138
168
  - ".travis.yml"
139
169
  - Appraisals
140
170
  - CHANGELOG.md
141
171
  - CODE_OF_CONDUCT.md
142
172
  - CONTRIBUTING.md
143
173
  - Gemfile
144
- - LICENSE.txt
174
+ - LICENSE
145
175
  - README.md
146
176
  - Rakefile
147
177
  - acts_as_textcaptcha.gemspec
148
178
  - bin/console
149
- - config/textcaptcha.yml
179
+ - bin/setup
150
180
  - gemfiles/rails_3.gemfile
151
181
  - gemfiles/rails_4.gemfile
152
182
  - gemfiles/rails_5.gemfile
153
183
  - lib/acts_as_textcaptcha.rb
184
+ - lib/acts_as_textcaptcha/errors.rb
154
185
  - lib/acts_as_textcaptcha/framework/rails.rb
155
186
  - lib/acts_as_textcaptcha/textcaptcha.rb
156
187
  - lib/acts_as_textcaptcha/textcaptcha_api.rb
157
188
  - lib/acts_as_textcaptcha/textcaptcha_cache.rb
189
+ - lib/acts_as_textcaptcha/textcaptcha_config.rb
158
190
  - lib/acts_as_textcaptcha/textcaptcha_helper.rb
159
191
  - lib/acts_as_textcaptcha/version.rb
160
192
  - lib/tasks/textcaptcha.rake
161
- - test/schema.rb
162
- - test/test_helper.rb
163
- - test/test_models.rb
164
- - test/textcaptcha_api_test.rb
165
- - test/textcaptcha_cache_test.rb
166
- - test/textcaptcha_helper_test.rb
167
- - test/textcaptcha_test.rb
168
193
  homepage: http://github.com/matthutchinson/acts_as_textcaptcha
169
194
  licenses:
170
195
  - MIT
171
196
  metadata:
197
+ homepage_uri: https://github.com/matthutchinson/acts_as_textcaptcha
198
+ changelog_uri: https://github.com/matthutchinson/acts_as_textcaptcha/blob/master/CHANGELOG.md
199
+ source_code_uri: https://github.com/matthutchinson/acts_as_textcaptcha
200
+ bug_tracker_uri: https://github.com/matthutchinson/acts_as_textcaptcha/issues
172
201
  allowed_push_host: https://rubygems.org
173
202
  post_install_message:
174
- rdoc_options: []
203
+ rdoc_options:
204
+ - "--title"
205
+ - ActAsTextcaptcha
206
+ - "--main"
207
+ - README.md
208
+ - "-ri"
175
209
  require_paths:
176
210
  - lib
177
211
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -186,9 +220,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
186
220
  version: '0'
187
221
  requirements: []
188
222
  rubyforge_project:
189
- rubygems_version: 2.7.3
223
+ rubygems_version: 2.7.6
190
224
  signing_key:
191
225
  specification_version: 4
192
- summary: Spam protection for your models via logic questions and the textcaptcha.com
193
- API
226
+ summary: A text-based logic question captcha for Rails
194
227
  test_files: []
data/.coveralls.yml DELETED
@@ -1 +0,0 @@
1
- service_name: travis-ci
data/LICENSE.txt DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2016 Matthew Hutchinson
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
data/test/schema.rb DELETED
@@ -1,34 +0,0 @@
1
- ActiveRecord::Schema.define(:version => 0) do
2
-
3
- create_table :widgets, :force => true do |t|
4
- t.string :name
5
- end
6
-
7
- create_table :comments, :force => true do |t|
8
- t.string :name
9
- end
10
-
11
- create_table :fast_comments, :force => true do |t|
12
- t.string :name
13
- end
14
-
15
- create_table :reviews, :force => true do |t|
16
- t.string :name
17
- end
18
-
19
- create_table :movie_reviews, :force => true do |t|
20
- t.string :name
21
- end
22
-
23
- create_table :notes, :force => true do |t|
24
- t.string :name
25
- end
26
-
27
- create_table :strong_protected_widgets, :force => true do |t|
28
- t.string :name
29
- end
30
-
31
- create_table :strong_accessible_widgets, :force => true do |t|
32
- t.string :name
33
- end
34
- end
data/test/test_helper.rb DELETED
@@ -1,28 +0,0 @@
1
- $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__)+'./../lib/acts_as_textcaptcha'))
2
-
3
- ENV['RAILS_ENV'] = 'test'
4
-
5
- # ensure tmp dir exists
6
- FileUtils.mkdir_p './tmp'
7
-
8
- require 'minitest/autorun'
9
- require 'webmock/minitest'
10
- require 'rails/all'
11
- require 'acts_as_textcaptcha'
12
- require './test/test_models'
13
-
14
- # load and initialize test db schema
15
- ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => 'tmp/acts_as_textcaptcha_test.sqlite3.db')
16
- load(File.dirname(__FILE__) + "/schema.rb")
17
-
18
- # initialize the Rails cache (use a basic memory store in tests)
19
- if Rails.version >= '4'
20
- Rails.cache = ActiveSupport::Cache::MemoryStore.new
21
- else
22
- RAILS_CACHE = ActiveSupport::Cache::MemoryStore.new
23
- end
24
-
25
- # additional helper methods for use in tests
26
- def find_in_cache(key)
27
- Rails.cache.read("#{ActsAsTextcaptcha::TextcaptchaCache::CACHE_KEY_PREFIX}#{key}")
28
- end
data/test/test_models.rb DELETED
@@ -1,69 +0,0 @@
1
- # models for use in tests
2
- class ApplicationRecord < ActiveRecord::Base
3
- self.abstract_class = true
4
- end
5
-
6
- class Widget < ApplicationRecord
7
- # uses textcaptcha.yml file for configuration
8
- acts_as_textcaptcha
9
- end
10
-
11
- class Comment < ApplicationRecord
12
- # inline options (symbol keys) with api_key only
13
- acts_as_textcaptcha :api_key => '8u5ixtdnq9csc84cok0owswgo'
14
- end
15
-
16
- class FastComment < ApplicationRecord
17
- # inline options with super fast (0.006 seconds) cache expiry time
18
- acts_as_textcaptcha :cache_expiry_minutes => '0.0001',
19
- :questions => [{ :question => '1+1', :answers => '2,two' }]
20
- end
21
-
22
- class Review < ApplicationRecord
23
- # inline options with all possible options
24
- acts_as_textcaptcha :api_key => '8u5ixtdnq9csc84cok0owswgo',
25
- :questions => [{ :question => 'The green hat is what color?', :answers => 'green' }]
26
- end
27
-
28
- class MovieReview < ApplicationRecord
29
- # inline options with all possible options
30
- acts_as_textcaptcha 'api_key' => '8u5ixtdnq9csc84cok0owswgo',
31
- 'questions' => [{ 'Question' => 'The green hat is what color?', 'answers' => nil }]
32
- end
33
-
34
- class Note < ApplicationRecord
35
- # inline options (string keys) with user defined questions only (no textcaptcha service)
36
- acts_as_textcaptcha 'questions' => [{ 'question' => '1+1', 'answers' => '2,two' }]
37
-
38
- # allows toggling perform_textcaptcha on/off (default on)
39
- attr_accessor :turn_off_captcha
40
-
41
- def perform_textcaptcha?
42
- super && !turn_off_captcha
43
- end
44
- end
45
-
46
- class Contact
47
- # non active record object (symbol keys), no API used
48
- include ActiveModel::Validations
49
- include ActiveModel::Conversion
50
- extend ActsAsTextcaptcha::Textcaptcha
51
- acts_as_textcaptcha :questions => [{ :question => 'one+1', :answers => "2,two,апельсин" }]
52
- end
53
-
54
- class StrongAccessibleWidget < ApplicationRecord
55
-
56
- # stub out attr_accessbile interface for testing
57
- def self.accessible_attributes(role = :default); end
58
- def self.attr_accessible(*args); end
59
-
60
- acts_as_textcaptcha 'questions' => [{ 'question' => '1+1', 'answers' => '2,two' }]
61
- end
62
-
63
- class StrongProtectedWidget < StrongAccessibleWidget
64
-
65
- # stub out attr_protected interface for testing
66
- def self.attr_protected(*args); end
67
-
68
- acts_as_textcaptcha 'questions' => [{ 'question' => '1+1', 'answers' => '2,two' }]
69
- end