Skip to content
This repository
branch: master
file 79 lines (73 sloc) 3.021 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
require "uri"
module Recaptcha
  module Verify
    # Your private API can be specified in the +options+ hash or preferably
    # using the Configuration.
    def verify_recaptcha(options = {})
      if !options.is_a? Hash
        options = {:model => options}
      end

      env = options[:env] || ENV['RAILS_ENV']
      return true if Recaptcha.configuration.skip_verify_env.include? env
      model = options[:model]
      attribute = options[:attribute] || :base
      private_key = options[:private_key] || Recaptcha.configuration.private_key
      raise RecaptchaError, "No private key specified." unless private_key

      begin
        recaptcha = nil
        if(Recaptcha.configuration.proxy)
          proxy_server = URI.parse(Recaptcha.configuration.proxy)
          http = Net::HTTP::Proxy(proxy_server.host, proxy_server.port, proxy_server.user, proxy_server.password)
        else
          http = Net::HTTP
        end

        Timeout::timeout(options[:timeout] || 3) do
          recaptcha = http.post_form(URI.parse(Recaptcha.configuration.verify_url), {
            "privatekey" => private_key,
            "remoteip" => request.remote_ip,
            "challenge" => params[:recaptcha_challenge_field],
            "response" => params[:recaptcha_response_field]
          })
        end
        answer, error = recaptcha.body.split.map { |s| s.chomp }
        unless answer == 'true'
          flash[:recaptcha_error] = if defined?(I18n)
            I18n.translate("recaptcha.errors.#{error}", {:default => error})
          else
            error
          end

          if model
            message = "Word verification response is incorrect, please try again."
            message = I18n.translate('recaptcha.errors.verification_failed', {:default => message}) if defined?(I18n)
            model.errors.add attribute, options[:message] || message
          end
          return false
        else
          flash.delete(:recaptcha_error)
          return true
        end
      rescue Timeout::Error
        if Recaptcha.configuration.handle_timeouts_gracefully
          flash[:recaptcha_error] = if defined?(I18n)
            I18n.translate('recaptcha.errors.recaptcha_unreachable', {:default => 'Recaptcha unreachable.'})
          else
            'Recaptcha unreachable.'
          end

          if model
            message = "Oops, we failed to validate your word verification response. Please try again."
            message = I18n.translate('recaptcha.errors.recaptcha_unreachable', :default => message) if defined?(I18n)
            model.errors.add attribute, options[:message] || message
          end
          return false
        else
          raise RecaptchaError, "Recaptcha unreachable."
        end
      rescue Exception => e
        raise RecaptchaError, e.message, e.backtrace
      end
    end # verify_recaptcha

    def verify_recaptcha!(options = {})
      verify_recaptcha(options) or raise VerifyError
    end #verify_recaptcha!
  end # Verify
end # Recaptcha
Something went wrong with that request. Please try again.