recaptcha 0.3.6 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,9 +28,7 @@ module Recaptcha
28
28
  # end
29
29
  #
30
30
  class Configuration
31
- attr_accessor :nonssl_api_server_url,
32
- :ssl_api_server_url,
33
- :verify_url,
31
+ attr_accessor :api_version,
34
32
  :skip_verify_env,
35
33
  :private_key,
36
34
  :public_key,
@@ -39,20 +37,38 @@ module Recaptcha
39
37
  :use_ssl_by_default
40
38
 
41
39
  def initialize #:nodoc:
42
- @nonssl_api_server_url = RECAPTCHA_API_SERVER_URL
43
- @ssl_api_server_url = RECAPTCHA_API_SECURE_SERVER_URL
44
- @verify_url = RECAPTCHA_VERIFY_URL
40
+ @api_version = RECAPTCHA_API_VERSION
45
41
  @skip_verify_env = SKIP_VERIFY_ENV
46
42
  @handle_timeouts_gracefully = HANDLE_TIMEOUTS_GRACEFULLY
47
43
  @use_ssl_by_default = USE_SSL_BY_DEFAULT
48
44
 
49
45
  @private_key = ENV['RECAPTCHA_PRIVATE_KEY']
50
- @public_key = ENV['RECAPTCHA_PUBLIC_KEY']
46
+ @public_key = ENV['RECAPTCHA_PUBLIC_KEY']
51
47
  end
52
48
 
53
49
  def api_server_url(ssl = nil) #:nodoc:
54
50
  ssl = use_ssl_by_default if ssl.nil?
55
51
  ssl ? ssl_api_server_url : nonssl_api_server_url
56
52
  end
53
+
54
+ def nonssl_api_server_url
55
+ CONFIG[@api_version]['server_url']
56
+ end
57
+
58
+ def ssl_api_server_url
59
+ CONFIG[@api_version]['secure_server_url']
60
+ end
61
+
62
+ def verify_url
63
+ CONFIG[@api_version]['verify_url']
64
+ end
65
+
66
+ def v1?
67
+ @api_version == 'v1'
68
+ end
69
+
70
+ def v2?
71
+ @api_version == 'v2'
72
+ end
57
73
  end
58
74
  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
@@ -0,0 +1,24 @@
1
+ require 'json'
2
+ require 'recaptcha'
3
+ require 'base64'
4
+ require 'securerandom'
5
+ require 'openssl'
6
+
7
+ module Recaptcha
8
+ module Token
9
+
10
+ def self.secure_token
11
+ private_key = Recaptcha.configuration.private_key
12
+ raise RecaptchaError, "No private key specified." unless private_key
13
+
14
+ stoken_json = {'session_id' => SecureRandom.uuid, 'ts_ms' => (Time.now.to_f * 1000).to_i}.to_json
15
+ cipher = OpenSSL::Cipher::AES128.new(:ECB)
16
+ private_key_digest = Digest::SHA1.digest(private_key)[0...16]
17
+
18
+ cipher.encrypt
19
+ cipher.key = private_key_digest
20
+ encrypted_stoken = cipher.update(stoken_json) << cipher.final
21
+ Base64.urlsafe_encode64(encrypted_stoken).gsub(/\=+\Z/, '')
22
+ end
23
+ end
24
+ end
@@ -1,15 +1,17 @@
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
- if !options.is_a? Hash
8
- options = {:model => options}
9
- end
11
+ options = {:model => options} unless options.is_a? Hash
10
12
 
11
- env = options[:env] || ENV['RAILS_ENV']
12
- return true if Recaptcha.configuration.skip_verify_env.include? env
13
+ env_options = options[:env] || ENV['RAILS_ENV'] || (Rails.env if defined? Rails.env)
14
+ return true if Recaptcha.configuration.skip_verify_env.include? env_options
13
15
  model = options[:model]
14
16
  attribute = options[:attribute] || :base
15
17
  private_key = options[:private_key] || Recaptcha.configuration.private_key
@@ -17,59 +19,98 @@ module Recaptcha
17
19
 
18
20
  begin
19
21
  recaptcha = nil
20
- if(Recaptcha.configuration.proxy)
22
+ if Recaptcha.configuration.proxy
21
23
  proxy_server = URI.parse(Recaptcha.configuration.proxy)
22
24
  http = Net::HTTP::Proxy(proxy_server.host, proxy_server.port, proxy_server.user, proxy_server.password)
23
25
  else
24
26
  http = Net::HTTP
25
27
  end
26
28
 
27
- Timeout::timeout(options[:timeout] || 3) do
28
- recaptcha = http.post_form(URI.parse(Recaptcha.configuration.verify_url), {
29
+ # env['REMOTE_ADDR'] to retrieve IP for Grape API
30
+ remote_ip = (request.respond_to?(:remote_ip) && request.remote_ip) || (env && env['REMOTE_ADDR'])
31
+ if Recaptcha.configuration.v1?
32
+ verify_hash = {
29
33
  "privatekey" => private_key,
30
- "remoteip" => request.remote_ip,
34
+ "remoteip" => remote_ip,
31
35
  "challenge" => params[:recaptcha_challenge_field],
32
36
  "response" => params[:recaptcha_response_field]
33
- })
37
+ }
38
+ Timeout::timeout(options[:timeout] || DEFAULT_TIMEOUT) do
39
+ recaptcha = http.post_form(URI.parse(Recaptcha.configuration.verify_url), verify_hash)
40
+ end
41
+ answer, error = recaptcha.body.split.map { |s| s.chomp }
34
42
  end
35
- answer, error = recaptcha.body.split.map { |s| s.chomp }
36
- unless answer == 'true'
37
- flash[:recaptcha_error] = if defined?(I18n)
38
- I18n.translate("recaptcha.errors.#{error}", {:default => error})
39
- else
40
- error
43
+
44
+ if Recaptcha.configuration.v2?
45
+ verify_hash = {
46
+ "secret" => private_key,
47
+ "remoteip" => remote_ip,
48
+ "response" => params['g-recaptcha-response']
49
+ }
50
+
51
+ Timeout::timeout(options[:timeout] || DEFAULT_TIMEOUT) do
52
+ uri = URI.parse(Recaptcha.configuration.verify_url + '?' + verify_hash.to_query)
53
+ http_instance = http.new(uri.host, uri.port)
54
+ if uri.port == 443
55
+ http_instance.use_ssl =
56
+ http_instance.verify_mode = OpenSSL::SSL::VERIFY_NONE
57
+ end
58
+ request = Net::HTTP::Get.new(uri.request_uri)
59
+ recaptcha = http_instance.request(request)
60
+ end
61
+ answer, error = JSON.parse(recaptcha.body).values
62
+ end
63
+
64
+ if answer.to_s == 'true'
65
+ flash.delete(:recaptcha_error) if request_in_html_format?
66
+ true
67
+ else
68
+ error = 'verification_failed' if error && Recaptcha.configuration.v2?
69
+ if request_in_html_format?
70
+ flash[:recaptcha_error] = if defined?(I18n)
71
+ I18n.translate("recaptcha.errors.#{error}", default: error)
72
+ else
73
+ error
74
+ end
41
75
  end
42
76
 
43
77
  if model
44
78
  message = "Word verification response is incorrect, please try again."
45
- 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)
46
80
  model.errors.add attribute, options[:message] || message
47
81
  end
48
- return false
49
- else
50
- flash.delete(:recaptcha_error)
51
- return true
82
+ false
52
83
  end
53
84
  rescue Timeout::Error
54
85
  if Recaptcha.configuration.handle_timeouts_gracefully
55
- flash[:recaptcha_error] = if defined?(I18n)
56
- I18n.translate('recaptcha.errors.recaptcha_unreachable', {:default => 'Recaptcha unreachable.'})
57
- else
58
- 'Recaptcha unreachable.'
86
+ if request_in_html_format?
87
+ flash[:recaptcha_error] = if defined?(I18n)
88
+ I18n.translate('recaptcha.errors.recaptcha_unreachable', default: 'Recaptcha unreachable.')
89
+ else
90
+ 'Recaptcha unreachable.'
91
+ end
59
92
  end
60
93
 
61
94
  if model
62
95
  message = "Oops, we failed to validate your word verification response. Please try again."
63
- 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)
64
97
  model.errors.add attribute, options[:message] || message
65
98
  end
66
- return false
99
+ false
67
100
  else
68
101
  raise RecaptchaError, "Recaptcha unreachable."
69
102
  end
70
- rescue Exception => e
103
+ rescue StandardError => e
71
104
  raise RecaptchaError, e.message, e.backtrace
72
105
  end
73
- end # verify_recaptcha
74
- end # Verify
75
- end # Recaptcha
106
+ end
107
+
108
+ def request_in_html_format?
109
+ request.respond_to?(:format) && request.format == :html && respond_to?(:flash)
110
+ end
111
+
112
+ def verify_recaptcha!(options = {})
113
+ verify_recaptcha(options) or raise VerifyError
114
+ end
115
+ end
116
+ end
@@ -1,3 +1,3 @@
1
1
  module Recaptcha
2
- VERSION = "0.3.6"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,98 +1,147 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: recaptcha
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.6.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: 2014-01-07 00:00:00.000000000 Z
11
+ date: 2015-11-19 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
16
30
  requirements:
17
- - - '>='
31
+ - - ">="
18
32
  - !ruby/object:Gem::Version
19
33
  version: '0'
20
34
  type: :development
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - '>='
38
+ - - ">="
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - '>='
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
47
  version: '0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - '>='
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: activesupport
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - '>='
59
+ - - ">="
46
60
  - !ruby/object:Gem::Version
47
61
  version: '0'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - '>='
66
+ - - ">="
53
67
  - !ruby/object:Gem::Version
54
68
  version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: i18n
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - '>='
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: maxitest
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry-byebug
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: bump
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
60
116
  - !ruby/object:Gem::Version
61
117
  version: '0'
62
118
  type: :development
63
119
  prerelease: false
64
120
  version_requirements: !ruby/object:Gem::Requirement
65
121
  requirements:
66
- - - '>='
122
+ - - ">="
67
123
  - !ruby/object:Gem::Version
68
124
  version: '0'
69
- description: This plugin adds helpers for the reCAPTCHA API
125
+ description: Helpers for the reCAPTCHA API
70
126
  email:
71
127
  - jasper@ambethia.com
72
128
  executables: []
73
129
  extensions: []
74
130
  extra_rdoc_files: []
75
131
  files:
76
- - .gitignore
77
132
  - CHANGELOG
78
- - Gemfile
79
133
  - LICENSE
80
- - README.rdoc
81
- - Rakefile
82
- - init.rb
134
+ - README.md
83
135
  - lib/recaptcha.rb
84
136
  - lib/recaptcha/client_helper.rb
85
137
  - lib/recaptcha/configuration.rb
86
- - lib/recaptcha/merb.rb
87
138
  - lib/recaptcha/rails.rb
88
- - lib/recaptcha/railtie.rb
139
+ - lib/recaptcha/token.rb
89
140
  - lib/recaptcha/verify.rb
90
141
  - lib/recaptcha/version.rb
91
- - recaptcha.gemspec
92
- - test/recaptcha_test.rb
93
- - test/verify_recaptcha_test.rb
94
142
  homepage: http://github.com/ambethia/recaptcha
95
- licenses: []
143
+ licenses:
144
+ - MIT
96
145
  metadata: {}
97
146
  post_install_message:
98
147
  rdoc_options: []
@@ -100,20 +149,18 @@ require_paths:
100
149
  - lib
101
150
  required_ruby_version: !ruby/object:Gem::Requirement
102
151
  requirements:
103
- - - '>='
152
+ - - ">="
104
153
  - !ruby/object:Gem::Version
105
- version: '0'
154
+ version: 2.0.0
106
155
  required_rubygems_version: !ruby/object:Gem::Requirement
107
156
  requirements:
108
- - - '>='
157
+ - - ">="
109
158
  - !ruby/object:Gem::Version
110
159
  version: '0'
111
160
  requirements: []
112
- rubyforge_project: recaptcha
113
- rubygems_version: 2.1.10
161
+ rubyforge_project:
162
+ rubygems_version: 2.4.5.1
114
163
  signing_key:
115
164
  specification_version: 4
116
165
  summary: Helpers for the reCAPTCHA API
117
- test_files:
118
- - test/recaptcha_test.rb
119
- - test/verify_recaptcha_test.rb
166
+ test_files: []
data/.gitignore DELETED
@@ -1,3 +0,0 @@
1
- rdoc
2
- pkg
3
- Gemfile.lock