propagate 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.
@@ -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
+