text_captcha 0.1.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d57f8ace78c88533691793609e4c8eec9f58647f
4
+ data.tar.gz: f57600a6f64133c5ba96b0a7b77beb632df63ac0
5
+ SHA512:
6
+ metadata.gz: b5de6360d50cceb40aacdb905f92d58ff251503226dc09e99a6d062a462bcc604ccaae6bae51de2cf917b154b67e51ddf67cd2f377624cd0fa94f760312f3b66
7
+ data.tar.gz: e1a833c5aa417185d282b74bc456ec856e86b01715466cd569b75cf40795f307e2663b21b733875527d758ce7eb31000e70ec1a76681be4b1ec50627e4d0436c
@@ -0,0 +1,5 @@
1
+ pkg
2
+ coverage
3
+ doc
4
+ .rvmrc
5
+ *.lock
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ cache: bundler
3
+ sudo: false
4
+ rvm:
5
+ - 2.3.0
6
+ - '2.2'
7
+ - '2.1'
8
+ notifications:
9
+ email: false
10
+ env:
11
+ global:
12
+ secure: Q1B+y6yPsyU3RhiUDMnCLk1a4AsDsokB1Q22CHCe6ftp1JkLFUjaFNg6Ayzq+lIwxmtXx0drM5Otf+A/ayT2CagQQf0ImpOpTjHtMiYYuwbvhgV3fYFdd2KsFP/mjJiRjwX7j3ES9bm0SrItgaZ3WGA9DwOOn8rgxo+AlUI7bYA=
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source "https://rubygems.org"
2
+ gemspec
@@ -0,0 +1,157 @@
1
+ # TextCaptcha
2
+
3
+ [![Travis-CI](https://travis-ci.org/fnando/text_captcha.png)](https://travis-ci.org/fnando/text_captcha)
4
+ [![Code Climate](https://codeclimate.com/github/fnando/text_captcha/badges/gpa.svg)](https://codeclimate.com/github/fnando/text_captcha)
5
+ [![Test Coverage](https://codeclimate.com/github/fnando/text_captcha/badges/coverage.svg)](https://codeclimate.com/github/fnando/text_captcha/coverage)
6
+ [![Gem](https://img.shields.io/gem/v/text_captcha.svg)](https://rubygems.org/gems/text_captcha)
7
+ [![Gem](https://img.shields.io/gem/dt/text_captcha.svg)](https://rubygems.org/gems/text_captcha)
8
+
9
+ A captcha verification for Rails apps, directly integrated into ActiveModel/ActiveRecord.
10
+
11
+ ## Installation
12
+
13
+ Just run
14
+
15
+ gem install text_captcha
16
+
17
+ ## Usage
18
+
19
+ Just add the validation to your model.
20
+
21
+ ```ruby
22
+ class Comment < ActiveRecord::Base
23
+ validates_captcha
24
+ end
25
+ ```
26
+
27
+ By default the `{:on => :create}` option will be used. You can provide any other option you want.
28
+
29
+ ```ruby
30
+ class Comment < ActiveRecord::Base
31
+ validates_captcha :if => :new_record?
32
+ end
33
+
34
+ @comment = Comment.new
35
+
36
+ @comment.challenge
37
+ #=> The color of a red T-shirt is?
38
+
39
+ @comment.challenge_answer = "red"
40
+ @comment.valid?
41
+ #=> true
42
+ ```
43
+
44
+ Note that you can answer the question without worrying about uppercase/lowercase. All strings are normalized before the comparison. So "ReD", "RED" or "red" will
45
+ pass the validation.
46
+
47
+ You can use TextCaptcha with a non-ActiveRecord class. You just need to include the `TextCaptcha::Validation` module.
48
+
49
+ ```ruby
50
+ class Comment
51
+ include ActiveModel::Validations
52
+ include TextCaptcha::Validation
53
+
54
+ validates_captcha
55
+ end
56
+
57
+ @comment = Comment.new
58
+ @comment.valid?
59
+ #=> false
60
+
61
+ @comment.errors[:challenge_answer]
62
+ #=> ["is not a valid answer"]
63
+ ```
64
+
65
+ You can disable TextCaptcha without having to remove all validations.
66
+ This is specially good when running tests.
67
+
68
+ ```ruby
69
+ TextCaptcha.enabled = false
70
+
71
+ class Comment
72
+ include ActiveModel::Validations
73
+ include TextCaptcha::Validation
74
+
75
+ validates_captcha
76
+ end
77
+
78
+ @comment = Comment.new
79
+ @comment.valid?
80
+ #=> true
81
+ ```
82
+
83
+ ### Creating a form
84
+
85
+ First, define the encryption key; this will be used to generate an encrypted version of the challenge id.
86
+
87
+ ```ruby
88
+ # config/initializers/text_captcha.rb
89
+ TextCaptcha.encryption_key = "SOME VALUE"
90
+ ```
91
+
92
+ Then you can create your form. I'm using an `User` model, which may have just a call to `validates_captcha` and an instance of it under the `@user` variable on the controller.
93
+
94
+ ```erb
95
+ <%= form_for @user do |f| %>
96
+ <!-- other fields, etc, etc, etc -->
97
+
98
+ <!-- this is important -->
99
+ <%= f.hidden_field :encrypted_challenge_id %>
100
+
101
+ <%= f.submit %>
102
+ <% end %>
103
+ ```
104
+
105
+ And your controller may be something like this:
106
+
107
+ ```ruby
108
+ class UsersController < ApplicationController
109
+ def new
110
+ @user = User.new
111
+ end
112
+
113
+ def create
114
+ @user = User.new(user_params)
115
+
116
+ if @user.save
117
+ # do something
118
+ else
119
+ render :new
120
+ end
121
+ end
122
+
123
+ private
124
+
125
+ def user_params
126
+ params.require(:user)
127
+ .permit(:name, :email, :password, :encrypted_challenge_id)
128
+ end
129
+ end
130
+ ```
131
+
132
+ ### I18n
133
+
134
+ To set the error message, just define the following scope:
135
+
136
+ ```yaml
137
+ en:
138
+ errors:
139
+ messages:
140
+ invalid_challenge_answer: "is invalid"
141
+ ```
142
+
143
+ ## To-Do
144
+
145
+ * Add more questions.
146
+
147
+ ## License
148
+
149
+ (The MIT License)
150
+
151
+ Copyright © 2010 - Nando Vieira - http://nandovieira.com
152
+
153
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
154
+
155
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
156
+
157
+ THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile CHANGED
@@ -1,48 +1,10 @@
1
- require "rcov/rcovtask"
1
+ require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
- require "rake/rdoctask"
4
- require "lib/text_captcha/version"
5
3
 
6
- Rcov::RcovTask.new do |t|
7
- t.test_files = FileList["test/**/*_test.rb"]
8
- t.rcov_opts = ["--sort coverage", "--exclude .gem"]
9
-
10
- t.output_dir = "coverage"
11
- t.libs << "test"
12
- t.verbose = true
13
- end
14
-
15
- Rake::TestTask.new do |t|
16
- t.libs << "lib"
4
+ Rake::TestTask.new(:test) do |t|
17
5
  t.libs << "test"
18
6
  t.test_files = FileList["test/**/*_test.rb"]
19
- t.verbose = true
20
- t.ruby_opts = %w[-rubygems]
7
+ t.warning = false
21
8
  end
22
9
 
23
- Rake::RDocTask.new do |rdoc|
24
- rdoc.main = "README.rdoc"
25
- rdoc.rdoc_dir = "doc"
26
- rdoc.title = "TextCaptcha API"
27
- rdoc.options += %w[ --line-numbers --inline-source --charset utf-8 ]
28
- rdoc.rdoc_files.include("README.rdoc")
29
- rdoc.rdoc_files.include("lib/**/*.rb")
30
- end
31
-
32
- begin
33
- require "jeweler"
34
-
35
- Jeweler::Tasks.new do |gem|
36
- gem.name = "text_captcha"
37
- gem.email = "fnando.vieira@gmail.com"
38
- gem.homepage = "http://github.com/fnando/text_captcha"
39
- gem.authors = ["Nando Vieira"]
40
- gem.version = TextCaptcha::Version::STRING
41
- gem.summary = "Simple captcha based on plain text questions."
42
- gem.files = FileList["README.rdoc", "{lib,test,locales}/**/*", "Rakefile"]
43
- end
44
-
45
- Jeweler::GemcutterTasks.new
46
- rescue LoadError => e
47
- puts "You need to install jeweler to build this gem."
48
- end
10
+ task default: :test
@@ -1,9 +1,8 @@
1
- require "active_record"
2
- require "active_support/all"
1
+ require "active_model"
3
2
 
4
3
  module TextCaptcha
5
- autoload :Validation, "text_captcha/validation"
6
- autoload :Version, "text_captcha/version"
4
+ require "text_captcha/validation"
5
+ require "text_captcha/version"
7
6
 
8
7
  class << self
9
8
  # You can disable TextCaptcha without having to remove all validations.
@@ -23,11 +22,24 @@ module TextCaptcha
23
22
  # #=> true
24
23
  #
25
24
  attr_accessor :enabled
25
+
26
+ # Set the encryption key.
27
+ # This value will be used to generate an encrypted challenge id.
28
+ attr_accessor :encryption_key
26
29
  end
27
30
 
28
31
  # TextCaptcha is enabled by default
29
32
  self.enabled = true
30
33
 
34
+ # Set a random key by default. This may invalidate loaded
35
+ # forms when restarting the server, but it's not a big problem.
36
+ self.encryption_key = nil
37
+
31
38
  I18n.load_path += Dir[File.dirname(__FILE__) + "/../locales/**/*.yml"]
32
- ::ActiveRecord::Base.send :include, TextCaptcha::Validation
39
+
40
+ begin
41
+ require "active_record"
42
+ ::ActiveRecord::Base.send :include, TextCaptcha::Validation
43
+ rescue LoadError
44
+ end
33
45
  end
@@ -26,7 +26,7 @@ module TextCaptcha
26
26
  # @comment = Comment.new
27
27
  #
28
28
  # @comment.challenge
29
- # #=> The colour of a red T-shirt is?
29
+ # #=> The color of a red T-shirt is?
30
30
  #
31
31
  # @comment.challenge_answer = "red"
32
32
  # @comment.valid?
@@ -51,7 +51,7 @@ module TextCaptcha
51
51
  # #=> false
52
52
  #
53
53
  # @comment.errors[:challenge_answer]
54
- # #=> ["You need to answer the anti-spam question."]
54
+ # #=> ["is not a valid answer"]
55
55
  #
56
56
  #
57
57
  def validates_captcha(options = {})
@@ -62,7 +62,7 @@ module TextCaptcha
62
62
  # Otherwise, validations won't run because regular classes don't
63
63
  # have save new record status.
64
64
  if self.ancestors.include?(::ActiveRecord::Base)
65
- options.reverse_merge!(:on => :create)
65
+ options.reverse_merge!(on: :create)
66
66
  end
67
67
 
68
68
  validate :check_challenge_answer, options
@@ -85,8 +85,23 @@ module TextCaptcha
85
85
  current_challenge.last
86
86
  end
87
87
 
88
- # Return the question id. If none is assigned it chooses on
89
- # randomly.
88
+ # Return an encrypted challenge id.
89
+ # This is useful to add to a form.
90
+ def encrypted_challenge_id
91
+ ActiveSupport::MessageEncryptor
92
+ .new(text_captcha_encryption_key)
93
+ .encrypt_and_sign(challenge_id.to_s)
94
+ end
95
+
96
+ # Assign decrypted challenge id.
97
+ def encrypted_challenge_id=(encrypted_challenge_id)
98
+ @challenge_id = ActiveSupport::MessageEncryptor
99
+ .new(text_captcha_encryption_key)
100
+ .decrypt_and_verify(encrypted_challenge_id.to_s)
101
+ .to_i
102
+ end
103
+
104
+ # Return the question id. If none is assigned it chooses one randomly.
90
105
  def challenge_id
91
106
  @challenge_id ||= Kernel.rand(all_challenges.count)
92
107
  end
@@ -96,22 +111,23 @@ module TextCaptcha
96
111
  @all_challenges ||= I18n.t("text_captcha.challenges")
97
112
  end
98
113
 
99
- # Detect if the answer is correct. Will also return true if <tt>TextCaptcha.enabled</tt>
100
- # is set to <tt>false</tt>.
114
+ # Detect if the answer is correct. Will also return true if
115
+ # <tt>TextCaptcha.enabled</tt> is set to <tt>false</tt>.
101
116
  def valid_challenge_answer?
102
- return false unless current_challenge
103
117
  return true unless TextCaptcha.enabled
118
+ return false unless current_challenge
104
119
 
105
- answers = challenge_answers.collect {|a| to_captcha(a)}
120
+ answers = challenge_answers.map {|a| to_captcha(a)}
106
121
  !challenge_answer.blank? && answers.include?(to_captcha(challenge_answer))
107
122
  end
108
123
 
109
124
  private
125
+
110
126
  # Check if the answer is correct. Add an error to
111
127
  # <tt><:challenge_answer/tt> attribute otherwise.
112
128
  def check_challenge_answer
113
129
  unless valid_challenge_answer?
114
- errors.add(:challenge_answer, I18n.t("text_captcha.error_message"))
130
+ errors.add(:challenge_answer, :invalid_challenge_answer)
115
131
  end
116
132
  end
117
133
 
@@ -119,6 +135,12 @@ module TextCaptcha
119
135
  def to_captcha(str)
120
136
  str.to_s.squish.downcase
121
137
  end
138
+
139
+ # Return the encryption key.
140
+ def text_captcha_encryption_key
141
+ return TextCaptcha.encryption_key if TextCaptcha.encryption_key
142
+ raise ArgumentError, "no TextCaptcha.encryption_key defined"
143
+ end
122
144
  end
123
145
  end
124
146
  end
@@ -1,8 +1,8 @@
1
1
  module TextCaptcha
2
2
  module Version
3
- MAJOR = 0
4
- MINOR = 1
5
- PATCH = 1
3
+ MAJOR = 1
4
+ MINOR = 0
5
+ PATCH = 0
6
6
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
7
  end
8
8
  end
@@ -1,12 +1,15 @@
1
1
  en:
2
+ errors:
3
+ messages:
4
+ invalid_challenge_answer: "is not a valid answer"
5
+
2
6
  text_captcha:
3
- error_message: "You need to answer the anti-spam question."
4
7
  challenges:
5
- - - "The colour of a red T-shirt is?"
8
+ - - "The color of a red T-shirt is?"
6
9
  - ["red"]
7
10
  - - "What is two plus two?"
8
11
  - ["4", "four"]
9
- - - "Green, tracksuit or elephant: the colour is?"
12
+ - - "Green, tracksuit or elephant: the color is?"
10
13
  - ["green"]
11
- - - "The colour of a blue shark is?"
12
- - ["blue"]
14
+ - - "The color of a blue shark is?"
15
+ - ["blue"]
@@ -1,6 +1,9 @@
1
- pt: &PT
1
+ pt-BR:
2
+ errors:
3
+ messages:
4
+ invalid_challenge_answer: "está incorreta"
5
+
2
6
  text_captcha:
3
- error_message: "Você precisa responder a pergunta anti-spam corretamente."
4
7
  challenges:
5
8
  - - Quanto é 2 + 2?
6
9
  - ["4", "quatro"]
@@ -8,6 +11,3 @@ pt: &PT
8
11
  - ["domingo"]
9
12
  - - Quantas horas tem 1 dia?
10
13
  - ["24"]
11
-
12
- pt-BR:
13
- <<: *PT
@@ -1,8 +1,9 @@
1
- require "rubygems"
2
- gem "test-unit"
3
- require "test/unit"
4
- require "mocha"
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
5
3
 
4
+ require "bundler/setup"
5
+ require "minitest/utils"
6
+ require "minitest/autorun"
6
7
  require "text_captcha"
7
8
 
8
9
  ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
@@ -5,7 +5,7 @@ class User < ActiveRecord::Base
5
5
  end
6
6
 
7
7
  class Account < ActiveRecord::Base
8
- validates_captcha :on => :save
8
+ validates_captcha :if => :new_record?
9
9
  end
10
10
 
11
11
  class Comment
@@ -15,7 +15,7 @@ class Comment
15
15
  validates_captcha
16
16
  end
17
17
 
18
- class TextCaptchaTest < Test::Unit::TestCase
18
+ class TextCaptchaTest < Minitest::Test
19
19
  def setup
20
20
  I18n.locale = :en
21
21
  TextCaptcha.enabled = true
@@ -29,6 +29,7 @@ class TextCaptchaTest < Test::Unit::TestCase
29
29
 
30
30
  def test_skip_captcha_validation_when_is_disabled
31
31
  TextCaptcha.enabled = false
32
+ @user.challenge_answer = nil
32
33
  assert @user.valid?
33
34
  end
34
35
 
@@ -54,12 +55,12 @@ class TextCaptchaTest < Test::Unit::TestCase
54
55
  end
55
56
 
56
57
  def test_return_challenge
57
- assert_not_nil @user.challenge
58
+ assert @user.challenge
58
59
  end
59
60
 
60
61
  def test_require_captcha_answer
61
- assert !@user.valid?
62
- assert_equal I18n.t("text_captcha.error_message"), @user.errors[:challenge_answer].to_s
62
+ refute @user.valid?
63
+ assert @user.errors[:challenge_answer].include?(I18n.t("errors.messages.invalid_challenge_answer"))
63
64
  end
64
65
 
65
66
  def test_accept_valid_answer
@@ -73,21 +74,40 @@ class TextCaptchaTest < Test::Unit::TestCase
73
74
  assert @user.valid?
74
75
  end
75
76
 
76
- def test_respect_on_save_option
77
+ def test_respect_if_option
77
78
  @account.challenge_answer = @account.challenge_answers.first
78
79
  assert @account.save
79
80
 
80
81
  @account.challenge_answer = nil
81
82
  @account.challenge_id = nil
82
83
 
83
- assert !@account.valid?
84
- assert_equal I18n.t("text_captcha.error_message"), @account.errors[:challenge_answer].to_s
84
+ assert @account.valid?
85
85
  end
86
86
 
87
87
  def test_extend_any_object
88
88
  @comment = Comment.new
89
- assert_not_nil @comment.challenge
90
- assert !@comment.valid?
91
- assert_equal I18n.t("text_captcha.error_message"), @comment.errors[:challenge_answer].to_s
89
+ assert @comment.challenge
90
+ refute @comment.valid?
91
+ assert @comment.errors[:challenge_answer].include?(I18n.t("errors.messages.invalid_challenge_answer"))
92
+ end
93
+
94
+ def test_return_encrypted_key
95
+ TextCaptcha.encryption_key = SecureRandom.hex(50)
96
+
97
+ @comment = Comment.new
98
+ challenge_id = @comment.challenge_id
99
+ encrypted_id = @comment.encrypted_challenge_id
100
+
101
+ refute_equal challenge_id, encrypted_id
102
+
103
+ @another_comment = Comment.new
104
+ @another_comment.encrypted_challenge_id = encrypted_id
105
+
106
+ assert_equal challenge_id, @another_comment.challenge_id
107
+ end
108
+
109
+ def test_raise_exception_when_have_no_encryption_key
110
+ TextCaptcha.encryption_key = nil
111
+ assert_raises(ArgumentError) { Comment.new.encrypted_challenge_id }
92
112
  end
93
113
  end
@@ -0,0 +1,28 @@
1
+ require "./lib/text_captcha/version"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.required_ruby_version = ">= 2.1.0"
5
+ spec.name = "text_captcha"
6
+ spec.version = TextCaptcha::Version::STRING
7
+ spec.authors = ["Nando Vieira"]
8
+ spec.email = ["fnando.vieira@gmail.com"]
9
+ spec.description = "Simple captcha based on plain text questions."
10
+ spec.summary = spec.description
11
+ spec.homepage = "http://github.com/fnando/text_captcha"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files`.split($/)
15
+ spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_dependency "activemodel"
20
+ spec.add_development_dependency "bundler", "~> 1.3"
21
+ spec.add_development_dependency "rake"
22
+ spec.add_development_dependency "minitest-utils"
23
+ spec.add_development_dependency "pry-meta"
24
+ spec.add_development_dependency "activerecord"
25
+ spec.add_development_dependency "sqlite3"
26
+ spec.add_development_dependency "mocha"
27
+ spec.add_development_dependency "codeclimate-test-reporter"
28
+ end
metadata CHANGED
@@ -1,79 +1,185 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: text_captcha
3
- version: !ruby/object:Gem::Version
4
- hash: 25
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 1
9
- - 1
10
- version: 0.1.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Nando Vieira
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2010-07-17 00:00:00 -03:00
19
- default_executable:
20
- dependencies: []
21
-
22
- description:
23
- email: fnando.vieira@gmail.com
11
+ date: 2016-04-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activemodel
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest-utils
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-meta
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activerecord
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: sqlite3
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: mocha
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: codeclimate-test-reporter
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'
139
+ description: Simple captcha based on plain text questions.
140
+ email:
141
+ - fnando.vieira@gmail.com
24
142
  executables: []
25
-
26
143
  extensions: []
27
-
28
- extra_rdoc_files:
29
- - README.rdoc
30
- files:
31
- - README.rdoc
144
+ extra_rdoc_files: []
145
+ files:
146
+ - ".gitignore"
147
+ - ".travis.yml"
148
+ - Gemfile
149
+ - README.md
32
150
  - Rakefile
33
151
  - lib/text_captcha.rb
34
- - lib/text_captcha/config.rb
35
152
  - lib/text_captcha/validation.rb
36
153
  - lib/text_captcha/version.rb
37
154
  - locales/en.yml
38
- - locales/pt.yml
39
- - test/config_test.rb
155
+ - locales/pt-BR.yml
40
156
  - test/test_helper.rb
41
- - test/text_captcha_test.rb
42
- has_rdoc: true
157
+ - test/text_captcha/text_captcha_test.rb
158
+ - text_captcha.gemspec
43
159
  homepage: http://github.com/fnando/text_captcha
44
- licenses: []
45
-
160
+ licenses:
161
+ - MIT
162
+ metadata: {}
46
163
  post_install_message:
47
- rdoc_options:
48
- - --charset=UTF-8
49
- require_paths:
164
+ rdoc_options: []
165
+ require_paths:
50
166
  - lib
51
- required_ruby_version: !ruby/object:Gem::Requirement
52
- none: false
53
- requirements:
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ requirements:
54
169
  - - ">="
55
- - !ruby/object:Gem::Version
56
- hash: 3
57
- segments:
58
- - 0
59
- version: "0"
60
- required_rubygems_version: !ruby/object:Gem::Requirement
61
- none: false
62
- requirements:
170
+ - !ruby/object:Gem::Version
171
+ version: 2.1.0
172
+ required_rubygems_version: !ruby/object:Gem::Requirement
173
+ requirements:
63
174
  - - ">="
64
- - !ruby/object:Gem::Version
65
- hash: 3
66
- segments:
67
- - 0
68
- version: "0"
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
69
177
  requirements: []
70
-
71
178
  rubyforge_project:
72
- rubygems_version: 1.3.7
179
+ rubygems_version: 2.5.1
73
180
  signing_key:
74
- specification_version: 3
181
+ specification_version: 4
75
182
  summary: Simple captcha based on plain text questions.
76
- test_files:
77
- - test/config_test.rb
183
+ test_files:
78
184
  - test/test_helper.rb
79
- - test/text_captcha_test.rb
185
+ - test/text_captcha/text_captcha_test.rb
@@ -1,89 +0,0 @@
1
- = TextCaptcha
2
-
3
- A captcha verification for Rails apps, directly integrated into ActiveRecord.
4
- It uses questions & answers instead of those ugly images.
5
-
6
- == Installation
7
-
8
- Just run
9
-
10
- gem install text_captcha
11
-
12
- == Usage
13
-
14
- Just add the validation to your model.
15
-
16
- class Comment < ActiveRecord::Base
17
- validates_captcha
18
- end
19
-
20
- By default the <tt>{:on => :create}</tt> option will be used. You can provide
21
- any other option you want.
22
-
23
- class Comment < ActiveRecord::Base
24
- validates_captcha :if => :new_record?
25
- end
26
-
27
- @comment = Comment.new
28
-
29
- @comment.challenge
30
- #=> The colour of a red T-shirt is?
31
-
32
- @comment.challenge_answer = "red"
33
- @comment.valid?
34
- #=> true
35
-
36
- Note that you can answer the question without worrying about uppercase/lowercase.
37
- All strings are normalized before the comparison. So "ReD", "RED" or "red" will
38
- pass the validation.
39
-
40
- You can use TextCaptcha with a non-ActiveRecord class. You just need to
41
- include the <tt>TextCaptcha::Validation</tt> module.
42
-
43
- class Comment
44
- include ActiveModel::Validations
45
- include TextCaptcha::Validation
46
-
47
- validates_captcha
48
- end
49
-
50
- @comment = Comment.new
51
- @comment.valid?
52
- #=> false
53
-
54
- @comment.errors[:challenge_answer]
55
- #=> ["You need to answer the anti-spam question."]
56
-
57
- You can disable TextCaptcha without having to remove all validations.
58
- This is specially good when running tests.
59
-
60
- TextCaptcha.enabled = false
61
-
62
- class Comment
63
- include ActiveModel::Validations
64
- include TextCaptcha::Validation
65
-
66
- validates_captcha
67
- end
68
-
69
- @comment = Comment.new
70
- @comment.valid?
71
- #=> true
72
-
73
- == To-Do
74
-
75
- * Add more questions.
76
-
77
- == License
78
-
79
- (The MIT License)
80
-
81
- Copyright © 2010:
82
-
83
- * Nando Vieira - http://nandovieira.com.br
84
-
85
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
86
-
87
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
88
-
89
- THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,13 +0,0 @@
1
- module TextCaptcha
2
- def self.configure(&block)
3
- yield TextCaptcha::Config
4
- end
5
-
6
- class Config
7
- class << self
8
- attr_accessor :enabled
9
- attr_accessor :challenge_attr
10
- attr_accessor :answer_attr
11
- end
12
- end
13
- end
File without changes