validates_captcha 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,12 @@
1
+ == 0.9.5 (October 9, 2009)
2
+
3
+ * API change: renamed Provider::Image to Provider::DynamicImage in order to guard against confusion
4
+
5
+ * API change: renamed ReversibleEncrypter to SymmetricEncryptor
6
+
7
+ * ReversibleEncrypter::Simple class now uses ActiveSupport's MessageEncryptor instead of custom implementation
8
+
9
+
1
10
  == 0.9.4 (October 7, 2009)
2
11
 
3
12
  * Include new StaticImage provider
data/README.rdoc CHANGED
@@ -178,7 +178,7 @@ You can set the captcha provider to use dynamically created image challenges
178
178
  with the code below. Dynamic means that the captcha image is created on invocation.
179
179
  If you want to utilize this provider, it is best to put this in a Rails initializer.
180
180
 
181
- ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Image.new
181
+ ValidatesCaptcha.provider = ValidatesCaptcha::Provider::DynamicImage.new
182
182
 
183
183
  By default, image captchas have a length of 6 characters and the text displayed
184
184
  on the captcha image is created by randomly selecting characters from a
@@ -233,7 +233,7 @@ that creates images that are harder to crack.
233
233
  Please see the documentation of the following classes for further information.
234
234
 
235
235
  * ValidatesCaptcha::StringGenerator::Simple
236
- * ValidatesCaptcha::ReversibleEncrypter::Simple
236
+ * ValidatesCaptcha::SymmetricEncryptor::Simple
237
237
  * ValidatesCaptcha::ImageGenerator::Simple
238
238
 
239
239
  Or you can implement a custom captcha challenge provider and assign it to
@@ -37,7 +37,7 @@ module ValidatesCaptcha
37
37
 
38
38
  module Provider
39
39
  autoload :Question, 'validates_captcha/provider/question'
40
- autoload :Image, 'validates_captcha/provider/image'
40
+ autoload :DynamicImage, 'validates_captcha/provider/dynamic_image'
41
41
  autoload :StaticImage, 'validates_captcha/provider/static_image'
42
42
  end
43
43
 
@@ -45,8 +45,8 @@ module ValidatesCaptcha
45
45
  autoload :Simple, 'validates_captcha/string_generator/simple'
46
46
  end
47
47
 
48
- module ReversibleEncrypter
49
- autoload :Simple, 'validates_captcha/reversible_encrypter/simple'
48
+ module SymmetricEncryptor
49
+ autoload :Simple, 'validates_captcha/symmetric_encryptor/simple'
50
50
  end
51
51
 
52
52
  module ImageGenerator
@@ -19,8 +19,7 @@ module ValidatesCaptcha
19
19
  # for your own implementations.
20
20
  #
21
21
  # You can implement your own (better) image generator by creating a
22
- # class that conforms to the method definitions of the example below and
23
- # assign an instance of it to ValidatesCaptcha::Provider::Image#image_generator=.
22
+ # class that conforms to the method definitions of the example below.
24
23
  #
25
24
  # Example for a custom image generator:
26
25
  #
@@ -40,8 +39,15 @@ module ValidatesCaptcha
40
39
  # end
41
40
  # end
42
41
  #
43
- # ValidatesCaptcha::Provider::Image.image_generator = AdvancedImageGenerator.new
44
- # ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Image.new
42
+ # Then assign an instance of it to ValidatesCaptcha::Provider::DynamicImage#image_generator=.
43
+ #
44
+ # ValidatesCaptcha::Provider::DynamicImage.image_generator = AdvancedImageGenerator.new
45
+ # ValidatesCaptcha.provider = ValidatesCaptcha::Provider::DynamicImage.new
46
+ #
47
+ # Or to ValidatesCaptcha::Provider::StaticImage#image_generator=.
48
+ #
49
+ # ValidatesCaptcha::Provider::StaticImage.image_generator = AdvancedImageGenerator.new
50
+ # ValidatesCaptcha.provider = ValidatesCaptcha::Provider::StaticImage.new
45
51
  #
46
52
  class Simple
47
53
  MIME_TYPE = 'image/gif'.freeze
@@ -63,7 +63,7 @@ module ValidatesCaptcha
63
63
  # An image captcha provider.
64
64
  #
65
65
  # This class contains the getters and setters for the backend classes:
66
- # image generator, string generator, and reversible encrypter. This
66
+ # image generator, string generator, and symmetric encryptor. This
67
67
  # allows you to replace them with your custom implementations. For more
68
68
  # information on how to bring the image provider to use your own
69
69
  # implementation instead of the default one, consult the documentation
@@ -75,11 +75,11 @@ module ValidatesCaptcha
75
75
  # But you are not bound to ImageMagick. If you want to provide a custom image
76
76
  # generator, take a look at the documentation for
77
77
  # ValidatesCaptcha::ImageGenerator::Simple on how to create your own.
78
- class Image
78
+ class DynamicImage
79
79
  include ActionView::Helpers
80
80
 
81
81
  @@string_generator = nil
82
- @@reversible_encrypter = nil
82
+ @@symmetric_encryptor = nil
83
83
  @@image_generator = nil
84
84
 
85
85
  class << self
@@ -95,16 +95,16 @@ module ValidatesCaptcha
95
95
  @@string_generator = generator
96
96
  end
97
97
 
98
- # Returns the current captcha reversible encrypter. Defaults to an
99
- # instance of the ValidatesCaptcha::ReversibleEncrypter::Simple class.
100
- def reversible_encrypter
101
- @@reversible_encrypter ||= ValidatesCaptcha::ReversibleEncrypter::Simple.new
98
+ # Returns the current captcha symmetric encryptor. Defaults to an
99
+ # instance of the ValidatesCaptcha::SymmetricEncryptor::Simple class.
100
+ def symmetric_encryptor
101
+ @@symmetric_encryptor ||= ValidatesCaptcha::SymmetricEncryptor::Simple.new
102
102
  end
103
103
 
104
- # Sets the current captcha reversible encrypter. Used to set a
105
- # custom reversible encrypter.
106
- def reversible_encrypter=(encrypter)
107
- @@reversible_encrypter = encrypter
104
+ # Sets the current captcha symmetric encryptor. Used to set a
105
+ # custom symmetric encryptor.
106
+ def symmetric_encryptor=(encryptor)
107
+ @@symmetric_encryptor = encryptor
108
108
  end
109
109
 
110
110
  # Returns the current captcha image generator. Defaults to an
@@ -166,7 +166,7 @@ module ValidatesCaptcha
166
166
  # Returns true if the captcha was solved using the given +challenge+ and +solution+,
167
167
  # otherwise false.
168
168
  def solved?(challenge, solution)
169
- challenge == encrypt(solution)
169
+ decrypt(challenge) == solution
170
170
  end
171
171
 
172
172
  # Returns an image tag with the source set to the url of the captcha image.
@@ -211,11 +211,11 @@ module ValidatesCaptcha
211
211
  end
212
212
 
213
213
  def encrypt(code) #:nodoc:
214
- self.class.reversible_encrypter.encrypt code
214
+ self.class.symmetric_encryptor.encrypt code
215
215
  end
216
216
 
217
217
  def decrypt(encrypted_code) #:nodoc:
218
- self.class.reversible_encrypter.decrypt encrypted_code
218
+ self.class.symmetric_encryptor.decrypt encrypted_code
219
219
  end
220
220
 
221
221
  def generate_code #:nodoc:
@@ -10,7 +10,8 @@ module ValidatesCaptcha
10
10
  #
11
11
  # You can implement your own string generator by creating a
12
12
  # class that conforms to the method definitions of the example below and
13
- # assign an instance of it to ValidatesCaptcha::Provider::Image#string_generator=.
13
+ # assign an instance of it to
14
+ # ValidatesCaptcha::Provider::DynamicImage#string_generator=.
14
15
  #
15
16
  # Example for a custom string generator:
16
17
  #
@@ -22,8 +23,10 @@ module ValidatesCaptcha
22
23
  # end
23
24
  # end
24
25
  #
25
- # ValidatesCaptcha::Provider::Image.string_generator = DictionaryGenerator.new
26
- # ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Image.new
26
+ # ValidatesCaptcha::Provider::DynamicImage.string_generator = DictionaryGenerator.new
27
+ # ValidatesCaptcha.provider = ValidatesCaptcha::Provider::DynamicImage.new
28
+ #
29
+ # You can also assign it to ValidatesCaptcha::Provider::StaticImage#string_generator=.
27
30
  #
28
31
  class Simple
29
32
  @@alphabet = 'abdefghjkmnqrtABDEFGHJKLMNQRT234678923467892346789'
@@ -0,0 +1,52 @@
1
+ require 'active_support'
2
+
3
+ module ValidatesCaptcha
4
+ module SymmetricEncryptor
5
+ # This class is responsible for encrypting and decrypting captcha codes.
6
+ # It internally uses ActiveSupport's MessageEncryptor to do the string
7
+ # encryption/decryption.
8
+ #
9
+ # You can implement your own symmetric encryptor by creating a class
10
+ # that conforms to the method definitions of the example below and
11
+ # assign an instance of it to
12
+ # ValidatesCaptcha::Provider::DynamicImage#symmetric_encryptor=.
13
+ #
14
+ # Example for a custom symmetric encryptor:
15
+ #
16
+ # class ReverseString # very insecure and easily cracked
17
+ # def encrypt(code)
18
+ # code.reverse
19
+ # end
20
+ #
21
+ # def decrypt(encrypted_code)
22
+ # encrypted_code.reverse
23
+ # rescue SomeKindOfDecryptionError
24
+ # nil
25
+ # end
26
+ # end
27
+ #
28
+ # ValidatesCaptcha::Provider::DynamicImage.symmetric_encryptor = ReverseString.new
29
+ # ValidatesCaptcha.provider = ValidatesCaptcha::Provider::DynamicImage.new
30
+ #
31
+ # Please note: The #decrypt method should return +nil+ if decryption fails.
32
+ class Simple
33
+ KEY = ::ActiveSupport::SecureRandom.hex(64).freeze
34
+
35
+ def initialize #:nodoc:
36
+ @symmetric_encryptor = ::ActiveSupport::MessageEncryptor.new(KEY)
37
+ end
38
+
39
+ # Encrypts a cleartext string.
40
+ def encrypt(code)
41
+ @symmetric_encryptor.encrypt(code).gsub('+', '%2B').gsub('/', '%2F')
42
+ end
43
+
44
+ # Decrypts an encrypted string.
45
+ def decrypt(encrypted_code)
46
+ @symmetric_encryptor.decrypt encrypted_code.gsub('%2F', '/').gsub('%2B', '+')
47
+ rescue ::ActiveSupport::MessageEncryptor::InvalidMessage
48
+ nil
49
+ end
50
+ end
51
+ end
52
+ end
@@ -2,7 +2,7 @@ module ValidatesCaptcha #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 9
5
- TINY = 4
5
+ TINY = 5
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -78,7 +78,7 @@ class ControllerValidationTest < ActionController::TestCase
78
78
 
79
79
  def with_dynamic_image_provider(&block)
80
80
  old_provider = ValidatesCaptcha.provider
81
- provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Image.new
81
+ provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::DynamicImage.new
82
82
  yield provider
83
83
  ValidatesCaptcha.provider = old_provider
84
84
  end
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
  class ModelValidationTest < ValidatesCaptcha::TestCase
4
4
  def with_dynamic_image_provider(&block)
5
5
  old_provider = ValidatesCaptcha.provider
6
- provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Image.new
6
+ provider = ValidatesCaptcha.provider = ValidatesCaptcha::Provider::DynamicImage.new
7
7
  yield provider
8
8
  ValidatesCaptcha.provider = old_provider
9
9
  end
@@ -1,8 +1,8 @@
1
1
  require 'test_helper'
2
2
 
3
- IMAGE = ValidatesCaptcha::Provider::Image
3
+ IMAGE = ValidatesCaptcha::Provider::DynamicImage
4
4
 
5
- class ImageTest < ValidatesCaptcha::TestCase
5
+ class DynamicImageTest < ValidatesCaptcha::TestCase
6
6
  test "defines a class level #string_generator method" do
7
7
  assert_respond_to IMAGE, :string_generator
8
8
  end
@@ -20,21 +20,21 @@ class ImageTest < ValidatesCaptcha::TestCase
20
20
  IMAGE.string_generator = old_string_generator
21
21
  end
22
22
 
23
- test "defines a class level #reversible_encrypter method" do
24
- assert_respond_to IMAGE, :reversible_encrypter
23
+ test "defines a class level #symmetric_encryptor method" do
24
+ assert_respond_to IMAGE, :symmetric_encryptor
25
25
  end
26
26
 
27
- test "defines a class level #reversible_encrypter= method" do
28
- assert_respond_to IMAGE, :reversible_encrypter=
27
+ test "defines a class level #symmetric_encryptor= method" do
28
+ assert_respond_to IMAGE, :symmetric_encryptor=
29
29
  end
30
30
 
31
- test "#reversible_encrypter method's return value should equal the value set using the #reversible_encrypter= method" do
32
- old_reversible_encrypter = IMAGE.reversible_encrypter
31
+ test "#symmetric_encryptor method's return value should equal the value set using the #symmetric_encryptor= method" do
32
+ old_symmetric_encryptor = IMAGE.symmetric_encryptor
33
33
 
34
- IMAGE.reversible_encrypter = 'abc'
35
- assert_equal 'abc', IMAGE.reversible_encrypter
34
+ IMAGE.symmetric_encryptor = 'abc'
35
+ assert_equal 'abc', IMAGE.symmetric_encryptor
36
36
 
37
- IMAGE.reversible_encrypter = old_reversible_encrypter
37
+ IMAGE.symmetric_encryptor = old_symmetric_encryptor
38
38
  end
39
39
 
40
40
  test "defines a class level #image_generator method" do
@@ -1,27 +1,27 @@
1
1
  require 'test_helper'
2
2
 
3
- RE = ValidatesCaptcha::ReversibleEncrypter::Simple
3
+ SE = ValidatesCaptcha::SymmetricEncryptor::Simple
4
4
 
5
- class ReversibleEncrypterTest < ValidatesCaptcha::TestCase
5
+ class SymmetricEncryptorTest < ValidatesCaptcha::TestCase
6
6
  test "defines an instance level #encrypt method" do
7
- assert_respond_to RE.new, :encrypt
7
+ assert_respond_to SE.new, :encrypt
8
8
  end
9
9
 
10
10
  test "instance level #encrypt method returns a string" do
11
- assert_kind_of String, RE.new.encrypt('abc')
11
+ assert_kind_of String, SE.new.encrypt('abc')
12
12
  end
13
13
 
14
14
  test "defines an instance level #decrypt method" do
15
- assert_respond_to RE.new, :decrypt
15
+ assert_respond_to SE.new, :decrypt
16
16
  end
17
17
 
18
18
  test "instance level #decrypt method returns nil if decryption failes" do
19
- assert_nil RE.new.decrypt('invalid')
19
+ assert_nil SE.new.decrypt('invalid')
20
20
  end
21
21
 
22
22
  test "decryption of encryption of string should equal the string" do
23
23
  %w(d3crypti0n 3ncrypt3d 5trin9 sh0u1d equ41 th3 c4ptch4).each do |captcha|
24
- assert_equal captcha, RE.new.decrypt(RE.new.encrypt(captcha))
24
+ assert_equal captcha, SE.new.decrypt(SE.new.encrypt(captcha))
25
25
  end
26
26
  end
27
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validates_captcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Andert
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-07 00:00:00 +02:00
12
+ date: 2009-10-09 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -53,11 +53,11 @@ files:
53
53
  - lib/validates_captcha/form_helper.rb
54
54
  - lib/validates_captcha/image_generator/simple.rb
55
55
  - lib/validates_captcha/model_validation.rb
56
- - lib/validates_captcha/provider/image.rb
56
+ - lib/validates_captcha/provider/dynamic_image.rb
57
57
  - lib/validates_captcha/provider/question.rb
58
58
  - lib/validates_captcha/provider/static_image.rb
59
- - lib/validates_captcha/reversible_encrypter/simple.rb
60
59
  - lib/validates_captcha/string_generator/simple.rb
60
+ - lib/validates_captcha/symmetric_encryptor/simple.rb
61
61
  - lib/validates_captcha/test_case.rb
62
62
  - lib/validates_captcha/version.rb
63
63
  - rails/init.rb
@@ -65,11 +65,11 @@ files:
65
65
  - test/cases/controller_validation_test.rb
66
66
  - test/cases/image_generator/simple_test.rb
67
67
  - test/cases/model_validation_test.rb
68
- - test/cases/provider/image_test.rb
68
+ - test/cases/provider/dynamic_image_test.rb
69
69
  - test/cases/provider/question_test.rb
70
70
  - test/cases/provider/static_image_test.rb
71
- - test/cases/reversible_encrypter/simple_test.rb
72
71
  - test/cases/string_generator/simple_test.rb
72
+ - test/cases/symmetric_encryptor/simple_test.rb
73
73
  - test/cases/validates_captcha_test.rb
74
74
  - test/test_helper.rb
75
75
  has_rdoc: true
@@ -79,7 +79,7 @@ licenses: []
79
79
  post_install_message:
80
80
  rdoc_options:
81
81
  - --title
82
- - Validates Captcha 0.9.4
82
+ - Validates Captcha 0.9.5
83
83
  - --main
84
84
  - README.rdoc
85
85
  - --line-numbers
@@ -111,10 +111,10 @@ test_files:
111
111
  - test/cases/controller_validation_test.rb
112
112
  - test/cases/image_generator/simple_test.rb
113
113
  - test/cases/model_validation_test.rb
114
- - test/cases/provider/image_test.rb
114
+ - test/cases/provider/dynamic_image_test.rb
115
115
  - test/cases/provider/question_test.rb
116
116
  - test/cases/provider/static_image_test.rb
117
- - test/cases/reversible_encrypter/simple_test.rb
118
117
  - test/cases/string_generator/simple_test.rb
118
+ - test/cases/symmetric_encryptor/simple_test.rb
119
119
  - test/cases/validates_captcha_test.rb
120
120
  - test/test_helper.rb
@@ -1,55 +0,0 @@
1
- require 'openssl'
2
- require 'active_support/secure_random'
3
-
4
- module ValidatesCaptcha
5
- module ReversibleEncrypter
6
- # This class is responsible for encrypting and decrypting captcha codes.
7
- # It internally uses AES256 to do the string encryption/decryption.
8
- #
9
- # You can implement your own reversible encrypter by creating a class
10
- # that conforms to the method definitions of the example below and
11
- # assign an instance of it to ValidatesCaptcha::Provider::Image#reversible_encrypter=.
12
- #
13
- # Example for a custom encrypter/decrypter:
14
- #
15
- # class ReverseString # very insecure and easily cracked
16
- # def encrypt(code)
17
- # code.reverse
18
- # end
19
- #
20
- # def decrypt(encrypted_code)
21
- # encrypted_code.reverse
22
- # rescue SomeKindOfDecryptionError
23
- # nil
24
- # end
25
- # end
26
- #
27
- # ValidatesCaptcha::Provider::Image.reversible_encrypter = ReverseString.new
28
- # ValidatesCaptcha.provider = ValidatesCaptcha::Provider::Image.new
29
- #
30
- # Please note: The #decrypt method should return +nil+ if decryption fails.
31
- class Simple
32
- KEY = ::ActiveSupport::SecureRandom.hex(32).freeze
33
-
34
- def initialize #:nodoc:
35
- @aes = OpenSSL::Cipher::Cipher.new('AES-256-ECB')
36
- end
37
-
38
- # Encrypts a cleartext string using #key as encryption key.
39
- def encrypt(code)
40
- @aes.encrypt
41
- @aes.key = KEY
42
- [@aes.update(code) + @aes.final].pack("m").tr('+/=', '-_ ').strip.gsub("\n", '')
43
- end
44
-
45
- # Decrypts an encrypted string using using #key as decryption key.
46
- def decrypt(encrypted_code)
47
- @aes.decrypt
48
- @aes.key = KEY
49
- @aes.update((encrypted_code + '=' * (4 - encrypted_code.size % 4)).tr('-_', '+/').unpack("m").first) + @aes.final
50
- rescue # OpenSSL::CipherError, OpenSSL::Cipher::CipherError
51
- nil
52
- end
53
- end
54
- end
55
- end