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.
#
# @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.
#

View File

@ -1,5 +1,17 @@
en:
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:
server_error: |-
The Vagrant Cloud server responded with a not-OK response:

View File

@ -6,35 +6,56 @@ require_relative "../client"
module VagrantPlugins
module LoginCommand
class AddAuthentication
ALLOWED_AUTHENTICATION_HOSTS = %w[
app.vagrantup.com
atlas.hashicorp.com
vagrantcloud.com
REPLACEMENT_HOSTS = [
"app.vagrantup.com".freeze,
"atlas.hashicorp.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)
@app = app
LoginCommand::Plugin.init!
end
def call(env)
client = Client.new(env[:env])
token = client.token
if token && Vagrant.server_url
server_uri = URI.parse(Vagrant.server_url)
env[:box_urls].map! do |url|
u = URI.parse(url)
replace = u.host == server_uri.host
if !replace
if ALLOWED_AUTHENTICATION_HOSTS.include?(u.host) &&
ALLOWED_AUTHENTICATION_HOSTS.include?(server_uri.host)
replace = true
if u.host != TARGET_HOST && REPLACEMENT_HOSTS.include?(u.host)
u.host = TARGET_HOST
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
if replace
q = CGI.parse(u.query || "")
current = q["access_token"]
@ -50,7 +71,7 @@ module VagrantPlugins
end
@app.call(env)
end
end.freeze
end
end
end

View File

@ -6,17 +6,20 @@ describe VagrantPlugins::LoginCommand::AddAuthentication do
include_context "unit"
let(:app) { lambda { |env| } }
let(:ui) { double("ui") }
let(:env) { {
env: iso_env,
ui: ui
} }
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) }
before do
allow(Vagrant).to receive(:server_url).and_return(server_url)
allow(ui).to receive(:warn)
stub_env("ATLAS_TOKEN" => nil)
end
@ -62,24 +65,48 @@ describe VagrantPlugins::LoginCommand::AddAuthentication do
expect(env[:box_urls]).to eq(expected)
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"
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"
VagrantPlugins::LoginCommand::Client.new(iso_env).store_token(token)
original = [
"http://google.com/box.box",
"http://app.vagrantup.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[1] = "#{original[1]}?access_token=#{token}"
expected[2] = "#{original[2]}?access_token=#{token}"
expected[3] = "#{original[3]}&access_token=#{token}"
expected[2] = expected[2] + "?access_token=#{token}"
expected[3] = expected[3] + "?access_token=#{token}"
expect(subject).to receive(:sleep).once
expect(ui).to receive(:warn).once
env[:box_urls] = original.dup
subject.call(env)
@ -87,6 +114,17 @@ describe VagrantPlugins::LoginCommand::AddAuthentication do
expect(env[:box_urls]).to eq(expected)
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
token = "foobarbaz"
VagrantPlugins::LoginCommand::Client.new(iso_env).store_token(token)