validates_captcha 0.9.5 → 0.9.6

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.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,8 @@
1
+ == 0.9.6 (October 30, 2009)
2
+
3
+ * Do not make captcha_challenge and captcha_solution attr_accessible. Instead overwrite AR#attributes= so they can be mass assigned.
4
+
5
+
1
6
  == 0.9.5 (October 9, 2009)
2
7
 
3
8
  * API change: renamed Provider::Image to Provider::DynamicImage in order to guard against confusion
@@ -20,3 +25,4 @@
20
25
  == 0.9.2 (September 27, 2009)
21
26
 
22
27
  * Initial version
28
+
data/Rakefile CHANGED
@@ -29,10 +29,10 @@ Rake::RDocTask.new do |rdoc|
29
29
  rdoc.rdoc_dir = 'doc'
30
30
  rdoc.title = "Validates Captcha"
31
31
  rdoc.main = "README.rdoc"
32
-
32
+
33
33
  rdoc.options << '--line-numbers' << '--inline-source'
34
34
  rdoc.options << '--charset' << 'utf-8'
35
-
35
+
36
36
  rdoc.rdoc_files.include 'README.rdoc'
37
37
  rdoc.rdoc_files.include 'MIT-LICENSE'
38
38
  rdoc.rdoc_files.include 'CHANGELOG.rdoc'
@@ -52,18 +52,18 @@ end
52
52
 
53
53
  desc 'Run tests by default'
54
54
  task :default => :test
55
-
55
+
56
56
  Rake::TestTask.new do |t|
57
57
  t.libs << 'test'
58
58
  t.test_files = FileList['test/**/*_test.rb']
59
59
  #t.verbose = true
60
60
  #t.warning = true
61
61
  end
62
-
63
-
64
-
62
+
63
+
64
+
65
65
  spec = eval(File.read('validates_captcha.gemspec'))
66
-
66
+
67
67
  Rake::GemPackageTask.new(spec) do |pkg|
68
68
  pkg.gem_spec = spec
69
69
  pkg.need_tar = true
@@ -76,9 +76,9 @@ desc 'Publish the release files to RubyForge'
76
76
  task :release => [:package] do
77
77
  require 'rubyforge'
78
78
  require 'rake/contrib/rubyforgepublisher'
79
-
79
+
80
80
  packages = %w(gem tgz zip).collect { |ext| "pkg/#{PKG_NAME}-#{PKG_VERSION}.#{ext}" }
81
-
81
+
82
82
  rubyforge = RubyForge.new
83
83
  rubyforge.configure
84
84
  rubyforge.add_release RUBY_FORGE_PROJECT, RUBY_FORGE_PROJECT, RELEASE_NAME, *packages
@@ -22,10 +22,10 @@
22
22
  #++
23
23
 
24
24
 
25
- # This module contains the getter and setter for the captcha provider.
26
- # This allows you to replace it with your custom implementation. For more
27
- # information on how to bring Validates Captcha to use your own
28
- # implementation instead of the default one, consult the documentation
25
+ # This module contains the getter and setter for the captcha provider.
26
+ # This allows you to replace it with your custom implementation. For more
27
+ # information on how to bring Validates Captcha to use your own
28
+ # implementation instead of the default one, consult the documentation
29
29
  # for the default provider.
30
30
  module ValidatesCaptcha
31
31
  autoload :ModelValidation, 'validates_captcha/model_validation'
@@ -34,34 +34,34 @@ module ValidatesCaptcha
34
34
  autoload :FormBuilder, 'validates_captcha/form_builder'
35
35
  autoload :TestCase, 'validates_captcha/test_case'
36
36
  autoload :VERSION, 'validates_captcha/version'
37
-
37
+
38
38
  module Provider
39
39
  autoload :Question, 'validates_captcha/provider/question'
40
40
  autoload :DynamicImage, 'validates_captcha/provider/dynamic_image'
41
41
  autoload :StaticImage, 'validates_captcha/provider/static_image'
42
42
  end
43
-
43
+
44
44
  module StringGenerator
45
45
  autoload :Simple, 'validates_captcha/string_generator/simple'
46
46
  end
47
-
47
+
48
48
  module SymmetricEncryptor
49
49
  autoload :Simple, 'validates_captcha/symmetric_encryptor/simple'
50
50
  end
51
-
51
+
52
52
  module ImageGenerator
53
53
  autoload :Simple, 'validates_captcha/image_generator/simple'
54
54
  end
55
-
55
+
56
56
  @@provider = nil
57
-
57
+
58
58
  class << self
59
59
  # Returns Validates Captcha's current version number.
60
60
  def version
61
61
  ValidatesCaptcha::VERSION::STRING
62
62
  end
63
-
64
- # Returns the current captcha challenge provider. Defaults to an instance of
63
+
64
+ # Returns the current captcha challenge provider. Defaults to an instance of
65
65
  # the ValidatesCaptcha::Provider::Question class.
66
66
  def provider
67
67
  @@provider ||= Provider::Question.new
@@ -3,12 +3,12 @@ module ValidatesCaptcha
3
3
  def self.included(base) #:nodoc:
4
4
  base.extend ClassMethods
5
5
  end
6
-
7
- # This module extends ActionController::Base with methods for captcha
6
+
7
+ # This module extends ActionController::Base with methods for captcha
8
8
  # verification.
9
- module ClassMethods
10
- # This method is the one Validates Captcha got its name from. It
11
- # internally calls #validates_captcha_of with the name of the controller
9
+ module ClassMethods
10
+ # This method is the one Validates Captcha got its name from. It
11
+ # internally calls #validates_captcha_of with the name of the controller
12
12
  # as first argument and passing the conditions hash.
13
13
  #
14
14
  # Usage Example:
@@ -26,13 +26,13 @@ module ValidatesCaptcha
26
26
  def validates_captcha(conditions = {})
27
27
  validates_captcha_of controller_name, conditions
28
28
  end
29
-
29
+
30
30
  # Activates captcha validation for the specified model.
31
31
  #
32
32
  # The +model+ argument can be a Class, a string, or a symbol.
33
33
  #
34
- # This method internally creates an around filter, passing the
35
- # +conditions+ argument to it. So you can (de)activate captcha
34
+ # This method internally creates an around filter, passing the
35
+ # +conditions+ argument to it. So you can (de)activate captcha
36
36
  # validation for specific actions.
37
37
  #
38
38
  # Usage examples:
@@ -43,11 +43,11 @@ module ValidatesCaptcha
43
43
  # validates_captcha_of 'user', :except => :persist
44
44
  #
45
45
  # # ... actions go here ...
46
- # end
46
+ # end
47
47
  def validates_captcha_of(model, conditions = {})
48
48
  model = model.is_a?(Class) ? model : model.to_s.classify.constantize
49
49
  without_formats = Array.wrap(conditions.delete(:without)).map(&:to_sym)
50
-
50
+
51
51
  around_filter(conditions) do |controller, action|
52
52
  if without_formats.include?(controller.request.format.to_sym)
53
53
  action.call
@@ -61,3 +61,4 @@ module ValidatesCaptcha
61
61
  end
62
62
  end
63
63
  end
64
+
@@ -3,11 +3,11 @@ module ValidatesCaptcha
3
3
  def captcha_challenge(options = {}) #:nodoc:
4
4
  @template.captcha_challenge @object_name, options.merge(:object => @object)
5
5
  end
6
-
6
+
7
7
  def captcha_field(options = {}) #:nodoc:
8
8
  @template.captcha_field @object_name, options.merge(:object => @object)
9
9
  end
10
-
10
+
11
11
  def regenerate_captcha_challenge_link(options = {}, html_options = {}) #:nodoc:
12
12
  @template.regenerate_captcha_challenge_link @object_name, options.merge(:object => @object), html_options
13
13
  end
@@ -1,37 +1,37 @@
1
1
  module ValidatesCaptcha
2
2
  module FormHelper
3
- # Returns the captcha challenge.
3
+ # Returns the captcha challenge.
4
4
  #
5
5
  # Internally calls the +render_challenge+ method of ValidatesCaptcha#provider.
6
6
  def captcha_challenge(object_name, options = {})
7
7
  options.symbolize_keys!
8
-
8
+
9
9
  object = options.delete(:object)
10
10
  sanitized_object_name = object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
11
-
11
+
12
12
  ValidatesCaptcha.provider.render_challenge sanitized_object_name, object, options
13
13
  end
14
-
14
+
15
15
  # Returns an input tag of the "text" type tailored for entering the captcha solution.
16
16
  #
17
- # Internally calls Rails' #text_field helper method, passing the +object_name+ and
17
+ # Internally calls Rails' #text_field helper method, passing the +object_name+ and
18
18
  # +options+ arguments.
19
19
  def captcha_field(object_name, options = {})
20
20
  options.delete(:id)
21
-
21
+
22
22
  hidden_field(object_name, :captcha_challenge, options) + text_field(object_name, :captcha_solution, options)
23
23
  end
24
-
25
- # By default, returns an anchor tag that makes an AJAX request to fetch a new captcha challenge and updates
24
+
25
+ # By default, returns an anchor tag that makes an AJAX request to fetch a new captcha challenge and updates
26
26
  # the current challenge after the request is complete.
27
- #
27
+ #
28
28
  # Internally calls +render_regenerate_challenge_link+ method of ValidatesCaptcha#provider.
29
29
  def regenerate_captcha_challenge_link(object_name, options = {}, html_options = {})
30
30
  options.symbolize_keys!
31
-
31
+
32
32
  object = options.delete(:object)
33
33
  sanitized_object_name = object_name.to_s.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
34
-
34
+
35
35
  ValidatesCaptcha.provider.render_regenerate_challenge_link sanitized_object_name, object, options, html_options
36
36
  end
37
37
  end
@@ -1,24 +1,24 @@
1
1
  module ValidatesCaptcha
2
2
  module ImageGenerator
3
- # This class is responsible for creating the captcha image. It internally
4
- # uses ImageMagick's +convert+ command to generate the image bytes. So
3
+ # This class is responsible for creating the captcha image. It internally
4
+ # uses ImageMagick's +convert+ command to generate the image bytes. So
5
5
  # ImageMagick must be installed on the system for it to work properly.
6
6
  #
7
- # In order to deliver the captcha image to the user's browser,
8
- # Validate Captcha's Rack middleware calls the methods of this class
9
- # to create the image, to retrieve its mime type, and to construct the
7
+ # In order to deliver the captcha image to the user's browser,
8
+ # Validate Captcha's Rack middleware calls the methods of this class
9
+ # to create the image, to retrieve its mime type, and to construct the
10
10
  # path to it.
11
11
  #
12
- # The image generation process is no rocket science. The chars are just
13
- # laid out next to each other with varying vertical positions, font sizes,
14
- # and weights. Then a slight rotation is performed and some randomly
12
+ # The image generation process is no rocket science. The chars are just
13
+ # laid out next to each other with varying vertical positions, font sizes,
14
+ # and weights. Then a slight rotation is performed and some randomly
15
15
  # positioned lines are rendered on the canvas.
16
16
  #
17
- # Sure, the created captcha can easily be cracked by intelligent
18
- # bots. As the name of the class suggests, it's rather a starting point
17
+ # Sure, the created captcha can easily be cracked by intelligent
18
+ # bots. As the name of the class suggests, it's rather a starting point
19
19
  # for your own implementations.
20
20
  #
21
- # You can implement your own (better) image generator by creating a
21
+ # You can implement your own (better) image generator by creating a
22
22
  # class that conforms to the method definitions of the example below.
23
23
  #
24
24
  # Example for a custom image generator:
@@ -48,43 +48,43 @@ module ValidatesCaptcha
48
48
  #
49
49
  # ValidatesCaptcha::Provider::StaticImage.image_generator = AdvancedImageGenerator.new
50
50
  # ValidatesCaptcha.provider = ValidatesCaptcha::Provider::StaticImage.new
51
- #
51
+ #
52
52
  class Simple
53
53
  MIME_TYPE = 'image/gif'.freeze
54
54
  FILE_EXTENSION = '.gif'.freeze
55
-
56
- # Returns a string containing the image bytes of the captcha.
55
+
56
+ # Returns a string containing the image bytes of the captcha.
57
57
  # As the only argument, the cleartext captcha text must be passed.
58
58
  def generate(captcha_code)
59
59
  image_width = captcha_code.length * 20 + 10
60
-
60
+
61
61
  cmd = []
62
62
  cmd << "convert -size #{image_width}x40 xc:grey84 -background grey84 -fill black "
63
-
63
+
64
64
  captcha_code.split(//).each_with_index do |char, i|
65
65
  cmd << " -pointsize #{rand(8) + 15} "
66
66
  cmd << " -weight #{rand(2) == 0 ? '4' : '8'}00 "
67
67
  cmd << " -draw 'text #{5 + 20 * i},#{rand(10) + 20} \"#{char}\"' "
68
68
  end
69
-
69
+
70
70
  cmd << " -rotate #{rand(2) == 0 ? '-' : ''}5 -fill grey40 "
71
-
71
+
72
72
  captcha_code.size.times do
73
73
  cmd << " -draw 'line #{rand(image_width)},0 #{rand(image_width)},60' "
74
74
  end
75
-
75
+
76
76
  cmd << " gif:-"
77
-
77
+
78
78
  image_magick_command = cmd.join
79
-
79
+
80
80
  `#{image_magick_command}`
81
81
  end
82
-
82
+
83
83
  # Returns the image mime type. This is always 'image/gif'.
84
84
  def mime_type
85
85
  MIME_TYPE
86
86
  end
87
-
87
+
88
88
  # Returns the image file extension. This is always '.gif'.
89
89
  def file_extension
90
90
  FILE_EXTENSION
@@ -92,3 +92,4 @@ module ValidatesCaptcha
92
92
  end
93
93
  end
94
94
  end
95
+
@@ -3,18 +3,19 @@ module ValidatesCaptcha
3
3
  def self.included(base) #:nodoc:
4
4
  base.extend ClassMethods
5
5
  base.send :include, InstanceMethods
6
-
6
+
7
7
  base.class_eval do
8
- attr_accessible :captcha_challenge, :captcha_solution
9
8
  attr_accessor :captcha_solution
10
9
  attr_writer :captcha_challenge
11
-
10
+
11
+ alias_method_chain :attributes=, :captcha_fields
12
+
12
13
  validate :validate_captcha, :if => :validate_captcha?
13
14
  end
14
15
  end
15
-
16
+
16
17
  module ClassMethods
17
- # Activates captcha validation on entering the block and deactivates
18
+ # Activates captcha validation on entering the block and deactivates
18
19
  # captcha validation on leaving the block.
19
20
  #
20
21
  # Example:
@@ -29,37 +30,52 @@ module ValidatesCaptcha
29
30
  self.validate_captcha = false
30
31
  result
31
32
  end
32
-
33
+
33
34
  # Returns +true+ if captcha validation is activated, otherwise +false+.
34
35
  def validate_captcha? #:nodoc:
35
36
  @validate_captcha == true
36
37
  end
37
-
38
+
38
39
  private
39
40
  def validate_captcha=(value) #:nodoc:
40
41
  @validate_captcha = value
41
42
  end
42
43
  end
43
-
44
+
44
45
  module InstanceMethods #:nodoc:
45
46
  def captcha_challenge #:nodoc:
46
47
  return @captcha_challenge unless @captcha_challenge.blank?
47
48
  @captcha_challenge = ValidatesCaptcha.provider.generate_challenge
48
49
  end
49
-
50
- private
50
+
51
+ def attributes_with_captcha_fields=(new_attributes, guard_protected_attributes = true)
52
+ if new_attributes && guard_protected_attributes &&
53
+ (new_attributes.key?('captcha_challenge') || new_attributes.key?(:captcha_challenge))
54
+ attributes = new_attributes.dup
55
+ attributes.stringify_keys!
56
+
57
+ self.captcha_challenge = attributes.delete('captcha_challenge')
58
+ self.captcha_solution = attributes.delete('captcha_solution')
59
+
60
+ new_attributes = attributes
61
+ end
62
+
63
+ send :attributes_without_captcha_fields=, new_attributes, guard_protected_attributes
64
+ end
65
+
66
+ private
51
67
  def validate_captcha? #:nodoc:
52
68
  self.class.validate_captcha?
53
69
  end
54
-
70
+
55
71
  def validate_captcha #:nodoc:
56
72
  errors.add(:captcha_solution, :blank) and return if captcha_solution.blank?
57
73
  errors.add(:captcha_solution, :invalid) unless captcha_valid?
58
74
  end
59
-
75
+
60
76
  def captcha_valid? #:nodoc:
61
77
  ValidatesCaptcha.provider.solved?(captcha_challenge, captcha_solution)
62
- end
78
+ end
63
79
  end
64
80
  end
65
81
  end
@@ -1,8 +1,8 @@
1
1
  require 'action_view/helpers'
2
2
 
3
3
  module ValidatesCaptcha
4
- # Here is how you can implement your own captcha challenge provider. Create a
5
- # class that conforms to the public method definitions of the example below
4
+ # Here is how you can implement your own captcha challenge provider. Create a
5
+ # class that conforms to the public method definitions of the example below
6
6
  # and assign an instance of it to ValidatesCaptcha#provider=.
7
7
  #
8
8
  # Example:
@@ -26,7 +26,7 @@ module ValidatesCaptcha
26
26
  #
27
27
  # def render_challenge(sanitized_object_name, object, options = {})
28
28
  # options[:id] = "#{sanitized_object_name}_captcha_question"
29
- #
29
+ #
30
30
  # content_tag :span, "What's the reverse of '#{object.captcha_challenge}'?", options
31
31
  # end
32
32
  #
@@ -36,7 +36,7 @@ module ValidatesCaptcha
36
36
  # "$('#{sanitized_object_name}_captcha_question').update(result.question); " \\
37
37
  # "$('#{sanitized_object_name}_captcha_challenge').value = result.challenge; " \\
38
38
  # "$('#{sanitized_object_name}_captcha_solution').value = '';"
39
- #
39
+ #
40
40
  # link_to_remote text, options.reverse_merge(:url => '/captchas/regenerate', :method => :get, :success => success), html_options
41
41
  # end
42
42
  #
@@ -44,7 +44,7 @@ module ValidatesCaptcha
44
44
  # if env['PATH_INFO'] == '/captchas/regenerate'
45
45
  # challenge = generate_challenge
46
46
  # json = { :question => "What's the reverse of '#{challenge}'?", :challenge => challenge }.to_json
47
- #
47
+ #
48
48
  # [200, { 'Content-Type' => 'application/json' }, [json]]
49
49
  # else
50
50
  # [404, { 'Content-Type' => 'text/html' }, ['Not Found']]
@@ -69,61 +69,61 @@ module ValidatesCaptcha
69
69
  # implementation instead of the default one, consult the documentation
70
70
  # for the specific default class.
71
71
  #
72
- # The default captcha image generator uses ImageMagick's +convert+ command to
73
- # create the captcha. So a recent and properly configured version of ImageMagick
74
- # must be installed on the system. The version used while developing was 6.4.5.
75
- # But you are not bound to ImageMagick. If you want to provide a custom image
76
- # generator, take a look at the documentation for
72
+ # The default captcha image generator uses ImageMagick's +convert+ command to
73
+ # create the captcha. So a recent and properly configured version of ImageMagick
74
+ # must be installed on the system. The version used while developing was 6.4.5.
75
+ # But you are not bound to ImageMagick. If you want to provide a custom image
76
+ # generator, take a look at the documentation for
77
77
  # ValidatesCaptcha::ImageGenerator::Simple on how to create your own.
78
78
  class DynamicImage
79
79
  include ActionView::Helpers
80
-
80
+
81
81
  @@string_generator = nil
82
82
  @@symmetric_encryptor = nil
83
83
  @@image_generator = nil
84
-
84
+
85
85
  class << self
86
86
  # Returns the current captcha string generator. Defaults to an
87
87
  # instance of the ValidatesCaptcha::StringGenerator::Simple class.
88
88
  def string_generator
89
89
  @@string_generator ||= ValidatesCaptcha::StringGenerator::Simple.new
90
90
  end
91
-
91
+
92
92
  # Sets the current captcha string generator. Used to set a
93
93
  # custom string generator.
94
94
  def string_generator=(generator)
95
95
  @@string_generator = generator
96
96
  end
97
-
97
+
98
98
  # Returns the current captcha symmetric encryptor. Defaults to an
99
99
  # instance of the ValidatesCaptcha::SymmetricEncryptor::Simple class.
100
100
  def symmetric_encryptor
101
101
  @@symmetric_encryptor ||= ValidatesCaptcha::SymmetricEncryptor::Simple.new
102
102
  end
103
-
103
+
104
104
  # Sets the current captcha symmetric encryptor. Used to set a
105
105
  # custom symmetric encryptor.
106
106
  def symmetric_encryptor=(encryptor)
107
107
  @@symmetric_encryptor = encryptor
108
108
  end
109
-
109
+
110
110
  # Returns the current captcha image generator. Defaults to an
111
111
  # instance of the ValidatesCaptcha::ImageGenerator::Simple class.
112
112
  def image_generator
113
113
  @@image_generator ||= ValidatesCaptcha::ImageGenerator::Simple.new
114
114
  end
115
-
115
+
116
116
  # Sets the current captcha image generator. Used to set a custom
117
117
  # image generator.
118
118
  def image_generator=(generator)
119
119
  @@image_generator = generator
120
120
  end
121
121
  end
122
-
122
+
123
123
  # This method is the one called by Rack.
124
- #
125
- # It returns HTTP status 404 if the path is not recognized. If the path is
126
- # recognized, it returns HTTP status 200 and delivers the image if it could
124
+ #
125
+ # It returns HTTP status 404 if the path is not recognized. If the path is
126
+ # recognized, it returns HTTP status 200 and delivers the image if it could
127
127
  # successfully decrypt the captcha code, otherwise HTTP status 422.
128
128
  #
129
129
  # Please take a look at the source code if you want to learn more.
@@ -132,16 +132,16 @@ module ValidatesCaptcha
132
132
  if $1 == 'regenerate'
133
133
  captcha_challenge = generate_challenge
134
134
  json = { :captcha_challenge => captcha_challenge, :captcha_image_path => image_path(captcha_challenge) }.to_json
135
-
135
+
136
136
  [200, { 'Content-Type' => 'application/json' }, [json]]
137
137
  else
138
138
  decrypted_code = decrypt($1)
139
-
139
+
140
140
  if decrypted_code.nil?
141
141
  [422, { 'Content-Type' => 'text/html' }, ['Unprocessable Entity']]
142
142
  else
143
143
  image_data = generate_image(decrypted_code)
144
-
144
+
145
145
  response_headers = {
146
146
  'Content-Length' => image_data.bytesize.to_s,
147
147
  'Content-Type' => image_mime_type,
@@ -149,7 +149,7 @@ module ValidatesCaptcha
149
149
  'Content-Transfer-Encoding' => 'binary',
150
150
  'Cache-Control' => 'private'
151
151
  }
152
-
152
+
153
153
  [200, response_headers, [image_data]]
154
154
  end
155
155
  end
@@ -157,79 +157,79 @@ module ValidatesCaptcha
157
157
  [404, { 'Content-Type' => 'text/html' }, ['Not Found']]
158
158
  end
159
159
  end
160
-
160
+
161
161
  # Returns a captcha challenge.
162
162
  def generate_challenge
163
163
  encrypt(generate_code)
164
164
  end
165
-
166
- # Returns true if the captcha was solved using the given +challenge+ and +solution+,
165
+
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
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.
173
- #
173
+ #
174
174
  # Internally calls Rails' +image_tag+ helper method, passing the +options+ argument.
175
175
  def render_challenge(sanitized_object_name, object, options = {})
176
176
  src = image_path(object.captcha_challenge)
177
-
177
+
178
178
  options[:alt] ||= 'CAPTCHA'
179
179
  options[:id] = "#{sanitized_object_name}_captcha_image"
180
-
180
+
181
181
  image_tag src, options
182
182
  end
183
-
184
- # Returns an anchor tag that makes an AJAX request to fetch a new captcha code and updates
183
+
184
+ # Returns an anchor tag that makes an AJAX request to fetch a new captcha code and updates
185
185
  # the captcha image after the request is complete.
186
- #
187
- # Internally calls Rails' +link_to_remote+ helper method, passing the +options+ and
188
- # +html_options+ arguments. So it relies on the Prototype javascript framework
186
+ #
187
+ # Internally calls Rails' +link_to_remote+ helper method, passing the +options+ and
188
+ # +html_options+ arguments. So it relies on the Prototype javascript framework
189
189
  # to be available on the web page.
190
190
  #
191
- # The anchor text defaults to 'Regenerate Captcha'. You can set this to a custom value
191
+ # The anchor text defaults to 'Regenerate Captcha'. You can set this to a custom value
192
192
  # providing a +:text+ key in the +options+ hash.
193
193
  def render_regenerate_challenge_link(sanitized_object_name, object, options = {}, html_options = {})
194
194
  text = options.delete(:text) || 'Regenerate Captcha'
195
195
  success = "var result = request.responseJSON; $('#{sanitized_object_name}_captcha_image').src = result.captcha_image_path; $('#{sanitized_object_name}_captcha_challenge').value = result.captcha_challenge; $('#{sanitized_object_name}_captcha_solution').value = '';"
196
-
196
+
197
197
  link_to_remote text, options.reverse_merge(:url => regenerate_path, :method => :get, :success => success), html_options
198
198
  end
199
-
200
- private
199
+
200
+ private
201
201
  def generate_image(code) #:nodoc:
202
202
  self.class.image_generator.generate code
203
203
  end
204
-
204
+
205
205
  def image_mime_type #:nodoc:
206
206
  self.class.image_generator.mime_type
207
207
  end
208
-
208
+
209
209
  def image_file_extension #:nodoc:
210
210
  self.class.image_generator.file_extension
211
211
  end
212
-
212
+
213
213
  def encrypt(code) #:nodoc:
214
214
  self.class.symmetric_encryptor.encrypt code
215
215
  end
216
-
216
+
217
217
  def decrypt(encrypted_code) #:nodoc:
218
218
  self.class.symmetric_encryptor.decrypt encrypted_code
219
219
  end
220
-
220
+
221
221
  def generate_code #:nodoc:
222
222
  self.class.string_generator.generate
223
223
  end
224
-
224
+
225
225
  def image_path(encrypted_code) #:nodoc:
226
226
  "/captchas/#{encrypted_code}#{image_file_extension}"
227
227
  end
228
-
228
+
229
229
  def regenerate_path #:nodoc:
230
230
  '/captchas/regenerate'
231
231
  end
232
-
232
+
233
233
  # This is needed by +link_to_remote+ called in +render_regenerate_link+.
234
234
  def protect_against_forgery? #:nodoc:
235
235
  false
@@ -237,4 +237,4 @@ module ValidatesCaptcha
237
237
  end
238
238
  end
239
239
  end
240
-
240
+