From 8252812845be8c55e3bef27c91a98c36a63f7091 Mon Sep 17 00:00:00 2001 From: Wes Morgan Date: Tue, 11 May 2010 16:07:46 -0400 Subject: [PATCH 01/23] made my changes less disruptive to the CanonicalString API --- lib/auth-hmac.rb | 2 +- spec/auth-hmac_spec.rb | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/auth-hmac.rb b/lib/auth-hmac.rb index c522c4b..1cfd679 100644 --- a/lib/auth-hmac.rb +++ b/lib/auth-hmac.rb @@ -74,7 +74,7 @@ def find_header(keys, headers) class CanonicalString < String # :nodoc: include Headers - def initialize(request, authenticate_referrer) + def initialize(request, authenticate_referrer=false) self << request_method(request) + "\n" self << header_values(headers(request)) + "\n" self << request_path(request, authenticate_referrer) diff --git a/spec/auth-hmac_spec.rb b/spec/auth-hmac_spec.rb index ab143d4..e05a4cf 100644 --- a/spec/auth-hmac_spec.rb +++ b/spec/auth-hmac_spec.rb @@ -9,10 +9,11 @@ require 'action_controller/test_process' require 'active_resource' require 'active_resource/http_mock' +require 'ruby-debug' # Class for doing a custom signature class CustomSignature < String - def initialize(request) + def initialize(request, authenticate_referrer=false) self << "Custom signature string: #{request.method}" end end @@ -65,6 +66,7 @@ def signature(value, secret) :service_id => 'MyService', :signature => CustomSignature } + # debugger AuthHMAC.sign!(@request, "my-key-id", "secret", options) @request['Authorization'].should == "MyService my-key-id:/L4N1v1BZSHfAYkQjsvZn696D9c=" end From b42a1b715b08e9422b89099c2cbc38aefa857295 Mon Sep 17 00:00:00 2001 From: Wes Morgan Date: Thu, 2 Sep 2010 17:11:30 -0400 Subject: [PATCH 02/23] added content-md5 generation when client doesn't supply it --- lib/auth-hmac.rb | 13 +++++++++---- spec/auth-hmac_spec.rb | 13 +++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/auth-hmac.rb b/lib/auth-hmac.rb index 1cfd679..381b53f 100644 --- a/lib/auth-hmac.rb +++ b/lib/auth-hmac.rb @@ -76,7 +76,7 @@ class CanonicalString < String # :nodoc: def initialize(request, authenticate_referrer=false) self << request_method(request) + "\n" - self << header_values(headers(request)) + "\n" + self << header_values(request) + "\n" self << request_path(request, authenticate_referrer) end @@ -93,9 +93,10 @@ def request_method(request) end end - def header_values(headers) + def header_values(request) + headers = headers(request) [ content_type(headers), - content_md5(headers), + (content_md5(headers) or (request.body.blank? ? '' : headers['Content-MD5'] = generate_content_md5(request))), (date(headers) or headers['Date'] = Time.now.utc.httpdate) ].join("\n") end @@ -109,7 +110,11 @@ def date(headers) end def content_md5(headers) - find_header(%w(CONTENT-MD5 CONTENT_MD5), headers) + find_header(%w(CONTENT-MD5 CONTENT_MD5 HTTP_CONTENT_MD5), headers) + end + + def generate_content_md5(request) + OpenSSL::Digest::MD5.hexdigest(request.body) end def request_path(request, authenticate_referrer) diff --git a/spec/auth-hmac_spec.rb b/spec/auth-hmac_spec.rb index e05a4cf..d71b964 100644 --- a/spec/auth-hmac_spec.rb +++ b/spec/auth-hmac_spec.rb @@ -243,6 +243,7 @@ def signature(value, secret) rack_req.stub!(:request_method).and_return('GET') rack_req.stub!(:path).and_return("/path/to/get?foo=bar&bar=foo") rack_req.stub!(:[]).and_return({'foo' => 'bar', 'bar' => 'foo'}) + rack_req.stub!(:body).and_return('') @authhmac.authenticated?(rack_req).should be_true end end @@ -277,6 +278,18 @@ def signature(value, secret) request = Net::HTTP::Put.new("/", {'content-md5' => 'adsada'}) AuthHMAC::CanonicalString.new(request).should match(/adsada/) end + + it "should generate the content-md5 if one wasn't included and there is a request body" do + request = Net::HTTP::Put.new("/") + request.body = "foo=bar&baz=qux" + content_md5 = OpenSSL::Digest::MD5.hexdigest(request.body) + AuthHMAC::CanonicalString.new(request).should match(/#{content_md5}/) + end + + it "should not generate a content-md5 when there is no request body" do + request = Net::HTTP::Get.new("/") + AuthHMAC::CanonicalString.new(request).should match(/^GET\n\n\n/) + end it "should include the date" do date = Time.now.httpdate From 3676c5cfc788fd639c1371368d1a275307047dd2 Mon Sep 17 00:00:00 2001 From: Wes Morgan Date: Thu, 2 Sep 2010 17:15:37 -0400 Subject: [PATCH 03/23] gutted Rails monkey-patching --- lib/auth-hmac.rb | 166 +----------------------------- spec/auth-hmac_spec.rb | 222 ----------------------------------------- 2 files changed, 1 insertion(+), 387 deletions(-) diff --git a/lib/auth-hmac.rb b/lib/auth-hmac.rb index 381b53f..304cb0e 100644 --- a/lib/auth-hmac.rb +++ b/lib/auth-hmac.rb @@ -261,168 +261,4 @@ def authorization_header(request) def authorization(request, access_key_id, secret) "#{@service_id} #{access_key_id}:#{signature(request, secret)}" end - - # Integration with Rails - # - class Rails # :nodoc: - module ControllerFilter # :nodoc: - module ClassMethods - # Call within a Rails Controller to initialize HMAC authentication for the controller. - # - # * +credentials+ must be a hash that indexes secrets by their access key id. - # * +options+ supports the following arguments: - # * +failure_message+: The text to use when authentication fails. - # * +only+: A list off actions to protect. - # * +except+: A list of actions to not protect. - # * +hmac+: Options for HMAC creation. See AuthHMAC#initialize for options. - # - def with_auth_hmac(credentials, options = {}) - unless credentials.nil? - self.credentials = credentials - self.authhmac_failure_message = (options.delete(:failure_message) or "HMAC Authentication failed") - self.authhmac = AuthHMAC.new(self.credentials, options.delete(:hmac)) - before_filter(:hmac_login_required, options) - else - $stderr.puts("with_auth_hmac called with nil credentials - authentication will be skipped") - end - end - end - - module InstanceMethods # :nodoc: - def hmac_login_required - unless hmac_authenticated? - response.headers['WWW-Authenticate'] = 'AuthHMAC' - render :text => self.class.authhmac_failure_message, :status => :unauthorized - end - end - - def hmac_authenticated? - self.class.authhmac.nil? ? true : self.class.authhmac.authenticated?(request) - end - end - - unless defined?(ActionController) - begin - require 'rubygems' - gem 'actionpack' - gem 'activesupport' - require 'action_controller' - require 'active_support' - rescue - nil - end - end - - if defined?(ActionController::Base) - ActionController::Base.class_eval do - class_inheritable_accessor :authhmac - class_inheritable_accessor :credentials - class_inheritable_accessor :authhmac_failure_message - end - - ActionController::Base.send(:include, ControllerFilter::InstanceMethods) - ActionController::Base.extend(ControllerFilter::ClassMethods) - end - end - - module ActiveResourceExtension # :nodoc: - module BaseHmac # :nodoc: - def self.included(base) - base.extend(ClassMethods) - - base.class_inheritable_accessor :hmac_access_id - base.class_inheritable_accessor :hmac_secret - base.class_inheritable_accessor :use_hmac - base.class_inheritable_accessor :hmac_options - end - - module ClassMethods - # Call with an Active Resource class definition to sign - # all HTTP requests sent by that class with the provided - # credentials. - # - # Can be called with either a hash or two separate parameters - # like so: - # - # class MyResource < ActiveResource::Base - # with_auth_hmac("my_access_id", "my_secret") - # end - # - # or - # - # class MyOtherResource < ActiveResource::Base - # with_auth_hmac("my_access_id" => "my_secret") - # end - # - # - # This has only been tested with Rails 2.1 and since it is virtually a monkey - # patch of the internals of ActiveResource it might not work with past or - # future versions. - # - def with_auth_hmac(access_id, secret = nil, options = nil) - if access_id.is_a?(Hash) - self.hmac_access_id = access_id.keys.first - self.hmac_secret = access_id[self.hmac_access_id] - else - self.hmac_access_id = access_id - self.hmac_secret = secret - end - self.use_hmac = true - self.hmac_options = options - - class << self - alias_method_chain :connection, :hmac - end - end - - def connection_with_hmac(refresh = false) # :nodoc: - c = connection_without_hmac(refresh) - c.hmac_access_id = self.hmac_access_id - c.hmac_secret = self.hmac_secret - c.use_hmac = self.use_hmac - c.hmac_options = self.hmac_options - c - end - end - - module InstanceMethods # :nodoc: - end - end - - module Connection # :nodoc: - def self.included(base) - base.send :alias_method_chain, :request, :hmac - base.class_eval do - attr_accessor :hmac_secret, :hmac_access_id, :use_hmac, :hmac_options - end - end - - def request_with_hmac(method, path, *arguments) - if use_hmac && hmac_access_id && hmac_secret - arguments.last['Date'] = Time.now.httpdate if arguments.last['Date'].nil? - temp = "Net::HTTP::#{method.to_s.capitalize}".constantize.new(path, arguments.last) - AuthHMAC.sign!(temp, hmac_access_id, hmac_secret, hmac_options) - arguments.last['Authorization'] = temp['Authorization'] - end - - request_without_hmac(method, path, *arguments) - end - end - - unless defined?(ActiveResource) - begin - require 'rubygems' - gem 'activeresource' - require 'activeresource' - rescue - nil - end - end - - if defined?(ActiveResource) - ActiveResource::Base.send(:include, BaseHmac) - ActiveResource::Connection.send(:include, Connection) - end - end - end -end +end diff --git a/spec/auth-hmac_spec.rb b/spec/auth-hmac_spec.rb index d71b964..4ffd701 100644 --- a/spec/auth-hmac_spec.rb +++ b/spec/auth-hmac_spec.rb @@ -323,226 +323,4 @@ def signature(value, secret) AuthHMAC::CanonicalString.new(request).should == "GET\n\n\n#{date}\n/path/to/get" end end - - describe AuthHMAC::Rails::ControllerFilter do - class TestController < ActionController::Base - with_auth_hmac YAML.load(File.read(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml'))), - :only => [:index] - - def index - render :nothing => true, :status => :ok - end - - def public - render :nothing => true, :status => :ok - end - - def rescue_action(e) raise(e) end - end - - class MessageTestController < ActionController::Base - with_auth_hmac YAML.load(File.read(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml'))), - :failure_message => "Stay away!", :except => :public - - def index - render :nothing => true, :status => :ok - end - - def public - render :nothing => true, :status => :ok - end - - def rescue_action(e) raise(e) end - end - - class NilCredentialsController < ActionController::Base - with_auth_hmac nil - before_filter :force_auth - - def index - render :nothing => true, :status => :ok - end - - def public - render :nothing => true, :status => :ok - end - - def rescue_action(e) raise(e) end - - private - def force_auth - hmac_authenticated? - end - end - - class CustomTestController < ActionController::Base - with_auth_hmac YAML.load(File.read(File.join(File.dirname(__FILE__), 'fixtures', 'credentials.yml'))), - :failure_message => "Stay away!", - :except => :public, - :hmac => { :service_id => 'MyService', :signature => CustomSignature } - - def index - render :nothing => true, :status => :ok - end - - def public - render :nothing => true, :status => :ok - end - - def rescue_action(e) raise(e) end - end - - describe NilCredentialsController do - it "should not raise an error when credentials are nil" do - request = ActionController::TestRequest.new - request.action = 'index' - request.path = "/index" - lambda do - NilCredentialsController.new.process(request, ActionController::TestResponse.new).code.should == "200" - end.should_not raise_error - end - end - - describe TestController do - it "should allow a request with the proper hmac" do - request = ActionController::TestRequest.new - request.env['Authorization'] = "AuthHMAC access key 1:6BVEVfAyIDoI3K+WallRMnDxROQ=" - request.env['DATE'] = "Thu, 10 Jul 2008 03:29:56 GMT" - request.action = 'index' - request.path = "/index" - TestController.new.process(request, ActionController::TestResponse.new).code.should == "200" - end - - it "should reject a request with no hmac" do - request = ActionController::TestRequest.new - request.action = 'index' - TestController.new.process(request, ActionController::TestResponse.new).code.should == "401" - end - - it "should reject a request with the wrong hmac" do - request = ActionController::TestRequest.new - request.action = 'index' - request.env['Authorization'] = "AuthHMAC bogus:bogus" - TestController.new.process(request, ActionController::TestResponse.new).code.should == "401" - end - - it "should include a WWW-Authenticate header with the schema AuthHMAC" do - request = ActionController::TestRequest.new - request.action = 'index' - request.env['Authorization'] = "AuthHMAC bogus:bogus" - TestController.new.process(request, ActionController::TestResponse.new).headers['WWW-Authenticate'].should == "AuthHMAC" - end - - it "should include a default error message" do - request = ActionController::TestRequest.new - request.action = 'index' - request.env['Authorization'] = "AuthHMAC bogus:bogus" - TestController.new.process(request, ActionController::TestResponse.new).body.should == "HMAC Authentication failed" - end - - it "should allow anything to access the public action (using only)" do - request = ActionController::TestRequest.new - request.action = 'public' - TestController.new.process(request, ActionController::TestResponse.new).code.should == "200" - end - end - - describe MessageTestController do - it "should reject a request with a given message" do - request = ActionController::TestRequest.new - request.action = 'index' - request.env['Authorization'] = "AuthHMAC bogus:bogus" - MessageTestController.new.process(request, ActionController::TestResponse.new).body.should == "Stay away!" - end - - it "should allow anything to access the public action (using except)" do - request = ActionController::TestRequest.new - request.action = 'public' - MessageTestController.new.process(request, ActionController::TestResponse.new).code.should == "200" - end - end - - describe CustomTestController do - it "should allow a request with the proper hmac" do - request = ActionController::TestRequest.new - request.env['Authorization'] = "MyService access key 1:J2W4dOrv/sGsL0C5adnZYiQ3d70=" - request.env['DATE'] = "Thu, 10 Jul 2008 03:29:56 GMT" - request.action = 'index' - request.path = "/index" - CustomTestController.new.process(request, ActionController::TestResponse.new).code.should == "200" - end - - it "should reject a request with no hmac" do - request = ActionController::TestRequest.new - request.action = 'index' - CustomTestController.new.process(request, ActionController::TestResponse.new).code.should == "401" - end - - it "should reject a request with the wrong hmac" do - request = ActionController::TestRequest.new - request.action = 'index' - request.env['Authorization'] = "AuthHMAC bogus:bogus" - CustomTestController.new.process(request, ActionController::TestResponse.new).code.should == "401" - end - - it "should reject a request with a given message" do - request = ActionController::TestRequest.new - request.action = 'index' - request.env['Authorization'] = "AuthHMAC bogus:bogus" - CustomTestController.new.process(request, ActionController::TestResponse.new).body.should == "Stay away!" - end - - it "should allow anything to access the public action (using except)" do - request = ActionController::TestRequest.new - request.action = 'public' - CustomTestController.new.process(request, ActionController::TestResponse.new).code.should == "200" - end - end - end - - describe AuthHMAC::Rails::ActiveResourceExtension do - class TestResource < ActiveResource::Base - with_auth_hmac("access_id", "secret") - self.site = "http://localhost/" - end - - class CustomTestResource < ActiveResource::Base - with_auth_hmac("access_id", "secret", { :service_id => 'MyService', :signature => CustomSignature }) - self.site = "http://localhost/" - end - - describe TestResource do - it "should send requests using HMAC authentication" do - now = Time.parse("Thu, 10 Jul 2008 03:29:56 GMT") - Time.should_receive(:now).at_least(1).and_return(now) - ActiveResource::HttpMock.respond_to do |mock| - mock.get "/test_resources/1.xml", - { - 'Authorization' => 'AuthHMAC access_id:44dvKATf4xanDtypqEA0EFYvOgI=', - 'Accept' => 'application/xml', - 'Date' => "Thu, 10 Jul 2008 03:29:56 GMT" - }, - { :id => "1" }.to_xml(:root => 'test_resource') - end - TestResource.find(1) - end - end - - describe CustomTestResource do - it "should send requests using HMAC authentication" do - now = Time.parse("Thu, 10 Jul 2008 03:29:56 GMT") - Time.should_receive(:now).at_least(1).and_return(now) - ActiveResource::HttpMock.respond_to do |mock| - mock.get "/custom_test_resources/1.xml", - { - 'Authorization' => 'MyService access_id:ZwCBL2rWLOMnwRrdF7wWEdJn7yA=', - 'Accept' => 'application/xml', - 'Date' => "Thu, 10 Jul 2008 03:29:56 GMT" - }, - { :id => "1" }.to_xml(:root => 'custom_test_resource') - end - CustomTestResource.find(1) - end - end - end end From f257ab430a7f13ab2bd604ee654f7189360f6a3c Mon Sep 17 00:00:00 2001 From: Wes Morgan Date: Fri, 3 Sep 2010 10:38:23 -0400 Subject: [PATCH 04/23] modified gemspec for our fork --- auth-hmac.gemspec | 22 +++++++--------------- config/hoe.rb | 48 +++++++++-------------------------------------- 2 files changed, 16 insertions(+), 54 deletions(-) diff --git a/auth-hmac.gemspec b/auth-hmac.gemspec index bd9403c..d44d6c6 100644 --- a/auth-hmac.gemspec +++ b/auth-hmac.gemspec @@ -1,26 +1,18 @@ # -*- encoding: utf-8 -*- Gem::Specification.new do |s| - s.name = %q{auth-hmac} - s.version = "1.1.0" + s.name = %q{dnclabs-auth-hmac} + s.version = "1.1.1.2010090201" s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= - s.authors = ["Sean Geoghegan", "ascarter"] - s.date = %q{2009-02-26} - s.description = %q{A gem providing HMAC based authentication for HTTP} - s.email = %q{seangeo@gmail.com} + s.authors = ["Sean Geoghegan", "ascarter", "Wes Morgan", "Adrian Cushman"] + s.date = %q{2010-09-02} + s.description = %q{A gem providing HMAC based authentication for HTTP. This is the DNC Labs fork.} + s.email = %q{innovationlab@dnc.org} s.extra_rdoc_files = ["History.txt", "License.txt", "Manifest.txt", "PostInstall.txt", "README.txt"] s.files = ["History.txt", "License.txt", "Manifest.txt", "PostInstall.txt", "README.txt", "Rakefile", "config/hoe.rb", "config/requirements.rb", "lib/auth-hmac.rb", "lib/auth-hmac/version.rb", "script/console", "script/destroy", "script/generate", "setup.rb", "spec/auth-hmac_spec.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/deployment.rake", "tasks/environment.rake", "tasks/rspec.rake", "tasks/website.rake"] s.has_rdoc = true - s.homepage = %q{http://auth-hmac.rubyforge.org} - s.post_install_message = %q{ -For more information on auth-hmac, see http://auth-hmac.rubyforge.org - -NOTE: Change this information in PostInstall.txt -You can also delete it if you don't want it. - - -} + s.homepage = %q{http://github.com/dnclabs/auth-hmac/} s.rdoc_options = ["--main", "README.txt"] s.require_paths = ["lib"] s.rubyforge_project = %q{auth-hmac} diff --git a/config/hoe.rb b/config/hoe.rb index 966f6d8..dc645db 100644 --- a/config/hoe.rb +++ b/config/hoe.rb @@ -1,37 +1,13 @@ require 'auth-hmac/version' -AUTHOR = ['Sean Geoghegan', 'ascarter'] # can also be an array of Authors -EMAIL = "seangeo@gmail.com" -DESCRIPTION = "A gem providing HMAC based authentication for HTTP" -GEM_NAME = 'auth-hmac' # what ppl will type to install your gem -RUBYFORGE_PROJECT = 'auth-hmac' # The unix name for your project -HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org" -DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}" -EXTRA_DEPENDENCIES = [ -# ['activesupport', '>= 1.3.1'] -] # An array of rubygem dependencies [name, version] - -@config_file = "~/.rubyforge/user-config.yml" -@config = nil -RUBYFORGE_USERNAME = "unknown" -def rubyforge_username - unless @config - begin - @config = YAML.load(File.read(File.expand_path(@config_file))) - rescue - puts <<-EOS -ERROR: No rubyforge config file found: #{@config_file} -Run 'rubyforge setup' to prepare your env for access to Rubyforge - - See http://newgem.rubyforge.org/rubyforge.html for more details - EOS - exit - end - end - RUBYFORGE_USERNAME.replace @config["username"] -end - - -REV = nil +AUTHOR = ['Sean Geoghegan', 'ascarter', "Wes Morgan", "Adrian Cushman"] # can also be an array of Authors +EMAIL = "innovationlab@dnc.org" +DESCRIPTION = "A gem providing HMAC based authentication for HTTP. This is the DNC Labs fork." +GEM_NAME = 'dnclabs-auth-hmac' # what ppl will type to install your gem +HOMEPATH = "http://github.com/dnclabs/auth-hmac/" +RUBYFORGE_PROJECT = '' + +REV = '2010090201' # UNCOMMENT IF REQUIRED: # REV = YAML.load(`svn info`)['Revision'] VERS = AuthHMAC::VERSION::STRING + (REV ? ".#{REV}" : "") @@ -65,10 +41,4 @@ def extra_deps #p.extra_deps = EXTRA_DEPENDENCIES #p.spec_extras = {} # A hash of extra values to set in the gemspec. - end - -CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n") -PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}" -$hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,'')) -$hoe.rsync_args = '-av --delete --ignore-errors' -$hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue "" \ No newline at end of file +end From 05169b82b3043660d8fe542ce1e2ebd359cace7b Mon Sep 17 00:00:00 2001 From: Robert Jackson Date: Fri, 3 Sep 2010 15:01:30 -0400 Subject: [PATCH 05/23] Remove Base64 and use Array#pack instead. --- lib/auth-hmac.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/auth-hmac.rb b/lib/auth-hmac.rb index 304cb0e..39ad261 100644 --- a/lib/auth-hmac.rb +++ b/lib/auth-hmac.rb @@ -7,7 +7,6 @@ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) require 'openssl' -require 'base64' # This module provides a HMAC Authentication method for HTTP requests. It should work with # net/http request classes and CGIRequest classes and hence Rails. @@ -247,7 +246,7 @@ def authenticated?(request) def signature(request, secret) digest = OpenSSL::Digest::Digest.new('sha1') - Base64.encode64(OpenSSL::HMAC.digest(digest, secret, canonical_string(request, @authenticate_referrer))).strip + [OpenSSL::HMAC.digest(digest, secret, canonical_string(request, @authenticate_referrer))].pack('m').strip end def canonical_string(request, authenticate_referrer=false) From c867567b2120db128de7039086527befb59f6d9d Mon Sep 17 00:00:00 2001 From: Wes Morgan Date: Fri, 3 Sep 2010 16:00:19 -0400 Subject: [PATCH 06/23] updated README.rdoc to better reflect the state of our fork --- README.rdoc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.rdoc b/README.rdoc index ce31a29..5fbb972 100644 --- a/README.rdoc +++ b/README.rdoc @@ -4,6 +4,9 @@ auth-hmac is a Ruby implementation of HMAC[http://en.wikipedia.org/wiki/HMAC] based authentication of HTTP requests. +This is the DNC Innovation Lab fork of the project. We added Rack support and some other more obscure stuff for HMAC proxying that you probably won't need unless you're doing something weird like we are. :) +Github user rjackson contributed Ruby 1.9 support, which is pretty awesome. + HMAC authentication involves a client and server having a shared secret key. When sending the request the client, signs the request using the secret key. This involves building a canonical representation of the request and then generating a HMAC of the request using the secret. The generated HMAC is then sent as part of the request. When the server receives the request it builds the same canonical representation and generates a HMAC using it's copy of the secret key, if the HMAC produced by the server matches the HMAC sent by the client, the server can be assured that the client also possesses the shared secret key. @@ -51,10 +54,6 @@ will sign +request+ with "access_id1" and it's corresponding secret key. Simila which will return true if the request has been signed with one of the access id and secret key pairs provided in the constructor. -=== Rails Integration - -AuthHMAC supports authentication within Rails controllers and signing of requests generated by Active Resource. See AuthHMAC::Rails::ControllerFilter::ClassMethods and AuthHMAC::Rails::ActiveResourceExtension::BaseHmac::ClassMethods for details. - == How does it work? When creating a signature for a HTTP request AuthHMAC first generates a canonical representation of the request. @@ -126,4 +125,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From afc03fe495edfbaeb75c7ded5650e9896eea7b15 Mon Sep 17 00:00:00 2001 From: Wes Morgan Date: Fri, 3 Sep 2010 16:06:07 -0400 Subject: [PATCH 07/23] fixed up some more stuff in the README.rdoc --- README.rdoc | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/README.rdoc b/README.rdoc index 5fbb972..4c44cd1 100644 --- a/README.rdoc +++ b/README.rdoc @@ -36,7 +36,7 @@ AuthHMAC.sign! takes a HTTP request object, an access id and a secret key and si * The secret key is the shared secret between the client and the server. You should make this sufficiently random so that is can't be guessed or exposed to dictionary attacks. The follow code will give you a pretty good secret key: random = File.read('/dev/random', 512) - secret_key = Base64.encode64(Digest::SHA2.new(512).digest(random)) + secret_key = [Digest::SHA2.new(512).digest(random)].pack('m') On the server side you can then authenticate these requests using the AuthHMAC.authenticated? method. This takes the same arguments as the sign! method but returns true if the request has been signed with the access id and secret or false if it hasn't. @@ -82,25 +82,23 @@ Using these details it is possible to build code that will sign and authenticate == INSTALL: -* sudo gem install auth-hmac +* sudo gem install dnclabs-auth-hmac == Source Code -The source repository is accessible via GitHub or Ruby Forge: +The source repository is accessible via GitHub: - git clone git://github.com/seangeo/auth-hmac.git - - - git clone git://rubyforge.org/auth-hmac.git + git clone git://github.com/dnclabs/auth-hmac.git == Contact Information -The project page is at http://rubyforge.org/projects/auth-hmac. Please file any bugs or feedback -using the trackers and forums there. +Please file any bugs or feedback on http://github.com/dnclabs/auth-hmac/ == Authors and Contributors -rAtom was developed by Peerworks[http://peerworks.org] and written by Sean Geoghegan. +Upstream credits: rAtom was developed by Peerworks[http://peerworks.org] and written by Sean Geoghegan. + +This fork: Maintained by the Democratic National Committee Innovation Labs team. == LICENSE: From a7e0c93b411dcbfae52034cac7e16107e62975eb Mon Sep 17 00:00:00 2001 From: Ultra Ninja Date: Fri, 3 Sep 2010 18:57:29 -0700 Subject: [PATCH 08/23] add gemfile for easier development --- .gitignore | 2 ++ Gemfile | 5 +++++ Gemfile.lock | 20 ++++++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 Gemfile create mode 100644 Gemfile.lock diff --git a/.gitignore b/.gitignore index 5fff1d9..9a1433f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ pkg +.bundle +vendor/bundle diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..c625081 --- /dev/null +++ b/Gemfile @@ -0,0 +1,5 @@ +source "http://rubygems.org" + +gem "rspec" +gem "ruby-debug" +gem "activesupport" diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..26976e4 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,20 @@ +GEM + remote: http://rubygems.org/ + specs: + activesupport (3.0.0) + columnize (0.3.1) + linecache (0.43) + rspec (1.3.0) + ruby-debug (0.10.3) + columnize (>= 0.1) + ruby-debug-base (~> 0.10.3.0) + ruby-debug-base (0.10.3) + linecache (>= 0.3) + +PLATFORMS + ruby + +DEPENDENCIES + activesupport + rspec + ruby-debug From 63426a16360337bb33ac417a01b0d72dffea2a8e Mon Sep 17 00:00:00 2001 From: Ultra Ninja Date: Fri, 3 Sep 2010 18:58:48 -0700 Subject: [PATCH 09/23] switch to AS 3 --- spec/auth-hmac_spec.rb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/spec/auth-hmac_spec.rb b/spec/auth-hmac_spec.rb index 4ffd701..c06f8c0 100644 --- a/spec/auth-hmac_spec.rb +++ b/spec/auth-hmac_spec.rb @@ -2,14 +2,8 @@ require "net/http" require 'time' require 'yaml' -require 'rubygems' -gem 'actionpack' -gem 'activeresource' -require 'action_controller' -require 'action_controller/test_process' -require 'active_resource' -require 'active_resource/http_mock' require 'ruby-debug' +require 'active_support/core_ext/hash/except' # Class for doing a custom signature class CustomSignature < String From 1d7cc33e5374808f604f24218c285c71adf85feb Mon Sep 17 00:00:00 2001 From: Ultra Ninja Date: Fri, 3 Sep 2010 18:58:18 -0700 Subject: [PATCH 10/23] make rack bodies work with content-md5 --- lib/auth-hmac.rb | 15 ++++++++++++--- spec/auth-hmac_spec.rb | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/auth-hmac.rb b/lib/auth-hmac.rb index 39ad261..cb54a69 100644 --- a/lib/auth-hmac.rb +++ b/lib/auth-hmac.rb @@ -95,11 +95,20 @@ def request_method(request) def header_values(request) headers = headers(request) [ content_type(headers), - (content_md5(headers) or (request.body.blank? ? '' : headers['Content-MD5'] = generate_content_md5(request))), + (content_md5(headers) or (read_body(request).nil? || read_body(request).empty? ? '' : headers['Content-MD5'] = generate_content_md5(request))), (date(headers) or headers['Date'] = Time.now.utc.httpdate) ].join("\n") end - + + def read_body(request) + if request.body.respond_to?(:read) + request.body.rewind + request.body.read + else + request.body + end + end + def content_type(headers) find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE), headers) end @@ -113,7 +122,7 @@ def content_md5(headers) end def generate_content_md5(request) - OpenSSL::Digest::MD5.hexdigest(request.body) + OpenSSL::Digest::MD5.hexdigest(read_body(request)) end def request_path(request, authenticate_referrer) diff --git a/spec/auth-hmac_spec.rb b/spec/auth-hmac_spec.rb index c06f8c0..997becd 100644 --- a/spec/auth-hmac_spec.rb +++ b/spec/auth-hmac_spec.rb @@ -237,7 +237,7 @@ def signature(value, secret) rack_req.stub!(:request_method).and_return('GET') rack_req.stub!(:path).and_return("/path/to/get?foo=bar&bar=foo") rack_req.stub!(:[]).and_return({'foo' => 'bar', 'bar' => 'foo'}) - rack_req.stub!(:body).and_return('') + rack_req.stub!(:body).and_return(StringIO.new('')) @authhmac.authenticated?(rack_req).should be_true end end From 533d7467472cdf13d73d7a88e8674cf48f65f68d Mon Sep 17 00:00:00 2001 From: Ultra Ninja Date: Fri, 3 Sep 2010 19:38:09 -0700 Subject: [PATCH 11/23] Use the CanonicalString as an object rather than passing request and headers around --- lib/auth-hmac.rb | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/lib/auth-hmac.rb b/lib/auth-hmac.rb index cb54a69..6cd08e6 100644 --- a/lib/auth-hmac.rb +++ b/lib/auth-hmac.rb @@ -74,13 +74,20 @@ class CanonicalString < String # :nodoc: include Headers def initialize(request, authenticate_referrer=false) - self << request_method(request) + "\n" - self << header_values(request) + "\n" - self << request_path(request, authenticate_referrer) + @request = request + @authenticate_referrer = authenticate_referrer + self << request_method + "\n" + self << header_values + "\n" + self << request_path end - + attr_reader :request, :authenticate_referrer + private - def request_method(request) + def headers + super(@request) + end + + def request_method if request.respond_to?(:request_method) && request.request_method.is_a?(String) request.request_method elsif request.respond_to?(:method) && request.method.is_a?(String) @@ -92,15 +99,14 @@ def request_method(request) end end - def header_values(request) - headers = headers(request) - [ content_type(headers), - (content_md5(headers) or (read_body(request).nil? || read_body(request).empty? ? '' : headers['Content-MD5'] = generate_content_md5(request))), - (date(headers) or headers['Date'] = Time.now.utc.httpdate) + def header_values + [ content_type, + (content_md5 or (read_body.nil? || read_body.empty? ? '' : headers['Content-MD5'] = generate_content_md5)), + (date or headers['Date'] = Time.now.utc.httpdate) ].join("\n") end - def read_body(request) + def read_body if request.body.respond_to?(:read) request.body.rewind request.body.read @@ -109,25 +115,25 @@ def read_body(request) end end - def content_type(headers) + def content_type find_header(%w(CONTENT-TYPE CONTENT_TYPE HTTP_CONTENT_TYPE), headers) end - def date(headers) + def date find_header(%w(DATE HTTP_DATE), headers) end - def content_md5(headers) + def content_md5 find_header(%w(CONTENT-MD5 CONTENT_MD5 HTTP_CONTENT_MD5), headers) end - def generate_content_md5(request) - OpenSSL::Digest::MD5.hexdigest(read_body(request)) + def generate_content_md5 + OpenSSL::Digest::MD5.hexdigest(read_body) end - def request_path(request, authenticate_referrer) + def request_path if authenticate_referrer - headers(request)['Referer'] =~ /^(?:http:\/\/)?[^\/]*(\/.*)$/ + headers['Referer'] =~ /^(?:http:\/\/)?[^\/]*(\/.*)$/ path = $1 else # Try unparsed_uri in case it is a Webrick request From a1bbcd0e96e31f0f18f2b50db5cdea8f1ed8485e Mon Sep 17 00:00:00 2001 From: Ultra Ninja Date: Fri, 3 Sep 2010 19:40:46 -0700 Subject: [PATCH 12/23] extract generated_md5 method and expand ternary --- lib/auth-hmac.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/auth-hmac.rb b/lib/auth-hmac.rb index 6cd08e6..eba0d01 100644 --- a/lib/auth-hmac.rb +++ b/lib/auth-hmac.rb @@ -101,7 +101,7 @@ def request_method def header_values [ content_type, - (content_md5 or (read_body.nil? || read_body.empty? ? '' : headers['Content-MD5'] = generate_content_md5)), + (content_md5 or generated_md5), (date or headers['Date'] = Time.now.utc.httpdate) ].join("\n") end @@ -127,6 +127,14 @@ def content_md5 find_header(%w(CONTENT-MD5 CONTENT_MD5 HTTP_CONTENT_MD5), headers) end + def generated_md5 + if read_body.nil? || read_body.empty? + '' + else + headers['Content-MD5'] = generate_content_md5 + end + end + def generate_content_md5 OpenSSL::Digest::MD5.hexdigest(read_body) end From 7ad0f8d68556c3d63474b615e79e001442abfc4c Mon Sep 17 00:00:00 2001 From: Ultra Ninja Date: Fri, 3 Sep 2010 19:54:47 -0700 Subject: [PATCH 13/23] Expose the service id --- lib/auth-hmac.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/auth-hmac.rb b/lib/auth-hmac.rb index eba0d01..e15392b 100644 --- a/lib/auth-hmac.rb +++ b/lib/auth-hmac.rb @@ -192,6 +192,8 @@ def initialize(credential_store, options = nil) @signature_method = lambda { |r,ar| @signature_class.send(:new, r, ar) } end + attr_reader :service_id + # Generates canonical signing string for given request # # Supports same options as AuthHMAC.initialize for overriding service_id and From ee594712e18d1ab16f76eaca5f0a19a4e5402733 Mon Sep 17 00:00:00 2001 From: Ultra Ninja Date: Fri, 3 Sep 2010 19:55:00 -0700 Subject: [PATCH 14/23] Rewind the body after reading --- lib/auth-hmac.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/auth-hmac.rb b/lib/auth-hmac.rb index e15392b..b085b91 100644 --- a/lib/auth-hmac.rb +++ b/lib/auth-hmac.rb @@ -108,8 +108,8 @@ def header_values def read_body if request.body.respond_to?(:read) - request.body.rewind request.body.read + request.body.rewind else request.body end From 8300a9b502550db2c3cd2d6bf82966e0c085e32e Mon Sep 17 00:00:00 2001 From: Ultra Ninja Date: Fri, 3 Sep 2010 21:02:15 -0700 Subject: [PATCH 15/23] Return the body of the request instead of the rewind --- lib/auth-hmac.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/auth-hmac.rb b/lib/auth-hmac.rb index b085b91..2288813 100644 --- a/lib/auth-hmac.rb +++ b/lib/auth-hmac.rb @@ -108,8 +108,9 @@ def header_values def read_body if request.body.respond_to?(:read) - request.body.read + body = request.body.read request.body.rewind + body else request.body end From c4332bd6f1b0ba60627c352c5280537edc3ec5cc Mon Sep 17 00:00:00 2001 From: Ultra Ninja Date: Tue, 5 Oct 2010 03:15:42 -0700 Subject: [PATCH 16/23] add the middleware --- lib/auth-hmac/middleware.rb | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 lib/auth-hmac/middleware.rb diff --git a/lib/auth-hmac/middleware.rb b/lib/auth-hmac/middleware.rb new file mode 100644 index 0000000..a265cb8 --- /dev/null +++ b/lib/auth-hmac/middleware.rb @@ -0,0 +1,34 @@ +class AuthHMAC + class Middleware + def initialize(app, credentials) + @app = app + @hmac = AuthHMAC.new(credentials) + end + + def call(env) + dup.call!(env) + end + + def call!(env) + @env = env + + if @hmac.authenticated?(request) + rx = Regexp.new("#{@hmac.service_id} ([^:]+):(.+)$") + + if md = rx.match(@hmac.authorization_header(request)) + env["hmac-auth.access_key_id"] = md[1] + else + raise "Unknown request" + end + + @app.call(env) + else + Rack::Response.new("Authorization required", 401).finish + end + end + + def request + @request ||= Rack::Request.new(@env) + end + end +end From 10002244c8b2847223d10e00b709ec47a2840002 Mon Sep 17 00:00:00 2001 From: Tim Carey-Smith Date: Wed, 6 Oct 2010 23:02:19 +1300 Subject: [PATCH 17/23] Change the env key to be more consistent --- lib/auth-hmac/middleware.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/auth-hmac/middleware.rb b/lib/auth-hmac/middleware.rb index a265cb8..f3a47c8 100644 --- a/lib/auth-hmac/middleware.rb +++ b/lib/auth-hmac/middleware.rb @@ -16,7 +16,7 @@ def call!(env) rx = Regexp.new("#{@hmac.service_id} ([^:]+):(.+)$") if md = rx.match(@hmac.authorization_header(request)) - env["hmac-auth.access_key_id"] = md[1] + env["auth-hmac.access_key_id"] = md[1] else raise "Unknown request" end From 6a3d421f854d5e2c9b24611ee1a68d3d27b81ff5 Mon Sep 17 00:00:00 2001 From: Simon Rozet Date: Mon, 29 Nov 2010 12:23:15 +0100 Subject: [PATCH 18/23] bundle rake --- Gemfile | 1 + Gemfile.lock | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Gemfile b/Gemfile index c625081..2ca95a0 100644 --- a/Gemfile +++ b/Gemfile @@ -3,3 +3,4 @@ source "http://rubygems.org" gem "rspec" gem "ruby-debug" gem "activesupport" +gem "rake" diff --git a/Gemfile.lock b/Gemfile.lock index 26976e4..a4cf3f8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -4,6 +4,7 @@ GEM activesupport (3.0.0) columnize (0.3.1) linecache (0.43) + rake (0.8.7) rspec (1.3.0) ruby-debug (0.10.3) columnize (>= 0.1) @@ -16,5 +17,6 @@ PLATFORMS DEPENDENCIES activesupport + rake rspec ruby-debug From 69e8429260a4c3152f59112692bcf638f4a8d288 Mon Sep 17 00:00:00 2001 From: Simon Rozet Date: Mon, 29 Nov 2010 12:25:11 +0100 Subject: [PATCH 19/23] exit 1 when gems are missing --- config/requirements.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/requirements.rb b/config/requirements.rb index 9292b69..12af4b4 100644 --- a/config/requirements.rb +++ b/config/requirements.rb @@ -8,7 +8,7 @@ rescue LoadError puts "This Rakefile requires the '#{req_gem}' RubyGem." puts "Installation: gem install #{req_gem} -y" - exit + exit 1 end end From cff0bdf49dcb30c93280eb94de0ec7416a09b7e1 Mon Sep 17 00:00:00 2001 From: Simon Rozet Date: Mon, 29 Nov 2010 12:33:12 +0100 Subject: [PATCH 20/23] bundle other random gems required by the rakefile --- Gemfile | 3 +++ Gemfile.lock | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/Gemfile b/Gemfile index 2ca95a0..f6f0c25 100644 --- a/Gemfile +++ b/Gemfile @@ -4,3 +4,6 @@ gem "rspec" gem "ruby-debug" gem "activesupport" gem "rake" +gem "hoe" +gem "newgem" +gem "rubigen" diff --git a/Gemfile.lock b/Gemfile.lock index a4cf3f8..88f3eae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,22 +1,41 @@ GEM remote: http://rubygems.org/ specs: + RedCloth (4.2.3) activesupport (3.0.0) columnize (0.3.1) + hoe (2.6.2) + rake (>= 0.8.7) + rubyforge (>= 2.0.4) + json_pure (1.4.6) linecache (0.43) + newgem (1.5.2) + RedCloth (>= 4.1.1) + activesupport (>= 2.0.2) + hoe (>= 2.3.1) + rubigen (>= 1.5.2) + syntax (>= 1.0.0) rake (0.8.7) rspec (1.3.0) + rubigen (1.5.2) + activesupport (>= 2.2.2) ruby-debug (0.10.3) columnize (>= 0.1) ruby-debug-base (~> 0.10.3.0) ruby-debug-base (0.10.3) linecache (>= 0.3) + rubyforge (2.0.4) + json_pure (>= 1.1.7) + syntax (1.0.0) PLATFORMS ruby DEPENDENCIES activesupport + hoe + newgem rake rspec + rubigen ruby-debug From 33ce859cfe2cc9530cd9c15e9d3bd83fe509204b Mon Sep 17 00:00:00 2001 From: Simon Rozet Date: Mon, 29 Nov 2010 17:15:26 +0100 Subject: [PATCH 21/23] do not require newgem and rubigen --- Gemfile | 2 -- Gemfile.lock | 12 ------------ config/requirements.rb | 2 +- 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/Gemfile b/Gemfile index f6f0c25..34d47bd 100644 --- a/Gemfile +++ b/Gemfile @@ -5,5 +5,3 @@ gem "ruby-debug" gem "activesupport" gem "rake" gem "hoe" -gem "newgem" -gem "rubigen" diff --git a/Gemfile.lock b/Gemfile.lock index 88f3eae..5de6c3d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,6 @@ GEM remote: http://rubygems.org/ specs: - RedCloth (4.2.3) activesupport (3.0.0) columnize (0.3.1) hoe (2.6.2) @@ -9,16 +8,8 @@ GEM rubyforge (>= 2.0.4) json_pure (1.4.6) linecache (0.43) - newgem (1.5.2) - RedCloth (>= 4.1.1) - activesupport (>= 2.0.2) - hoe (>= 2.3.1) - rubigen (>= 1.5.2) - syntax (>= 1.0.0) rake (0.8.7) rspec (1.3.0) - rubigen (1.5.2) - activesupport (>= 2.2.2) ruby-debug (0.10.3) columnize (>= 0.1) ruby-debug-base (~> 0.10.3.0) @@ -26,7 +17,6 @@ GEM linecache (>= 0.3) rubyforge (2.0.4) json_pure (>= 1.1.7) - syntax (1.0.0) PLATFORMS ruby @@ -34,8 +24,6 @@ PLATFORMS DEPENDENCIES activesupport hoe - newgem rake rspec - rubigen ruby-debug diff --git a/config/requirements.rb b/config/requirements.rb index 12af4b4..a9b8c4e 100644 --- a/config/requirements.rb +++ b/config/requirements.rb @@ -2,7 +2,7 @@ include FileUtils require 'rubygems' -%w[rake hoe newgem rubigen].each do |req_gem| +%w[rake hoe].each do |req_gem| begin require req_gem rescue LoadError From cca8fb482a4791daa621e3cbb68686af85957a00 Mon Sep 17 00:00:00 2001 From: Simon Rozet Date: Mon, 29 Nov 2010 17:18:45 +0100 Subject: [PATCH 22/23] remove deployment, environment and website tasks --- tasks/deployment.rake | 34 ---------------------------------- tasks/environment.rake | 7 ------- tasks/website.rake | 9 --------- 3 files changed, 50 deletions(-) delete mode 100644 tasks/deployment.rake delete mode 100644 tasks/environment.rake delete mode 100644 tasks/website.rake diff --git a/tasks/deployment.rake b/tasks/deployment.rake deleted file mode 100644 index 2f43742..0000000 --- a/tasks/deployment.rake +++ /dev/null @@ -1,34 +0,0 @@ -desc 'Release the website and new gem version' -task :deploy => [:check_version, :website, :release] do - puts "Remember to create SVN tag:" - puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " + - "svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} " - puts "Suggested comment:" - puts "Tagging release #{CHANGES}" -end - -desc 'Runs tasks website_generate and install_gem as a local deployment of the gem' -task :local_deploy => [:website_generate, :install_gem] - -task :check_version do - unless ENV['VERSION'] - puts 'Must pass a VERSION=x.y.z release version' - exit - end - unless ENV['VERSION'] == VERS - puts "Please update your version.rb to match the release version, currently #{VERS}" - exit - end -end - -desc 'Install the package as a gem, without generating documentation(ri/rdoc)' -task :install_gem_no_doc => [:clean, :package] do - sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri" -end - -namespace :manifest do - desc 'Recreate Manifest.txt to include ALL files' - task :refresh do - `rake check_manifest | patch -p0 > Manifest.txt` - end -end \ No newline at end of file diff --git a/tasks/environment.rake b/tasks/environment.rake deleted file mode 100644 index 691ed3b..0000000 --- a/tasks/environment.rake +++ /dev/null @@ -1,7 +0,0 @@ -task :ruby_env do - RUBY_APP = if RUBY_PLATFORM =~ /java/ - "jruby" - else - "ruby" - end unless defined? RUBY_APP -end diff --git a/tasks/website.rake b/tasks/website.rake deleted file mode 100644 index 63081ec..0000000 --- a/tasks/website.rake +++ /dev/null @@ -1,9 +0,0 @@ -# stubs for the website generation -# To install the website framework: -# script/generate website - -task :website_generate - -task :website_upload - -task :website => :publish_docs From 72eb60ad2004108a0e6e9f52c29fb5e75db12032 Mon Sep 17 00:00:00 2001 From: Simon Rozet Date: Mon, 29 Nov 2010 17:21:03 +0100 Subject: [PATCH 23/23] move rspec.task to Rakefile --- Rakefile | 13 +++++++++---- tasks/rspec.rake | 21 --------------------- 2 files changed, 9 insertions(+), 25 deletions(-) delete mode 100644 tasks/rspec.rake diff --git a/Rakefile b/Rakefile index e469154..c6c7562 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,9 @@ -require 'config/requirements' -require 'config/hoe' # setup Hoe + all gem configuration - -Dir['tasks/**/*.rake'].each { |rake| load rake } \ No newline at end of file +require 'config/requirements' +require 'config/hoe' # setup Hoe + all gem configuration + +require 'spec/rake/spectask' +desc "Run the specs under spec/models" +Spec::Rake::SpecTask.new do |t| + t.spec_opts = ['--options', "spec/spec.opts"] + t.spec_files = FileList['spec/**/*_spec.rb'] +end diff --git a/tasks/rspec.rake b/tasks/rspec.rake deleted file mode 100644 index 2415fa4..0000000 --- a/tasks/rspec.rake +++ /dev/null @@ -1,21 +0,0 @@ -begin - require 'spec' -rescue LoadError - require 'rubygems' - require 'spec' -end -begin - require 'spec/rake/spectask' -rescue LoadError - puts <<-EOS -To use rspec for testing you must install rspec gem: - gem install rspec -EOS - exit(0) -end - -desc "Run the specs under spec/models" -Spec::Rake::SpecTask.new do |t| - t.spec_opts = ['--options', "spec/spec.opts"] - t.spec_files = FileList['spec/**/*_spec.rb'] -end