Class: ValidatesCaptcha::Provider::StaticImage
- Inherits:
-
Object
- Object
- ValidatesCaptcha::Provider::StaticImage
- Includes:
- ActionView::Helpers
- Defined in:
- lib/validates_captcha/provider/static_image.rb
Overview
An image captcha provider that relies on pre-created captcha images.
There is a Rake tast for creating the captcha images:
rake validates_captcha:create_static_images
This will create 3 images in #filesystem_dir. To create a different number of images, provide a COUNT argument:
rake validates_captcha:create_static_images COUNT=50
This class contains the getters and setters for the backend classes: image generator and string generator. This allows you to replace them with your custom implementations. For more information on how to bring the image provider to use your own implementation instead of the default one, consult the documentation for the specific default class.
The default captcha image generator uses ImageMagick’s convert command to create the captcha. So a recent and properly configured version of ImageMagick must be installed on the system. The version used while developing was 6.4.5. But you are not bound to ImageMagick. If you want to provide a custom image generator, take a look at the documentation for ValidatesCaptcha::ImageGenerator::Simple on how to create your own.
Constant Summary collapse
- SALT =
"3f(61&831_fa0712d4a?b58-eb4b8$a2%.36378f".freeze
- @@string_generator =
nil- @@image_generator =
nil- @@filesystem_dir =
nil- @@web_dir =
nil- @@salt =
nil
Class Method Summary collapse
-
.create_image ⇒ Object
Creates a captcha image in the #filesystem_dir and returns the path to it and the code displayed on the image.
-
.encrypt(code) ⇒ Object
Return the encryption of the
codeusing #salt. -
.filesystem_dir ⇒ Object
Returns the current captcha image file system directory.
-
.filesystem_dir=(dir) ⇒ Object
Sets the current captcha image file system directory.
-
.image_generator ⇒ Object
Returns the current captcha image generator.
-
.image_generator=(generator) ⇒ Object
Sets the current captcha image generator.
-
.salt ⇒ Object
Returns the current salt used for encryption.
-
.salt=(salt) ⇒ Object
Sets the current salt used for encryption.
-
.string_generator ⇒ Object
Returns the current captcha string generator.
-
.string_generator=(generator) ⇒ Object
Sets the current captcha string generator.
-
.web_dir ⇒ Object
Returns the current captcha image web directory.
-
.web_dir=(dir) ⇒ Object
Sets the current captcha image web directory.
Instance Method Summary collapse
-
#call(env) ⇒ Object
This method is the one called by Rack.
-
#challenges ⇒ Object
Returns an array containing the available challenges (encrypted captcha codes).
-
#generate_challenge ⇒ Object
Returns a captcha challenge.
-
#images ⇒ Object
Returns an array containing the paths to the available captcha images.
-
#render_challenge(sanitized_object_name, object, options = {}) ⇒ Object
Returns an image tag with the source set to the url of the captcha image.
-
#render_regenerate_challenge_link(sanitized_object_name, object, options = {}, html_options = {}) ⇒ Object
Returns an anchor tag that makes an AJAX request to fetch a new captcha code and updates the captcha image after the request is complete.
-
#solved?(challenge, solution) ⇒ Boolean
Returns true if the captcha was solved using the given
challengeandsolution, otherwise false.
Class Method Details
.create_image ⇒ Object
Creates a captcha image in the #filesystem_dir and returns the path to it and the code displayed on the image.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/validates_captcha/provider/static_image.rb', line 107 def create_image code = string_generator.generate encrypted_code = encrypt(code) image_filename = "#{encrypted_code}#{image_generator.file_extension}" image_path = File.join(filesystem_dir, image_filename) image_bytes = image_generator.generate(code) File.open image_path, 'w' do |os| os.write image_bytes end return image_path, code end |
.encrypt(code) ⇒ Object
Return the encryption of the code using #salt.
101 102 103 |
# File 'lib/validates_captcha/provider/static_image.rb', line 101 def encrypt(code) ::Digest::SHA1.hexdigest "#{salt}--#{code}" end |
.filesystem_dir ⇒ Object
Returns the current captcha image file system directory. Defaults to RAILS_ROOT/public/images/captchas.
67 68 69 |
# File 'lib/validates_captcha/provider/static_image.rb', line 67 def filesystem_dir @@filesystem_dir ||= ::File.join(::Rails.public_path, 'images', 'captchas') end |
.filesystem_dir=(dir) ⇒ Object
Sets the current captcha image file system directory. Used to set a custom image directory.
73 74 75 |
# File 'lib/validates_captcha/provider/static_image.rb', line 73 def filesystem_dir=(dir) @@filesystem_dir = dir end |
.image_generator ⇒ Object
Returns the current captcha image generator. Defaults to an instance of the ValidatesCaptcha::ImageGenerator::Simple class.
55 56 57 |
# File 'lib/validates_captcha/provider/static_image.rb', line 55 def image_generator @@image_generator ||= ValidatesCaptcha::ImageGenerator::Simple.new end |
.image_generator=(generator) ⇒ Object
Sets the current captcha image generator. Used to set a custom image generator.
61 62 63 |
# File 'lib/validates_captcha/provider/static_image.rb', line 61 def image_generator=(generator) @@image_generator = generator end |
.salt ⇒ Object
Returns the current salt used for encryption.
90 91 92 |
# File 'lib/validates_captcha/provider/static_image.rb', line 90 def salt @@salt ||= SALT end |
.salt=(salt) ⇒ Object
Sets the current salt used for encryption. Used to set a custom salt.
96 97 98 |
# File 'lib/validates_captcha/provider/static_image.rb', line 96 def salt=(salt) @@salt = salt end |
.string_generator ⇒ Object
Returns the current captcha string generator. Defaults to an instance of the ValidatesCaptcha::StringGenerator::Simple class.
43 44 45 |
# File 'lib/validates_captcha/provider/static_image.rb', line 43 def string_generator @@string_generator ||= ValidatesCaptcha::StringGenerator::Simple.new end |
.string_generator=(generator) ⇒ Object
Sets the current captcha string generator. Used to set a custom string generator.
49 50 51 |
# File 'lib/validates_captcha/provider/static_image.rb', line 49 def string_generator=(generator) @@string_generator = generator end |
.web_dir ⇒ Object
Returns the current captcha image web directory. Defaults to /images/captchas.
79 80 81 |
# File 'lib/validates_captcha/provider/static_image.rb', line 79 def web_dir @@web_dir ||= '/images/captchas' end |
.web_dir=(dir) ⇒ Object
Sets the current captcha image web directory. Used to set a custom image directory.
85 86 87 |
# File 'lib/validates_captcha/provider/static_image.rb', line 85 def web_dir=(dir) @@web_dir = dir end |
Instance Method Details
#call(env) ⇒ Object
This method is the one called by Rack.
It returns HTTP status 404 if the path is not recognized. If the path is recognized, it returns HTTP status 200 and delivers a new challenge in JSON format.
Please take a look at the source code if you want to learn more.
130 131 132 133 134 135 136 137 138 139 |
# File 'lib/validates_captcha/provider/static_image.rb', line 130 def call(env) if env['PATH_INFO'] == regenerate_path captcha_challenge = generate_challenge json = { :captcha_challenge => captcha_challenge, :captcha_image_path => image_path(captcha_challenge) }.to_json [200, { 'Content-Type' => 'application/json' }, [json]] else [404, { 'Content-Type' => 'text/html' }, ['Not Found']] end end |
#challenges ⇒ Object
Returns an array containing the available challenges (encrypted captcha codes).
147 148 149 |
# File 'lib/validates_captcha/provider/static_image.rb', line 147 def challenges @challenges ||= images.map { |path| File.basename(path, image_file_extension) } end |
#generate_challenge ⇒ Object
Returns a captcha challenge.
152 153 154 155 156 |
# File 'lib/validates_captcha/provider/static_image.rb', line 152 def generate_challenge raise("no captcha images found in #{filesystem_dir}") if challenges.empty? challenges[rand(challenges.size)] end |
#images ⇒ Object
Returns an array containing the paths to the available captcha images.
142 143 144 |
# File 'lib/validates_captcha/provider/static_image.rb', line 142 def images @images ||= Dir[File.join(filesystem_dir, "*#{image_file_extension}")] end |
#render_challenge(sanitized_object_name, object, options = {}) ⇒ Object
Returns an image tag with the source set to the url of the captcha image.
Internally calls Rails’ image_tag helper method, passing the options argument.
167 168 169 170 171 172 173 174 |
# File 'lib/validates_captcha/provider/static_image.rb', line 167 def render_challenge(sanitized_object_name, object, = {}) src = image_path(object.captcha_challenge) [:alt] ||= 'CAPTCHA' [:id] = "#{sanitized_object_name}_captcha_image" image_tag src, end |
#render_regenerate_challenge_link(sanitized_object_name, object, options = {}, html_options = {}) ⇒ Object
Returns an anchor tag that makes an AJAX request to fetch a new captcha code and updates the captcha image after the request is complete.
Internally calls Rails’ link_to_remote helper method, passing the options and html_options arguments. So it relies on the Prototype javascript framework to be available on the web page. As of version 0.9.8 you can pass :jquery => true as an option to render Javascript that’s based on jQuery.
The anchor text defaults to ‘Regenerate Captcha’. You can set this to a custom value providing a :text key in the options hash.
186 187 188 189 190 191 192 193 194 195 |
# File 'lib/validates_captcha/provider/static_image.rb', line 186 def render_regenerate_challenge_link(sanitized_object_name, object, = {}, = {}) text = .delete(:text) || 'Regenerate Captcha' if .delete(:jquery) onclick = "jQuery.getJSON('#{regenerate_path}', function(result){jQuery('##{sanitized_object_name}_captcha_image').attr('src',result.captcha_image_path); jQuery('##{sanitized_object_name}_captcha_challenge').val(result.captcha_challenge); jQuery('##{sanitized_object_name}_captcha_solution').val('');});return false;" link_to text, "#", .reverse_merge(:onclick => onclick), else 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 = '';" link_to_remote text, .reverse_merge(:url => regenerate_path, :method => :get, :success => success), end end |
#solved?(challenge, solution) ⇒ Boolean
Returns true if the captcha was solved using the given challenge and solution, otherwise false.
160 161 162 |
# File 'lib/validates_captcha/provider/static_image.rb', line 160 def solved?(challenge, solution) challenge == encrypt(solution) end |