recaptcha 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d9928918ae6c300aacb0a2df19c974edf706f770
4
- data.tar.gz: e0c54cc33cb1bb416644c531a3d687db4d9b357b
3
+ metadata.gz: 9d8c84c84605f3b19d067af5b08d173f5dd681f2
4
+ data.tar.gz: c0126d1350d3da2dda33a8d4a2932a0b1ad5f504
5
5
  SHA512:
6
- metadata.gz: b90152d14acb163ec175bfc44e89ac7a0fc9e05ec460ce181fb8f80b734e09ca20ec6f52a10fcea9b6958a6e32dad59d307d8394345f7a60dcec96802ad7a213
7
- data.tar.gz: d44621c515e8ce8ce0c615aab4622c747918c29d0fa63161dedd7bea435059be44a1309a6e0e8ad25d242b1c6e5c9388cc07a1ecd08a303e358103c5e0e68632
6
+ metadata.gz: 2ee980f5953e85425572add41e07b142b323743f8f0c14824145604a8f20176b6a54b5d365852f4dbadd283ecc3e67bf203599e8f03c4c9afc5a5d58c541c5a4
7
+ data.tar.gz: 8a8677420abff0ceac5f2674fd58da71623b980ff3336c6a2aaf196562adce8d295257d73c964cf220ed98ea1119f4723ea794c7acd7c4b004ff83edcda1fa10
@@ -0,0 +1,295 @@
1
+ # reCAPTCHA
2
+
3
+ Author: Jason L Perry (http://ambethia.com)<br/>
4
+ Copyright: Copyright (c) 2007-2013 Jason L Perry<br/>
5
+ License: [MIT](http://creativecommons.org/licenses/MIT/)<br/>
6
+ Info: https://github.com/ambethia/recaptcha<br/>
7
+ Bugs: https://github.com/ambethia/recaptcha/issues<br/>
8
+
9
+ This plugin adds helpers for the [reCAPTCHA API](https://www.google.com/recaptcha). In your
10
+ views you can use the `recaptcha_tags` method to embed the needed javascript,
11
+ and you can validate in your controllers with `verify_recaptcha` or `verify_recaptcha!`,
12
+ which throws an error on failiure.
13
+
14
+ Beforehand you need to configure Recaptcha with your custom private and public
15
+ key. You may find detailed examples below. Exceptions will be raised if you
16
+ call these methods and the keys can't be found.
17
+
18
+ ## Rails Installation
19
+
20
+ ```Ruby
21
+ gem "recaptcha", require: "recaptcha/rails"
22
+ ```
23
+
24
+ (Rails < 3.0: install an older release and view it's README)
25
+
26
+ ## Setting up your API Keys
27
+
28
+ There are multiple ways to setup your reCAPTCHA API key once you
29
+ [obtain a pair](https://www.google.com/recaptcha/admin).
30
+
31
+ ### Recaptcha.configure
32
+
33
+ You may use the block style configuration. The following code could be placed
34
+ into a `config/initializers/recaptcha.rb` when used in a Rails project.
35
+
36
+ ```Ruby
37
+ Recaptcha.configure do |config|
38
+ config.public_key = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
39
+ config.private_key = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
40
+ # Uncomment the following line if you are using a proxy server:
41
+ # config.proxy = 'http://myproxy.com.au:8080'
42
+ # Uncomment if you want to use the older version of the API,
43
+ # only works for versions >= 0.3.7, default value is 'v2':
44
+ # config.api_version = 'v1'
45
+ end
46
+ ```
47
+
48
+ This way, you may also set additional options to fit recaptcha into your
49
+ deployment environment.
50
+
51
+ ### Recaptcha.with_configuration
52
+
53
+ If you want to temporarily overwrite the configuration you set with
54
+ `Recaptcha.configure` (when testing, for example), you can use a
55
+ `Recaptcha#with_configuration` block:
56
+
57
+ ```Ruby
58
+ Recaptcha.with_configuration(public_key: '12345') do
59
+ # Do stuff with the overwritten public_key.
60
+ end
61
+ ```
62
+
63
+ ### Heroku & Shell environment
64
+
65
+ Or, you can keep your keys out of your code base by exporting the following
66
+ environment variables. You might do this in the .profile/rc, or equivalent for
67
+ the user running your application. This would also be the preffered method
68
+ in an Heroku deployment.
69
+
70
+ ```
71
+ export RECAPTCHA_PUBLIC_KEY = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
72
+ export RECAPTCHA_PRIVATE_KEY = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
73
+ ```
74
+
75
+ ### Per call
76
+
77
+ You can also pass in your keys as options at runtime, for example:
78
+
79
+ ```Ruby
80
+ recaptcha_tags public_key: '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
81
+ ```
82
+
83
+ and later,
84
+
85
+ ```Ruby
86
+ verify_recaptcha private_key: '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
87
+ ```
88
+
89
+ This option might be useful, if the same code base is used for multiple
90
+ reCAPTCHA setups.
91
+
92
+ ## To use 'recaptcha'
93
+
94
+ Add `recaptcha_tags` to each form you want to protect.
95
+ Place it where you want the recaptcha widget to appear.
96
+
97
+ Example:
98
+
99
+ ```Erb
100
+ <%= form_for @foo do |f| %>
101
+ # ... additional lines truncated for brevity ...
102
+ <%= recaptcha_tags %>
103
+ # ... additional lines truncated for brevity ...
104
+ <% end %>
105
+ ```
106
+
107
+ And, add `verify_recaptcha` logic to each form action that you've protected.
108
+
109
+ ### recaptcha_tags
110
+
111
+ Some of the options available:
112
+
113
+ | Option | Description |
114
+ |-------------|-------------|
115
+ | :ssl | Uses secure http for captcha widget (default `false`, but can be changed by setting `config.use_ssl_by_default`)|
116
+ | :noscript | Include <noscript> content (default `true`)|
117
+ | :display | Takes a hash containing the `theme` and `tabindex` options per the API. (default `nil`), options: 'red', 'white', 'blackglass', 'clean', 'custom'|
118
+ | :ajax | Render the dynamic AJAX captcha per the API. (default `false`)|
119
+ | :public_key | Your public API key, takes precedence over the ENV variable (default `nil`)|
120
+ | :error | Override the error code returned from the reCAPTCHA API (default `nil`)|
121
+ | :stoken | Include in reCAPTCHA API v2 the security token (default `true`)|
122
+ | :size | Specify a size (default `nil`)|
123
+
124
+
125
+ You can also override the html attributes for the sizes of the generated `textarea` and `iframe`
126
+ elements, if CSS isn't your thing. Inspect the source of `recaptcha_tags` to see these options.
127
+
128
+ ### verify_recaptcha
129
+
130
+ This method returns `true` or `false` after processing the parameters from the reCAPTCHA widget. Why
131
+ isn't this a model validation? Because that violates MVC. You can use it like this, or how ever you
132
+ like. Passing in the ActiveRecord object is optional, if you do--and the captcha fails to verify--an
133
+ error will be added to the object for you to use.
134
+
135
+ Some of the options available:
136
+
137
+ | Option | Description |
138
+ |--------------|-------------|
139
+ | :model | Model to set errors
140
+ | :attribute | Model attribute to receive errors (default :base)
141
+ | :message | Custom error message
142
+ | :private_key | Your private API key, takes precedence over the ENV variable (default `nil`).
143
+ | :timeout | The number of seconds to wait for reCAPTCHA servers before give up. (default `3`)
144
+
145
+ ```Ruby
146
+ respond_to do |format|
147
+ if verify_recaptcha(model @post, message: "Oh! It's error with reCAPTCHA!") && @post.save
148
+ # ...
149
+ else
150
+ # ...
151
+ end
152
+ end
153
+ ```
154
+
155
+ ### Add multiple widgets to the same page
156
+
157
+ This is an example taken from the [official google documentation](https://developers.google.com/recaptcha/docs/display).
158
+
159
+ Add a script tag for a callback
160
+
161
+ ```Html
162
+ <script type="text/javascript">
163
+ var verifyCallback = function(response) {
164
+ alert(response);
165
+ };
166
+ var widgetId1;
167
+ var widgetId2;
168
+ var onloadCallback = function() {
169
+ // Renders the HTML element with id 'example1' as a reCAPTCHA widget.
170
+ // The id of the reCAPTCHA widget is assigned to 'widgetId1'.
171
+ widgetId1 = grecaptcha.render('example1', {
172
+ 'sitekey' : "<%= Recaptcha.configuration.public_key %>",
173
+ 'theme' : 'light'
174
+ });
175
+ widgetId2 = grecaptcha.render(document.getElementById('example2'), {
176
+ 'sitekey' : "<%= Recaptcha.configuration.public_key %>"
177
+ });
178
+ grecaptcha.render('example3', {
179
+ 'sitekey' : "<%= Recaptcha.configuration.public_key %>",
180
+ 'callback' : verifyCallback,
181
+ 'theme' : 'dark'
182
+ });
183
+ };
184
+ </script>
185
+ ```
186
+
187
+ In the callback you will have the `sitekey` generated by this gem with `<%= Recaptcha.configuration.public_key %>`
188
+
189
+ Next you need to have some elements with an id matching those specified in the callback
190
+
191
+ ```Erb
192
+ <%= form_for @foo do |f| %>
193
+ # ... additional lines truncated for brevity ...
194
+ <div id="example1"></div>
195
+ # ... additional lines truncated for brevity ...
196
+ <% end %>
197
+ <%= form_for @foo2 do |f| %>
198
+ # ... additional lines truncated for brevity ...
199
+ <div id="example2"></div>
200
+ # ... additional lines truncated for brevity ...
201
+ <% end %>
202
+ <%= form_for @foo3 do |f| %>
203
+ # ... additional lines truncated for brevity ...
204
+ <div id="example3"></div>
205
+ # ... additional lines truncated for brevity ...
206
+ <% end %>
207
+ ```
208
+
209
+ And finally you need a script tag that gets the reCAPTCHA code from google and tells it that your code is explicit and gives it the callback.
210
+
211
+ ```Html
212
+ <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
213
+ ```
214
+
215
+ Now all together:
216
+
217
+ ```Html
218
+ <html>
219
+ <head>
220
+ <title>reCAPTCHA demo: Explicit render for multiple widgets</title>
221
+ <script type="text/javascript">
222
+ var verifyCallback = function(response) {
223
+ alert(response);
224
+ };
225
+ var widgetId1;
226
+ var widgetId2;
227
+ var onloadCallback = function() {
228
+ // Renders the HTML element with id 'example1' as a reCAPTCHA widget.
229
+ // The id of the reCAPTCHA widget is assigned to 'widgetId1'.
230
+ widgetId1 = grecaptcha.render('example1', {
231
+ 'sitekey' : "<%= Recaptcha.configuration.public_key %>",
232
+ 'theme' : 'light'
233
+ });
234
+ widgetId2 = grecaptcha.render(document.getElementById('example2'), {
235
+ 'sitekey' : "<%= Recaptcha.configuration.public_key %>"
236
+ });
237
+ grecaptcha.render('example3', {
238
+ 'sitekey' : "<%= Recaptcha.configuration.public_key %>",
239
+ 'callback' : verifyCallback,
240
+ 'theme' : 'dark'
241
+ });
242
+ };
243
+ </script>
244
+ </head>
245
+ <body>
246
+ <%= form_for @foo do |f| %>
247
+ # ... additional lines truncated for brevity ...
248
+ <div id="example1"></div>
249
+ # ... additional lines truncated for brevity ...
250
+ <% end %>
251
+ <%= form_for @foo2 do |f| %>
252
+ # ... additional lines truncated for brevity ...
253
+ <div id="example2"></div>
254
+ # ... additional lines truncated for brevity ...
255
+ <% end %>
256
+ <%= form_for @foo3 do |f| %>
257
+ # ... additional lines truncated for brevity ...
258
+ <div id="example3"></div>
259
+ # ... additional lines truncated for brevity ...
260
+ <% end %>
261
+ <script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script>
262
+ </body>
263
+ </html>
264
+ ```
265
+
266
+ The only real difference between this example and the google example is you will use the `<%= Recaptcha.configuration.public_key %>` for the `sitekey`
267
+
268
+ If your callback has to live on another file (maybe a layout), then you would set the callback on window `window.onloadCallback = function() {...}`
269
+
270
+ Then on the backend, you will still use the `verify_recaptcha` as explained in this readme.
271
+
272
+ ## I18n support
273
+ reCAPTCHA passes two types of error explanation to a linked model. It will use the I18n gem
274
+ to translate the default error message if I18n is available. To customize the messages to your locale,
275
+ add these keys to your I18n backend:
276
+
277
+ `recaptcha.errors.verification_failed` error message displayed if the captcha words didn't match
278
+ `recaptcha.errors.recaptcha_unreachable` displayed if a timeout error occured while attempting to verify the captcha
279
+
280
+ Also you can translate API response errors to human friendly by adding translations to the locale (`config/locales/en.yml`):
281
+
282
+ ```Yaml
283
+ en:
284
+ recaptcha:
285
+ errors:
286
+ incorrect-captcha-sol: 'Fail'
287
+ ```
288
+
289
+ ## Testing
290
+ By default, reCAPTCHA is skipped on "test" env, so if you need to make sure it's working properly, just remove the "test" entry of the skip_environment inside Recapcha class, look:
291
+
292
+
293
+ ```Ruby
294
+ Recaptcha.configuration.skip_verify_env.delete("test")
295
+ ```
@@ -18,7 +18,7 @@ module Recaptcha
18
18
  }
19
19
  }
20
20
 
21
- RECAPTCHA_API_VERSION = 'v2'
21
+ RECAPTCHA_API_VERSION = 'v2'
22
22
  USE_SSL_BY_DEFAULT = false
23
23
  HANDLE_TIMEOUTS_GRACEFULLY = true
24
24
  SKIP_VERIFY_ENV = ['test', 'cucumber']
@@ -58,9 +58,4 @@ module Recaptcha
58
58
 
59
59
  class VerifyError < RecaptchaError
60
60
  end
61
-
62
- end
63
-
64
- if defined?(Rails)
65
- require 'recaptcha/rails'
66
61
  end
@@ -63,20 +63,39 @@ module Recaptcha
63
63
  end
64
64
 
65
65
  def v2_tags(options)
66
- key = options[:public_key] ||= Recaptcha.configuration.public_key
67
- raise RecaptchaError, "No public key specified." unless key
68
- error = options[:error] ||= ((defined? flash) ? flash[:recaptcha_error] : "")
66
+ public_key = options[:public_key] ||= Recaptcha.configuration.public_key
67
+ raise RecaptchaError, "No public key specified." unless public_key
68
+ private_key = options[:private_key] ||= Recaptcha.configuration.private_key
69
+ raise RecaptchaError, "No private key specified." unless private_key
70
+ error = options[:error] ||= ((defined? flash) ? flash[:recaptcha_error] : "") # TODO not being used !?
69
71
  uri = Recaptcha.configuration.api_server_url(options[:ssl])
70
72
  uri += "?hl=#{options[:hl]}" unless options[:hl].blank?
71
-
72
- v2_options = options.slice(:theme, :type, :callback).map {|k,v| %{data-#{k}="#{v}"} }.join(" ")
73
73
 
74
74
  html = ""
75
75
  html << %{<script src="#{uri}" async defer></script>\n}
76
- html << %{<div class="g-recaptcha" data-sitekey="#{key}" #{v2_options}></div>\n}
77
-
76
+
77
+ data_attributes = options.slice(:theme, :type, :callback, :expired_callback, :size)
78
+ data_attributes[:sitekey] = public_key
79
+
80
+ if options[:stoken] != false
81
+ stoken_json = hash_to_json({'session_id' => SecureRandom.uuid, 'ts_ms' => (Time.now.to_f * 1000).to_i})
82
+ cipher = OpenSSL::Cipher::AES128.new(:ECB)
83
+ private_key_digest = Digest::SHA1.digest(private_key)[0...16]
84
+
85
+ cipher.encrypt
86
+ cipher.key = private_key_digest
87
+ encrypted_stoken = cipher.update(stoken_json) << cipher.final
88
+ encoded_stoken = Base64.urlsafe_encode64(encrypted_stoken).gsub(/\=+\Z/, '')
89
+
90
+ data_attributes[:stoken] = encoded_stoken
91
+ end
92
+
93
+ data_attributes = data_attributes.map {|k,v| %{data-#{k.to_s.gsub(/_/,'-')}="#{v}"} }.join(" ")
94
+
95
+ html << %{<div class="g-recaptcha" #{data_attributes}></div>\n}
96
+
78
97
  unless options[:noscript] == false
79
- fallback_uri = "#{uri.chomp('.js')}/fallback?k=#{key}"
98
+ fallback_uri = "#{uri.chomp('.js')}/fallback?k=#{public_key}"
80
99
  html << %{<noscript>}
81
100
  html << %{<div style="width: 302px; height: 352px;">}
82
101
  html << %{ <div style="width: 302px; height: 352px; position: relative;">}
@@ -99,7 +118,7 @@ module Recaptcha
99
118
  html << %{</noscript>}
100
119
  end
101
120
 
102
- return (html.respond_to?(:html_safe) && html.html_safe) || html
121
+ (html.respond_to?(:html_safe) && html.html_safe) || html
103
122
  end
104
123
 
105
124
  private
@@ -109,7 +128,7 @@ module Recaptcha
109
128
  result << hash.map do |k, v|
110
129
  if v.is_a?(Hash)
111
130
  "\"#{k}\": #{hash_to_json(v)}"
112
- elsif ! v.is_a?(String) || k.to_s == "callback"
131
+ elsif ! v.is_a?(String) || k.to_s =~ %r{(callback|expired-callback)}
113
132
  "\"#{k}\": #{v}"
114
133
  else
115
134
  "\"#{k}\": \"#{v}\""
@@ -117,5 +136,5 @@ module Recaptcha
117
136
  end.join(", ")
118
137
  result << "}"
119
138
  end
120
- end # ClientHelper
121
- end # Recaptcha
139
+ end
140
+ end
@@ -1,5 +1,13 @@
1
1
  require 'net/http'
2
2
  require 'recaptcha'
3
3
 
4
- ActionView::Base.send(:include, Recaptcha::ClientHelper)
5
- ActionController::Base.send(:include, Recaptcha::Verify)
4
+ module Rails
5
+ module Recaptcha
6
+ class Railtie < Rails::Railtie
7
+ initializer :recaptcha do
8
+ ActionView::Base.send(:include, ::Recaptcha::ClientHelper)
9
+ ActionController::Base.send(:include, ::Recaptcha::Verify)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,12 +1,16 @@
1
1
  require "uri"
2
+ require "json"
3
+
2
4
  module Recaptcha
3
5
  module Verify
6
+ DEFAULT_TIMEOUT = 3
7
+
4
8
  # Your private API can be specified in the +options+ hash or preferably
5
9
  # using the Configuration.
6
10
  def verify_recaptcha(options = {})
7
11
  options = {:model => options} unless options.is_a? Hash
8
12
 
9
- env_options = options[:env] || ENV['RAILS_ENV']
13
+ env_options = options[:env] || ENV['RAILS_ENV'] || (Rails.env if defined? Rails.env)
10
14
  return true if Recaptcha.configuration.skip_verify_env.include? env_options
11
15
  model = options[:model]
12
16
  attribute = options[:attribute] || :base
@@ -15,7 +19,7 @@ module Recaptcha
15
19
 
16
20
  begin
17
21
  recaptcha = nil
18
- if(Recaptcha.configuration.proxy)
22
+ if Recaptcha.configuration.proxy
19
23
  proxy_server = URI.parse(Recaptcha.configuration.proxy)
20
24
  http = Net::HTTP::Proxy(proxy_server.host, proxy_server.port, proxy_server.user, proxy_server.password)
21
25
  else
@@ -31,7 +35,7 @@ module Recaptcha
31
35
  "challenge" => params[:recaptcha_challenge_field],
32
36
  "response" => params[:recaptcha_response_field]
33
37
  }
34
- Timeout::timeout(options[:timeout] || 3) do
38
+ Timeout::timeout(options[:timeout] || DEFAULT_TIMEOUT) do
35
39
  recaptcha = http.post_form(URI.parse(Recaptcha.configuration.verify_url), verify_hash)
36
40
  end
37
41
  answer, error = recaptcha.body.split.map { |s| s.chomp }
@@ -44,10 +48,10 @@ module Recaptcha
44
48
  "response" => params['g-recaptcha-response']
45
49
  }
46
50
 
47
- Timeout::timeout(options[:timeout] || 3) do
51
+ Timeout::timeout(options[:timeout] || DEFAULT_TIMEOUT) do
48
52
  uri = URI.parse(Recaptcha.configuration.verify_url + '?' + verify_hash.to_query)
49
53
  http_instance = http.new(uri.host, uri.port)
50
- if uri.port==443
54
+ if uri.port == 443
51
55
  http_instance.use_ssl =
52
56
  http_instance.verify_mode = OpenSSL::SSL::VERIFY_NONE
53
57
  end
@@ -57,55 +61,56 @@ module Recaptcha
57
61
  answer, error = JSON.parse(recaptcha.body).values
58
62
  end
59
63
 
60
- unless answer.to_s == 'true'
64
+ if answer.to_s == 'true'
65
+ flash.delete(:recaptcha_error) if request_in_html_format?
66
+ true
67
+ else
61
68
  error = 'verification_failed' if error && Recaptcha.configuration.v2?
62
69
  if request_in_html_format?
63
70
  flash[:recaptcha_error] = if defined?(I18n)
64
- I18n.translate("recaptcha.errors.#{error}", {:default => error})
65
- else
66
- error
67
- end
71
+ I18n.translate("recaptcha.errors.#{error}", default: error)
72
+ else
73
+ error
74
+ end
68
75
  end
69
76
 
70
77
  if model
71
78
  message = "Word verification response is incorrect, please try again."
72
- message = I18n.translate('recaptcha.errors.verification_failed', {:default => message}) if defined?(I18n)
79
+ message = I18n.translate('recaptcha.errors.verification_failed', default: message) if defined?(I18n)
73
80
  model.errors.add attribute, options[:message] || message
74
81
  end
75
- return false
76
- else
77
- flash.delete(:recaptcha_error) if request_in_html_format?
78
- return true
82
+ false
79
83
  end
80
84
  rescue Timeout::Error
81
85
  if Recaptcha.configuration.handle_timeouts_gracefully
82
86
  if request_in_html_format?
83
87
  flash[:recaptcha_error] = if defined?(I18n)
84
- I18n.translate('recaptcha.errors.recaptcha_unreachable', {:default => 'Recaptcha unreachable.'})
85
- else
86
- 'Recaptcha unreachable.'
87
- end
88
+ I18n.translate('recaptcha.errors.recaptcha_unreachable', default: 'Recaptcha unreachable.')
89
+ else
90
+ 'Recaptcha unreachable.'
91
+ end
88
92
  end
89
93
 
90
94
  if model
91
95
  message = "Oops, we failed to validate your word verification response. Please try again."
92
- message = I18n.translate('recaptcha.errors.recaptcha_unreachable', :default => message) if defined?(I18n)
96
+ message = I18n.translate('recaptcha.errors.recaptcha_unreachable', default: message) if defined?(I18n)
93
97
  model.errors.add attribute, options[:message] || message
94
98
  end
95
- return false
99
+ false
96
100
  else
97
101
  raise RecaptchaError, "Recaptcha unreachable."
98
102
  end
99
- rescue Exception => e
103
+ rescue StandardError => e
100
104
  raise RecaptchaError, e.message, e.backtrace
101
105
  end
102
- end # verify_recaptcha
106
+ end
103
107
 
104
108
  def request_in_html_format?
105
109
  request.respond_to?(:format) && request.format == :html && respond_to?(:flash)
106
110
  end
111
+
107
112
  def verify_recaptcha!(options = {})
108
113
  verify_recaptcha(options) or raise VerifyError
109
- end #verify_recaptcha!
110
- end # Verify
111
- end # Recaptcha
114
+ end
115
+ end
116
+ end
@@ -1,3 +1,3 @@
1
1
  module Recaptcha
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: recaptcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jason L Perry
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-22 00:00:00.000000000 Z
11
+ date: 2015-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: mocha
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -67,19 +81,19 @@ dependencies:
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
- name: minitest
84
+ name: maxitest
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - "~>"
87
+ - - ">="
74
88
  - !ruby/object:Gem::Version
75
- version: '5.0'
89
+ version: '0'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - "~>"
94
+ - - ">="
81
95
  - !ruby/object:Gem::Version
82
- version: '5.0'
96
+ version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: pry-byebug
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -94,37 +108,39 @@ dependencies:
94
108
  - - ">="
95
109
  - !ruby/object:Gem::Version
96
110
  version: '0'
97
- description: This plugin adds helpers for the reCAPTCHA API
111
+ - !ruby/object:Gem::Dependency
112
+ name: bump
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ description: Helpers for the reCAPTCHA API
98
126
  email:
99
127
  - jasper@ambethia.com
100
128
  executables: []
101
129
  extensions: []
102
130
  extra_rdoc_files: []
103
131
  files:
104
- - ".gitignore"
105
- - ".travis.yml"
106
132
  - CHANGELOG
107
- - Gemfile
108
- - Gemfile.lock
109
133
  - LICENSE
110
- - README.rdoc
111
- - Rakefile
112
- - init.rb
134
+ - README.md
113
135
  - lib/recaptcha.rb
114
136
  - lib/recaptcha/client_helper.rb
115
137
  - lib/recaptcha/configuration.rb
116
- - lib/recaptcha/merb.rb
117
138
  - lib/recaptcha/rails.rb
118
- - lib/recaptcha/railtie.rb
119
139
  - lib/recaptcha/verify.rb
120
140
  - lib/recaptcha/version.rb
121
- - recaptcha.gemspec
122
- - test/recaptcha_configuration_test.rb
123
- - test/recaptcha_test.rb
124
- - test/recaptcha_v1_test.rb
125
- - test/verify_recaptcha_test.rb
126
141
  homepage: http://github.com/ambethia/recaptcha
127
- licenses: []
142
+ licenses:
143
+ - MIT
128
144
  metadata: {}
129
145
  post_install_message:
130
146
  rdoc_options: []
@@ -134,20 +150,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
150
  requirements:
135
151
  - - ">="
136
152
  - !ruby/object:Gem::Version
137
- version: '0'
153
+ version: 2.0.0
138
154
  required_rubygems_version: !ruby/object:Gem::Requirement
139
155
  requirements:
140
156
  - - ">="
141
157
  - !ruby/object:Gem::Version
142
158
  version: '0'
143
159
  requirements: []
144
- rubyforge_project: recaptcha
145
- rubygems_version: 2.4.5
160
+ rubyforge_project:
161
+ rubygems_version: 2.4.5.1
146
162
  signing_key:
147
163
  specification_version: 4
148
164
  summary: Helpers for the reCAPTCHA API
149
- test_files:
150
- - test/recaptcha_configuration_test.rb
151
- - test/recaptcha_test.rb
152
- - test/recaptcha_v1_test.rb
153
- - test/verify_recaptcha_test.rb
165
+ test_files: []
data/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- rdoc
2
- pkg
3
- .ruby-gemset
4
- .ruby-version
5
- .bundle
6
-
7
- .gems
8
- .rbenv-gemsets
@@ -1,3 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.1.2
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
@@ -1,52 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- recaptcha (0.4.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activesupport (4.1.8)
10
- i18n (~> 0.6, >= 0.6.9)
11
- json (~> 1.7, >= 1.7.7)
12
- minitest (~> 5.1)
13
- thread_safe (~> 0.1)
14
- tzinfo (~> 1.1)
15
- byebug (3.5.1)
16
- columnize (~> 0.8)
17
- debugger-linecache (~> 1.2)
18
- slop (~> 3.6)
19
- coderay (1.1.0)
20
- columnize (0.8.9)
21
- debugger-linecache (1.2.0)
22
- i18n (0.6.11)
23
- json (1.8.1)
24
- metaclass (0.0.4)
25
- method_source (0.8.2)
26
- minitest (5.4.3)
27
- mocha (1.1.0)
28
- metaclass (~> 0.0.1)
29
- pry (0.10.1)
30
- coderay (~> 1.1.0)
31
- method_source (~> 0.8.1)
32
- slop (~> 3.4)
33
- pry-byebug (2.0.0)
34
- byebug (~> 3.4)
35
- pry (~> 0.10)
36
- rake (10.3.2)
37
- slop (3.6.0)
38
- thread_safe (0.3.4)
39
- tzinfo (1.2.2)
40
- thread_safe (~> 0.1)
41
-
42
- PLATFORMS
43
- ruby
44
-
45
- DEPENDENCIES
46
- activesupport
47
- i18n
48
- minitest (~> 5.0)
49
- mocha
50
- pry-byebug
51
- rake
52
- recaptcha!
@@ -1,151 +0,0 @@
1
- = reCAPTCHA
2
-
3
- Author:: Jason L Perry (http://ambethia.com)
4
- Copyright:: Copyright (c) 2007-2013 Jason L Perry
5
- License:: {MIT}[http://creativecommons.org/licenses/MIT/]
6
- Info:: http://github.com/ambethia/recaptcha
7
- Bugs:: http://github.com/ambethia/recaptcha/issues
8
-
9
- This plugin adds helpers for the {reCAPTCHA API}[https://www.google.com/recaptcha]. In your
10
- views you can use the +recaptcha_tags+ method to embed the needed javascript,
11
- and you can validate in your controllers with +verify_recaptcha+ or +verify_recaptcha!+,
12
- which throws an error on failiure.
13
-
14
- Beforehand you need to configure Recaptcha with your custom private and public
15
- key. You may find detailed examples below. Exceptions will be raised if you
16
- call these methods and the keys can't be found.
17
-
18
- == Rails Installation
19
-
20
- reCAPTCHA for Rails > 3.0, add this to your Gemfile:
21
-
22
- gem "recaptcha", :require => "recaptcha/rails"
23
-
24
- Rails apps below 3.0 are no longer supported, but you can install an older
25
- release and view it's README.
26
-
27
- == Setting up your API Keys
28
-
29
- There are multiple ways to setup your reCAPTCHA API key once you
30
- {obtain}[https://www.google.com/recaptcha/admin] a pair.
31
-
32
- === Recaptcha.configure
33
-
34
- You may use the block style configuration. The following code could be placed
35
- into a +config/initializers/recaptcha.rb+ when used in a Rails project.
36
-
37
- Recaptcha.configure do |config|
38
- config.public_key = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
39
- config.private_key = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
40
- # Uncomment the following line if you are using a proxy server:
41
- # config.proxy = 'http://myproxy.com.au:8080'
42
- # Uncomment if you want to use the newer version of the API,
43
- # only works for versions >= 0.3.7:
44
- # config.api_version = 'v2'
45
- end
46
-
47
- This way, you may also set additional options to fit recaptcha into your
48
- deployment environment.
49
-
50
- == Recaptcha#with_configuration
51
-
52
- If you want to temporarily overwrite the configuration you set with `Recaptcha.configure` (when testing, for example), you can use a `Recaptcha#with_configuration` block:
53
-
54
- Recaptcha.with_configuration(:public_key => '12345') do
55
- # Do stuff with the overwritten public_key.
56
- end
57
-
58
- === Heroku & Shell environment
59
-
60
- Or, you can keep your keys out of your code base by exporting the following
61
- environment variables. You might do this in the .profile/rc, or equivalent for
62
- the user running your application. This would also be the preffered method
63
- in an Heroku deployment.
64
-
65
- export RECAPTCHA_PUBLIC_KEY = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
66
- export RECAPTCHA_PRIVATE_KEY = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
67
-
68
- === Per call
69
-
70
- You can also pass in your keys as options at runtime, for example:
71
-
72
- recaptcha_tags :public_key => '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
73
-
74
- and later,
75
-
76
- verify_recaptcha :private_key => '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
77
-
78
- This option might be useful, if the same code base is used for multiple
79
- reCAPTCHA setups.
80
-
81
- == To use 'recaptcha'
82
-
83
- Add +recaptcha_tags+ to each form you want to protect. Place it where you want the recaptcha widget to appear.
84
-
85
- Example:
86
-
87
- <%= form_for @foo do |f| %>
88
- # ... additional lines truncated for brevity ...
89
- <%= recaptcha_tags %>
90
- # ... additional lines truncated for brevity ...
91
- <% end %>
92
-
93
- And, add +verify_recaptcha+ logic to each form action that you've protected.
94
-
95
- === +recaptcha_tags+
96
-
97
- Some of the options available:
98
-
99
- <tt>:ssl</tt>:: Uses secure http for captcha widget (default +false+, but can be changed by setting +config.use_ssl_by_default+)
100
- <tt>:noscript</tt>:: Include <noscript> content (default +true+)
101
- <tt>:display</tt>:: Takes a hash containing the +theme+ and +tabindex+ options per the API. (default +nil+), options: 'red', 'white', 'blackglass', 'clean', 'custom'
102
- <tt>:ajax</tt>:: Render the dynamic AJAX captcha per the API. (default +false+)
103
- <tt>:public_key</tt>:: Your public API key, takes precedence over the ENV variable (default +nil+)
104
- <tt>:error</tt>:: Override the error code returned from the reCAPTCHA API (default +nil+)
105
-
106
- You can also override the html attributes for the sizes of the generated +textarea+ and +iframe+
107
- elements, if CSS isn't your thing. Inspect the source of +recaptcha_tags+ to see these options.
108
-
109
- === +verify_recaptcha+
110
-
111
- This method returns +true+ or +false+ after processing the parameters from the reCAPTCHA widget. Why
112
- isn't this a model validation? Because that violates MVC. You can use it like this, or how ever you
113
- like. Passing in the ActiveRecord object is optional, if you do--and the captcha fails to verify--an
114
- error will be added to the object for you to use.
115
-
116
- Some of the options available:
117
-
118
- <tt>:model</tt>:: Model to set errors
119
- <tt>:attribute</tt>:: Model attribute to receive errors (default :base)
120
- <tt>:message</tt>:: Custom error message
121
- <tt>:private_key</tt>:: Your private API key, takes precedence over the ENV variable (default +nil+).
122
- <tt>:timeout</tt>:: The number of seconds to wait for reCAPTCHA servers before give up. (default +3+)
123
-
124
- respond_to do |format|
125
- if verify_recaptcha(:model => @post, :message => "Oh! It's error with reCAPTCHA!") && @post.save
126
- # ...
127
- else
128
- # ...
129
- end
130
- end
131
-
132
- == I18n support
133
- reCAPTCHA passes two types of error explanation to a linked model. It will use the I18n gem
134
- to translate the default error message if I18n is available. To customize the messages to your locale,
135
- add these keys to your I18n backend:
136
-
137
- <tt>recaptcha.errors.verification_failed</tt>:: error message displayed if the captcha words didn't match
138
- <tt>recaptcha.errors.recaptcha_unreachable</tt>:: displayed if a timeout error occured while attempting to verify the captcha
139
-
140
- Also you can translate API response errors to human friendly by adding translations to the locale (+config/locales/en.yml+):
141
-
142
- en:
143
- recaptcha:
144
- errors:
145
- incorrect-captcha-sol: 'Fail'
146
-
147
- == TODO
148
- * Remove Rails/ActionController dependencies
149
- * Framework agnostic
150
- * Add some helpers to use in before_filter and what not
151
- * Better documentation
data/Rakefile DELETED
@@ -1,8 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
3
-
4
- Rake::TestTask.new do |t|
5
- t.test_files = FileList['test/*_test.rb']
6
- end
7
-
8
- task :default => :test
data/init.rb DELETED
@@ -1,5 +0,0 @@
1
- # Rails plugin initialization.
2
- # You can also install it as a gem:
3
- # config.gem "ambethia-recaptcha", :lib => "recaptcha/rails", :source => "http://gems.github.com"
4
-
5
- require 'recaptcha/rails'
@@ -1,4 +0,0 @@
1
- require 'recaptcha'
2
-
3
- Merb::GlobalHelpers.send(:include, Recaptcha::ClientHelper)
4
- Merb::Controller.send(:include, Recaptcha::Verify)
@@ -1,15 +0,0 @@
1
- require 'net/http'
2
- require 'recaptcha'
3
- module Rails
4
- module Recaptcha
5
- class Railtie < Rails::Railtie
6
- initializer "setup config" do
7
- begin
8
- ActionView::Base.send(:include, ::Recaptcha::ClientHelper)
9
- ActionController::Base.send(:include, ::Recaptcha::Verify)
10
- end
11
- end
12
- end
13
- end
14
- end
15
-
@@ -1,26 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "recaptcha/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = "recaptcha"
7
- s.version = Recaptcha::VERSION
8
- s.authors = ["Jason L Perry"]
9
- s.email = ["jasper@ambethia.com"]
10
- s.homepage = "http://github.com/ambethia/recaptcha"
11
- s.summary = %q{Helpers for the reCAPTCHA API}
12
- s.description = %q{This plugin adds helpers for the reCAPTCHA API}
13
-
14
- s.rubyforge_project = "recaptcha"
15
-
16
- s.files = `git ls-files`.split("\n")
17
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- s.require_paths = ["lib"]
19
-
20
- s.add_development_dependency "mocha"
21
- s.add_development_dependency "rake"
22
- s.add_development_dependency "activesupport"
23
- s.add_development_dependency "i18n"
24
- s.add_development_dependency "minitest", "~> 5.0"
25
- s.add_development_dependency "pry-byebug"
26
- end
@@ -1,44 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'cgi'
3
- require File.dirname(File.expand_path(__FILE__)) + '/../lib/recaptcha'
4
-
5
- class RecaptchaConfigurationTest < Minitest::Test
6
- include Recaptcha
7
- include Recaptcha::ClientHelper
8
- include Recaptcha::Verify
9
-
10
- attr_accessor :session
11
-
12
- def setup
13
- @session = {}
14
- @nonssl_api_server_url = Regexp.new(Regexp.quote(Recaptcha.configuration.nonssl_api_server_url) + '(.*)')
15
- @ssl_api_server_url = Regexp.new(Regexp.quote(Recaptcha.configuration.ssl_api_server_url) + '(.*)')
16
- Recaptcha.configure do |config|
17
- config.public_key = '0000000000000000000000000000000000000000'
18
- config.private_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
19
- config.api_version = 'v2'
20
- end
21
- end
22
-
23
- def test_recaptcha_api_version_default
24
- assert_equal(Recaptcha.configuration.api_version, Recaptcha::RECAPTCHA_API_VERSION)
25
- end
26
-
27
- def test_v2_with_v2_api?
28
- assert Recaptcha.configuration.v2?
29
- refute Recaptcha.configuration.v1?
30
- end
31
-
32
- def test_different_configuration_within_with_configuration_block
33
- key = Recaptcha.with_configuration(:public_key => '12345') do
34
- Recaptcha.configuration.public_key
35
- end
36
-
37
- assert_equal('12345', key)
38
- end
39
-
40
- def test_reset_configuration_after_with_configuration_block
41
- Recaptcha.with_configuration(:public_key => '12345')
42
- assert_equal('0000000000000000000000000000000000000000', Recaptcha.configuration.public_key)
43
- end
44
- end
@@ -1,54 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'cgi'
3
- require File.dirname(File.expand_path(__FILE__)) + '/../lib/recaptcha'
4
-
5
- class RecaptchaClientHelperTest < Minitest::Test
6
- include Recaptcha
7
- include Recaptcha::ClientHelper
8
- include Recaptcha::Verify
9
-
10
- attr_accessor :session
11
-
12
- def setup
13
- @session = {}
14
- @nonssl_api_server_url = Regexp.new(Regexp.quote(Recaptcha.configuration.nonssl_api_server_url) + '(.*)')
15
- @ssl_api_server_url = Regexp.new(Regexp.quote(Recaptcha.configuration.ssl_api_server_url) + '(.*)')
16
- Recaptcha.configure do |config|
17
- config.public_key = '0000000000000000000000000000000000000000'
18
- config.private_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
19
- end
20
- end
21
-
22
- def test_recaptcha_tags_v2
23
- Recaptcha.configuration.api_version = 'v2'
24
- # match a v2 only tag
25
- assert_match /data-sitekey/, recaptcha_tags
26
- # refute a v1 only tag
27
- refute_match /\/challenge\?/, recaptcha_tags
28
- end
29
-
30
- def test_ssl_by_default
31
- Recaptcha.configuration.use_ssl_by_default = true
32
- assert_match @ssl_api_server_url, recaptcha_tags
33
- end
34
-
35
- def test_relative_protocol_by_default_without_ssl
36
- Recaptcha.configuration.use_ssl_by_default = false
37
- assert_match @nonssl_api_server_url, recaptcha_tags(:ssl => false)
38
- end
39
-
40
- def test_recaptcha_tags_with_ssl
41
- assert_match @ssl_api_server_url, recaptcha_tags(:ssl => true)
42
- end
43
-
44
- def test_recaptcha_tags_without_noscript
45
- refute_match /noscript/, recaptcha_tags(:noscript => false)
46
- end
47
-
48
- def test_should_raise_exception_without_public_key
49
- assert_raises RecaptchaError do
50
- Recaptcha.configuration.public_key = nil
51
- recaptcha_tags
52
- end
53
- end
54
- end
@@ -1,35 +0,0 @@
1
- require 'minitest/autorun'
2
- require 'cgi'
3
- require File.dirname(File.expand_path(__FILE__)) + '/../lib/recaptcha'
4
-
5
- class RecaptchaV1Test < Minitest::Test
6
- include Recaptcha
7
- include Recaptcha::ClientHelper
8
- include Recaptcha::Verify
9
-
10
- attr_accessor :session
11
-
12
- def setup
13
- @session = {}
14
- @nonssl_api_server_url = Regexp.new(Regexp.quote(Recaptcha.configuration.nonssl_api_server_url) + '(.*)')
15
- @ssl_api_server_url = Regexp.new(Regexp.quote(Recaptcha.configuration.ssl_api_server_url) + '(.*)')
16
- Recaptcha.configure do |config|
17
- config.public_key = '0000000000000000000000000000000000000000'
18
- config.private_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
19
- config.api_version = 'v1'
20
- end
21
- end
22
-
23
- def test_v1_with_v1_api?
24
- assert Recaptcha.configuration.v1?
25
- refute Recaptcha.configuration.v2?
26
- end
27
-
28
- def test_recaptcah_tags_v1
29
- Recaptcha.configuration.api_version = 'v1'
30
- # match a v1 only tag
31
- assert_match /\/challenge\?/, recaptcha_tags
32
- # refute a v2 only tag
33
- refute_match /data-sitekey/, recaptcha_tags
34
- end
35
- end
@@ -1,191 +0,0 @@
1
- # coding: utf-8
2
-
3
- require 'minitest/autorun'
4
- require 'rubygems'
5
- require 'active_support'
6
- require 'active_support/core_ext/string'
7
- require 'mocha/setup'
8
- require 'i18n'
9
- require 'net/http'
10
- require File.dirname(File.expand_path(__FILE__)) + '/../lib/recaptcha'
11
-
12
- class RecaptchaVerifyTest < Minitest::Test
13
- def setup
14
- Recaptcha.configuration.private_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
15
- @controller = TestController.new
16
- @controller.request = stub(:remote_ip => "1.1.1.1", format: :html)
17
-
18
- @expected_post_data = {}
19
- @expected_post_data["remoteip"] = @controller.request.remote_ip
20
- @expected_post_data["response"] = "response"
21
-
22
- if Recaptcha.configuration.v1?
23
- @controller.params = {:recaptcha_challenge_field => "challenge", :recaptcha_response_field => "response"}
24
- @expected_post_data["privatekey"] = Recaptcha.configuration.private_key
25
- @expected_post_data["challenge"] = "challenge"
26
- end
27
-
28
- if Recaptcha.configuration.v2?
29
- @controller.params = {:recaptcha_response_field => "response"}
30
- @expected_post_data["secret"] = Recaptcha.configuration.private_key
31
- end
32
-
33
- @expected_uri = URI.parse(Recaptcha.configuration.verify_url)
34
- end
35
-
36
- def test_should_raise_exception_when_calling_bang_method
37
- @controller.expects(:verify_recaptcha).returns(false)
38
-
39
- assert_raises Recaptcha::VerifyError do
40
- @controller.verify_recaptcha!
41
- end
42
- end
43
-
44
- def test_should_return_whatever_verify_method_returns_when_using_bang_method
45
- @controller.expects(:verify_recaptcha).returns(:foo)
46
-
47
- assert_equal :foo, @controller.verify_recaptcha!
48
- end
49
-
50
- def test_should_raise_exception_without_private_key
51
- skip
52
- assert_raises Recaptcha::RecaptchaError do
53
- Recaptcha.configuration.private_key = nil
54
- @controller.verify_recaptcha
55
- end
56
- end
57
-
58
- def test_should_return_false_when_key_is_invalid
59
- skip
60
- expect_http_post(response_with_body("false\ninvalid-site-private-key"))
61
-
62
- assert !@controller.verify_recaptcha
63
- assert_equal "invalid-site-private-key", @controller.flash[:recaptcha_error]
64
- end
65
-
66
- def test_returns_true_on_success
67
- skip
68
- @controller.flash[:recaptcha_error] = "previous error that should be cleared"
69
- expect_http_post(response_with_body("true\n"))
70
-
71
- assert @controller.verify_recaptcha
72
- assert_nil @controller.flash[:recaptcha_error]
73
- end
74
-
75
- def test_errors_should_be_added_to_model
76
- skip
77
- expect_http_post(response_with_body("false\nbad-news"))
78
-
79
- errors = mock
80
- errors.expects(:add).with(:base, "Word verification response is incorrect, please try again.")
81
- model = mock(:errors => errors)
82
-
83
- assert !@controller.verify_recaptcha(:model => model)
84
- assert_equal "bad-news", @controller.flash[:recaptcha_error]
85
- end
86
-
87
- def test_returns_true_on_success_with_optional_key
88
- skip
89
- @controller.flash[:recaptcha_error] = "previous error that should be cleared"
90
- # reset private key
91
- @expected_post_data["privatekey"] = 'ADIFFERENTPRIVATEKEYXXXXXXXXXXXXXX'
92
- expect_http_post(response_with_body("true\n"))
93
-
94
- assert @controller.verify_recaptcha(:private_key => 'ADIFFERENTPRIVATEKEYXXXXXXXXXXXXXX')
95
- assert_nil @controller.flash[:recaptcha_error]
96
- end
97
-
98
- def test_timeout
99
- skip
100
- expect_http_post(Timeout::Error, :exception => true)
101
- assert !@controller.verify_recaptcha()
102
- assert_equal "Recaptcha unreachable.", @controller.flash[:recaptcha_error]
103
- end
104
-
105
- def test_timeout_when_handle_timeouts_gracefully_disabled
106
- skip
107
- Recaptcha.with_configuration(:handle_timeouts_gracefully => false) do
108
- expect_http_post(Timeout::Error, :exception => true)
109
- assert_raises Recaptcha::RecaptchaError, "Recaptcha unreachable." do
110
- assert @controller.verify_recaptcha()
111
- end
112
- assert_nil @controller.flash[:recaptcha_error]
113
- end
114
- end
115
-
116
- def test_message_should_use_i18n
117
- skip
118
- I18n.locale = :de
119
- verification_failed_translated = "Sicherheitscode konnte nicht verifiziert werden."
120
- verification_failed_default = "Word verification response is incorrect, please try again."
121
- recaptcha_unreachable_translated = "Netzwerkfehler, bitte versuchen Sie es später erneut."
122
- recaptcha_unreachable_default = "Oops, we failed to validate your word verification response. Please try again."
123
-
124
- I18n.expects(:translate).with('recaptcha.errors.bad-news', {:default => 'bad-news'})
125
- I18n.expects(:translate).with('recaptcha.errors.recaptcha_unreachable', {:default => 'Recaptcha unreachable.'})
126
-
127
- I18n.expects(:translate).with('recaptcha.errors.verification_failed', :default => verification_failed_default).returns(verification_failed_translated)
128
- I18n.expects(:translate).with('recaptcha.errors.recaptcha_unreachable', :default => recaptcha_unreachable_default).returns(recaptcha_unreachable_translated)
129
-
130
- errors = mock
131
- errors.expects(:add).with(:base, verification_failed_translated)
132
- errors.expects(:add).with(:base, recaptcha_unreachable_translated)
133
- model = mock; model.stubs(:errors => errors)
134
-
135
- expect_http_post(response_with_body("false\nbad-news"))
136
- @controller.verify_recaptcha(:model => model)
137
-
138
- expect_http_post(Timeout::Error, :exception => true)
139
- @controller.verify_recaptcha(:model => model)
140
-
141
- end
142
-
143
- def test_it_translates_api_response_with_i18n
144
- skip
145
- api_error_translated = "Bad news, body :("
146
- expect_http_post(response_with_body("false\nbad-news"))
147
- I18n.expects(:translate).with('recaptcha.errors.bad-news', :default => 'bad-news').returns(api_error_translated)
148
-
149
- assert !@controller.verify_recaptcha
150
- assert_equal api_error_translated, @controller.flash[:recaptcha_error]
151
- end
152
-
153
- def test_it_fallback_to_api_response_if_i18n_translation_is_missing
154
- skip
155
- expect_http_post(response_with_body("false\nbad-news"))
156
-
157
- assert !@controller.verify_recaptcha
158
- assert_equal 'bad-news', @controller.flash[:recaptcha_error]
159
- end
160
-
161
- def test_not_flashing_error_if_request_format_not_in_html
162
- skip
163
- @controller.request = stub(:remote_ip => "1.1.1.1", format: :json)
164
- expect_http_post(response_with_body("false\nbad-news"))
165
- assert !@controller.verify_recaptcha
166
- assert_nil @controller.flash[:recaptcha_error]
167
- end
168
-
169
- private
170
-
171
- class TestController
172
- include Recaptcha::Verify
173
- attr_accessor :request, :params, :flash
174
-
175
- def initialize
176
- @flash = {}
177
- end
178
- end
179
-
180
- def expect_http_post(response, options = {})
181
- unless options[:exception]
182
- Net::HTTP.expects(:post_form).with(@expected_uri, @expected_post_data).returns(response)
183
- else
184
- Net::HTTP.expects(:post_form).raises response
185
- end
186
- end
187
-
188
- def response_with_body(body)
189
- stub(:body => body)
190
- end
191
- end