rack-recaptcha 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # rack-recaptcha
1
+ # rack-recaptcha [![](http://stillmaintained.com/achiu/rack-recaptcha.png)](http://stillmaintained.com/achiu/rack-recaptcha)
2
2
 
3
3
  Drop this Rack middleware in your web application to enable CAPTCHA verification via Recaptcha API.
4
4
 
@@ -84,7 +84,7 @@ In Padrino, here's how you would use the helpers.
84
84
  ### Contributors
85
85
 
86
86
  - Daniel Mendler(minad) - support for multiple paths and helpers clean up
87
-
87
+ - Eric Anderson(eric1234) - Make verify independently usable.
88
88
 
89
89
 
90
90
  #### Note on Patches/Pull Requests
@@ -99,4 +99,4 @@ In Padrino, here's how you would use the helpers.
99
99
 
100
100
  #### Copyright
101
101
 
102
- Copyright (c) 2010 Arthur Chiu. See LICENSE for details.
102
+ Copyright (c) 2011 Arthur Chiu. See LICENSE for details.
data/Rakefile CHANGED
@@ -1,25 +1,5 @@
1
- require 'rubygems'
2
- require 'rake'
3
-
4
- begin
5
- require 'jeweler'
6
- Jeweler::Tasks.new do |gem|
7
- gem.name = "rack-recaptcha"
8
- gem.summary = %Q{Rack middleware for Recaptcha}
9
- gem.description = %Q{Rack middleware Captcha verification using Recaptcha API.}
10
- gem.email = "mr.arthur.chiu@gmail.com"
11
- gem.homepage = "http://github.com/achiu/rack-recaptcha"
12
- gem.authors = ["Arthur Chiu"]
13
- gem.add_runtime_dependency "json", ">=0"
14
- gem.add_development_dependency "riot", ">= 0"
15
- gem.add_development_dependency "rack-test", ">=0"
16
- gem.add_development_dependency "rr", ">=0"
17
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
18
- end
19
- Jeweler::GemcutterTasks.new
20
- rescue LoadError
21
- puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
22
- end
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
23
3
 
24
4
  require 'rake/testtask'
25
5
  Rake::TestTask.new(:test) do |test|
@@ -28,29 +8,4 @@ Rake::TestTask.new(:test) do |test|
28
8
  test.verbose = true
29
9
  end
30
10
 
31
- begin
32
- require 'rcov/rcovtask'
33
- Rcov::RcovTask.new do |test|
34
- test.libs << 'test'
35
- test.pattern = 'test/**/*_test.rb'
36
- test.verbose = true
37
- end
38
- rescue LoadError
39
- task :rcov do
40
- abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
- end
42
- end
43
-
44
- task :test => :check_dependencies
45
-
46
- task :default => :test
47
-
48
- require 'rake/rdoctask'
49
- Rake::RDocTask.new do |rdoc|
50
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
51
-
52
- rdoc.rdoc_dir = 'rdoc'
53
- rdoc.title = "rack-recaptcha #{version}"
54
- rdoc.rdoc_files.include('README*')
55
- rdoc.rdoc_files.include('lib/**/*.rb')
56
- end
11
+ task :default => [:test]
@@ -1,11 +1,10 @@
1
- require 'json'
2
- require 'rack/recaptcha/helpers'
1
+ require File.expand_path '../recaptcha/helpers', __FILE__
3
2
 
4
3
  module Rack
5
4
  class Recaptcha
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'
5
+ API_URL = 'http://www.google.com/recaptcha/api'
6
+ API_SECURE_URL = 'https://www.google.com/recaptcha/api'
7
+ VERIFY_URL = 'http://www.google.com/recaptcha/api/verify'
9
8
  CHALLENGE_FIELD = 'recaptcha_challenge_field'
10
9
  RESPONSE_FIELD = 'recaptcha_response_field'
11
10
 
@@ -13,6 +12,10 @@ module Rack
13
12
  attr_accessor :private_key, :public_key
14
13
  end
15
14
 
15
+ # Initialize the Rack Middleware. Some of the available options are:
16
+ # :public_key -- your ReCaptcha API public key *(required)*
17
+ # :private_key -- your ReCaptcha API private key *(required)*
18
+ # :paths -- where user goes to login or access the recaptcha (array of paths or single path)
16
19
  def initialize(app,options = {})
17
20
  @app = app
18
21
  @paths = options[:paths] && [options[:paths]].flatten.compact
@@ -28,18 +31,22 @@ module Rack
28
31
  request = Request.new(env)
29
32
  if request.params[CHALLENGE_FIELD] and
30
33
  request.params[RESPONSE_FIELD] and (not @paths or @paths.include?(request.path))
31
- value, msg = verify(request)
34
+ value, msg = verify(
35
+ request.ip,
36
+ request.params[CHALLENGE_FIELD],
37
+ request.params[RESPONSE_FIELD]
38
+ )
32
39
  env.merge!('recaptcha.valid' => value == 'true', 'recaptcha.msg' => msg)
33
40
  end
34
41
  @app.call(env)
35
42
  end
36
43
 
37
- def verify(request)
44
+ def verify(ip, challenge, response)
38
45
  params = {
39
46
  'privatekey' => Rack::Recaptcha.private_key,
40
- 'remoteip' => request.ip,
41
- 'challenge' => request.params[CHALLENGE_FIELD],
42
- 'response' => request.params[RESPONSE_FIELD]
47
+ 'remoteip' => ip,
48
+ 'challenge' => challenge,
49
+ 'response' => response
43
50
  }
44
51
  response = Net::HTTP.post_form URI.parse(VERIFY_URL), params
45
52
  response.body.split("\n")
@@ -1,3 +1,5 @@
1
+ require 'json'
2
+
1
3
  module Rack
2
4
  class Recaptcha
3
5
  module Helpers
@@ -9,6 +11,24 @@ module Rack
9
11
  :cols => 5
10
12
  }
11
13
 
14
+ # Helper method to output a recaptcha form. Some of the available
15
+ # types you can have are:
16
+ #
17
+ # :challenge - Returns a javascript recaptcha form
18
+ # :noscript - Return a non-javascript recaptcha form
19
+ # :ajax - Return a ajax recaptcha form
20
+ #
21
+ # You also have a few available options:
22
+ #
23
+ # For :ajax:
24
+ # :display - You can adjust the display of the ajax form. An example:
25
+ # recaptcha_tag :ajax, :display => {:theme => 'red'}.
26
+ # For :challenge and :noscript
27
+ # :public_key - Set the public key. Overrides the key set in Middleware option
28
+ # :height - Adjust the height of the form
29
+ # :width - Adjust the width of the form
30
+ # :row - Adjust the rows for the challenge field
31
+ # :cols - Adjust the column for the challenge field
12
32
  def recaptcha_tag(type= :noscript, options={})
13
33
  options = DEFAULT.merge(options)
14
34
  options[:public_key] ||= Rack::Recaptcha.public_key
@@ -41,6 +61,7 @@ module Rack
41
61
  end + html
42
62
  end
43
63
 
64
+ # Helper to return whether the recaptcha was accepted.
44
65
  def recaptcha_valid?
45
66
  request.env['recaptcha.valid']
46
67
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{rack-recaptcha}
3
- s.version = "0.2.2"
3
+ s.version = "0.3.0"
4
4
  s.required_rubygems_version = ">=1.3.6"
5
5
  s.authors = ["Arthur Chiu"]
6
6
  s.date = %q{2010-07-18}
@@ -14,8 +14,9 @@ Gem::Specification.new do |s|
14
14
  s.rubygems_version = %q{1.3.7}
15
15
  s.summary = %q{Rack middleware for Recaptcha}
16
16
  s.test_files = Dir.glob("test/**/*")
17
- s.add_runtime_dependency("json", [">= 0"])
18
- s.add_development_dependency("riot", [">= 0"])
19
- s.add_development_dependency("rack-test", [">= 0"])
20
- s.add_development_dependency("rr", [">= 0"])
17
+ s.add_runtime_dependency "json", ">= 0"
18
+ s.add_development_dependency "riot", "~> 0.12.1"
19
+ s.add_development_dependency "rack-test", "~> 0.5.7"
20
+ s.add_development_dependency "fakeweb", "~> 1.3.0"
21
+ s.add_development_dependency "rr", "~> 1.0.2"
21
22
  end
@@ -1,6 +1,4 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__),'teststrap'))
2
- require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','rack','recaptcha','helpers'))
3
- require 'riot/rr'
1
+ require File.expand_path '../teststrap', __FILE__
4
2
 
5
3
  class HelperTest
6
4
  attr_accessor :request
@@ -16,51 +14,60 @@ class HelperTest
16
14
  end
17
15
 
18
16
  context "Rack::Recaptcha::Helpers" do
19
- setup do
20
- Rack::Recaptcha.public_key = '0'*40
21
- @helper = HelperTest.new
22
- end
17
+ setup { Rack::Recaptcha.public_key = '0'*40 }
18
+
19
+ helper(:helper_test) { HelperTest.new }
23
20
 
24
21
 
25
22
  context "recaptcha_tag" do
26
23
 
27
24
  context "ajax" do
28
25
  context "with display" do
29
- setup { @helper.recaptcha_tag(:ajax,:display => {:theme => 'red'}) }
30
- asserts("has js") { topic }.matches %r{recaptcha_ajax.js}
31
- asserts("has div") { topic }.matches %r{<div id="ajax_recaptcha"></div>}
32
- asserts("has display") { topic }.matches %r{RecaptchaOptions}
33
- asserts("has red theme") { topic }.matches %r{"theme":"red"}
26
+ setup { helper_test.recaptcha_tag(:ajax,:display => {:theme => 'red'}) }
27
+
28
+ asserts_topic('has js').matches %r{recaptcha_ajax.js}
29
+ asserts_topic('has div').matches %r{<div id="ajax_recaptcha"></div>}
30
+ asserts_topic('has display').matches %r{RecaptchaOptions}
31
+ asserts_topic('has theme').matches %r{"theme":"red"}
34
32
  end
35
33
  context "without display" do
36
- setup { @helper.recaptcha_tag(:ajax) }
37
- asserts("has js") { topic }.matches %r{recaptcha_ajax.js}
38
- asserts("has div") { topic }.matches %r{<div id="ajax_recaptcha"></div>}
39
- asserts("has display") { topic =~ %r{RecaptchaOptions} }.not!
40
- asserts("has red theme") { topic =~ %r{"theme":"red"} }.not!
34
+ setup { helper_test.recaptcha_tag(:ajax) }
35
+
36
+ asserts_topic('has js').matches %r{recaptcha_ajax.js}
37
+ asserts_topic('has div').matches %r{<div id="ajax_recaptcha"></div>}
38
+ denies_topic('has display').matches %r{RecaptchaOptions}
39
+ denies_topic('has theme').matches %r{"theme":"red"}
41
40
  end
42
41
  end
43
42
 
44
43
  context "noscript" do
45
- setup { @helper.recaptcha_tag :noscript, :public_key => "hello_world_world" }
46
- asserts("iframe") { topic }.matches %r{iframe}
47
- asserts("no script tag") { topic }.matches %r{<noscript>}
48
- asserts("public key") { topic }.matches %r{hello_world_world}
49
- asserts("has js") { topic =~ %r{recaptcha_ajax.js} }.not!
44
+ setup { helper_test.recaptcha_tag :noscript, :public_key => "hello_world_world" }
45
+
46
+ asserts_topic("iframe").matches %r{iframe}
47
+ asserts_topic("no script tag").matches %r{<noscript>}
48
+ asserts_topic("public key").matches %r{hello_world_world}
49
+ denies_topic("has js").matches %r{recaptcha_ajax.js}
50
50
  end
51
51
 
52
52
  context "challenge" do
53
- setup { @helper.recaptcha_tag(:challenge) }
54
- asserts("has script tag") { topic }.matches %r{script}
55
- asserts("has challenge js") { topic }.matches %r{challenge}
56
- asserts("has js") { topic =~ %r{recaptcha_ajax.js} }.not!
57
- asserts("has display") { topic =~ %r{RecaptchaOptions} }.not!
58
- asserts("has public_key") { topic }.matches %r{#{'0'*40}}
53
+ setup { helper_test.recaptcha_tag(:challenge) }
54
+
55
+ asserts_topic("has script tag").matches %r{script}
56
+ asserts_topic("has challenge js").matches %r{challenge}
57
+ denies_topic("has js").matches %r{recaptcha_ajax.js}
58
+ denies_topic("has display").matches %r{RecaptchaOptions}
59
+ asserts_topic("has public_key").matches %r{#{'0'*40}}
59
60
  end
60
61
 
61
62
  context "server" do
62
- asserts("using ssl url") { @helper.recaptcha_tag(:challenge, :ssl => true) }.matches %r{https://api-secure.recaptcha.net}
63
- asserts("using non ssl url") { @helper.recaptcha_tag(:ajax) }.matches %r{http://api.recaptcha.net}
63
+
64
+ asserts("using ssl url") do
65
+ helper_test.recaptcha_tag(:challenge, :ssl => true)
66
+ end.matches %r{#{Rack::Recaptcha::API_SECURE_URL}}
67
+
68
+ asserts("using non ssl url") do
69
+ helper_test.recaptcha_tag(:ajax)
70
+ end.matches %r{#{Rack::Recaptcha::API_URL}}
64
71
  end
65
72
 
66
73
  end
@@ -69,18 +76,18 @@ context "Rack::Recaptcha::Helpers" do
69
76
 
70
77
  context "passing" do
71
78
  setup do
72
- mock(@helper.request.env).[]('recaptcha.valid').returns(true)
73
- @helper.recaptcha_valid?
79
+ mock(helper_test.request.env).[]('recaptcha.valid').returns(true)
74
80
  end
75
- asserts_topic
81
+
82
+ asserts("retrieves request") { helper_test.recaptcha_valid? }
76
83
  end
77
84
 
78
85
  context "failing" do
79
86
  setup do
80
- mock(@helper.request.env).[]('recaptcha.valid').returns(false)
81
- @helper.recaptcha_valid?
87
+ mock(helper_test.request.env).[]('recaptcha.valid').returns(false)
82
88
  end
83
- asserts_topic.not!
89
+
90
+ denies("that it retrieves request") { helper_test.recaptcha_valid? }
84
91
  end
85
92
 
86
93
  end
@@ -1,19 +1,20 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__),'teststrap'))
2
- require 'fakeweb'
1
+ require File.expand_path '../teststrap', __FILE__
3
2
 
4
3
  FakeWeb.allow_net_connect = false
5
4
  context "Rack::Recaptcha" do
6
5
 
7
6
  context "basic request" do
8
- setup { get("/")}
9
- asserts("status is 200") { last_response.status }.equals 200
10
- asserts("body is hello world") { last_response.body }.equals 'Hello world'
7
+ setup { get("/") ; last_response }
8
+
9
+ asserts(:status).equals 200
10
+ asserts(:body).equals "Hello world"
11
11
  end
12
12
 
13
13
  context "exposes" do
14
14
  setup { Rack::Recaptcha }
15
- asserts("private key") { topic.private_key }.equals PRIVATE_KEY
16
- asserts("public key") { topic.public_key }.equals PUBLIC_KEY
15
+
16
+ asserts(:private_key).equals PRIVATE_KEY
17
+ asserts(:public_key).equals PUBLIC_KEY
17
18
  end
18
19
 
19
20
  context "login path" do
@@ -7,7 +7,8 @@ require 'rack/builder'
7
7
  require 'rr'
8
8
  require 'riot'
9
9
  require 'riot/rr'
10
- require File.expand_path(File.join(File.dirname(__FILE__),'..','lib','rack','recaptcha'))
10
+ require 'fakeweb'
11
+ require File.expand_path '../../lib/rack/recaptcha', __FILE__
11
12
 
12
13
  PUBLIC_KEY = '0'*40
13
14
  PRIVATE_KEY = 'X'*40
@@ -38,5 +39,12 @@ class Riot::Situation
38
39
  builder.run main_app
39
40
  builder.to_app
40
41
  end
42
+ end
43
+
44
+ class Riot::Context
41
45
 
46
+ # denies_topic currently on edge. Will remove once its released
47
+ def denies_topic(what)
48
+ denies(what) { topic }
49
+ end
42
50
  end
metadata CHANGED
@@ -2,12 +2,12 @@
2
2
  name: rack-recaptcha
3
3
  version: !ruby/object:Gem::Version
4
4
  hash: 19
5
- prerelease: false
5
+ prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 2
10
- version: 0.2.2
8
+ - 3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Arthur Chiu
@@ -38,12 +38,14 @@ dependencies:
38
38
  requirement: &id002 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
- - - ">="
41
+ - - ~>
42
42
  - !ruby/object:Gem::Version
43
- hash: 3
43
+ hash: 45
44
44
  segments:
45
45
  - 0
46
- version: "0"
46
+ - 12
47
+ - 1
48
+ version: 0.12.1
47
49
  type: :development
48
50
  version_requirements: *id002
49
51
  - !ruby/object:Gem::Dependency
@@ -52,28 +54,48 @@ dependencies:
52
54
  requirement: &id003 !ruby/object:Gem::Requirement
53
55
  none: false
54
56
  requirements:
55
- - - ">="
57
+ - - ~>
56
58
  - !ruby/object:Gem::Version
57
- hash: 3
59
+ hash: 5
58
60
  segments:
59
61
  - 0
60
- version: "0"
62
+ - 5
63
+ - 7
64
+ version: 0.5.7
61
65
  type: :development
62
66
  version_requirements: *id003
63
67
  - !ruby/object:Gem::Dependency
64
- name: rr
68
+ name: fakeweb
65
69
  prerelease: false
66
70
  requirement: &id004 !ruby/object:Gem::Requirement
67
71
  none: false
68
72
  requirements:
69
- - - ">="
73
+ - - ~>
70
74
  - !ruby/object:Gem::Version
71
- hash: 3
75
+ hash: 27
72
76
  segments:
77
+ - 1
78
+ - 3
73
79
  - 0
74
- version: "0"
80
+ version: 1.3.0
75
81
  type: :development
76
82
  version_requirements: *id004
83
+ - !ruby/object:Gem::Dependency
84
+ name: rr
85
+ prerelease: false
86
+ requirement: &id005 !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ~>
90
+ - !ruby/object:Gem::Version
91
+ hash: 19
92
+ segments:
93
+ - 1
94
+ - 0
95
+ - 2
96
+ version: 1.0.2
97
+ type: :development
98
+ version_requirements: *id005
77
99
  description: Rack middleware Captcha verification using Recaptcha API.
78
100
  email: mr.arthur.chiu@gmail.com
79
101
  executables: []
@@ -127,7 +149,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
149
  requirements: []
128
150
 
129
151
  rubyforge_project:
130
- rubygems_version: 1.3.7
152
+ rubygems_version: 1.6.1
131
153
  signing_key:
132
154
  specification_version: 3
133
155
  summary: Rack middleware for Recaptcha