rack-picatcha 0.1.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.
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