rack-picatcha 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
File without changes
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 James Ayvaz
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,123 @@
1
+ Dropin replacement for rack-recaptcha that uses picatcha verification.
2
+
3
+ ## How to Use
4
+
5
+ ### Configuration
6
+
7
+ First, install the library with:
8
+ [sudo] gem install rack-picatcha
9
+
10
+ You have to require 'rack-picatcha' in your gemfile.
11
+
12
+ ````ruby
13
+ ## Gemfile
14
+ gem 'rack-picatcha', :require => 'rack/picatcha'
15
+ ````
16
+
17
+
18
+ Available options for `Rack::Picatcha` middleware are:
19
+
20
+ * :public_key -- your Picatcha API public key *(required)*
21
+ * :private_key -- your Picatcha API private key *(required)*
22
+ * :proxy_host -- the HTTP Proxy hostname *(optional)*
23
+ * :proxy_port -- the HTTP Proxy port *(optional)*
24
+ * :proxy_user -- the HTTP Proxy user *(optional, omit unless the proxy requires it)*
25
+ * :proxy_password -- the HTTP Proxy password *(optional, omit unless the proxy requires it)*
26
+
27
+ Now configure your app to use the middleware. This might be different across each web framework.
28
+ Only tested with Sinatra
29
+
30
+ #### Sinatra
31
+
32
+ ````ruby
33
+ ## app.rb
34
+ use Rack::Picatcha, :public_key => 'KEY', :private_key => 'SECRET'
35
+ helpers Rack::Picatcha::Helpers
36
+ ````
37
+
38
+ #### Padrino
39
+
40
+ ````ruby
41
+ ## app/app.rb
42
+ use Rack::Picatcha, :public_key => 'KEY', :private_key => 'SECRET'
43
+ helpers Rack::Picatcha::Helpers
44
+ ````
45
+
46
+
47
+ #### Rails
48
+
49
+ ````ruby
50
+ ## application.rb:
51
+ module YourRailsAppName
52
+ class Application < Rails::Application
53
+ ...
54
+ config.gem 'rack-picatcha', :lib => 'rack/picatcha'
55
+ config.middleware.use Rack::Picatcha, :public_key => 'KEY', :private_key => 'SECRET'
56
+ end
57
+ end
58
+
59
+ ## application_helper.rb or whatever helper you want it in.
60
+ module ApplicationHelper
61
+ include Rack::Picatcha::Helpers
62
+ end
63
+
64
+ ## application_controller.rb or whatever controller you want it in.
65
+ class ApplicationController < ActionController::Base
66
+ ...
67
+ include Rack::Picatcha::Helpers
68
+ ...
69
+ end
70
+ ````
71
+
72
+ ### Helpers
73
+
74
+ The `Rack::Picatcha::Helpers` module (for Sinatra, Rails, Padrino) adds these methods to your app:
75
+
76
+ Return a picatcha form
77
+ ```ruby
78
+ picatcha_tag :challenge, :public_key => PUBLIC_KEY
79
+ ```
80
+
81
+ To test whether or not the verification passed, you can use:
82
+
83
+ ```ruby
84
+ picatcha_valid?
85
+ ```
86
+
87
+ or
88
+
89
+ ```ruby
90
+ picatcha_valid? :picatcha => params[:picatcha], :private_key => "#{recaptcha_privatekey}"
91
+ ```
92
+
93
+ The `picatcha_valid?` helper can also be overloaded during tests. You
94
+ can set its response to either true or false by doing the following:
95
+
96
+ ```ruby
97
+ # Have picatcha_valid? return true
98
+ Rack::Picatcha.test_mode!
99
+
100
+ # Or have it return false
101
+ Rack::Picatcha.test_mode! :return => false
102
+ ```
103
+
104
+
105
+ ### Contributors
106
+
107
+ James Ayvaz - [ayvazj](https://github.com/ayvazj)
108
+
109
+ * drop in replacement for rack-recaptcha
110
+
111
+ #### Note on Patches/Pull Requests
112
+
113
+ * Fork the project.
114
+ * Make your feature addition or bug fix.
115
+ * Add tests for it. This is important so I don't break it in a
116
+ future version unintentionally.
117
+ * Commit, do not mess with rakefile, version, or history.
118
+ (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)
119
+ * Send me a pull request. Bonus points for topic branches.
120
+
121
+ #### Copyright
122
+
123
+ Copyright (c) 2012 James Ayvaz. See LICENSE for details.
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/*_test.rb'
8
+ test.warning = true
9
+ test.verbose = true
10
+ end
11
+
12
+ task :default => [:test]
@@ -0,0 +1,146 @@
1
+ require File.expand_path '../picatcha/helpers', __FILE__
2
+ require 'net/http'
3
+
4
+ module Rack
5
+ class Picatcha
6
+ API_URL = 'http://api.picatcha.com'
7
+ API_SECURE_URL = 'https://api.picatcha.com'
8
+ VERIFY_URL = 'http://api.picatcha.com/v'
9
+ CHALLENGE_FIELD = 'picatcha'
10
+
11
+ SKIP_VERIFY_ENV = ['test', 'cucumber']
12
+
13
+ class << self
14
+ attr_accessor :private_key, :public_key, :test_mode, :proxy_host, :proxy_port, :proxy_user, :proxy_password
15
+
16
+ def test_mode!(options = {})
17
+ value = options[:return]
18
+ self.test_mode = value.nil? ? true : options[:return]
19
+ end
20
+ end
21
+
22
+ # Initialize the Rack Middleware. Some of the available options are:
23
+ # :public_key -- your Picatcha API public key *(required)*
24
+ # :private_key -- your Picatcha API private key *(required)*
25
+ #
26
+ def initialize(app,options = {})
27
+ @app = app
28
+ @paths = options[:paths] && [options[:paths]].flatten.compact
29
+ self.class.private_key = options[:private_key]
30
+ self.class.public_key = options[:public_key]
31
+ self.class.proxy_host = options[:proxy_host]
32
+ self.class.proxy_port = options[:proxy_port]
33
+ self.class.proxy_user = options[:proxy_user]
34
+ self.class.proxy_password = options[:proxy_password]
35
+ end
36
+
37
+ def call(env)
38
+ # LOGGER.debug "def call"
39
+ dup._call(env)
40
+ end
41
+
42
+ def _call(env)
43
+ request = Request.new(env)
44
+ # LOGGER.debug "def _call env=#{env} params=#{request.params}"
45
+ if request.params[CHALLENGE_FIELD]
46
+ value, msg = verify({
47
+ :request => request,
48
+ :ip => request.ip,
49
+ :challenge => request.params[CHALLENGE_FIELD]
50
+ })
51
+ env.merge!('picatcha.valid' => value == 'true', 'picatcha.msg' => msg)
52
+ end
53
+ @app.call(env)
54
+ end
55
+
56
+ def verify(options = {})
57
+ if !options.is_a? Hash
58
+ options = {:model => options}
59
+ end
60
+
61
+ model = options[:model]
62
+ request = options[:request]
63
+
64
+ return Rack::Picatcha.verify_picatcha({
65
+ :private_key => Rack::Picatcha.private_key,
66
+ :ipaddr => request.ip,
67
+ :proxy_host => self.class.proxy_host,
68
+ :proxy_port => self.class.proxy_port,
69
+ :proxy_user => self.class.proxy_user,
70
+ :proxy_password => self.class.proxy_password,
71
+ :picatcha => request.params["picatcha"]
72
+ })
73
+ end
74
+
75
+ def self.verify_picatcha(options = {})
76
+ if !options.is_a? Hash
77
+ options = {:model => options}
78
+ end
79
+
80
+ ipaddr = options[:ipaddr]
81
+ proxy_host = options[:proxy_host]
82
+ proxy_port = options[:proxy_port]
83
+ proxy_user = options[:proxy_user]
84
+ proxy_password = options[:proxy_password]
85
+
86
+ private_key = options[:private_key]
87
+ picatchadata = options[:picatcha]
88
+
89
+ data = {
90
+ "k" => private_key,
91
+ "ip" => ipaddr,
92
+ "ua"=> "Rack-Picatcha Ruby Gem",
93
+ "s" => picatchadata[:stages], #the number of stages
94
+ "t" => picatchadata[:token], #the challenge token
95
+ "r" => picatchadata[:r] #the array of images
96
+ }
97
+
98
+ payload = data.to_json
99
+ # LOGGER.debug "payload = #{payload}"
100
+
101
+ uri = URI.parse(VERIFY_URL)
102
+ http = Net::HTTP.start(uri.host, uri.port)
103
+
104
+ if proxy_host && proxy_port
105
+ http = Net::HTTP.Proxy(proxy_host,
106
+ proxy_port,
107
+ proxy_user,
108
+ proxy_password).start(uri.host, uri.port)
109
+ end
110
+
111
+ request = Net::HTTP::Post.new(uri.path)
112
+ request.body = payload
113
+ response = http.request(request)
114
+
115
+ # debugging info
116
+ # LOGGER.debug "response.body = #{response.body}"
117
+
118
+ if response.body !=nil
119
+ parsed_json = JSON(response.body)
120
+ else
121
+ return false, 'No reponse captured'
122
+ end
123
+
124
+ # LOGGER.error "error? = #{parsed_json["e"]}"
125
+
126
+ error = parsed_json["e"]
127
+
128
+ # so far just a simple if.. else to check if the picatcha was
129
+ # solved correctly. will revisit later and make it more
130
+ # verbose
131
+ if parsed_json["s"]==true
132
+ return true, ""
133
+ else
134
+ message = "Sorry, you incorrectly filled out Picatcha. Please try again."
135
+ message = I18n.translate(:'picatcha.errors.verification_failed', :default => message) if defined?(I18n)
136
+ return false, message
137
+ end
138
+ end
139
+
140
+
141
+
142
+
143
+ class PicatchaError < StandardError
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,90 @@
1
+ require 'json'
2
+
3
+ module Rack
4
+ class Picatcha
5
+ module Helpers
6
+
7
+ DEFAULT= {
8
+ :height => 300,
9
+ :width => 500,
10
+ :row => 3,
11
+ :cols => 5,
12
+ :format => '2',
13
+ :style => '#2a1f19',
14
+ :link => '1',
15
+ :img_size => '75',
16
+ :noise_level => '2',
17
+ :noise_type => '0',
18
+ :lang => 'en',
19
+ :lang_override => '0',
20
+ :ssl => false
21
+ }
22
+
23
+ # Helper method to output a picatcha form. Some of the available
24
+ # types you can have are:
25
+ #
26
+ # :challenge - Returns a javascript picatcha form
27
+ # :noscript - Return a non-javascript picatcha form
28
+ # :ajax - Return a ajax picatcha form
29
+ #
30
+ # You also have a few available options:
31
+ #
32
+ # For :challenge and :noscript
33
+ # :public_key - Set the public key. Overrides the key set in Middleware option
34
+ def picatcha_tag(type= :noscript, options={})
35
+ # Default options
36
+ options = DEFAULT.merge(options)
37
+ options[:public_key] ||= Rack::Picatcha.public_key
38
+ path = options[:ssl] ? Rack::Picatcha::API_SECURE_URL : Rack::Picatcha::API_URL
39
+
40
+ raise PicatchaError, "No public key specified." unless options[:public_key].to_s != ''
41
+ error = options[:error] ||= (defined? flash ? flash[:picatcha_error] : "")
42
+ html = ""
43
+ elm_id = "picatcha"
44
+
45
+ html << <<-EOS
46
+ <script type="text/javascript" src="#{path}/static/client/jquery.min.js"></script>
47
+ <script type="text/javascript" src="#{path}/static/client/picatcha.js"></script>
48
+ <link href="#{path}/static/client/picatcha.css" rel="stylesheet" type="text/css">
49
+ <script>Picatcha.PUBLIC_KEY="#{options[:public_key]}";
50
+ Picatcha.setCustomization({"format":"#{options[:format]}","color":"#{options[:style]}","link":"#{options[:link]}","image_size":"#{options[:img_size]}","lang":"#{options[:lang]}","langOverride":"#{options[:lang_override]}","noise_level":"#{options[:noise_level]}","noise_type":"#{options[:noise_type]}"});
51
+ window.onload=function(){Picatcha.create("#{elm_id}", {});};</script>
52
+ <div id="#{elm_id}"></div>
53
+ EOS
54
+
55
+ if options[:display]
56
+ %{<script type="text/javascript">
57
+ var PicatchaOptions = #{options[:display].to_json};
58
+ </script>}.gsub(/^ +/, '')
59
+ else
60
+ ''
61
+ end + html
62
+ end
63
+
64
+ # Helper to return whether the picatcha was accepted.
65
+ def picatcha_valid?(options={})
66
+ # LOGGER.debug "def picatchs_valid? options=#{options}"
67
+ picatchadata = options[:picatcha] || ""
68
+ private_key = options[:private_key] || Rack::Picatcha.private_key
69
+ if picatchadata.to_s == "" then
70
+ test = Rack::Picatcha.test_mode
71
+ test.nil? ? request.env['picatcha.valid'] : test
72
+ else
73
+ retval, msg = Rack::Picatcha.verify_picatcha({
74
+ :private_key => private_key,
75
+ :ipaddr => request.ip,
76
+ :picatcha => picatchadata
77
+ })
78
+ return retval
79
+ end
80
+ end
81
+
82
+ private
83
+
84
+ def uri_parser
85
+ @uri_parser ||= URI.const_defined?(:Parser) ? URI::Parser.new : URI
86
+ end
87
+
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,23 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = %q{rack-picatcha}
3
+ s.version = "0.1.0"
4
+ s.required_rubygems_version = ">=1.3.6"
5
+ s.authors = ["James Ayvaz"]
6
+ s.date = %q{2012-10-04}
7
+ s.description = %q{Rack middleware verification using Picatcha API.}
8
+ s.email = %q{james.ayvaz@gmail.com}
9
+ s.extra_rdoc_files = ["LICENSE", "README.md"]
10
+ s.files = %w{.gitignore LICENSE README.md Rakefile rack-picatcha.gemspec} + Dir.glob("{lib,test}/**/*")
11
+ s.homepage = %q{http://github.com/ayvazj/rack-picatcha}
12
+ s.rdoc_options = ["--charset=UTF-8"]
13
+ s.require_paths = ["lib"]
14
+ s.rubygems_version = %q{1.3.7}
15
+ s.summary = %q{Rack middleware for Picatcha}
16
+ s.test_files = Dir.glob("test/**/*")
17
+ s.add_runtime_dependency "json", ">= 0"
18
+ s.add_development_dependency "rake", "~> 0.9.2"
19
+ s.add_development_dependency "riot", "~> 0.12.3"
20
+ s.add_development_dependency "rack-test", "~> 0.5.7"
21
+ s.add_development_dependency "fakeweb", "~> 1.3.0"
22
+ s.add_development_dependency "rr", "~> 1.0.2"
23
+ end
@@ -0,0 +1,176 @@
1
+ require File.expand_path '../teststrap', __FILE__
2
+
3
+ class HelperTest
4
+ attr_accessor :request
5
+ include Rack::Picatcha::Helpers
6
+
7
+ def initialize
8
+ @request = HelperTest::Request.new
9
+ end
10
+
11
+ class Request
12
+ attr_accessor :env
13
+ end
14
+ end
15
+
16
+
17
+ # With "attr_accessor :request" HelperTest has "request" defined as a method
18
+ # even when @request is set to nil
19
+ #
20
+ # defined?(request)
21
+ # => method
22
+ # request
23
+ # => nil
24
+ # self
25
+ # => #<HelperTest:0x00000002125000 @request=nil>
26
+ class HelperTestWithoutRequest
27
+ include Rack::Picatcha::Helpers
28
+ end
29
+
30
+ context "Rack::Picatcha::Helpers" do
31
+ helper(:helper_test) { HelperTest.new }
32
+
33
+ setup { Rack::Picatcha.public_key = '0'*40 }
34
+
35
+ context "picatcha_tag" do
36
+
37
+ context "ajax" do
38
+ context "with display" do
39
+ setup do
40
+ mock(helper_test.request.env).[]('picatcha.msg').returns(nil)
41
+ helper_test.picatcha_tag(:ajax,:display => {:theme => 'red'})
42
+ end
43
+
44
+ asserts_topic('has js').matches %r{picatcha_ajax.js}
45
+ asserts_topic('has div').matches %r{<div id="ajax_picatcha"></div>}
46
+ asserts_topic('has display').matches %r{PicatchaOptions}
47
+ asserts_topic('has theme').matches %r{"theme":"red"}
48
+ end
49
+
50
+ context "without display" do
51
+ setup do
52
+ mock(helper_test.request.env).[]('picatcha.msg').returns(nil)
53
+ helper_test.picatcha_tag(:ajax)
54
+ end
55
+
56
+ asserts_topic('has js').matches %r{picatcha_ajax.js}
57
+ asserts_topic('has div').matches %r{<div id="ajax_picatcha"></div>}
58
+ denies_topic('has display').matches %r{PicatchaOptions}
59
+ denies_topic('has theme').matches %r{"theme":"red"}
60
+ end
61
+ end
62
+
63
+ context "noscript" do
64
+ setup do
65
+ mock(helper_test.request.env).[]('picatcha.msg').returns(nil)
66
+ helper_test.picatcha_tag :noscript, :public_key => "hello_world_world", :language => :en
67
+ end
68
+
69
+ asserts_topic("iframe").matches %r{iframe}
70
+ asserts_topic("no script tag").matches %r{<noscript>}
71
+ asserts_topic("public key").matches %r{hello_world_world}
72
+ asserts_topic("has language").matches %r{hl=en}
73
+ denies_topic("has js").matches %r{picatcha_ajax.js}
74
+ end
75
+
76
+ context "challenge" do
77
+ setup do
78
+ mock(helper_test.request.env).[]('picatcha.msg').returns(nil)
79
+ helper_test.picatcha_tag(:challenge, :language => :en)
80
+ end
81
+
82
+ asserts_topic("has script tag").matches %r{script}
83
+ asserts_topic("has challenge js").matches %r{challenge}
84
+ denies_topic("has js").matches %r{picatcha_ajax.js}
85
+ denies_topic("has display").matches %r{PicatchaOptions}
86
+ asserts_topic("has public_key").matches %r{#{'0'*40}}
87
+ asserts_topic("has language").matches %r{hl=en}
88
+ end
89
+
90
+ context "server" do
91
+
92
+ asserts("using ssl url") do
93
+ mock(helper_test.request.env).[]('picatcha.msg').returns(nil)
94
+ helper_test.picatcha_tag(:challenge, :ssl => true)
95
+ end.matches %r{#{Rack::Picatcha::API_SECURE_URL}}
96
+
97
+ asserts("using non ssl url") do
98
+ mock(helper_test.request.env).[]('picatcha.msg').returns(nil)
99
+ helper_test.picatcha_tag(:ajax)
100
+ end.matches %r{#{Rack::Picatcha::API_URL}}
101
+ end
102
+
103
+ end
104
+
105
+ context "picatcha_tag_errors" do
106
+ context "challenge with error" do
107
+ setup do
108
+ mock(helper_test.request.env).[]('picatcha.msg').returns("Sample Error")
109
+ helper_test.picatcha_tag(:challenge)
110
+ end
111
+
112
+ asserts_topic("has script tag").matches %r{script}
113
+ asserts_topic("has challenge js").matches %r{challenge}
114
+ denies_topic("has js").matches %r{picatcha_ajax.js}
115
+ denies_topic("has display").matches %r{PicatchaOptions}
116
+ asserts_topic("has public_key").matches %r{#{'0'*40}}
117
+ asserts_topic("has previous error").matches %r{Sample%20Error}
118
+ end
119
+
120
+ context "noscript with error" do
121
+ setup do
122
+ mock(helper_test.request.env).[]('picatcha.msg').returns("Sample Error")
123
+ helper_test.picatcha_tag :noscript, :public_key => "hello_world_world"
124
+ end
125
+
126
+ asserts_topic("iframe").matches %r{iframe}
127
+ asserts_topic("no script tag").matches %r{<noscript>}
128
+ asserts_topic("public key").matches %r{hello_world_world}
129
+ denies_topic("has js").matches %r{picatcha_ajax.js}
130
+ asserts_topic("has previous error").matches %r{Sample%20Error}
131
+ end
132
+
133
+ end
134
+
135
+ context "picatcha_valid?" do
136
+
137
+ asserts "that it passes when picatcha.valid is true" do
138
+ Rack::Picatcha.test_mode = nil
139
+ mock(helper_test.request.env).[]('picatcha.valid').returns(true)
140
+ helper_test.picatcha_valid?
141
+ end
142
+
143
+ denies "that it passes when picatcha.valid is false" do
144
+ Rack::Picatcha.test_mode = nil
145
+ mock(helper_test.request.env).[]('picatcha.valid').returns(false)
146
+ helper_test.picatcha_valid?
147
+ end
148
+
149
+ asserts "that it passes when test mode set to pass" do
150
+ Rack::Picatcha.test_mode!
151
+ helper_test.picatcha_valid?
152
+ end
153
+
154
+ denies "that it passes when test mode set to fail" do
155
+ Rack::Picatcha.test_mode! :return => false
156
+ helper_test.picatcha_valid?
157
+ end
158
+
159
+ end
160
+ end
161
+
162
+
163
+ context Rack::Picatcha::Helpers do
164
+ helper(:helper_test) { HelperTestWithoutRequest.new }
165
+ context "request object not available. Rack-picatcha shouldn't die" do
166
+ setup do
167
+ helper_test.picatcha_tag(:challenge)
168
+ end
169
+
170
+ asserts_topic("has script tag").matches %r{script}
171
+ asserts_topic("has challenge js").matches %r{challenge}
172
+ denies_topic("has js").matches %r{picatcha_ajax.js}
173
+ denies_topic("has display").matches %r{PicatchaOptions}
174
+ asserts_topic("has public_key").matches %r{#{'0'*40}}
175
+ end
176
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path './teststrap'
2
+
3
+ FakeWeb.allow_net_connect = false
4
+ context "Rack::Picatcha" do
5
+
6
+ context "basic request" do
7
+ setup { get("/") ; last_response }
8
+
9
+ asserts(:status).equals 200
10
+ asserts(:body).equals "Hello world"
11
+ end
12
+
13
+ context "exposes" do
14
+ setup { Rack::Picatcha }
15
+
16
+ asserts(:private_key).equals PRIVATE_KEY
17
+ asserts(:public_key).equals PUBLIC_KEY
18
+ end
19
+
20
+ context "#test_mode!" do
21
+ setup { Rack::Picatcha }
22
+
23
+ asserts "that it sets @@test_mode to be true" do
24
+ topic.test_mode!
25
+ topic.test_mode
26
+ end
27
+
28
+ denies "that it sets @@test_mode to be true if option set to false" do
29
+ topic.test_mode! :return => false
30
+ topic.test_mode
31
+ end
32
+ end
33
+
34
+ context "login path" do
35
+
36
+ asserts "GET login" do
37
+ get '/login'
38
+ last_response.body
39
+ end.equals 'login'
40
+
41
+
42
+ asserts "POST login passes and" do
43
+ puts Rack::Picatcha::VERIFY_URL
44
+ FakeWeb.register_uri(:post, Rack::Picatcha::VERIFY_URL, :body => "true\nsuccess")
45
+ puts "HERE2"
46
+ post("/login", 'picatcha_challenge_field' => 'challenge', 'picatcha_response_field' => 'response')
47
+ puts "HERE3"
48
+ last_response.body
49
+ end.equals 'post login'
50
+
51
+ asserts "POST login fails and" do
52
+ FakeWeb.register_uri(:post, Rack::Picatcha::VERIFY_URL, :body => "false\nfailed")
53
+ post("/login", 'picatcha_challenge_field' => 'challenge', 'picatcha_response_field' => 'response')
54
+ last_response.body
55
+ end.equals 'post fail'
56
+ end
57
+
58
+ end
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'rack/test'
3
+ require 'rack/mock'
4
+ require 'rack/utils'
5
+ require 'rack/session/cookie'
6
+ require 'rack/builder'
7
+ require 'rr'
8
+ require 'riot'
9
+ require 'riot/rr'
10
+ require 'fakeweb'
11
+ require File.expand_path '../../lib/rack/picatcha', __FILE__
12
+
13
+ PUBLIC_KEY = '0'*40
14
+ PRIVATE_KEY = 'X'*40
15
+
16
+ class Riot::Situation
17
+ include Rack::Test::Methods
18
+
19
+ def app
20
+ main_app = lambda { |env|
21
+ request = Rack::Request.new(env)
22
+ return_code, body_text =
23
+ case request.path
24
+ when '/' then [200,'Hello world']
25
+ when '/login'
26
+ if request.post?
27
+ env['picatcha.valid'] ? [200, 'post login'] : [200, 'post fail']
28
+ else
29
+ [200,'login']
30
+ end
31
+ else
32
+ [404,'Nothing here']
33
+ end
34
+ [return_code,{'Content-type' => 'text/plain'}, [body_text]]
35
+ }
36
+
37
+ builder = Rack::Builder.new
38
+ builder.use Rack::Picatcha, :private_key => PRIVATE_KEY, :public_key => PUBLIC_KEY
39
+ builder.run main_app
40
+ builder.to_app
41
+ end
42
+ end
43
+
44
+ class Riot::Context
45
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-picatcha
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - James Ayvaz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.9.2
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.9.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: riot
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.12.3
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.12.3
62
+ - !ruby/object:Gem::Dependency
63
+ name: rack-test
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.5.7
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.5.7
78
+ - !ruby/object:Gem::Dependency
79
+ name: fakeweb
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 1.3.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 1.3.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: rr
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 1.0.2
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 1.0.2
110
+ description: Rack middleware verification using Picatcha API.
111
+ email: james.ayvaz@gmail.com
112
+ executables: []
113
+ extensions: []
114
+ extra_rdoc_files:
115
+ - LICENSE
116
+ - README.md
117
+ files:
118
+ - .gitignore
119
+ - LICENSE
120
+ - README.md
121
+ - Rakefile
122
+ - rack-picatcha.gemspec
123
+ - lib/rack/picatcha/helpers.rb
124
+ - lib/rack/picatcha.rb
125
+ - test/helpers_test.rb
126
+ - test/picatcha_test.rb
127
+ - test/teststrap.rb
128
+ homepage: http://github.com/ayvazj/rack-picatcha
129
+ licenses: []
130
+ post_install_message:
131
+ rdoc_options:
132
+ - --charset=UTF-8
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ none: false
137
+ requirements:
138
+ - - ! '>='
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ none: false
143
+ requirements:
144
+ - - ! '>='
145
+ - !ruby/object:Gem::Version
146
+ version: 1.3.6
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 1.8.24
150
+ signing_key:
151
+ specification_version: 3
152
+ summary: Rack middleware for Picatcha
153
+ test_files:
154
+ - test/helpers_test.rb
155
+ - test/picatcha_test.rb
156
+ - test/teststrap.rb