Merge pull request #9499 from chrisroberts/f-vc-urls

Update behavior of the authentication middleware
This commit is contained in:
Chris Roberts 2018-02-23 09:28:04 -08:00 committed by GitHub
commit 00400c95d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 22 deletions

View File

@ -10,7 +10,7 @@ module Vagrant
# of Vagrant that may require remote access. # of Vagrant that may require remote access.
# #
# @return [String] # @return [String]
DEFAULT_SERVER_URL = "https://vagrantcloud.com" DEFAULT_SERVER_URL = "https://vagrantcloud.com".freeze
# Max number of seconds to wait for joining an active thread. # Max number of seconds to wait for joining an active thread.
# #

View File

@ -1,5 +1,17 @@
en: en:
login_command: login_command:
middleware:
authentication:
different_target: |-
Vagrant has detected a custom Vagrant server in use for downloading
box files. An authentication token is currently set which will be
added to the box request. If the custom Vagrant server should not
be receiving the authentication token, please unset it.
Known Vagrant server: %{known_host}
Custom Vagrant server: %{custom_host}
Press ctrl-c to cancel...
errors: errors:
server_error: |- server_error: |-
The Vagrant Cloud server responded with a not-OK response: The Vagrant Cloud server responded with a not-OK response:

View File

@ -6,35 +6,56 @@ require_relative "../client"
module VagrantPlugins module VagrantPlugins
module LoginCommand module LoginCommand
class AddAuthentication class AddAuthentication
ALLOWED_AUTHENTICATION_HOSTS = %w[ REPLACEMENT_HOSTS = [
app.vagrantup.com "app.vagrantup.com".freeze,
atlas.hashicorp.com "atlas.hashicorp.com".freeze
vagrantcloud.com
].freeze ].freeze
TARGET_HOST = "vagrantcloud.com".freeze
CUSTOM_HOST_NOTIFY_WAIT = 5
def self.custom_host_notified!
@_host_notify = true
end
def self.custom_host_notified?
if defined?(@_host_notify)
@_host_notify
else
false
end
end
def initialize(app, env) def initialize(app, env)
@app = app @app = app
LoginCommand::Plugin.init!
end end
def call(env) def call(env)
client = Client.new(env[:env]) client = Client.new(env[:env])
token = client.token token = client.token
if token && Vagrant.server_url
server_uri = URI.parse(Vagrant.server_url)
env[:box_urls].map! do |url| env[:box_urls].map! do |url|
u = URI.parse(url) u = URI.parse(url)
replace = u.host == server_uri.host if u.host != TARGET_HOST && REPLACEMENT_HOSTS.include?(u.host)
u.host = TARGET_HOST
if !replace
if ALLOWED_AUTHENTICATION_HOSTS.include?(u.host) &&
ALLOWED_AUTHENTICATION_HOSTS.include?(server_uri.host)
replace = true
end end
u.to_s
end
server_uri = URI.parse(Vagrant.server_url.to_s)
if token && !server_uri.host.to_s.empty?
env[:box_urls].map! do |url|
u = URI.parse(url)
if u.host == server_uri.host
if server_uri.host != TARGET_HOST && !self.class.custom_host_notified?
env[:ui].warn(I18n.t("login_command.middleware.authentication.different_target",
custom_host: server_uri.host, known_host: TARGET_HOST) + "\n")
sleep CUSTOM_HOST_NOTIFY_WAIT
self.class.custom_host_notified!
end end
if replace
q = CGI.parse(u.query || "") q = CGI.parse(u.query || "")
current = q["access_token"] current = q["access_token"]
@ -50,7 +71,7 @@ module VagrantPlugins
end end
@app.call(env) @app.call(env)
end end.freeze
end end
end end
end end

View File

@ -6,17 +6,20 @@ describe VagrantPlugins::LoginCommand::AddAuthentication do
include_context "unit" include_context "unit"
let(:app) { lambda { |env| } } let(:app) { lambda { |env| } }
let(:ui) { double("ui") }
let(:env) { { let(:env) { {
env: iso_env, env: iso_env,
ui: ui
} } } }
let(:iso_env) { isolated_environment.create_vagrant_env } let(:iso_env) { isolated_environment.create_vagrant_env }
let(:server_url) { "http://foo.com" } let(:server_url) { "http://vagrantcloud.com" }
subject { described_class.new(app, env) } subject { described_class.new(app, env) }
before do before do
allow(Vagrant).to receive(:server_url).and_return(server_url) allow(Vagrant).to receive(:server_url).and_return(server_url)
allow(ui).to receive(:warn)
stub_env("ATLAS_TOKEN" => nil) stub_env("ATLAS_TOKEN" => nil)
end end
@ -62,24 +65,48 @@ describe VagrantPlugins::LoginCommand::AddAuthentication do
expect(env[:box_urls]).to eq(expected) expect(env[:box_urls]).to eq(expected)
end end
it "appends the access token to vagrantcloud.com URLs if Atlas" do it "does not append the access token to vagrantcloud.com URLs if Atlas" do
server_url = "https://atlas.hashicorp.com" server_url = "https://atlas.hashicorp.com"
allow(Vagrant).to receive(:server_url).and_return(server_url) allow(Vagrant).to receive(:server_url).and_return(server_url)
allow(subject).to receive(:sleep)
token = "foobarbaz"
VagrantPlugins::LoginCommand::Client.new(iso_env).store_token(token)
original = [
"http://google.com/box.box",
"http://vagrantcloud.com/foo.box",
"http://vagrantcloud.com/bar.box?arg=true",
]
expected = original.dup
env[:box_urls] = original.dup
subject.call(env)
expect(env[:box_urls]).to eq(expected)
end
it "warns when adding token to custom server" do
server_url = "https://example.com"
allow(Vagrant).to receive(:server_url).and_return(server_url)
token = "foobarbaz" token = "foobarbaz"
VagrantPlugins::LoginCommand::Client.new(iso_env).store_token(token) VagrantPlugins::LoginCommand::Client.new(iso_env).store_token(token)
original = [ original = [
"http://google.com/box.box", "http://google.com/box.box",
"http://app.vagrantup.com/foo.box",
"http://vagrantcloud.com/foo.box", "http://vagrantcloud.com/foo.box",
"http://vagrantcloud.com/bar.box?arg=true", "http://example.com/bar.box",
"http://example.com/foo.box"
] ]
expected = original.dup expected = original.dup
expected[1] = "#{original[1]}?access_token=#{token}" expected[2] = expected[2] + "?access_token=#{token}"
expected[2] = "#{original[2]}?access_token=#{token}" expected[3] = expected[3] + "?access_token=#{token}"
expected[3] = "#{original[3]}&access_token=#{token}"
expect(subject).to receive(:sleep).once
expect(ui).to receive(:warn).once
env[:box_urls] = original.dup env[:box_urls] = original.dup
subject.call(env) subject.call(env)
@ -87,6 +114,17 @@ describe VagrantPlugins::LoginCommand::AddAuthentication do
expect(env[:box_urls]).to eq(expected) expect(env[:box_urls]).to eq(expected)
end end
it "modifies host URL to target if authorized host" do
originals = VagrantPlugins::LoginCommand::AddAuthentication::
REPLACEMENT_HOSTS.map{ |h| "http://#{h}/box.box" }
expected = "http://#{VagrantPlugins::LoginCommand::AddAuthentication::TARGET_HOST}/box.box"
env[:box_urls] = originals
subject.call(env)
env[:box_urls].each do |url|
expect(url).to eq(expected)
end
end
it "does not append multiple access_tokens" do it "does not append multiple access_tokens" do
token = "foobarbaz" token = "foobarbaz"
VagrantPlugins::LoginCommand::Client.new(iso_env).store_token(token) VagrantPlugins::LoginCommand::Client.new(iso_env).store_token(token)