rack-recaptcha 0.1.1 → 0.2.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.
- data/README.md +16 -9
- data/VERSION +1 -1
- data/lib/rack/recaptcha.rb +18 -16
- data/lib/rack/recaptcha/helpers.rb +20 -29
- data/rack-recaptcha.gemspec +4 -4
- data/test/helpers_test.rb +7 -7
- data/test/recaptcha_test.rb +4 -4
- data/test/teststrap.rb +3 -3
- metadata +18 -5
data/README.md
CHANGED
@@ -19,27 +19,28 @@ You have to require 'rack-recaptcha' in your gemfile.
|
|
19
19
|
|
20
20
|
* :public_key -- your ReCaptcha API public key *(required)*
|
21
21
|
* :private_key -- your ReCaptcha API private key *(required)*
|
22
|
-
* :
|
22
|
+
* :paths -- where user goes to login or access the recaptcha (array of paths or single path)
|
23
23
|
|
24
24
|
|
25
25
|
Now configure your app to use the middleware. This might be different across each web framework.
|
26
26
|
|
27
27
|
#### Sinatra
|
28
|
-
|
29
|
-
use Rack::Recaptcha, :public_key => 'KEY', :private_key => 'SECRET', :
|
28
|
+
## app.rb
|
29
|
+
use Rack::Recaptcha, :public_key => 'KEY', :private_key => 'SECRET', :paths => 'PATH'
|
30
30
|
helpers Rack::Recaptcha::Helpers
|
31
31
|
|
32
32
|
#### Padrino
|
33
33
|
|
34
34
|
## app/app.rb
|
35
|
-
use Rack::Recaptcha, :public_key => 'KEY', :private_key => 'SECRET', :
|
35
|
+
use Rack::Recaptcha, :public_key => 'KEY', :private_key => 'SECRET', :paths => 'PATH'
|
36
36
|
helpers Rack::Recaptcha::Helpers
|
37
37
|
|
38
38
|
|
39
39
|
#### Rails
|
40
40
|
|
41
41
|
## environment.rb:
|
42
|
-
config.
|
42
|
+
config.gem 'rack-recaptcha', :lib => 'rack/recaptcha'
|
43
|
+
config.middleware.use Rack::Recaptcha, :public_key => 'KEY', :private_key => 'SECRET', :paths => 'PATH'
|
43
44
|
|
44
45
|
## application_controller.rb
|
45
46
|
include Rack::Recaptcha::Helpers
|
@@ -57,7 +58,7 @@ The `Rack::Recaptcha::Helpers` module (for Sinatra, Rails, Padrino) adds these m
|
|
57
58
|
- you can also pass in :public\_key manually as well.
|
58
59
|
- recaptcha\_tag(:challenge,:public\_key => 'PUBLIC')
|
59
60
|
|
60
|
-
* `
|
61
|
+
* `recaptcha_valid?` -- returns whether or not the verification passed.
|
61
62
|
|
62
63
|
#### Example
|
63
64
|
|
@@ -72,7 +73,7 @@ In Padrino, here's how you would use the helpers.
|
|
72
73
|
|
73
74
|
## sessions.rb
|
74
75
|
post :create, :map => '/login' do
|
75
|
-
if
|
76
|
+
if recaptcha_valid?
|
76
77
|
"passed!"
|
77
78
|
else
|
78
79
|
"failed!"
|
@@ -80,7 +81,13 @@ In Padrino, here's how you would use the helpers.
|
|
80
81
|
end
|
81
82
|
|
82
83
|
|
83
|
-
|
84
|
+
#### Contributors
|
85
|
+
|
86
|
+
- Daniel Mendler(minad) - support for multiple paths and helpers clean up
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
#### Note on Patches/Pull Requests
|
84
91
|
|
85
92
|
* Fork the project.
|
86
93
|
* Make your feature addition or bug fix.
|
@@ -90,6 +97,6 @@ In Padrino, here's how you would use the helpers.
|
|
90
97
|
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
91
98
|
* Send me a pull request. Bonus points for topic branches.
|
92
99
|
|
93
|
-
|
100
|
+
#### Copyright
|
94
101
|
|
95
102
|
Copyright (c) 2010 Arthur Chiu. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/rack/recaptcha.rb
CHANGED
@@ -1,43 +1,45 @@
|
|
1
1
|
require 'json'
|
2
|
-
|
3
|
-
RECAPTCHA_API_URL = 'http://api.recaptcha.net'
|
4
|
-
RECAPTCHA_API_SECURE_URL = 'https://api-secure.recaptcha.net'
|
5
|
-
RECAPTCHA_VERIFY_URL = 'http://api-verify.recaptcha.net/verify'
|
6
|
-
|
7
|
-
require File.expand_path(File.join(File.dirname(__FILE__),'recaptcha','helpers'))
|
2
|
+
require 'rack/recaptcha/helpers'
|
8
3
|
|
9
4
|
module Rack
|
10
5
|
class Recaptcha
|
11
|
-
|
6
|
+
API_URL = 'http://api.recaptcha.net'
|
7
|
+
API_SECURE_URL = 'https://api-secure.recaptcha.net'
|
8
|
+
VERIFY_URL = 'http://api-verify.recaptcha.net/verify'
|
9
|
+
CHALLENGE_FIELD = 'recaptcha_challenge_field'
|
10
|
+
RESPONSE_FIELD = 'recaptcha_response_field'
|
11
|
+
|
12
12
|
class << self
|
13
13
|
attr_accessor :private_key, :public_key
|
14
14
|
end
|
15
15
|
|
16
16
|
def initialize(app,options = {})
|
17
|
-
@app
|
17
|
+
@app = app
|
18
|
+
@paths = options[:paths] && [options[:paths]].flatten.compact
|
18
19
|
self.class.private_key = options[:private_key]
|
19
20
|
self.class.public_key = options[:public_key]
|
20
21
|
end
|
21
22
|
|
22
23
|
def call(env)
|
23
24
|
request = Request.new(env)
|
24
|
-
if request.
|
25
|
+
if request.params[CHALLENGE_FIELD] and
|
26
|
+
request.params[RESPONSE_FIELD] and (not @paths or @paths.include?(request.path))
|
25
27
|
value, msg = verify(request)
|
26
|
-
env.merge!('recaptcha.
|
28
|
+
env.merge!('recaptcha.valid' => value == 'true', 'recaptcha.msg' => msg)
|
27
29
|
end
|
28
30
|
@app.call(env)
|
29
31
|
end
|
30
32
|
|
31
33
|
def verify(request)
|
32
34
|
params = {
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
'privatekey' => Rack::Recaptcha.private_key,
|
36
|
+
'remoteip' => request.ip,
|
37
|
+
'challenge' => request.params[CHALLENGE_FIELD],
|
38
|
+
'response' => request.params[RESPONSE_FIELD]
|
37
39
|
}
|
38
|
-
response = Net::HTTP.post_form URI.parse(
|
40
|
+
response = Net::HTTP.post_form URI.parse(VERIFY_URL), params
|
39
41
|
response.body.split("\n")
|
40
42
|
end
|
41
43
|
|
42
44
|
end
|
43
|
-
end
|
45
|
+
end
|
@@ -9,49 +9,40 @@ module Rack
|
|
9
9
|
:cols => 5
|
10
10
|
}
|
11
11
|
|
12
|
-
|
13
12
|
def recaptcha_tag(type= :noscript, options={})
|
14
13
|
options = DEFAULT.merge(options)
|
15
14
|
options[:public_key] ||= Rack::Recaptcha.public_key
|
16
|
-
path = options[:ssl] ?
|
15
|
+
path = options[:ssl] ? Rack::Recaptcha::API_SECURE_URL : Rack::Recaptcha::API_URL
|
17
16
|
html = case type.to_sym
|
18
17
|
when :challenge
|
19
|
-
|
20
|
-
|
21
|
-
</script>
|
22
|
-
CHALLENGE
|
18
|
+
%{<script type="text/javascript" src="#{path}/challenge?k=#{options[:public_key]}">
|
19
|
+
</script>}.gsub(/^ +/, '')
|
23
20
|
when :noscript
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
</noscript>
|
30
|
-
NOSCRIPT
|
21
|
+
%{<noscript>
|
22
|
+
<iframe src="#{path}/noscript?k=#{options[:public_key]}" height="#{options[:height]}" width="#{options[:width]}" frameborder="0"></iframe><br>
|
23
|
+
<textarea name="recaptcha_challenge_field" rows="#{options[:row]}" cols="#{options[:cols]}"></textarea>
|
24
|
+
<input type="hidden" name="recaptcha_response_field" value="manual_challenge">
|
25
|
+
</noscript>}.gsub(/^ +/, '')
|
31
26
|
when :ajax
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
</script>
|
38
|
-
AJAX
|
27
|
+
%{<div id="ajax_recaptcha"></div>
|
28
|
+
<script type="text/javascript" src="#{path}/js/recaptcha_ajax.js"></script>
|
29
|
+
<script type="text/javascript">
|
30
|
+
Recaptcha.create('#{options[:public_key]}', document.getElementById('ajax_recaptcha')#{options[:display] ? ',RecaptchaOptions' : ''});
|
31
|
+
</script>}.gsub(/^ +/, '')
|
39
32
|
else
|
40
|
-
|
33
|
+
''
|
41
34
|
end
|
42
35
|
if options[:display]
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
</script>
|
47
|
-
DISPLAY
|
36
|
+
%{<script type="text/javascript">
|
37
|
+
var RecaptchaOptions = #{options[:display].to_json};
|
38
|
+
</script>}.gsub(/^ +/, '')
|
48
39
|
else
|
49
|
-
|
40
|
+
''
|
50
41
|
end + html
|
51
42
|
end
|
52
43
|
|
53
|
-
def
|
54
|
-
env['recaptcha.
|
44
|
+
def recaptcha_valid?
|
45
|
+
env['recaptcha.valid']
|
55
46
|
end
|
56
47
|
|
57
48
|
end
|
data/rack-recaptcha.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{rack-recaptcha}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Arthur Chiu"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-05-19}
|
13
13
|
s.description = %q{Rack middleware Captcha verification using Recaptcha API.}
|
14
14
|
s.email = %q{mr.arthur.chiu@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.homepage = %q{http://github.com/achiu/rack-recaptcha}
|
35
35
|
s.rdoc_options = ["--charset=UTF-8"]
|
36
36
|
s.require_paths = ["lib"]
|
37
|
-
s.rubygems_version = %q{1.3.
|
37
|
+
s.rubygems_version = %q{1.3.7}
|
38
38
|
s.summary = %q{Rack middleware for Recaptcha}
|
39
39
|
s.test_files = [
|
40
40
|
"test/helpers_test.rb",
|
@@ -46,7 +46,7 @@ Gem::Specification.new do |s|
|
|
46
46
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
47
47
|
s.specification_version = 3
|
48
48
|
|
49
|
-
if Gem::Version.new(Gem::
|
49
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
50
50
|
s.add_runtime_dependency(%q<json>, [">= 0"])
|
51
51
|
s.add_development_dependency(%q<riot>, [">= 0"])
|
52
52
|
s.add_development_dependency(%q<rack-test>, [">= 0"])
|
data/test/helpers_test.rb
CHANGED
@@ -2,7 +2,7 @@ require File.expand_path(File.join(File.dirname(__FILE__),'teststrap'))
|
|
2
2
|
require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','rack','recaptcha','helpers'))
|
3
3
|
require 'riot/rr'
|
4
4
|
|
5
|
-
class
|
5
|
+
class HelperTest
|
6
6
|
attr_accessor :env
|
7
7
|
include Rack::Recaptcha::Helpers
|
8
8
|
end
|
@@ -10,7 +10,7 @@ end
|
|
10
10
|
context "Rack::Recaptcha::Helpers" do
|
11
11
|
setup do
|
12
12
|
Rack::Recaptcha.public_key = '0'*40
|
13
|
-
@helper =
|
13
|
+
@helper = HelperTest.new
|
14
14
|
end
|
15
15
|
|
16
16
|
|
@@ -57,20 +57,20 @@ context "Rack::Recaptcha::Helpers" do
|
|
57
57
|
|
58
58
|
end
|
59
59
|
|
60
|
-
context "
|
60
|
+
context "recaptcha_valid?" do
|
61
61
|
|
62
62
|
context "passing" do
|
63
63
|
setup do
|
64
|
-
mock(@helper.env).[]('recaptcha.
|
65
|
-
@helper.
|
64
|
+
mock(@helper.env).[]('recaptcha.valid').returns(true)
|
65
|
+
@helper.recaptcha_valid?
|
66
66
|
end
|
67
67
|
asserts_topic
|
68
68
|
end
|
69
69
|
|
70
70
|
context "failing" do
|
71
71
|
setup do
|
72
|
-
mock(@helper.env).[]('recaptcha.
|
73
|
-
@helper.
|
72
|
+
mock(@helper.env).[]('recaptcha.valid').returns(false)
|
73
|
+
@helper.recaptcha_valid?
|
74
74
|
end
|
75
75
|
asserts_topic.not!
|
76
76
|
end
|
data/test/recaptcha_test.rb
CHANGED
@@ -25,16 +25,16 @@ context "Rack::Recaptcha" do
|
|
25
25
|
|
26
26
|
context "post pass" do
|
27
27
|
setup do
|
28
|
-
FakeWeb.register_uri(:post,
|
29
|
-
post("/login")
|
28
|
+
FakeWeb.register_uri(:post, Rack::Recaptcha::VERIFY_URL, :body => "true\nsuccess")
|
29
|
+
post("/login", 'recaptcha_challenge_field' => 'challenge', 'recaptcha_response_field' => 'response')
|
30
30
|
end
|
31
31
|
asserts("post login") { last_response.body }.equals 'post login'
|
32
32
|
end
|
33
33
|
|
34
34
|
context "post fail" do
|
35
35
|
setup do
|
36
|
-
FakeWeb.register_uri(:post,
|
37
|
-
post("/login")
|
36
|
+
FakeWeb.register_uri(:post, Rack::Recaptcha::VERIFY_URL, :body => "false\nfailed")
|
37
|
+
post("/login", 'recaptcha_challenge_field' => 'challenge', 'recaptcha_response_field' => 'response')
|
38
38
|
end
|
39
39
|
asserts("post fail") { last_response.body }.equals 'post fail'
|
40
40
|
end
|
data/test/teststrap.rb
CHANGED
@@ -23,18 +23,18 @@ class Riot::Situation
|
|
23
23
|
when '/' then [200,'Hello world']
|
24
24
|
when '/login'
|
25
25
|
if request.post?
|
26
|
-
env['recaptcha.
|
26
|
+
env['recaptcha.valid'] ? [200, 'post login'] : [200, 'post fail']
|
27
27
|
else
|
28
28
|
[200,'login']
|
29
29
|
end
|
30
30
|
else
|
31
31
|
[404,'Nothing here']
|
32
32
|
end
|
33
|
-
[return_code,{'Content-type' => 'text/plain'}, body_text]
|
33
|
+
[return_code,{'Content-type' => 'text/plain'}, [body_text]]
|
34
34
|
}
|
35
35
|
|
36
36
|
builder = Rack::Builder.new
|
37
|
-
builder.use Rack::Recaptcha, :private_key => PRIVATE_KEY, :public_key => PUBLIC_KEY, :
|
37
|
+
builder.use Rack::Recaptcha, :private_key => PRIVATE_KEY, :public_key => PUBLIC_KEY, :paths => '/login'
|
38
38
|
builder.run main_app
|
39
39
|
builder.to_app
|
40
40
|
end
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-recaptcha
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Arthur Chiu
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-05-19 00:00:00 -07:00
|
18
19
|
default_executable:
|
19
20
|
dependencies:
|
20
21
|
- !ruby/object:Gem::Dependency
|
21
22
|
name: json
|
22
23
|
prerelease: false
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
24
26
|
requirements:
|
25
27
|
- - ">="
|
26
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
27
30
|
segments:
|
28
31
|
- 0
|
29
32
|
version: "0"
|
@@ -33,9 +36,11 @@ dependencies:
|
|
33
36
|
name: riot
|
34
37
|
prerelease: false
|
35
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
36
40
|
requirements:
|
37
41
|
- - ">="
|
38
42
|
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
39
44
|
segments:
|
40
45
|
- 0
|
41
46
|
version: "0"
|
@@ -45,9 +50,11 @@ dependencies:
|
|
45
50
|
name: rack-test
|
46
51
|
prerelease: false
|
47
52
|
requirement: &id003 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
48
54
|
requirements:
|
49
55
|
- - ">="
|
50
56
|
- !ruby/object:Gem::Version
|
57
|
+
hash: 3
|
51
58
|
segments:
|
52
59
|
- 0
|
53
60
|
version: "0"
|
@@ -57,9 +64,11 @@ dependencies:
|
|
57
64
|
name: rr
|
58
65
|
prerelease: false
|
59
66
|
requirement: &id004 !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
60
68
|
requirements:
|
61
69
|
- - ">="
|
62
70
|
- !ruby/object:Gem::Version
|
71
|
+
hash: 3
|
63
72
|
segments:
|
64
73
|
- 0
|
65
74
|
version: "0"
|
@@ -98,23 +107,27 @@ rdoc_options:
|
|
98
107
|
require_paths:
|
99
108
|
- lib
|
100
109
|
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
101
111
|
requirements:
|
102
112
|
- - ">="
|
103
113
|
- !ruby/object:Gem::Version
|
114
|
+
hash: 3
|
104
115
|
segments:
|
105
116
|
- 0
|
106
117
|
version: "0"
|
107
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
108
120
|
requirements:
|
109
121
|
- - ">="
|
110
122
|
- !ruby/object:Gem::Version
|
123
|
+
hash: 3
|
111
124
|
segments:
|
112
125
|
- 0
|
113
126
|
version: "0"
|
114
127
|
requirements: []
|
115
128
|
|
116
129
|
rubyforge_project:
|
117
|
-
rubygems_version: 1.3.
|
130
|
+
rubygems_version: 1.3.7
|
118
131
|
signing_key:
|
119
132
|
specification_version: 3
|
120
133
|
summary: Rack middleware for Recaptcha
|