Module: ValidatesCaptcha::Provider

Defined in:
lib/validates_captcha/provider/dynamic_image.rb,
lib/validates_captcha.rb,
lib/validates_captcha/provider/question.rb,
lib/validates_captcha/provider/static_image.rb

Overview

Here is how you can implement your own captcha challenge provider. Create a class that conforms to the public method definitions of the example below and assign an instance of it to ValidatesCaptcha#provider=.

Example:

require 'action_view/helpers'

class ReverseProvider
  include ActionView::Helpers # for content_tag, link_to_remote

  def initialize
    @string_generator = ValidatesCaptcha::StringGenerator::Simple.new
  end

  def generate_challenge
    @string_generator.generate  # creates a random string
  end

  def solved?(challenge, solution)
    challenge.reverse == solution
  end

  def render_challenge(sanitized_object_name, object, options = {})
    options[:id] = "#{sanitized_object_name}_captcha_question"

    content_tag :span, "What's the reverse of '#{object.captcha_challenge}'?", options
  end

  def render_regenerate_challenge_link(sanitized_object_name, object, options = {}, html_options = {})
    text = options.delete(:text) || 'Regenerate'
    on_success = "var result = request.responseJSON; " \\
                 "$('#{sanitized_object_name}_captcha_question').update(result.question); " \\
                 "$('#{sanitized_object_name}_captcha_challenge').value = result.challenge; " \\
                 "$('#{sanitized_object_name}_captcha_solution').value = '';"

    link_to_remote text, options.reverse_merge(:url => '/captchas/regenerate', :method => :get, :success => success), html_options
  end

  def call(env)  # this is executed by Rack
    if env['PATH_INFO'] == '/captchas/regenerate'
      challenge = generate_challenge
      json = { :question => "What's the reverse of '#{challenge}'?", :challenge => challenge }.to_json

      [200, { 'Content-Type' => 'application/json' }, [json]]
    else
      [404, { 'Content-Type' => 'text/html' }, ['Not Found']]
    end
  end

  private
    # Hack: This is needed by +link_to_remote+ called in +render_regenerate_challenge_link+.
    def protect_against_forgery?
      false
    end
end

ValidatesCaptcha.provider = ReverseProvider.new

Defined Under Namespace

Classes: DynamicImage, Question, StaticImage