captchachacha 0.0.3
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.tar.gz.sig +0 -0
- data/.gitignore +15 -0
- data/CHANGES +1 -0
- data/Gemfile +4 -0
- data/README +22 -0
- data/Rakefile +9 -0
- data/captchachacha.gemspec +25 -0
- data/lib/rack/captchachacha.rb +62 -0
- data/lib/rack/captchachacha/helpers.rb +33 -0
- data/lib/rack/captchachacha/version.rb +5 -0
- data/spec/captchachacha_spec.rb +78 -0
- metadata +120 -0
- metadata.gz.sig +0 -0
data.tar.gz.sig
ADDED
Binary file
|
data/.gitignore
ADDED
data/CHANGES
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
v0.0.1 Start of project.
|
data/Gemfile
ADDED
data/README
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
## Rack::Captchachacha ##
|
2
|
+
|
3
|
+
Rack middleware for using the [captchator.com][1] service.
|
4
|
+
|
5
|
+
### Usage ###
|
6
|
+
|
7
|
+
#### Sinatra ####
|
8
|
+
|
9
|
+
## app.rb
|
10
|
+
use Rack::Captchachacha
|
11
|
+
helpers Rack::Recaptcha::Helpers
|
12
|
+
|
13
|
+
|
14
|
+
### Acknowledgments ###
|
15
|
+
|
16
|
+
The vast majority of this code comes from [sinatra-captcha][2] and [rack-recaptcha][3]
|
17
|
+
|
18
|
+
Many thanks to Blake Mizerany, the author of sinatra-captcha, and Arthur Chiu, author of rack-recaptcha for making their code public.
|
19
|
+
|
20
|
+
[1]: http://captchator.com/
|
21
|
+
[2]: https://github.com/bmizerany/sinatra-captcha
|
22
|
+
[3]: https://github.com/achiu/rack-recaptcha
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('./lib')
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
require 'rack/captchachacha/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "captchachacha"
|
8
|
+
s.summary = "Captchator for rack with helpers for sinatra"
|
9
|
+
s.description = <<-EOF
|
10
|
+
Captchator as Rack middleware, and helpers for sinatra.
|
11
|
+
EOF
|
12
|
+
s.version = Rack::Captchachacha::VERSION
|
13
|
+
s.platform = Gem::Platform::RUBY
|
14
|
+
s.require_path = 'lib'
|
15
|
+
s.required_ruby_version = ">= 1.9.2"
|
16
|
+
s.author = "Iain Barnett"
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.add_dependency('rack', '=1.3.0')
|
19
|
+
s.add_dependency('curb', '=0.7.15')
|
20
|
+
s.email = "iainspeed @nospam@ gmail.com"
|
21
|
+
s.homepage = "https://github.com/yb66/Captchachacha"
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}`.split("\n")
|
23
|
+
s.signing_key = ENV['HOME'] + '/.ssh/gem-private_key.pem'
|
24
|
+
s.cert_chain = [ENV['HOME'] + '/.ssh/gem-public_cert.pem']
|
25
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require_relative './captchachacha/helpers.rb'
|
4
|
+
|
5
|
+
module Rack
|
6
|
+
|
7
|
+
class Captchachacha
|
8
|
+
|
9
|
+
VERIFY_URL = "http://captchator.com/captcha/check_answer"
|
10
|
+
CHALLENGE_FIELD = 'captcha_session'
|
11
|
+
RESPONSE_FIELD = 'captcha_answer'
|
12
|
+
|
13
|
+
|
14
|
+
# @param app Rack application
|
15
|
+
# @param [optional,Hash] options Hash of options
|
16
|
+
# @option options [String, Array<String>] paths Where user goes to login or access the captcha.
|
17
|
+
def initialize( app, options={} )
|
18
|
+
@app = app
|
19
|
+
|
20
|
+
# this is here because it's in the Rack::Recaptcha API, I've no idea what it does really.
|
21
|
+
@paths = options[:paths] && [options[:paths]].flatten.compact
|
22
|
+
end
|
23
|
+
|
24
|
+
def call(env)
|
25
|
+
dup._call env
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param env Rack environment
|
29
|
+
def _call(env)
|
30
|
+
request = Request.new(env)
|
31
|
+
|
32
|
+
if request.params[CHALLENGE_FIELD] && request.params[RESPONSE_FIELD]
|
33
|
+
|
34
|
+
result, msg = verify(
|
35
|
+
request.params[CHALLENGE_FIELD].to_i,
|
36
|
+
request.params[RESPONSE_FIELD] )
|
37
|
+
|
38
|
+
# captchator doesn't give an error message, but in the spirit of keeping a similar API
|
39
|
+
# to reCAPTCHA, and because it's an easy place to stick a default error message, I'll
|
40
|
+
# pretend that `verify` returns two results.
|
41
|
+
# If it's a fail then the usual course of action would be to redirect back to the
|
42
|
+
# captcha form, but on success to continue, so the error message will be ignored unless
|
43
|
+
# of failure.
|
44
|
+
msg ||= "incorrect response, please try again"
|
45
|
+
|
46
|
+
env.merge!('captcha.valid' => result == true, 'captcha.msg' => msg )
|
47
|
+
end
|
48
|
+
@app.call(env)
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
def verify( session_id, answer )
|
53
|
+
return false if session_id == 0
|
54
|
+
return false if answer.nil?
|
55
|
+
|
56
|
+
require 'curb'
|
57
|
+
Curl::Easy.perform("#{VERIFY_URL}/#{session_id}/#{answer}").body_str.to_i == 1
|
58
|
+
end # def
|
59
|
+
|
60
|
+
end # class
|
61
|
+
|
62
|
+
end # Rack
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
|
4
|
+
# @author Iain Barnett
|
5
|
+
#
|
6
|
+
# A module to take advantage of the http://captchator.com service
|
7
|
+
module Rack
|
8
|
+
class Captchachacha
|
9
|
+
module Helpers
|
10
|
+
|
11
|
+
|
12
|
+
def captcha_valid?
|
13
|
+
request.env['captcha.valid']
|
14
|
+
end # def
|
15
|
+
|
16
|
+
|
17
|
+
def captcha_session
|
18
|
+
@captcha_session ||= rand(9000) + 1000
|
19
|
+
end
|
20
|
+
|
21
|
+
|
22
|
+
def captcha_answer_tag
|
23
|
+
%Q!<input id="captcha-answer" name="captcha_answer" type="text" size="10"/>!
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
def captcha_image_tag
|
28
|
+
%Q!<input name="captcha_session" type="hidden" value="#{captcha_session}"/>\n<img id="captcha-image" src="http://captchator.com/captcha/image/#{captcha_session}"/>!
|
29
|
+
end
|
30
|
+
|
31
|
+
end # Helpers
|
32
|
+
end # Captchachacha
|
33
|
+
end # Rack
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require 'rack/test'
|
3
|
+
require 'rack/mock'
|
4
|
+
require 'curb'
|
5
|
+
require 'webmock/rspec'
|
6
|
+
|
7
|
+
require_relative '../lib/rack/captchachacha.rb'
|
8
|
+
|
9
|
+
|
10
|
+
describe "Rack::Captchachacha" do
|
11
|
+
include Rack::Test::Methods
|
12
|
+
|
13
|
+
before do
|
14
|
+
WebMock.reset!
|
15
|
+
WebMock.disable_net_connect!
|
16
|
+
end
|
17
|
+
|
18
|
+
def app
|
19
|
+
main_app = lambda { |env|
|
20
|
+
request = Rack::Request.new(env)
|
21
|
+
return_code, body_text =
|
22
|
+
case request.path
|
23
|
+
when '/' then [200,'Hello world']
|
24
|
+
when '/login'
|
25
|
+
if request.post?
|
26
|
+
env['captcha.valid'] ? [200, 'post login'] : [200, 'post fail']
|
27
|
+
else
|
28
|
+
[200,'login']
|
29
|
+
end
|
30
|
+
else
|
31
|
+
[404,'Nothing here']
|
32
|
+
end
|
33
|
+
[return_code,{'Content-type' => 'text/plain'}, [body_text]]
|
34
|
+
}
|
35
|
+
|
36
|
+
builder = Rack::Builder.new
|
37
|
+
builder.use Rack::Captchachacha
|
38
|
+
builder.run main_app
|
39
|
+
builder.to_app
|
40
|
+
end
|
41
|
+
|
42
|
+
context "basic request" do
|
43
|
+
it "is a 200 ok response code" do
|
44
|
+
get("/")
|
45
|
+
last_response.status == 200
|
46
|
+
end
|
47
|
+
it "should say hello" do
|
48
|
+
get("/")
|
49
|
+
last_response.body == "Hello world"
|
50
|
+
end
|
51
|
+
end # context
|
52
|
+
|
53
|
+
context "a page that requires a captcha" do
|
54
|
+
let(:session_id){ rand(1000) }
|
55
|
+
let(:url_to_request) { "#{Rack::Captchachacha::VERIFY_URL}/#{session_id}/response" }
|
56
|
+
|
57
|
+
it "should pass the captcha" do
|
58
|
+
stub_request(:get, url_to_request).to_return({:body => "1"})
|
59
|
+
post "/login", {'captcha_session' => session_id, 'captcha_answer' => 'response'}
|
60
|
+
|
61
|
+
WebMock.should have_requested(:get, url_to_request)
|
62
|
+
|
63
|
+
last_response.status.should == 200
|
64
|
+
last_response.body.should == 'post login'
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
it "should fail the captcha" do
|
69
|
+
stub_request(:get, url_to_request).to_return({:body => "0"})
|
70
|
+
post "/login", {'captcha_session' => session_id, 'captcha_answer' => 'response'}
|
71
|
+
|
72
|
+
WebMock.should have_requested(:get, url_to_request)
|
73
|
+
|
74
|
+
last_response.status.should == 200
|
75
|
+
last_response.body.should == 'post fail'
|
76
|
+
end
|
77
|
+
end # context
|
78
|
+
end
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: captchachacha
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Iain Barnett
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain:
|
12
|
+
- ! '-----BEGIN CERTIFICATE-----
|
13
|
+
|
14
|
+
MIIDNDCCAhygAwIBAgIBADANBgkqhkiG9w0BAQUFADBAMRIwEAYDVQQDDAlpYWlu
|
15
|
+
|
16
|
+
c3BlZWQxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
|
17
|
+
|
18
|
+
bTAeFw0xMDA4MTkyMTQwMDlaFw0xMTA4MTkyMTQwMDlaMEAxEjAQBgNVBAMMCWlh
|
19
|
+
|
20
|
+
aW5zcGVlZDEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYD
|
21
|
+
|
22
|
+
Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApraebFPxvJVrayuZ
|
23
|
+
|
24
|
+
xJkFZLAId7j0G3QG4oyJcRaJVhaJ36zcCUeg6/6f9LC78nZSmL2zA2ZG9H3Lzda0
|
25
|
+
|
26
|
+
0j+McpynbK/eSq0XpruQbuuhcOBow1KgDfjdhz3qXylHJ/iIzBosQzoEIk5eVY84
|
27
|
+
|
28
|
+
R0qD+vNHwZQoDE+k4PB8LWIfbJPi+dmnL16C0qireO3nZASwTSGm1JdUtgESP0Hn
|
29
|
+
|
30
|
+
f1KAe/ox00S8cSQNGUZ/fAsrnhAOApL9V38TwxiL0eMVcY+TbUspI26MB8oNwsgV
|
31
|
+
|
32
|
+
zkBNt2lI45/SguV5wWMOWbWZ2v//w3PrBCUenkk+vwZmpOQUlk/8Ebrk+UeoAN1F
|
33
|
+
|
34
|
+
NqE2DQIDAQABozkwNzAJBgNVHRMEAjAAMB0GA1UdDgQWBBTMWVuCrozPKTpMRYkm
|
35
|
+
|
36
|
+
RUAqQFsGdDALBgNVHQ8EBAMCBLAwDQYJKoZIhvcNAQEFBQADggEBAFqZW23axU5A
|
37
|
+
|
38
|
+
Hf/p5iBfRlJLIZqFmVbGb1A+mxaPFUkhERH7FfY4ay4p2Ci1DNhSYQLy5dsB1ik0
|
39
|
+
|
40
|
+
J0tlNaXxkJ0uq6up65yoj4/XBJArm9oiO7PcwrzC52bmiEv4Ir67/AGRyfmgIU0A
|
41
|
+
|
42
|
+
5jv3cSFcnbrwCvClZOoVhNkvaxer3/DgLecpjgXfSwY++JHU0L/5HplidHzjE3PZ
|
43
|
+
|
44
|
+
1YGYQYJGIy5Hap8Lpn1x9/Q2C8pMX33JRItrIVie6UIsrGXVtGS5lZS/pri9Budd
|
45
|
+
|
46
|
+
+ikjZ+dLa/HjsXQ5HcI6WdySxyKElXr2Ecs8ipmnxCk6+KH9/2OnXrpBzeIXJoMS
|
47
|
+
|
48
|
+
YK13fiGcldY=
|
49
|
+
|
50
|
+
-----END CERTIFICATE-----
|
51
|
+
|
52
|
+
'
|
53
|
+
date: 2011-06-14 00:00:00.000000000Z
|
54
|
+
dependencies:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rack
|
57
|
+
requirement: &2161671660 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - =
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.3.0
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: *2161671660
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: curb
|
68
|
+
requirement: &2161671200 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - =
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 0.7.15
|
74
|
+
type: :runtime
|
75
|
+
prerelease: false
|
76
|
+
version_requirements: *2161671200
|
77
|
+
description: ! ' Captchator as Rack middleware, and helpers for sinatra.
|
78
|
+
|
79
|
+
'
|
80
|
+
email: iainspeed @nospam@ gmail.com
|
81
|
+
executables: []
|
82
|
+
extensions: []
|
83
|
+
extra_rdoc_files: []
|
84
|
+
files:
|
85
|
+
- .gitignore
|
86
|
+
- CHANGES
|
87
|
+
- Gemfile
|
88
|
+
- README
|
89
|
+
- Rakefile
|
90
|
+
- captchachacha.gemspec
|
91
|
+
- lib/rack/captchachacha.rb
|
92
|
+
- lib/rack/captchachacha/helpers.rb
|
93
|
+
- lib/rack/captchachacha/version.rb
|
94
|
+
- spec/captchachacha_spec.rb
|
95
|
+
homepage: https://github.com/yb66/Captchachacha
|
96
|
+
licenses: []
|
97
|
+
post_install_message:
|
98
|
+
rdoc_options: []
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: 1.9.2
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ! '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 1.8.5
|
116
|
+
signing_key:
|
117
|
+
specification_version: 3
|
118
|
+
summary: Captchator for rack with helpers for sinatra
|
119
|
+
test_files:
|
120
|
+
- spec/captchachacha_spec.rb
|
metadata.gz.sig
ADDED
Binary file
|