Module: BarkestCore::RecaptchaHelper

Included in:
ApplicationControllerBase
Defined in:
app/helpers/barkest_core/recaptcha_helper.rb

Overview

This module makes it easy to work with Google’s recaptcha service.

Simply add recaptcha_public_key and recaptch_private_key to your secrets.yml configuration file, or provide RECAPTCHA_PUBLIC_KEY and RECAPTCHA_PRIVATE_KEY environment variables.

Instance Method Summary collapse

Instance Method Details

#add_recaptcha_challenge(include_break = true) ⇒ Object

Adds the recaptcha challenge to a form.

This will include the recaptcha API from Google automatically and inserts a
sequence after the challenge if include_break is set to true (the default).



40
41
42
43
44
# File 'app/helpers/barkest_core/recaptcha_helper.rb', line 40

def add_recaptcha_challenge(include_break = true)
  unless recaptcha_disabled?
    "<div class=\"g-recaptcha\" data-sitekey=\"#{h recaptcha_site_key}\"></div>\n<script src=\"https://www.google.com/recaptcha/api.js\"></script>#{include_break ? '<br>' : ''}".html_safe
  end
end

#verify_recaptcha_challenge(model = nil) ⇒ Object

Verifies the response from a recaptcha challenge in a controller.

It will return true if the recaptcha challenge passed. It always returns true in the ‘test’ environment.

If a model is provided, then an error will be added to the model if the challenge fails. Because this is handled outside of the model (since it’s based on the request and not the model), you should first check if the model is valid and then verify the recaptcha challenge to ensure you don’t lose the recaptcha error message.

if model.valid? && verify_recaptcha_challenge(model)
  model.save
  redirect_to :show, id: model
else
  render 'edit'
end


63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'app/helpers/barkest_core/recaptcha_helper.rb', line 63

def verify_recaptcha_challenge(model = nil)

  # always true in tests.
  return true if recaptcha_disabled?

  # model must respond to the 'errors' message and the result of that must respond to 'add'
  if !model || !model.respond_to?('errors') || !model.send('errors').respond_to?('add')
    model = nil
  end

  begin
    recaptcha = nil

    http = Net::HTTP

    remote_ip = (request.respond_to?('remote_ip') && request.send('remote_ip')) || (env && env['REMOTE_ADDR'])
    verify_hash = {
        secret: recaptcha_secret_key,
        remoteip: remote_ip,
        response: params['g-recaptcha-response']
    }

    Timeout::timeout(5) do
      uri = URI.parse('https://www.google.com/recaptcha/api/siteverify')
      http_instance = http.new(uri.host, uri.port)
      if uri.port == 443
        http_instance.use_ssl = true
        http_instance.verify_mode = OpenSSL::SSL::VERIFY_NONE
      end
      request = Net::HTTP::Post.new(uri.request_uri)
      request.set_form_data(verify_hash)
      recaptcha = http_instance.request(request)
    end
    answer = JSON.parse(recaptcha.body)

    if answer['success'].to_s.downcase == 'true'
      return true
    else
      if model
        model.errors.add(:base, 'Recaptcha verification failed.')
      end
      return false
    end

  rescue Timeout::Error
    if model
      model.errors.add(:base, 'Recaptcha unreachable.')
    end
  end
end