iGEL-ruby-recaptcha 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest ADDED
@@ -0,0 +1,11 @@
1
+ Manifest
2
+ Rakefile
3
+ test/test_recaptcha.rb
4
+ test/test_helper.rb
5
+ script/console
6
+ script/generate
7
+ script/destroy
8
+ lib/recaptcha.rb
9
+ lib/ruby-recaptcha.rb
10
+ README.textile
11
+ ruby-recaptcha.gemspec
data/README.textile ADDED
@@ -0,0 +1,15 @@
1
+ h2. About this fork
2
+
3
+ This is my almost unchanged fork of "ruby-recaptcha":http://bitbucket.org/mml/ruby-recaptcha/wiki/Home See there for the original by McClain Looney and others.
4
+
5
+ I just want to change the error message, so I made it customable.
6
+
7
+ h2. License
8
+
9
+ Copyright (c) 2009 McClain Looney
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+
5
+ Echoe.new('ruby-recaptcha', "1.0.0") do |p|
6
+ p.description = "My almost unchanged fork of ruby-recaptcha"
7
+ p.url = "http://bitbucket.org/mml/ruby-recaptcha/wiki/Home"
8
+ p.author = "Johannes Barre"
9
+ p.email = "igel@igels.net"
10
+ p.ignore_pattern = ["pkg/*", "logs/*", "output*", "nbproject/**", "nbproject/private/*"]
11
+ p.development_dependencies = []
12
+ end
data/lib/recaptcha.rb ADDED
@@ -0,0 +1,142 @@
1
+ #Copyright (c) 2007, 2008, 2009 McClain Looney
2
+ #
3
+ #Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ #of this software and associated documentation files (the "Software"), to deal
5
+ #in the Software without restriction, including without limitation the rights
6
+ #to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ #copies of the Software, and to permit persons to whom the Software is
8
+ #furnished to do so, subject to the following conditions:
9
+ #
10
+ #The above copyright notice and this permission notice shall be included in
11
+ #all copies or substantial portions of the Software.
12
+ #
13
+ #THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ #IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ #FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ #AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ #LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ #OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ #THE SOFTWARE.
20
+ require 'openssl'
21
+ require 'base64'
22
+ require 'cgi'
23
+ require 'net/http'
24
+ require 'net/https'
25
+ module ReCaptcha
26
+ module ViewHelper
27
+ def get_captcha(options={})
28
+ k = ReCaptcha::Client.new(options[:rcc_pub] || RCC_PUB, options[:rcc_priv] || RCC_PRIV, options[:ssl] || false)
29
+ r = k.get_challenge(session[:rcc_err] || '', options)
30
+ session[:rcc_err]=''
31
+ r
32
+ end
33
+ def mail_hide(address, contents=nil)
34
+ contents = truncate(address,10) if contents.nil?
35
+ k = ReCaptcha::MHClient.new(MH_PUB, MH_PRIV)
36
+ enciphered = k.encrypt(address)
37
+ uri = "http://mailhide.recaptcha.net/d?k=#{MH_PUB}&c=#{enciphered}"
38
+ t =<<-EOF
39
+ <a href="#{uri}"
40
+ onclick="window.open('#{uri}', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;" title="Reveal this e-mail address">#{contents}</a>
41
+ EOF
42
+ end
43
+
44
+ end
45
+ module AppHelper
46
+ private
47
+ def validate_recap(p, errors, options = {:msg => "Captcha failed."})
48
+ rcc=ReCaptcha::Client.new(options[:rcc_pub] || RCC_PUB, options[:rcc_priv] || RCC_PRIV)
49
+ res = rcc.validate(request.remote_ip, p[:recaptcha_challenge_field], p[:recaptcha_response_field], errors, options[:msg])
50
+ session[:rcc_err]=rcc.last_error
51
+
52
+ res
53
+ end
54
+ end
55
+ class MHClient
56
+ def initialize(pubkey, privkey)
57
+ @pubkey=pubkey
58
+ @privkey=privkey
59
+ @host='mailhide.recaptcha.net'
60
+ end
61
+ def encrypt(string)
62
+ padded = pad(string)
63
+ iv="\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"
64
+ cipher=OpenSSL::Cipher::Cipher.new("AES-128-CBC")
65
+ binkey = @privkey.unpack('a2'*16).map{|x| x.hex}.pack('c'*16)
66
+ cipher.encrypt
67
+ cipher.key=binkey
68
+ cipher.iv=iv
69
+ ciphertext = []
70
+ cipher.padding=0
71
+ ciphertext = cipher.update(padded)
72
+ ciphertext << cipher.final() rescue nil
73
+ Base64.encode64(ciphertext).strip.gsub(/\+/, '-').gsub(/\//, '_').gsub(/\n/,'')
74
+ end
75
+ def pad(str)
76
+ l= 16-(str.length%16)
77
+ l.times do
78
+ str<< l
79
+ end
80
+ str
81
+ end
82
+ end
83
+ class Client
84
+
85
+ def initialize(pubkey, privkey, ssl=false)
86
+ @pubkey = pubkey
87
+ @privkey=privkey
88
+ @host = ssl ? 'api-secure.recaptcha.net':'api.recaptcha.net'
89
+ @vhost = 'api-verify.recaptcha.net'
90
+ @proto = ssl ? 'https' : 'http'
91
+ @ssl = ssl
92
+ @last_error=nil
93
+ end
94
+
95
+ def get_challenge(error='', options={})
96
+ s=''
97
+ if options[:options]
98
+ s << "<script type=\"text/javascript\">\nvar RecaptchaOptions = { "
99
+ options[:options].each do |k,v|
100
+ val = (v.class == Fixnum) ? "#{v}" : "\"#{v}\""
101
+ s << "#{k} : #{val}, "
102
+ end
103
+ s.sub!(/, $/, '};')
104
+ s << "\n</script>\n"
105
+ end
106
+ errslug = (error.empty?||error==nil||error=="success") ? '' : "&error=#{CGI.escape(error)}"
107
+ s <<<<-EOF
108
+ <script type="text/javascript" src="#{@proto}://#{@host}/challenge?k=#{CGI.escape(@pubkey)}#{errslug}"> </script>
109
+ <noscript>
110
+ <iframe src="#{@proto}://#{@host}/noscript?k=#{CGI.escape(@pubkey)}#{errslug}"
111
+ height="300" width="500" frameborder="0"></iframe><br>
112
+ <textarea name="recaptcha_challenge_field" rows="3" cols="40">
113
+ </textarea>
114
+ <input type="hidden" name="recaptcha_response_field"
115
+ value="manual_challenge">
116
+ </noscript>
117
+ EOF
118
+ end
119
+
120
+ def last_error
121
+ @last_error
122
+ end
123
+ def validate(remoteip, challenge, response, errors, msg)
124
+ unless response and challenge
125
+ errors.add_to_base(msg)
126
+ return false
127
+ end
128
+ proxy_host, proxy_port = nil, nil
129
+ proxy_host, proxy_port = ENV['proxy_host'].split(':') if ENV.has_key?('proxy_host')
130
+ http = Net::HTTP::Proxy(proxy_host, proxy_port).start(@vhost)
131
+ path='/verify'
132
+ data = "privatekey=#{CGI.escape(@privkey)}&remoteip=#{CGI.escape(remoteip)}&challenge=#{CGI.escape(challenge)}&response=#{CGI.escape(response)}"
133
+ resp, data = http.post(path, data, {'Content-Type'=>'application/x-www-form-urlencoded'})
134
+ response = data.split
135
+ result = response[0].chomp
136
+ @last_error=response[1].chomp
137
+ errors.add_to_base(msg) if result != 'true'
138
+ result == 'true'
139
+ end
140
+ end
141
+
142
+ end
@@ -0,0 +1,7 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'recaptcha'
5
+ module RubyRecaptcha
6
+ VERSION = '1.0.0'
7
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{ruby-recaptcha}
5
+ s.version = "1.0.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Johannes Barre"]
9
+ s.date = %q{2009-03-16}
10
+ s.description = %q{My almost unchanged fork of ruby-recaptcha}
11
+ s.email = %q{igel@igels.net}
12
+ s.extra_rdoc_files = ["lib/recaptcha.rb", "lib/ruby-recaptcha.rb", "README.textile"]
13
+ s.files = ["Manifest", "Rakefile", "test/test_recaptcha.rb", "test/test_helper.rb", "script/console", "script/generate", "script/destroy", "lib/recaptcha.rb", "lib/ruby-recaptcha.rb", "README.textile", "ruby-recaptcha.gemspec"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://bitbucket.org/mml/ruby-recaptcha/wiki/Home}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Ruby-recaptcha", "--main", "README.textile"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{ruby-recaptcha}
19
+ s.rubygems_version = %q{1.3.1}
20
+ s.summary = %q{My almost unchanged fork of ruby-recaptcha}
21
+ s.test_files = ["test/test_recaptcha.rb", "test/test_helper.rb"]
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 2
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ else
29
+ end
30
+ else
31
+ end
32
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/ruby-recaptcha.rb'}"
9
+ puts "Loading ruby-recaptcha gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require File.dirname(__FILE__) + '/../lib/ruby-recaptcha'
@@ -0,0 +1,336 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+ require 'rubygems'
3
+ gem 'mocha'
4
+ require 'mocha'
5
+ gem 'rails'
6
+
7
+ module ReCaptcha
8
+ module ViewHelper
9
+ def self.define_public_key
10
+ class_eval "RCC_PUB = 'foo'"
11
+ end
12
+ def self.define_private_key
13
+ class_eval "RCC_PRIV = 'bar'"
14
+ end
15
+ def self.undefine_public_key
16
+ remove_const :RCC_PUB
17
+ end
18
+ def self.undefine_private_key
19
+ remove_const :RCC_PRIV
20
+ end
21
+ end
22
+ module AppHelper
23
+ def self.define_public_key
24
+ class_eval "RCC_PUB = 'foo'"
25
+ end
26
+ def self.define_private_key
27
+ class_eval "RCC_PRIV = 'bar'"
28
+ end
29
+ def self.undefine_public_key
30
+ remove_const :RCC_PUB
31
+ end
32
+ def self.undefine_private_key
33
+ remove_const :RCC_PRIV
34
+ end
35
+ public :validate_recap
36
+ end
37
+ end
38
+
39
+ class TestRecaptcha < Test::Unit::TestCase
40
+ class ViewFixture
41
+ PRIVKEY='6LdnAQAAAAAAAPYLVPwVvR7Cy9YLhRQcM3NWsK_C'
42
+ PUBKEY='6LdnAQAAAAAAAKEk59yjuP3csGEeDmdj__7cyMtY'
43
+ include ReCaptcha::ViewHelper
44
+ # views in Rails "inherit" the controller's session...
45
+ def session
46
+ @session ||= {}
47
+ end
48
+ end
49
+ class ControllerFixture
50
+ include ReCaptcha::AppHelper
51
+ attr_reader :request
52
+ # all Rails controllers have a session...
53
+ def session
54
+ @session ||= {}
55
+ end
56
+ def initialize()
57
+ @request = mock()
58
+ @request.stubs(:remote_ip).returns('0.0.0.0') # this will skip the actual captcha validation...
59
+ @request
60
+ end
61
+ include Mocha::Standalone
62
+ end
63
+
64
+ def setup
65
+ @vf = ViewFixture.new
66
+ @cf = ControllerFixture.new
67
+ end
68
+
69
+ def test_encrypt
70
+ mhc = ReCaptcha::MHClient.new('01S1TOX9aibKxfC9oJlp8IeA==', 'deadbeefdeadbeefdeadbeefdeadbeef')
71
+ z =mhc.encrypt('x@example.com')
72
+ assert_equal 'wBG7nOgntKqWeDpF9ucVNQ==', z
73
+ z =mhc.encrypt('johndoe@example.com')
74
+ assert_equal 'whWIqk0r4urZ-3S7y7uSceC9_ECd3hpAGy71E2o0HpI=', z
75
+ end
76
+ def test_encrypt_long
77
+ mhc = ReCaptcha::MHClient.new('01S1TOX9aibKxfC9oJlp8IeA==', 'deadbeefdeadbeefdeadbeefdeadbeef')
78
+ z =mhc.encrypt('averylongemailaddressofmorethan32cdharactersx@example.com')
79
+ assert_equal "q-0LLVT2bIxWbFpfLfpNhJAGadkfWXVk4hAxSlVaLrdnXrsB1NKNubavS5N-7PBued3K531vifN6NB3iz3W7qQ==",z
80
+ z =mhc.encrypt('johndoe@example.com')
81
+ assert_equal 'whWIqk0r4urZ-3S7y7uSceC9_ECd3hpAGy71E2o0HpI=', z
82
+ end
83
+
84
+ def test_nil_challenge
85
+ client = new_client
86
+ estub = stub_everything('errors')
87
+ client.validate('abc', nil, 'foo', estub)
88
+
89
+ end
90
+
91
+ def test_constructor
92
+ client = new_client('abc', 'def', true)
93
+ expected= <<-EOF
94
+ <script type=\"text/javascript\" src=\"https://api-secure.recaptcha.net/challenge?k=abc\"> </script>\n <noscript>\n <iframe src=\"https://api-secure.recaptcha.net/noscript?k=abc\"\n height=\"300\" width=\"500\" frameborder=\"0\"></iframe><br>\n <textarea name=\"recaptcha_challenge_field\" rows=\"3\" cols=\"40\">\n </textarea>\n <input type=\"hidden\" name=\"recaptcha_response_field\" \n value=\"manual_challenge\">\n </noscript>
95
+ EOF
96
+ assert_equal expected.strip, client.get_challenge.strip
97
+ client = new_client
98
+ expected= <<-EOF
99
+ <script type=\"text/javascript\" src=\"http://api.recaptcha.net/challenge?k=abc\"> </script>\n <noscript>\n <iframe src=\"http://api.recaptcha.net/noscript?k=abc\"\n height=\"300\" width=\"500\" frameborder=\"0\"></iframe><br>\n <textarea name=\"recaptcha_challenge_field\" rows=\"3\" cols=\"40\">\n </textarea>\n <input type=\"hidden\" name=\"recaptcha_response_field\" \n value=\"manual_challenge\">\n </noscript>
100
+ EOF
101
+ assert_equal expected.strip, client.get_challenge.strip
102
+ client = new_client
103
+ expected= <<-EOF
104
+ <script type=\"text/javascript\" src=\"http://api.recaptcha.net/challenge?k=abc\"> </script>\n <noscript>\n <iframe src=\"http://api.recaptcha.net/noscript?k=abc\"\n height=\"300\" width=\"500\" frameborder=\"0\"></iframe><br>\n <textarea name=\"recaptcha_challenge_field\" rows=\"3\" cols=\"40\">\n </textarea>\n <input type=\"hidden\" name=\"recaptcha_response_field\" \n value=\"manual_challenge\">\n </noscript>
105
+ EOF
106
+ assert_equal expected.strip, client.get_challenge.strip
107
+ end
108
+
109
+ def test_constructor_with_recaptcha_options
110
+ # "Look and Feel Customization" per http://recaptcha.net/apidocs/captcha/
111
+ client = new_client
112
+ expected= <<-EOF
113
+ <script type=\"text/javascript\">\nvar RecaptchaOptions = { theme : \"white\", tabindex : 10};\n</script>\n <script type=\"text/javascript\" src=\"http://api.recaptcha.net/challenge?k=abc&error=somerror\"> </script>\n <noscript>\n <iframe src=\"http://api.recaptcha.net/noscript?k=abc&error=somerror\"\n height=\"300\" width=\"500\" frameborder=\"0\"></iframe><br>\n <textarea name=\"recaptcha_challenge_field\" rows=\"3\" cols=\"40\">\n </textarea>\n <input type=\"hidden\" name=\"recaptcha_response_field\" \n value=\"manual_challenge\">\n </noscript>
114
+ EOF
115
+ assert_equal expected.strip, client.get_challenge('somerror', :options => {:theme => 'white', :tabindex => 10}).strip
116
+ end
117
+
118
+ def test_validate_fails
119
+ badwords_resp="false\r\n360 incorrect-captcha-sol"
120
+ err_stub=mock()
121
+ err_stub.expects(:add_to_base).with("Captcha failed.")
122
+ stub_proxy=mock('proxy')
123
+ stub_http = mock('http mock')
124
+ stub_proxy.expects(:start).with('api-verify.recaptcha.net').returns(stub_http)
125
+ stub_http.expects(:post).with('/verify', 'privatekey=def&remoteip=localhost&challenge=abc&response=def', {'Content-Type' => 'application/x-www-form-urlencoded'}).returns(['foo', badwords_resp])
126
+ Net::HTTP.expects(:Proxy).returns(stub_proxy)
127
+ client = new_client
128
+ assert !client.validate('localhost', 'abc', 'def', err_stub)
129
+ end
130
+ def test_validate_good
131
+ goodwords_resp="true\r\nsuccess"
132
+ err_stub=mock()
133
+ stub_proxy=mock('proxy')
134
+ stub_http = mock('http mock')
135
+ stub_proxy.expects(:start).with('api-verify.recaptcha.net').returns(stub_http)
136
+ stub_http.expects(:post).with('/verify', 'privatekey=def&remoteip=localhost&challenge=abc&response=def', {'Content-Type' => 'application/x-www-form-urlencoded'}).returns(['foo', goodwords_resp])
137
+ Net::HTTP.expects(:Proxy).with(nil, nil).returns(stub_proxy)
138
+ client = new_client
139
+ assert client.validate('localhost', 'abc', 'def', err_stub)
140
+ end
141
+ def test_validate_good_proxy
142
+ ENV['proxy_host']='fubar:8080'
143
+ goodwords_resp="true\r\nsuccess"
144
+ err_stub=mock()
145
+ stub_proxy=mock('proxy')
146
+ stub_http = mock('http mock')
147
+ stub_proxy.expects(:start).with('api-verify.recaptcha.net').returns(stub_http)
148
+ stub_http.expects(:post).with('/verify', 'privatekey=def&remoteip=localhost&challenge=abc&response=def', {'Content-Type' => 'application/x-www-form-urlencoded'}).returns(['foo', goodwords_resp])
149
+ Net::HTTP.expects(:Proxy).with('fubar', '8080').returns(stub_proxy)
150
+ client = new_client
151
+ assert client.validate('localhost', 'abc', 'def', err_stub)
152
+ ENV['proxy_host']='fubar'
153
+ err_stub=mock()
154
+ stub_proxy=mock('proxy')
155
+ stub_http = mock('http mock')
156
+ stub_proxy.expects(:start).with('api-verify.recaptcha.net').returns(stub_http)
157
+ stub_http.expects(:post).with('/verify', 'privatekey=def&remoteip=localhost&challenge=abc&response=def', {'Content-Type' => 'application/x-www-form-urlencoded'}).returns(['foo', goodwords_resp])
158
+ Net::HTTP.expects(:Proxy).with('fubar', nil).returns(stub_proxy)
159
+ client = new_client
160
+ assert client.validate('localhost', 'abc', 'def', err_stub)
161
+ end
162
+
163
+ #
164
+ # unit tests for the get_captcha() ViewHelper method
165
+ #
166
+
167
+ def test_get_captcha_fails_without_key_constants
168
+ assert !ReCaptcha::ViewHelper.const_defined?(:RCC_PUB)
169
+ assert !ReCaptcha::ViewHelper.const_defined?(:RCC_PRIV)
170
+ assert_raise NameError do
171
+ @vf.get_captcha
172
+ end
173
+ end
174
+ def test_get_captcha_fails_without_public_key_constant
175
+ assert !ReCaptcha::ViewHelper.const_defined?(:RCC_PUB)
176
+ assert !ReCaptcha::ViewHelper.const_defined?(:RCC_PRIV)
177
+ ReCaptcha::ViewHelper.define_private_key
178
+ assert ReCaptcha::ViewHelper.const_defined?(:RCC_PRIV)
179
+ assert_raise NameError do
180
+ @vf.get_captcha
181
+ end
182
+ ReCaptcha::ViewHelper.undefine_private_key
183
+ end
184
+ def test_get_captcha_fails_without_private_key_constant
185
+ assert !ReCaptcha::ViewHelper.const_defined?(:RCC_PUB)
186
+ assert !ReCaptcha::ViewHelper.const_defined?(:RCC_PRIV)
187
+ ReCaptcha::ViewHelper.define_public_key
188
+ assert ReCaptcha::ViewHelper.const_defined?(:RCC_PUB)
189
+ assert_raise NameError do
190
+ @vf.get_captcha
191
+ end
192
+ ReCaptcha::ViewHelper.undefine_public_key
193
+ end
194
+ def test_get_captcha_succeeds_with_key_constants
195
+ mock_client = mock('client')
196
+ ReCaptcha::Client.expects(:new).returns(mock_client)
197
+ mock_client.expects(:get_challenge).with('', {})
198
+ assert !ReCaptcha::ViewHelper.const_defined?(:RCC_PUB)
199
+ assert !ReCaptcha::ViewHelper.const_defined?(:RCC_PRIV)
200
+ ReCaptcha::ViewHelper.define_public_key
201
+ ReCaptcha::ViewHelper.define_private_key
202
+ assert ReCaptcha::ViewHelper.const_defined?(:RCC_PUB)
203
+ assert ReCaptcha::ViewHelper.const_defined?(:RCC_PRIV)
204
+ assert_nothing_raised do
205
+ @vf.get_captcha
206
+ end
207
+ ReCaptcha::ViewHelper.undefine_public_key
208
+ ReCaptcha::ViewHelper.undefine_private_key
209
+ end
210
+ def test_get_captcha_succeeds_without_key_constants_but_with_options
211
+ assert !ReCaptcha::ViewHelper.const_defined?(:RCC_PUB)
212
+ assert !ReCaptcha::ViewHelper.const_defined?(:RCC_PRIV)
213
+ assert_nothing_raised do
214
+ @vf.get_captcha(:rcc_pub => 'foo', :rcc_priv => 'bar')
215
+ end
216
+ end
217
+ def test_get_captcha_is_correct_with_constants_and_with_options
218
+ expected= <<-EOF
219
+ <script type=\"text/javascript\" src=\"http://api.recaptcha.net/challenge?k=%s\"> </script>\n <noscript>\n <iframe src=\"http://api.recaptcha.net/noscript?k=%s\"\n height=\"300\" width=\"500\" frameborder=\"0\"></iframe><br>\n <textarea name=\"recaptcha_challenge_field\" rows=\"3\" cols=\"40\">\n </textarea>\n <input type=\"hidden\" name=\"recaptcha_response_field\" \n value=\"manual_challenge\">\n </noscript>
220
+ EOF
221
+ # first, with constants
222
+ ReCaptcha::ViewHelper.define_public_key # 'foo'
223
+ ReCaptcha::ViewHelper.define_private_key # 'bar'
224
+ actual = @vf.get_captcha
225
+ assert_equal(((expected % ['foo', 'foo']).strip), actual.strip)
226
+ ReCaptcha::ViewHelper.undefine_public_key
227
+ ReCaptcha::ViewHelper.undefine_private_key
228
+ # next, with options
229
+ actual = @vf.get_captcha(:rcc_pub => 'foobar', :rcc_priv => 'blegga')
230
+ assert_equal(((expected % ['foobar', 'foobar']).strip), actual.strip)
231
+ end
232
+
233
+ #
234
+ # unit tests for the validate_recap() AppHelper method
235
+ #
236
+
237
+ def test_validate_recap_fails_without_key_constants
238
+ assert !ReCaptcha::AppHelper.const_defined?(:RCC_PUB)
239
+ assert !ReCaptcha::AppHelper.const_defined?(:RCC_PRIV)
240
+ assert_raise NameError do
241
+ @cf.validate_recap({}, {})
242
+ end
243
+ end
244
+ def test_validate_recap_fails_without_public_key_constant
245
+ assert !ReCaptcha::AppHelper.const_defined?(:RCC_PUB)
246
+ assert !ReCaptcha::AppHelper.const_defined?(:RCC_PRIV)
247
+ ReCaptcha::AppHelper.define_private_key
248
+ assert ReCaptcha::AppHelper.const_defined?(:RCC_PRIV)
249
+ assert_raise NameError do
250
+ @cf.validate_recap({}, {})
251
+ end
252
+ ReCaptcha::AppHelper.undefine_private_key
253
+ end
254
+ def test_validate_recap_fails_without_private_key_constant
255
+ assert !ReCaptcha::AppHelper.const_defined?(:RCC_PUB)
256
+ assert !ReCaptcha::AppHelper.const_defined?(:RCC_PRIV)
257
+ ReCaptcha::AppHelper.define_public_key
258
+ assert ReCaptcha::AppHelper.const_defined?(:RCC_PUB)
259
+ assert_raise NameError do
260
+ @cf.validate_recap({}, {})
261
+ end
262
+ ReCaptcha::AppHelper.undefine_public_key
263
+ end
264
+ def test_validate_recap_succeeds_with_key_constants
265
+ e = mock('errors')
266
+ e.expects(:add_to_base).with('Captcha failed.')
267
+ assert !ReCaptcha::AppHelper.const_defined?(:RCC_PUB)
268
+ assert !ReCaptcha::AppHelper.const_defined?(:RCC_PRIV)
269
+ ReCaptcha::AppHelper.define_public_key
270
+ ReCaptcha::AppHelper.define_private_key
271
+ assert ReCaptcha::AppHelper.const_defined?(:RCC_PUB)
272
+ assert ReCaptcha::AppHelper.const_defined?(:RCC_PRIV)
273
+ assert_nothing_raised do
274
+ @cf.validate_recap({}, e)
275
+ end
276
+ ReCaptcha::AppHelper.undefine_public_key
277
+ ReCaptcha::AppHelper.undefine_private_key
278
+ end
279
+ def test_validate_recap_succeeds_without_key_constants_but_with_options
280
+ mock = mock('client')
281
+ ReCaptcha::Client.expects(:new).returns(mock)
282
+ mock.expects(:validate).with('0.0.0.0', nil, nil, {}).returns(true)
283
+ mock.expects(:last_error)
284
+ assert !ReCaptcha::AppHelper.const_defined?(:RCC_PUB)
285
+ assert !ReCaptcha::AppHelper.const_defined?(:RCC_PRIV)
286
+ @cf.validate_recap({}, {}, :rcc_pub => 'foo', :rcc_priv => 'bar')
287
+ end
288
+ def test_validate_recap_is_correct_with_constants_and_with_options
289
+ # first, with constants
290
+ e = mock('errors')
291
+ mock = mock('client')
292
+ ReCaptcha::Client.expects(:new).returns(mock).times(2)
293
+ mock.expects(:validate).with('0.0.0.0', nil, nil, {}).returns(true)
294
+ mock.expects(:last_error).times(2)
295
+ ReCaptcha::AppHelper.define_public_key # 'foo'
296
+ ReCaptcha::AppHelper.define_private_key # 'bar'
297
+ assert @cf.validate_recap({}, {})
298
+ ReCaptcha::AppHelper.undefine_public_key
299
+ ReCaptcha::AppHelper.undefine_private_key
300
+ # next, with options
301
+ mock.expects(:validate).with('0.0.0.0', nil, nil, e).returns(true)
302
+ assert @cf.validate_recap({}, e, {:rcc_pub => 'foobar', :rcc_priv => 'blegga'})
303
+ end
304
+
305
+ #
306
+ # unit tests for HTTP/HTTPS-variants of get_captcha() method
307
+ #
308
+
309
+ def test_get_captcha_uses_http_without_options
310
+ expected= <<-EOF
311
+ <script type=\"text/javascript\" src=\"http://api.recaptcha.net/challenge?k=%s\"> </script>\n <noscript>\n <iframe src=\"http://api.recaptcha.net/noscript?k=%s\"\n height=\"300\" width=\"500\" frameborder=\"0\"></iframe><br>\n <textarea name=\"recaptcha_challenge_field\" rows=\"3\" cols=\"40\">\n </textarea>\n <input type=\"hidden\" name=\"recaptcha_response_field\" \n value=\"manual_challenge\">\n </noscript>
312
+ EOF
313
+ actual = @vf.get_captcha(:rcc_pub => 'foobar', :rcc_priv => 'blegga')
314
+ assert_equal(((expected % ['foobar', 'foobar']).strip), actual.strip)
315
+ end
316
+ def test_get_captcha_uses_https_with_options_true
317
+ expected= <<-EOF
318
+ <script type=\"text/javascript\" src=\"https://api-secure.recaptcha.net/challenge?k=%s\"> </script>\n <noscript>\n <iframe src=\"https://api-secure.recaptcha.net/noscript?k=%s\"\n height=\"300\" width=\"500\" frameborder=\"0\"></iframe><br>\n <textarea name=\"recaptcha_challenge_field\" rows=\"3\" cols=\"40\">\n </textarea>\n <input type=\"hidden\" name=\"recaptcha_response_field\" \n value=\"manual_challenge\">\n </noscript>
319
+ EOF
320
+ actual = @vf.get_captcha(:rcc_pub => 'foobar', :rcc_priv => 'blegga', :ssl => true)
321
+ assert_equal(((expected % ['foobar', 'foobar']).strip), actual.strip)
322
+ end
323
+ def test_get_captcha_uses_http_with_options_false
324
+ expected= <<-EOF
325
+ <script type=\"text/javascript\" src=\"http://api.recaptcha.net/challenge?k=%s\"> </script>\n <noscript>\n <iframe src=\"http://api.recaptcha.net/noscript?k=%s\"\n height=\"300\" width=\"500\" frameborder=\"0\"></iframe><br>\n <textarea name=\"recaptcha_challenge_field\" rows=\"3\" cols=\"40\">\n </textarea>\n <input type=\"hidden\" name=\"recaptcha_response_field\" \n value=\"manual_challenge\">\n </noscript>
326
+ EOF
327
+ actual = @vf.get_captcha(:rcc_pub => 'foobar', :rcc_priv => 'blegga', :ssl => false)
328
+ assert_equal(((expected % ['foobar', 'foobar']).strip), actual.strip)
329
+ end
330
+
331
+ private
332
+
333
+ def new_client(pubkey='abc', privkey='def', ssl=false)
334
+ ReCaptcha::Client.new(pubkey, privkey, ssl)
335
+ end
336
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: iGEL-ruby-recaptcha
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Johannes Barre
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-03-16 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: My almost unchanged fork of ruby-recaptcha
17
+ email: igel@igels.net
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - lib/recaptcha.rb
24
+ - lib/ruby-recaptcha.rb
25
+ - README.textile
26
+ files:
27
+ - Manifest
28
+ - Rakefile
29
+ - test/test_recaptcha.rb
30
+ - test/test_helper.rb
31
+ - script/console
32
+ - script/generate
33
+ - script/destroy
34
+ - lib/recaptcha.rb
35
+ - lib/ruby-recaptcha.rb
36
+ - README.textile
37
+ - ruby-recaptcha.gemspec
38
+ has_rdoc: true
39
+ homepage: http://bitbucket.org/mml/ruby-recaptcha/wiki/Home
40
+ post_install_message:
41
+ rdoc_options:
42
+ - --line-numbers
43
+ - --inline-source
44
+ - --title
45
+ - Ruby-recaptcha
46
+ - --main
47
+ - README.textile
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "1.2"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project: ruby-recaptcha
65
+ rubygems_version: 1.2.0
66
+ signing_key:
67
+ specification_version: 2
68
+ summary: My almost unchanged fork of ruby-recaptcha
69
+ test_files:
70
+ - test/test_recaptcha.rb
71
+ - test/test_helper.rb