File: add_downloader_authentication_test.rb

package info (click to toggle)
vagrant 2.2.14%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 9,800 kB
  • sloc: ruby: 97,301; sh: 375; makefile: 16; lisp: 1
file content (155 lines) | stat: -rw-r--r-- 5,475 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
require File.expand_path("../../../../../../base", __FILE__)

require Vagrant.source_root.join("plugins/commands/cloud/auth/middleware/add_downloader_authentication")
require "vagrant/util/downloader"

describe VagrantPlugins::CloudCommand::AddDownloaderAuthentication 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://vagrantcloud.com/box.box" }
  let(:dwnloader) { Vagrant::Util::Downloader.new(server_url, "/some/path", {}) }

  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

  describe "#call" do
    context "non full paths" do
      let(:server_url) { "http://vagrantcloud.com" }
      let(:dwnloader) { Vagrant::Util::Downloader.new(server_url, "/some/path", {}) }

      it "does nothing if we have no server set" do
        allow(Vagrant).to receive(:server_url).and_return(nil)
        VagrantPlugins::CloudCommand::Client.new(iso_env).store_token("fooboohoo")

        env[:downloader] = dwnloader
        subject.call(env)
        expect(env[:downloader].headers.empty?).to eq(true)
      end

      it "does nothing if we aren't logged in" do
        env[:downloader] = dwnloader
        subject.call(env)
        expect(env[:downloader].headers.empty?).to eq(true)
      end
    end

    context "custom server" do
      let(:server_url) { "http://surprise.com/box.box" }
      let(:dwnloader) { Vagrant::Util::Downloader.new(server_url, "/some/path", {}) }

      it "warns when adding token to custom server" do
        server_url = "https://surprise.com"
        allow(Vagrant).to receive(:server_url).and_return(server_url)
  
        token = "foobarbaz"
        VagrantPlugins::CloudCommand::Client.new(iso_env).store_token(token)
  
        expect(subject).to receive(:sleep).once
        expect(ui).to receive(:warn).once
  
        env[:downloader] = dwnloader
        subject.call(env)
  
        expect(env[:downloader].headers).to eq(["Authorization: Bearer #{token}"])
      end
    end

    context "replacement hosts" do
      let(:dwnloader) { Vagrant::Util::Downloader.new("https://app.vagrantup.com", "/some/path", {}) }

      it "modifies host URL to target if authorized host" do
        token = "foobarbaz"
        VagrantPlugins::CloudCommand::Client.new(iso_env).store_token(token)
        env[:downloader] = dwnloader
        subject.call(env)
        expect(env[:downloader].headers).to eq(["Authorization: Bearer #{token}"])
        expect(URI.parse(env[:downloader].source).host).to eq(VagrantPlugins::CloudCommand::AddDownloaderAuthentication::TARGET_HOST)
      end
    end

    context "malformed url" do
      let(:bad_url) { "this is not a valid url" }
      let(:dwnloader) { Vagrant::Util::Downloader.new(bad_url, "/some/path", {}) }

      it "ignores urls that it cannot parse" do
        # Ensure the bad URL does cause an exception
        expect{ URI.parse(bad_url) }.to raise_error URI::Error
        env[:downloader] = dwnloader
        subject.call(env)
        expect(env[:downloader].source).to eq(bad_url)
      end
    end

    context "with an headers already added" do
      let(:auth_header) { "Authorization Bearer: token" }
      let(:other_header) {"some: thing"}
      let(:dwnloader) { Vagrant::Util::Downloader.new(server_url, "/some/path", {headers: [other_header]}) }
    
      it "appends the auth header" do
        token = "foobarbaz"
        VagrantPlugins::CloudCommand::Client.new(iso_env).store_token(token)
  
        env[:downloader] = dwnloader
        subject.call(env)

        expect(env[:downloader].headers).to eq([other_header, "Authorization: Bearer #{token}"])
      end

      context "with local file path" do
        let(:file_path) { "file:////path/to/box.box" }
        let(:dwnloader) { Vagrant::Util::Downloader.new(file_path, "/some/path", {}) }

        it "returns original urls when not modified" do
          env[:downloader] = dwnloader
          subject.call(env)
          
          expect(env[:downloader].source).to eq(file_path)
          expect(env[:downloader].headers.empty?).to eq(true)
        end
      end

      it "does not append multiple access_tokens" do
        dwnloader.headers << auth_header
        token = "foobarbaz"
        VagrantPlugins::CloudCommand::Client.new(iso_env).store_token(token)
  
        env[:downloader] = dwnloader
        subject.call(env)

        expect(env[:downloader].headers).to eq([other_header, auth_header])
      end
    end

    it "adds a token to the headers" do
      token = "foobarbaz"
      VagrantPlugins::CloudCommand::Client.new(iso_env).store_token(token)
      env[:downloader] = dwnloader
      subject.call(env)
      expect(env[:downloader].headers).to eq(["Authorization: Bearer #{token}"])
    end

    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::CloudCommand::Client.new(iso_env).store_token(token)
      env[:downloader] = dwnloader
      subject.call(env)
      expect(env[:downloader].headers.empty?).to eq(true)
    end
  end
end