diff options
-rw-r--r-- | lib/bundler/fetcher.rb | 12 | ||||
-rw-r--r-- | lib/bundler/fetcher/downloader.rb | 2 | ||||
-rw-r--r-- | lib/bundler/fetcher/index.rb | 3 | ||||
-rw-r--r-- | spec/bundler/bundler/fetcher/downloader_spec.rb | 10 | ||||
-rw-r--r-- | spec/bundler/bundler/fetcher/index_spec.rb | 23 |
5 files changed, 27 insertions, 23 deletions
diff --git a/lib/bundler/fetcher.rb b/lib/bundler/fetcher.rb index e12c15af8a..2119799f68 100644 --- a/lib/bundler/fetcher.rb +++ b/lib/bundler/fetcher.rb @@ -61,6 +61,16 @@ module Bundler end end + # This error is raised if HTTP authentication is correct, but lacks + # necessary permissions. + class AuthenticationForbiddenError < HTTPError + def initialize(remote_uri) + remote_uri = filter_uri(remote_uri) + super "Access token could not be authenticated for #{remote_uri}.\n" \ + "Make sure it's valid and has the necessary scopes configured." + end + end + # Exceptions classes that should bypass retry attempts. If your password didn't work the # first time, it's not going to the third time. NET_ERRORS = [:HTTPBadGateway, :HTTPBadRequest, :HTTPFailedDependency, @@ -70,7 +80,7 @@ module Bundler :HTTPRequestURITooLong, :HTTPUnauthorized, :HTTPUnprocessableEntity, :HTTPUnsupportedMediaType, :HTTPVersionNotSupported].freeze FAIL_ERRORS = begin - fail_errors = [AuthenticationRequiredError, BadAuthenticationError, FallbackError] + fail_errors = [AuthenticationRequiredError, BadAuthenticationError, AuthenticationForbiddenError, FallbackError] fail_errors << Gem::Requirement::BadRequirementError fail_errors.concat(NET_ERRORS.map {|e| Net.const_get(e) }) end.freeze diff --git a/lib/bundler/fetcher/downloader.rb b/lib/bundler/fetcher/downloader.rb index 28d33f1aed..3062899e0e 100644 --- a/lib/bundler/fetcher/downloader.rb +++ b/lib/bundler/fetcher/downloader.rb @@ -41,6 +41,8 @@ module Bundler when Net::HTTPUnauthorized raise BadAuthenticationError, uri.host if uri.userinfo raise AuthenticationRequiredError, uri.host + when Net::HTTPForbidden + raise AuthenticationForbiddenError, uri.host when Net::HTTPNotFound raise FallbackError, "Net::HTTPNotFound: #{filtered_uri}" else diff --git a/lib/bundler/fetcher/index.rb b/lib/bundler/fetcher/index.rb index 6bb9fcc193..c623647f01 100644 --- a/lib/bundler/fetcher/index.rb +++ b/lib/bundler/fetcher/index.rb @@ -15,8 +15,7 @@ module Bundler raise BadAuthenticationError, remote_uri if remote_uri.userinfo raise AuthenticationRequiredError, remote_uri when /403/ - raise BadAuthenticationError, remote_uri if remote_uri.userinfo - raise AuthenticationRequiredError, remote_uri + raise AuthenticationForbiddenError, remote_uri else raise HTTPError, "Could not fetch specs from #{display_uri} due to underlying error <#{e.message}>" end diff --git a/spec/bundler/bundler/fetcher/downloader_spec.rb b/spec/bundler/bundler/fetcher/downloader_spec.rb index 0412ddb83a..22aa3a8b0c 100644 --- a/spec/bundler/bundler/fetcher/downloader_spec.rb +++ b/spec/bundler/bundler/fetcher/downloader_spec.rb @@ -98,6 +98,16 @@ RSpec.describe Bundler::Fetcher::Downloader do end end + context "when the request response is a Net::HTTPForbidden" do + let(:http_response) { Net::HTTPForbidden.new("1.1", 403, "Forbidden") } + let(:uri) { Bundler::URI("http://user:password@www.uri-to-fetch.com") } + + it "should raise a Bundler::Fetcher::AuthenticationForbiddenError with the uri host" do + expect { subject.fetch(uri, options, counter) }.to raise_error(Bundler::Fetcher::AuthenticationForbiddenError, + /Access token could not be authenticated for www.uri-to-fetch.com/) + end + end + context "when the request response is a Net::HTTPNotFound" do let(:http_response) { Net::HTTPNotFound.new("1.1", 404, "Not Found") } diff --git a/spec/bundler/bundler/fetcher/index_spec.rb b/spec/bundler/bundler/fetcher/index_spec.rb index f0db07583c..971b64ce8f 100644 --- a/spec/bundler/bundler/fetcher/index_spec.rb +++ b/spec/bundler/bundler/fetcher/index_spec.rb @@ -63,26 +63,9 @@ RSpec.describe Bundler::Fetcher::Index do context "when a 403 response occurs" do let(:error_message) { "403" } - before do - allow(remote_uri).to receive(:userinfo).and_return(userinfo) - end - - context "and there was userinfo" do - let(:userinfo) { double(:userinfo) } - - it "should raise a Bundler::Fetcher::BadAuthenticationError" do - expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::BadAuthenticationError, - %r{Bad username or password for http://remote-uri.org}) - end - end - - context "and there was no userinfo" do - let(:userinfo) { nil } - - it "should raise a Bundler::Fetcher::AuthenticationRequiredError" do - expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::AuthenticationRequiredError, - %r{Authentication is required for http://remote-uri.org}) - end + it "should raise a Bundler::Fetcher::AuthenticationForbiddenError" do + expect { subject.specs(gem_names) }.to raise_error(Bundler::Fetcher::AuthenticationForbiddenError, + %r{Access token could not be authenticated for http://remote-uri.org}) end end |