propagate 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ rdoc
2
+ pkg
3
+ Gemfile.lock
@@ -0,0 +1,28 @@
1
+ == 0.3.4 / 2011-12-13
2
+
3
+ * Rails 3
4
+ * Remove jeweler
5
+
6
+ == 0.2.2 / 2009-09-14
7
+
8
+ * Add a timeout to the validator
9
+ * Give the documentation some love
10
+
11
+ == 0.2.1 / 2009-09-14
12
+
13
+ * Removed Ambethia namespace, and restructured classes a bit
14
+ * Added an example rails app in the example-rails branch
15
+
16
+ == 0.2.0 / 2009-09-12
17
+
18
+ * RecaptchaOptions AJAX API Fix
19
+ * Added 'cucumber' as a test environment to skip
20
+ * Ruby 1.9 compat fixes
21
+ * Added option :message => 'Custom error message' to verify_recaptcha
22
+ * Removed dependency on ActiveRecord constant
23
+ * Add I18n
24
+
25
+ == 0.1.0 / 2008-2-8
26
+
27
+ * 1 major enhancement
28
+ * Initial Gem Release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2007 Jason L Perry
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,7 @@
1
+ Propagate
2
+ =========
3
+
4
+ This plugin allows for easy insertion of Propagate into your Ruby site. This is
5
+ an adaptation of Jason L Perry's plugin for Recaptcha, which can be found at
6
+ http://github.com/ambethia/recaptcha/tree/master
7
+
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new :test do |test|
5
+ test.libs << "lib"
6
+ test.pattern = "test/*_test.rb"
7
+ end
8
+
9
+ task :default => :test
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/init.rb ADDED
@@ -0,0 +1,5 @@
1
+ # Rails plugin initialization.
2
+ # You can also install it as a gem:
3
+ # config.gem "propagate", :lib => "propagate/rails", :source => "http://gems.github.com"
4
+
5
+ require 'propagate/rails'
@@ -0,0 +1,49 @@
1
+ require 'propagate/configuration'
2
+ require 'propagate/client_helper'
3
+ require 'propagate/verify'
4
+
5
+ module Propagate
6
+ PROPAGATE_API_SERVER_URL = 'http://nakeit.propagate.com.br'
7
+ PROPAGATE_API_SECURE_SERVER_URL = 'https://nakeit.propagate.com.br'
8
+ PROPAGATE_VERIFY_URL = 'http://nakeit.propagate.com.br'
9
+
10
+ HANDLE_TIMEOUTS_GRACEFULLY = true
11
+ SKIP_VERIFY_ENV = ['test', 'cucumber']
12
+
13
+ # Gives access to the current Configuration.
14
+ def self.configuration
15
+ @configuration ||= Configuration.new
16
+ end
17
+
18
+ # Allows easy setting of multiple configuration options. See Configuration
19
+ # for all available options.
20
+ #--
21
+ # The temp assignment is only used to get a nicer rdoc. Feel free to remove
22
+ # this hack.
23
+ #++
24
+ def self.configure
25
+ config = configuration
26
+ yield(config)
27
+ end
28
+
29
+ def self.with_configuration(config)
30
+ original_config = {}
31
+
32
+ config.each do |key, value|
33
+ original_config[key] = configuration.send(key)
34
+ configuration.send("#{key}=", value)
35
+ end
36
+
37
+ result = yield if block_given?
38
+
39
+ original_config.each { |key, value| configuration.send("#{key}=", value) }
40
+ result
41
+ end
42
+
43
+ class PropagateError < StandardError
44
+ end
45
+ end
46
+
47
+ if defined?(Rails)
48
+ require 'propagate/rails'
49
+ end
@@ -0,0 +1,20 @@
1
+ module Propagate
2
+ module ClientHelper
3
+ # Your public API can be specified in the +options+ hash or preferably
4
+ # using the Configuration.
5
+ def propagate_tags(options = {})
6
+ # Default options
7
+ key = options[:public_key] ||= Propagate.configuration.public_key
8
+ raise PropagateError, "No public key specified." unless key
9
+ error = options[:error] ||= (defined? flash ? flash[:propagate_error] : "")
10
+ uri = Propagate.configuration.api_server_url(options[:ssl])
11
+ html = ""
12
+
13
+
14
+ html << %{<script type="text/javascript" src="#{uri}/site/#{key}/session/?}
15
+ html << %{#{error ? "&amp;error=#{CGI::escape(error)}" : ""}"></script>\n}
16
+
17
+ return (html.respond_to?(:html_safe) && html.html_safe) || html
18
+ end # propagate_tags
19
+ end # ClientHelper
20
+ end # Propagate
@@ -0,0 +1,55 @@
1
+ module Propagate
2
+ # This class enables detailed configuration of the propagate services.
3
+ #
4
+ # By calling
5
+ #
6
+ # Propagate.configuration # => instance of Propagate::Configuration
7
+ #
8
+ # or
9
+ # Propagate.configure do |config|
10
+ # config # => instance of Propagate::Configuration
11
+ # end
12
+ #
13
+ # you are able to perform configuration updates.
14
+ #
15
+ # Your are able to customize all attributes listed below. All values have
16
+ # sensitive default and will very likely not need to be changed.
17
+ #
18
+ # Please note that the public and private key for the Propagate API Access
19
+ # have no useful default value. The keys may be set via the Shell enviroment
20
+ # or using this configuration. Settings within this configuration always take
21
+ # precedence.
22
+ #
23
+ # Setting the keys with this Configuration
24
+ #
25
+ # Propagate.configure do |config|
26
+ # config.public_key = '6Lc6BAAAAAAAAChqRbQZcn_yyyyyyyyyyyyyyyyy'
27
+ # config.private_key = '6Lc6BAAAAAAAAKN3DRm6VA_xxxxxxxxxxxxxxxxx'
28
+ # end
29
+ #
30
+ class Configuration
31
+ attr_accessor :nonssl_api_server_url,
32
+ :ssl_api_server_url,
33
+ :verify_url,
34
+ :skip_verify_env,
35
+ :private_key,
36
+ :public_key,
37
+ :proxy,
38
+ :handle_timeouts_gracefully
39
+
40
+ def initialize #:nodoc:
41
+ @nonssl_api_server_url = PROPAGATE_API_SERVER_URL
42
+ @ssl_api_server_url = PROPAGATE_API_SECURE_SERVER_URL
43
+ @verify_url = PROPAGATE_VERIFY_URL
44
+ @skip_verify_env = SKIP_VERIFY_ENV
45
+ @handle_timeouts_gracefully = HANDLE_TIMEOUTS_GRACEFULLY
46
+
47
+ @private_key = ENV['PROPAGATE_PRIVATE_KEY']
48
+ @public_key = ENV['PROPAGATE_PUBLIC_KEY']
49
+ end
50
+
51
+ def api_server_url(ssl = false) #:nodoc:
52
+ ssl ? ssl_api_server_url : nonssl_api_server_url
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,4 @@
1
+ require 'propagate'
2
+
3
+ Merb::GlobalHelpers.send(:include, Propagate::ClientHelper)
4
+ Merb::Controller.send(:include, Propagate::Verify)
@@ -0,0 +1,5 @@
1
+ require 'net/http'
2
+ require 'propagate'
3
+
4
+ ActionView::Base.send(:include, Propagate::ClientHelper)
5
+ ActionController::Base.send(:include, Propagate::Verify)
@@ -0,0 +1,15 @@
1
+ require 'net/http'
2
+ require 'propagate'
3
+ module Rails
4
+ module Propagate
5
+ class Railtie < Rails::Railtie
6
+ initializer "setup config" do
7
+ begin
8
+ ActionView::Base.send(:include, ::Propagate::ClientHelper)
9
+ ActionController::Base.send(:include, ::Propagate::Verify)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,78 @@
1
+ require "uri"
2
+ module Propagate
3
+ module Verify
4
+ # Your private API can be specified in the +options+ hash or preferably
5
+ # using the Configuration.
6
+ def verify_propagate(options = {})
7
+ if !options.is_a? Hash
8
+ options = {:model => options}
9
+ end
10
+
11
+ env = options[:env] || ENV['RAILS_ENV']
12
+ return true if Propagate.configuration.skip_verify_env.include? env
13
+ model = options[:model]
14
+ attribute = options[:attribute] || :base
15
+ private_key = options[:private_key] || Propagate.configuration.private_key
16
+ raise PropagateError, "No private key specified." unless private_key
17
+
18
+ begin
19
+ propagate = nil
20
+ if(Propagate.configuration.proxy)
21
+ proxy_server = URI.parse(Propagate.configuration.proxy)
22
+ http = Net::HTTP::Proxy(proxy_server.host, proxy_server.port, proxy_server.user, proxy_server.password)
23
+ else
24
+ http = Net::HTTP
25
+ end
26
+
27
+ Timeout::timeout(options[:timeout] || 3) do
28
+ uri = Propagate.configuration.verify_url + '/session/' + params[:propagate_sid] + '/answer/'
29
+ propagate = http.post_form(URI.parse(uri), {
30
+ "pk" => private_key,
31
+ "remote_addr" => request.remote_ip,
32
+ "forwarded_for" => request.env['HTTP_X_FORWARDED_FOR'] || '',
33
+ "user_agent" => request.env['HTTP_USER_AGENT'],
34
+ "sid" => params[:propagate_sid],
35
+ "answer" => params[:propagate_challenge]
36
+ })
37
+ end
38
+ answer, error = propagate.body.split.map { |s| s.chomp }
39
+ unless answer == 'Ok'
40
+ flash[:propagate_error] = if defined?(I18n)
41
+ I18n.translate("propagate.errors.#{error}", {:default => error})
42
+ else
43
+ error
44
+ end
45
+
46
+ if model
47
+ message = "Word verification response is incorrect, please try again."
48
+ message = I18n.translate('propagate.errors.verification_failed', {:default => message}) if defined?(I18n)
49
+ model.errors.add attribute, options[:message] || message
50
+ end
51
+ return false
52
+ else
53
+ flash.delete(:propagate_error)
54
+ return true
55
+ end
56
+ rescue Timeout::Error
57
+ if Propagate.configuration.handle_timeouts_gracefully
58
+ flash[:propagate_error] = if defined?(I18n)
59
+ I18n.translate('propagate.errors.propagate_unreachable', {:default => 'Propagate unreachable.'})
60
+ else
61
+ 'Propagate unreachable.'
62
+ end
63
+
64
+ if model
65
+ message = "Oops, we failed to validate your word verification response. Please try again."
66
+ message = I18n.translate('propagate.errors.propagate_unreachable', :default => message) if defined?(I18n)
67
+ model.errors.add attribute, options[:message] || message
68
+ end
69
+ return false
70
+ else
71
+ raise PropagateError, "Propagate unreachable."
72
+ end
73
+ rescue Exception => e
74
+ raise PropagateError, e.message, e.backtrace
75
+ end
76
+ end # verify_propagate
77
+ end # Verify
78
+ end # Propagate
@@ -0,0 +1,3 @@
1
+ module Propagate
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "propagate/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "propagate"
7
+ s.version = Propagate::VERSION
8
+ s.authors = ["Propagate"]
9
+ s.email = ["propagate@arcane.com.br"]
10
+ s.homepage = "http://www.propagate.com.br/"
11
+ s.summary = %q{Helpers for the Propagate API}
12
+ s.description = %q{This plugin adds helpers for the Propagate API}
13
+
14
+ s.rubyforge_project = "propagate"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_development_dependency "mocha"
21
+ s.add_development_dependency "rake"
22
+ s.add_development_dependency "activesupport"
23
+ s.add_development_dependency "i18n"
24
+ end
@@ -0,0 +1,52 @@
1
+ require 'test/unit'
2
+ require 'cgi'
3
+ require File.dirname(File.expand_path(__FILE__)) + '/../lib/recaptcha'
4
+
5
+ class RecaptchaClientHelperTest < Test::Unit::TestCase
6
+ include Recaptcha
7
+ include Recaptcha::ClientHelper
8
+ include Recaptcha::Verify
9
+
10
+ attr_accessor :session
11
+
12
+ def setup
13
+ @session = {}
14
+ Recaptcha.configure do |config|
15
+ config.public_key = '0000000000000000000000000000000000000000'
16
+ config.private_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
17
+ end
18
+ end
19
+
20
+ def test_recaptcha_tags
21
+ # Might as well match something...
22
+ assert_match /http:\/\/www.google.com\/recaptcha\/api\/challenge/, recaptcha_tags
23
+ end
24
+
25
+ def test_recaptcha_tags_with_ssl
26
+ assert_match /https:\/\/www.google.com\/recaptcha\/api\/challenge/, recaptcha_tags(:ssl => true)
27
+ end
28
+
29
+ def test_recaptcha_tags_without_noscript
30
+ assert_no_match /noscript/, recaptcha_tags(:noscript => false)
31
+ end
32
+
33
+ def test_should_raise_exception_without_public_key
34
+ assert_raise RecaptchaError do
35
+ Recaptcha.configuration.public_key = nil
36
+ recaptcha_tags
37
+ end
38
+ end
39
+
40
+ def test_different_configuration_within_with_configuration_block
41
+ key = Recaptcha.with_configuration(:public_key => '12345') do
42
+ Recaptcha.configuration.public_key
43
+ end
44
+
45
+ assert_equal('12345', key)
46
+ end
47
+
48
+ def test_reset_configuration_after_with_configuration_block
49
+ Recaptcha.with_configuration(:public_key => '12345')
50
+ assert_equal('0000000000000000000000000000000000000000', Recaptcha.configuration.public_key)
51
+ end
52
+ end
@@ -0,0 +1,151 @@
1
+ # coding: utf-8
2
+
3
+ require 'test/unit'
4
+ require 'rubygems'
5
+ require 'active_support'
6
+ require 'active_support/core_ext/string'
7
+ require 'mocha'
8
+ require 'i18n'
9
+ require 'net/http'
10
+ require File.dirname(File.expand_path(__FILE__)) + '/../lib/recaptcha'
11
+
12
+ class RecaptchaVerifyTest < Test::Unit::TestCase
13
+ def setup
14
+ Recaptcha.configuration.private_key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
15
+ @controller = TestController.new
16
+ @controller.request = stub(:remote_ip => "1.1.1.1")
17
+ @controller.params = {:recaptcha_challenge_field => "challenge", :recaptcha_response_field => "response"}
18
+
19
+ @expected_post_data = {}
20
+ @expected_post_data["privatekey"] = Recaptcha.configuration.private_key
21
+ @expected_post_data["remoteip"] = @controller.request.remote_ip
22
+ @expected_post_data["challenge"] = "challenge"
23
+ @expected_post_data["response"] = "response"
24
+
25
+ @expected_uri = URI.parse(Recaptcha.configuration.verify_url)
26
+ end
27
+
28
+ def test_should_raise_exception_without_private_key
29
+ assert_raise Recaptcha::RecaptchaError do
30
+ Recaptcha.configuration.private_key = nil
31
+ @controller.verify_recaptcha
32
+ end
33
+ end
34
+
35
+ def test_should_return_false_when_key_is_invalid
36
+ expect_http_post(response_with_body("false\ninvalid-site-private-key"))
37
+
38
+ assert !@controller.verify_recaptcha
39
+ assert_equal "invalid-site-private-key", @controller.flash[:recaptcha_error]
40
+ end
41
+
42
+ def test_returns_true_on_success
43
+ @controller.flash[:recaptcha_error] = "previous error that should be cleared"
44
+ expect_http_post(response_with_body("true\n"))
45
+
46
+ assert @controller.verify_recaptcha
47
+ assert_nil @controller.flash[:recaptcha_error]
48
+ end
49
+
50
+ def test_errors_should_be_added_to_model
51
+ expect_http_post(response_with_body("false\nbad-news"))
52
+
53
+ errors = mock
54
+ errors.expects(:add).with(:base, "Word verification response is incorrect, please try again.")
55
+ model = mock(:errors => errors)
56
+
57
+ assert !@controller.verify_recaptcha(:model => model)
58
+ assert_equal "bad-news", @controller.flash[:recaptcha_error]
59
+ end
60
+
61
+ def test_returns_true_on_success_with_optional_key
62
+ @controller.flash[:recaptcha_error] = "previous error that should be cleared"
63
+ # reset private key
64
+ @expected_post_data["privatekey"] = 'ADIFFERENTPRIVATEKEYXXXXXXXXXXXXXX'
65
+ expect_http_post(response_with_body("true\n"))
66
+
67
+ assert @controller.verify_recaptcha(:private_key => 'ADIFFERENTPRIVATEKEYXXXXXXXXXXXXXX')
68
+ assert_nil @controller.flash[:recaptcha_error]
69
+ end
70
+
71
+ def test_timeout
72
+ expect_http_post(Timeout::Error, :exception => true)
73
+ assert !@controller.verify_recaptcha()
74
+ assert_equal "Recaptcha unreachable.", @controller.flash[:recaptcha_error]
75
+ end
76
+
77
+ def test_timeout_when_handle_timeouts_gracefully_disabled
78
+ Recaptcha.with_configuration(:handle_timeouts_gracefully => false) do
79
+ expect_http_post(Timeout::Error, :exception => true)
80
+ assert_raise Recaptcha::RecaptchaError, "Recaptcha unreachable." do
81
+ assert @controller.verify_recaptcha()
82
+ end
83
+ assert_nil @controller.flash[:recaptcha_error]
84
+ end
85
+ end
86
+
87
+ def test_message_should_use_i18n
88
+ I18n.locale = :de
89
+ verification_failed_translated = "Sicherheitscode konnte nicht verifiziert werden."
90
+ verification_failed_default = "Word verification response is incorrect, please try again."
91
+ recaptcha_unreachable_translated = "Netzwerkfehler, bitte versuchen Sie es später erneut."
92
+ recaptcha_unreachable_default = "Oops, we failed to validate your word verification response. Please try again."
93
+
94
+ I18n.expects(:translate).with('recaptcha.errors.bad-news', {:default => 'bad-news'})
95
+ I18n.expects(:translate).with('recaptcha.errors.recaptcha_unreachable', {:default => 'Recaptcha unreachable.'})
96
+
97
+ I18n.expects(:translate).with('recaptcha.errors.verification_failed', :default => verification_failed_default).returns(verification_failed_translated)
98
+ I18n.expects(:translate).with('recaptcha.errors.recaptcha_unreachable', :default => recaptcha_unreachable_default).returns(recaptcha_unreachable_translated)
99
+
100
+ errors = mock
101
+ errors.expects(:add).with(:base, verification_failed_translated)
102
+ errors.expects(:add).with(:base, recaptcha_unreachable_translated)
103
+ model = mock; model.stubs(:errors => errors)
104
+
105
+ expect_http_post(response_with_body("false\nbad-news"))
106
+ @controller.verify_recaptcha(:model => model)
107
+
108
+ expect_http_post(Timeout::Error, :exception => true)
109
+ @controller.verify_recaptcha(:model => model)
110
+
111
+ end
112
+
113
+ def test_it_translates_api_response_with_i18n
114
+ api_error_translated = "Bad news, body :("
115
+ expect_http_post(response_with_body("false\nbad-news"))
116
+ I18n.expects(:translate).with('recaptcha.errors.bad-news', :default => 'bad-news').returns(api_error_translated)
117
+
118
+ assert !@controller.verify_recaptcha
119
+ assert_equal api_error_translated, @controller.flash[:recaptcha_error]
120
+ end
121
+
122
+ def test_it_fallback_to_api_response_if_i18n_translation_is_missing
123
+ expect_http_post(response_with_body("false\nbad-news"))
124
+
125
+ assert !@controller.verify_recaptcha
126
+ assert_equal 'bad-news', @controller.flash[:recaptcha_error]
127
+ end
128
+
129
+ private
130
+
131
+ class TestController
132
+ include Recaptcha::Verify
133
+ attr_accessor :request, :params, :flash
134
+
135
+ def initialize
136
+ @flash = {}
137
+ end
138
+ end
139
+
140
+ def expect_http_post(response, options = {})
141
+ unless options[:exception]
142
+ Net::HTTP.expects(:post_form).with(@expected_uri, @expected_post_data).returns(response)
143
+ else
144
+ Net::HTTP.expects(:post_form).raises response
145
+ end
146
+ end
147
+
148
+ def response_with_body(body)
149
+ stub(:body => body)
150
+ end
151
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: propagate
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Propagate
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-03-14 00:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: mocha
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :development
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :development
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: activesupport
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :development
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
60
+ name: i18n
61
+ prerelease: false
62
+ requirement: &id004 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ type: :development
71
+ version_requirements: *id004
72
+ description: This plugin adds helpers for the Propagate API
73
+ email:
74
+ - propagate@arcane.com.br
75
+ executables: []
76
+
77
+ extensions: []
78
+
79
+ extra_rdoc_files: []
80
+
81
+ files:
82
+ - .gitignore
83
+ - CHANGELOG
84
+ - Gemfile
85
+ - LICENSE
86
+ - README
87
+ - Rakefile
88
+ - VERSION
89
+ - init.rb
90
+ - lib/propagate.rb
91
+ - lib/propagate/client_helper.rb
92
+ - lib/propagate/configuration.rb
93
+ - lib/propagate/merb.rb
94
+ - lib/propagate/rails.rb
95
+ - lib/propagate/railtie.rb
96
+ - lib/propagate/verify.rb
97
+ - lib/propagate/version.rb
98
+ - propagate.gemspec
99
+ - test/propagate_test.rb
100
+ - test/verify_propagate_test.rb
101
+ has_rdoc: true
102
+ homepage: http://www.propagate.com.br/
103
+ licenses: []
104
+
105
+ post_install_message:
106
+ rdoc_options: []
107
+
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ segments:
116
+ - 0
117
+ version: "0"
118
+ required_rubygems_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ requirements: []
127
+
128
+ rubyforge_project: propagate
129
+ rubygems_version: 1.3.7
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: Helpers for the Propagate API
133
+ test_files: []
134
+