rack-recaptcha 0.2.2 → 0.3.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 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