lastobelus-merb-recaptcha 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +45 -0
  3. data/Rakefile +81 -0
  4. data/TODO +1 -0
  5. data/lib/merb-recaptcha.rb +30 -0
  6. data/lib/merb-recaptcha/constants.rb +7 -0
  7. data/lib/merb-recaptcha/controller_mixin.rb +47 -0
  8. data/lib/merb-recaptcha/exceptions.rb +30 -0
  9. data/lib/merb-recaptcha/merbtasks.rb +0 -0
  10. data/lib/merb-recaptcha/view_helpers.rb +117 -0
  11. data/merb-recaptcha.gemspec +44 -0
  12. data/spec/fixture/app/controllers/application.rb +2 -0
  13. data/spec/fixture/app/controllers/exceptions.rb +13 -0
  14. data/spec/fixture/app/controllers/recaptcha.rb +29 -0
  15. data/spec/fixture/app/helpers/global_helpers.rb +5 -0
  16. data/spec/fixture/app/helpers/recaptcha_helpers.rb +4 -0
  17. data/spec/fixture/app/views/exceptions/not_acceptable.html.erb +63 -0
  18. data/spec/fixture/app/views/exceptions/not_found.html.erb +47 -0
  19. data/spec/fixture/app/views/layout/application.html.erb +10 -0
  20. data/spec/fixture/app/views/recaptcha/ajax.html.erb +2 -0
  21. data/spec/fixture/app/views/recaptcha/ajax_with_callback.html.erb +2 -0
  22. data/spec/fixture/app/views/recaptcha/ajax_with_jquery.html.erb +2 -0
  23. data/spec/fixture/app/views/recaptcha/ajax_with_options.html.erb +2 -0
  24. data/spec/fixture/app/views/recaptcha/noajax_with_noscript.html.erb +1 -0
  25. data/spec/fixture/app/views/recaptcha/noajax_with_options.html.erb +1 -0
  26. data/spec/fixture/app/views/recaptcha/noajax_without_noscript.html.erb +1 -0
  27. data/spec/recaptcha_ajax_spec.rb +39 -0
  28. data/spec/recaptcha_ajax_with_callback_spec.rb +35 -0
  29. data/spec/recaptcha_ajax_with_jquery_spec.rb +39 -0
  30. data/spec/recaptcha_ajax_with_options_spec.rb +35 -0
  31. data/spec/recaptcha_noajax_with_noscript_spec.rb +59 -0
  32. data/spec/recaptcha_noajax_with_options_spec.rb +39 -0
  33. data/spec/recaptcha_noajax_without_noscript_spec.rb +39 -0
  34. data/spec/recaptcha_valid_spec.rb +125 -0
  35. data/spec/spec_helper.rb +46 -0
  36. metadata +152 -0
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Anton Ageev
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.
data/README.rdoc ADDED
@@ -0,0 +1,45 @@
1
+ = merb-recaptcha
2
+
3
+ == About
4
+
5
+ Merb-recaptcha is plugin for Merb web-framework. It provides view and controller helpers for Recaptcha service.
6
+
7
+ == Installation
8
+
9
+ Install gem from github.com:
10
+ gem install antage-merb-recaptcha --source=http://gems.github.com
11
+
12
+ Add following line in <tt>config/dependencies.rb</tt> of your web application:
13
+ dependency "antage-merb-recaptcha", "~> 1.0.0", :require_as => "merb-recaptcha"
14
+
15
+ Sign up at Recaptcha and get public and private keys. Add keys in <tt>config/init.rb</tt>:
16
+ Merb::BootLoader.after_app_loads do
17
+ Merb::Plugins.config[:merb_recaptcha][:public_key] = "... here your public key ..."
18
+ Merb::Plugins.config[:merb_recaptcha][:private_key] = "... here your private key ..."
19
+ end
20
+
21
+ == Usage
22
+
23
+ Just add helper in your form:
24
+ <%= form_for @users, :action => resource(:users), :method => :post do %>
25
+ .....
26
+ <%= recaptcha_tags %>
27
+ <%= submit "Send" %>
28
+ <% end %>
29
+
30
+ And then check captcha in controller:
31
+ class Users < Application
32
+ ......
33
+ def create(user)
34
+ @user = User.new(user)
35
+ if (captcha_correct = recaptcha_valid?) && @user.save
36
+ redirect resource(@user)
37
+ else
38
+ unless captcha_correct
39
+ @user.valid?
40
+ @user.errors.add(:general, "Captcha code is incorrect")
41
+ end
42
+ render :new
43
+ end
44
+ ......
45
+ end
data/Rakefile ADDED
@@ -0,0 +1,81 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/clean'
5
+
6
+ require 'yard'
7
+ require 'yard/rake/yardoc_task'
8
+
9
+ require 'spec/rake/spectask'
10
+
11
+ require 'merb-core'
12
+ require 'merb-core/tasks/merb'
13
+
14
+ GEM_NAME = "merb-recaptcha"
15
+ GEM_VERSION = "1.0.2"
16
+ AUTHOR = "Anton Ageev"
17
+ EMAIL = "antage@gmail.com"
18
+ HOMEPAGE = "http://github.com/antage/merb-recaptcha/"
19
+ SUMMARY = "Merb plugin that provides helpers for recaptcha.net service"
20
+
21
+ spec = Gem::Specification.new do |s|
22
+ s.rubyforge_project = 'merb-recaptcha'
23
+ s.name = GEM_NAME
24
+ s.version = GEM_VERSION
25
+ s.platform = Gem::Platform::RUBY
26
+ s.has_rdoc = true
27
+ s.extra_rdoc_files = [ "README.rdoc", "LICENSE" ]
28
+ s.rdoc_options << "--main" << "README.rdoc"
29
+ s.summary = SUMMARY
30
+ s.description = s.summary
31
+ s.author = AUTHOR
32
+ s.email = EMAIL
33
+ s.homepage = HOMEPAGE
34
+ s.require_path = 'lib'
35
+ s.files = %w(LICENSE README.rdoc Rakefile TODO merb-recaptcha.gemspec) + Dir["lib/**/*"].select { |f| File.file?(f) }
36
+ s.test_files = %w(spec/spec_helper.rb) + Dir["spec/*_spec.rb"] + Dir["spec/fixture/app/**/*"].select { |f| File.file?(f) }
37
+
38
+ s.add_runtime_dependency "merb-core", ">= 1.0.0"
39
+ s.add_runtime_dependency "builder", "~> 2.0"
40
+ s.add_development_dependency "rspec", ">= 1.1.0"
41
+ s.add_development_dependency "mocha", ">= 0.9.3"
42
+ end
43
+
44
+ Rake::GemPackageTask.new(spec) do |pkg|
45
+ pkg.gem_spec = spec
46
+ end
47
+
48
+ desc "install the plugin as a gem"
49
+ task :install do
50
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
51
+ end
52
+
53
+ desc "Uninstall the gem"
54
+ task :uninstall do
55
+ Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
56
+ end
57
+
58
+ desc "Create a gemspec file"
59
+ task :gemspec do
60
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
61
+ file.puts spec.to_ruby
62
+ end
63
+ end
64
+
65
+ Rake::RDocTask.new do |rdoc|
66
+ files = ["README.rdoc", "LICENSE", "lib/**/*.rb"]
67
+ rdoc.rdoc_files.add(files)
68
+ rdoc.main = "README.rdoc"
69
+ rdoc.title = "merb-recaptcha docs"
70
+ rdoc.rdoc_dir = "doc"
71
+ rdoc.options << "--line-numbers" << "--inline-source"
72
+ end
73
+
74
+ Spec::Rake::SpecTask.new(:spec) do |t|
75
+ t.spec_opts << '--format' << 'specdoc' << '--colour'
76
+ t.spec_opts << '--loadby' << 'random'
77
+ t.spec_files = Pathname.glob(ENV['FILES'] || 'spec/**/*_spec.rb')
78
+ t.rcov = false
79
+ end
80
+
81
+ task :default => :spec
data/TODO ADDED
@@ -0,0 +1 @@
1
+ TODO:
@@ -0,0 +1,30 @@
1
+ # make sure we're running inside Merb
2
+ if defined?(Merb::Plugins)
3
+
4
+ # Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
5
+ Merb::Plugins.config[:merb_recaptcha] = {
6
+ :public_key => "",
7
+ :private_key => "",
8
+ :allow_disable_by_cookie => false
9
+ }
10
+
11
+ Merb::BootLoader.before_app_loads do
12
+ # require code that must be loaded before the application
13
+ require 'merb-recaptcha/constants.rb'
14
+ require 'merb-recaptcha/view_helpers.rb'
15
+ require 'merb-recaptcha/exceptions.rb'
16
+ require 'merb-recaptcha/controller_mixin.rb'
17
+ module Merb::GlobalHelpers # :nodoc:
18
+ include Merb::Helpers::Recaptcha
19
+ end
20
+ class Merb::Controller # :nodoc:
21
+ include Merb::RecaptchaMixin
22
+ end
23
+ end
24
+
25
+ Merb::BootLoader.after_app_loads do
26
+ # code that can be required after the application loads
27
+ end
28
+
29
+ Merb::Plugins.add_rakefiles "merb-recaptcha/merbtasks"
30
+ end
@@ -0,0 +1,7 @@
1
+ module Merb
2
+ module Recaptcha
3
+ API_SERVER = "http://api.recaptcha.net"
4
+ API_SECURE_SERVER = "https://api-secure.recaptcha.net"
5
+ API_VERIFY_SERVER = "http://api-verify.recaptcha.net"
6
+ end
7
+ end
@@ -0,0 +1,47 @@
1
+ require 'net/http'
2
+
3
+ module Merb # :nodoc:
4
+ module RecaptchaMixin
5
+
6
+ # This method checks challenge and response data via Recaptcha API server.
7
+ # * It will return true, if filled captcha response is correct.
8
+ # * It will return false, if captcha is incorrect.
9
+ # * It will raise exception, if Recaptcha API server returns error.
10
+ #
11
+ def recaptcha_valid?
12
+ return true if (Merb.testing? && !Merb::RecaptchaMixin.const_defined?(:DO_NOT_IGNORE_RECAPTCHA_IN_TESTING_ENV))
13
+ return true if Merb::Plugins.config[:merb_recaptcha][:allow_disable_by_cookie] && cookies[:recaptcha_disabled]=="true"
14
+ begin
15
+ response = Net::HTTP.post_form(URI.parse("#{Merb::Recaptcha::API_VERIFY_SERVER}/verify"), {
16
+ :privatekey => Merb::Plugins.config[:merb_recaptcha][:private_key],
17
+ :remoteip => request.remote_ip,
18
+ :challenge => params[:recaptcha_challenge_field],
19
+ :response => params[:recaptcha_response_field]
20
+ })
21
+ rescue Exception => e
22
+ if Merb.env?(:production) || ENV['OFFLINE']
23
+ Merb.logger.error("when trying to connect to recaptcha, got #{e.message}")
24
+ return true;
25
+ else
26
+ raise
27
+ end
28
+ end
29
+ answer, error = response.body.split.map { |s| s.chomp }
30
+ if answer == "true"
31
+ true
32
+ else
33
+ Merb.logger.fatal("recaptcha error: #{error} for #{request.remote_ip}")
34
+ case error
35
+ when "incorrect-captcha-sol" then false
36
+ when "invalid-site-public-key" then raise Merb::Recaptcha::InvalidSitePublicKey
37
+ when "invalid-site-private-key" then raise Merb::Recaptcha::InvalidSitePrivateKey
38
+ when "invalid-request-cookie" then raise Merb::Recaptcha::InvalidRequestCookie
39
+ when "verify-params-incorrect" then raise Merb::Recaptcha::VerifyParamsIncorrect
40
+ when "invalid-referrer" then raise Merb::Recaptcha::InvalidReferrer
41
+ else
42
+ raise Merb::Recaptcha::GenericError
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,30 @@
1
+ module Merb # :nodoc:
2
+ module Recaptcha
3
+ class GenericError < RuntimeError; end
4
+
5
+ # We weren't able to verify the public key.
6
+ # Possible solutions:
7
+ #
8
+ # * Did you swap the public and private key? It is important to use the correct one
9
+ # * Did you make sure to copy the entire key, with all hyphens and underscores, but without any spaces? The key should be exactly 40 letters long.
10
+ #
11
+ class InvalidSitePublicKey < GenericError; end
12
+
13
+ # We weren't able to verify the private key.
14
+ # Possible solutions:
15
+ #
16
+ # * Did you swap the public and private key? It is important to use the correct one
17
+ # * Did you make sure to copy the entire key, with all hyphens and underscores, but without any spaces? The key should be exactly 40 letters long.
18
+ #
19
+ class InvalidSitePrivateKey < GenericError; end
20
+
21
+ # The challenge parameter of the verify script was incorrect.
22
+ class InvalidRequestCookie < GenericError; end
23
+
24
+ # The parameters to /verify were incorrect, make sure you are passing all the required parameters.
25
+ class VerifyParamsIncorrect < GenericError; end
26
+
27
+ # reCAPTCHA API keys are tied to a specific domain name for security reasons.
28
+ class InvalidReferrer < GenericError; end
29
+ end
30
+ end
File without changes
@@ -0,0 +1,117 @@
1
+ require 'builder'
2
+
3
+ module Merb # :nodoc:
4
+ module Helpers # :nodoc:
5
+ module Recaptcha
6
+
7
+ # Display recaptcha widget in various ways.
8
+ #
9
+ # * Display in-place:
10
+ # <%= recaptcha_tags :ajax => false, :noscript => false %>
11
+ #
12
+ # * Display in-place with <noscript></noscript> block:
13
+ # <%= recaptcha_tags :ajax => false, :noscript => true, :iframe_height => 100, :iframe_width => 100 %>
14
+ #
15
+ # * Dynamically create Recaptcha widget:
16
+ # <%= recaptcha_tags :ajax => true, :element_id => "recaptcha_place" %>
17
+ # <div id="recaptcha_place"></div>
18
+ # The above code bind javascript code on onload event:
19
+ # <script type="text/javascript">
20
+ # ....
21
+ # window.onload = function() { Recaptcha.create(....); }
22
+ # ....
23
+ # </script>
24
+ # If you use jQuery, you could use special value for :ajax parameter:
25
+ # <%= recaptcha_tags :ajax => :jquery %>
26
+ # <div id="recpatcha"></div>
27
+ # This code generates following:
28
+ # <script type="text/javascript">
29
+ # ....
30
+ # $(document).ready(function() { Recaptcha.create(....); });
31
+ # ....
32
+ # </script>
33
+ # You can specified callback function that will be invoked after widget has been created:
34
+ # <%= recaptcha_tags :ajax => true, :callback => "Recaptcha.focus_response_field" %>
35
+ # <div id="recaptcha"></div>
36
+ # This code will set focus on response field of created widget.
37
+ #
38
+ # For both displaying ways, you can customize widget:
39
+ # <%= recaptcha_tags :theme => "clean", :tabindex => 2 %>
40
+ # More detailed description of customizing options is at http://recaptcha.net/apidocs/captcha/client.html
41
+ #
42
+ # Default values of options:
43
+ # * :ajax => false
44
+ # * :element_id => "recaptcha"
45
+ # * :callback => nil
46
+ # * :noscript => false
47
+ # * :iframe_height => 300
48
+ # * :iframe_width => 500
49
+ #
50
+ def recaptcha_tags(options = {})
51
+ public_key = Merb::Plugins.config[:merb_recaptcha][:public_key]
52
+
53
+ ajax = options.delete(:ajax) || false # boolean or :jquery
54
+ element_id = options.delete(:element_id) || "recaptcha" # string, html element id, only if ajax == true
55
+ callback = options.delete(:callback) # string, javascript function name, only if ajax == true
56
+ noscript = options.delete(:noscript) || false # boolean
57
+ iframe_height = options.delete(:iframe_height) || 300 # integer, only if noscript == true
58
+ iframe_width = options.delete(:iframe_width) || 500 # integer, only if noscript == true
59
+
60
+ api_url = if request.ssl?
61
+ Merb::Recaptcha::API_SECURE_SERVER
62
+ else
63
+ Merb::Recaptcha::API_SERVER
64
+ end
65
+
66
+ result = ""
67
+ xhtml = Builder::XmlMarkup.new(:target => result, :indent => 2)
68
+ if ajax
69
+ xhtml.script(:type => "text/javascript", :src => "#{api_url}/js/recaptcha_ajax.js") {}
70
+ xhtml.script(:type => "text/javascript") do |js|
71
+ options_and_callback = callback.nil? ? options : options.merge(:callback => callback)
72
+ js << "//<![CDATA[\n"
73
+ js << "var options = #{hash_to_json(options_and_callback)};\n"
74
+ if ajax == :jquery
75
+ js << "$(document).ready(function() { Recaptcha.create('#{public_key}', document.getElementById('#{element_id}'), options); });\n"
76
+ else
77
+ js << "window.onload = function() { Recaptcha.create('#{public_key}', document.getElementById('#{element_id}'), options); };\n"
78
+ end
79
+ js << "//]]>\n"
80
+ end
81
+ else
82
+ unless options.empty?
83
+ xhtml.script(:type => "text/javascript") do |js|
84
+ js << "//<![CDATA[\n"
85
+ js << "var RecaptchaOptions = #{hash_to_json(options)};\n"
86
+ js << "//]]>\n"
87
+ end
88
+ end
89
+ xhtml.script(:type => "text/javascript", :src => "#{api_url}/challenge?k=#{public_key}") {}
90
+ if noscript
91
+ xhtml.noscript do
92
+ xhtml.iframe(:src => "#{api_url}/noscript?k=#{public_key}", :height => iframe_height, :width => iframe_width, :frameborder => 0) {}
93
+ xhtml.br
94
+ xhtml.textarea(:name => "recaptcha_challenge_field", :rows => 3, :cols => 40) {}
95
+ xhtml.input :name => "recaptcha_response_field", :type => "hidden", :value => "manual_challenge"
96
+ end
97
+ end
98
+ end
99
+ result
100
+ end
101
+
102
+ private
103
+
104
+ def hash_to_json(hash)
105
+ result = "{"
106
+ result << hash.map do |k, v|
107
+ if ! v.is_a?(String) || k.to_s == "callback"
108
+ "\"#{k}\": #{v}"
109
+ else
110
+ "\"#{k}\": \"#{v}\""
111
+ end
112
+ end.join(", ")
113
+ result << "}"
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,44 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{merb-recaptcha}
5
+ s.version = "1.0.3"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Anton Ageev", "Michael Johnston"]
9
+ s.date = %q{2008-12-19}
10
+ s.description = %q{Merb plugin that provides helpers for recaptcha.net service}
11
+ s.email = %q{antage@gmail.com}
12
+ s.extra_rdoc_files = ["README.rdoc", "LICENSE"]
13
+ s.files = ["LICENSE", "README.rdoc", "Rakefile", "TODO", "merb-recaptcha.gemspec", "lib/merb-recaptcha/constants.rb", "lib/merb-recaptcha/merbtasks.rb", "lib/merb-recaptcha/controller_mixin.rb", "lib/merb-recaptcha/view_helpers.rb", "lib/merb-recaptcha/exceptions.rb", "lib/merb-recaptcha.rb", "spec/spec_helper.rb", "spec/recaptcha_ajax_with_options_spec.rb", "spec/recaptcha_noajax_without_noscript_spec.rb", "spec/recaptcha_noajax_with_noscript_spec.rb", "spec/recaptcha_valid_spec.rb", "spec/recaptcha_ajax_spec.rb", "spec/recaptcha_ajax_with_callback_spec.rb", "spec/recaptcha_noajax_with_options_spec.rb", "spec/recaptcha_ajax_with_jquery_spec.rb", "spec/fixture/app/controllers/application.rb", "spec/fixture/app/controllers/exceptions.rb", "spec/fixture/app/controllers/recaptcha.rb", "spec/fixture/app/views/exceptions/not_acceptable.html.erb", "spec/fixture/app/views/exceptions/not_found.html.erb", "spec/fixture/app/views/layout/application.html.erb", "spec/fixture/app/views/recaptcha/ajax.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_callback.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_options.html.erb", "spec/fixture/app/views/recaptcha/noajax_without_noscript.html.erb", "spec/fixture/app/views/recaptcha/noajax_with_options.html.erb", "spec/fixture/app/views/recaptcha/noajax_with_noscript.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_jquery.html.erb", "spec/fixture/app/helpers/global_helpers.rb", "spec/fixture/app/helpers/recaptcha_helpers.rb"]
14
+ s.has_rdoc = true
15
+ s.homepage = %q{http://github.com/antage/merb-recaptcha/}
16
+ s.rdoc_options = ["--main", "README.rdoc"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{merb-recaptcha}
19
+ s.rubygems_version = %q{1.3.3}
20
+ s.summary = %q{Merb plugin that provides helpers for recaptcha.net service}
21
+ s.test_files = ["spec/spec_helper.rb", "spec/recaptcha_ajax_with_options_spec.rb", "spec/recaptcha_noajax_without_noscript_spec.rb", "spec/recaptcha_noajax_with_noscript_spec.rb", "spec/recaptcha_valid_spec.rb", "spec/recaptcha_ajax_spec.rb", "spec/recaptcha_ajax_with_callback_spec.rb", "spec/recaptcha_noajax_with_options_spec.rb", "spec/recaptcha_ajax_with_jquery_spec.rb", "spec/fixture/app/controllers/application.rb", "spec/fixture/app/controllers/exceptions.rb", "spec/fixture/app/controllers/recaptcha.rb", "spec/fixture/app/views/exceptions/not_acceptable.html.erb", "spec/fixture/app/views/exceptions/not_found.html.erb", "spec/fixture/app/views/layout/application.html.erb", "spec/fixture/app/views/recaptcha/ajax.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_callback.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_options.html.erb", "spec/fixture/app/views/recaptcha/noajax_without_noscript.html.erb", "spec/fixture/app/views/recaptcha/noajax_with_options.html.erb", "spec/fixture/app/views/recaptcha/noajax_with_noscript.html.erb", "spec/fixture/app/views/recaptcha/ajax_with_jquery.html.erb", "spec/fixture/app/helpers/global_helpers.rb", "spec/fixture/app/helpers/recaptcha_helpers.rb"]
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 3
26
+
27
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
28
+ s.add_runtime_dependency(%q<merb-core>, [">= 1.0.0"])
29
+ s.add_runtime_dependency(%q<builder>, ["~> 2.0"])
30
+ s.add_development_dependency(%q<rspec>, [">= 1.1.0"])
31
+ s.add_development_dependency(%q<mocha>, [">= 0.9.3"])
32
+ else
33
+ s.add_dependency(%q<merb-core>, [">= 1.0.0"])
34
+ s.add_dependency(%q<builder>, ["~> 2.0"])
35
+ s.add_dependency(%q<rspec>, [">= 1.1.0"])
36
+ s.add_dependency(%q<mocha>, [">= 0.9.3"])
37
+ end
38
+ else
39
+ s.add_dependency(%q<merb-core>, [">= 1.0.0"])
40
+ s.add_dependency(%q<builder>, ["~> 2.0"])
41
+ s.add_dependency(%q<rspec>, [">= 1.1.0"])
42
+ s.add_dependency(%q<mocha>, [">= 0.9.3"])
43
+ end
44
+ end
@@ -0,0 +1,2 @@
1
+ class Application < Merb::Controller
2
+ end
@@ -0,0 +1,13 @@
1
+ class Exceptions < Merb::Controller
2
+
3
+ # handle NotFound exceptions (404)
4
+ def not_found
5
+ render :format => :html
6
+ end
7
+
8
+ # handle NotAcceptable exceptions (406)
9
+ def not_acceptable
10
+ render :format => :html
11
+ end
12
+
13
+ end