diff --git a/plugins/commands/login/command.rb b/plugins/commands/login/command.rb index e16b1afaf..203b09009 100644 --- a/plugins/commands/login/command.rb +++ b/plugins/commands/login/command.rb @@ -18,6 +18,10 @@ module VagrantPlugins o.on("-k", "--logout", "Logs you out if you're logged in") do |k| options[:logout] = k end + + o.on("-t", "--token TOKEN", String, "Set the Atlas token") do |t| + options[:token] = t + end end # Parse the options @@ -31,6 +35,8 @@ module VagrantPlugins return execute_check elsif options[:logout] return execute_logout + elsif options[:token] + return execute_token(options[:token]) end # Let the user know what is going on. @@ -78,6 +84,19 @@ module VagrantPlugins @env.ui.success(I18n.t("login_command.logged_out")) return 0 end + + def execute_token(token) + @client.store_token(token) + @env.ui.success(I18n.t("login_command.token_saved")) + + if @client.logged_in? + @env.ui.success(I18n.t("login_command.check_logged_in")) + return 0 + else + @env.ui.error(I18n.t("login_command.invalid_token")) + return 1 + end + end end end end diff --git a/plugins/commands/login/locales/en.yml b/plugins/commands/login/locales/en.yml index 51020df1d..dba4d52d7 100644 --- a/plugins/commands/login/locales/en.yml +++ b/plugins/commands/login/locales/en.yml @@ -24,7 +24,11 @@ en: https://atlas.hashicorp.com. invalid_login: |- Invalid username or password. Please try again. + invalid_token: |- + Invalid token. Please try again. logged_in: |- You are now logged in. logged_out: |- You are logged out. + token_saved: |- + The token was successfully saved. diff --git a/test/unit/plugins/commands/login/command_test.rb b/test/unit/plugins/commands/login/command_test.rb new file mode 100644 index 000000000..c92c51174 --- /dev/null +++ b/test/unit/plugins/commands/login/command_test.rb @@ -0,0 +1,96 @@ +require File.expand_path("../../../../base", __FILE__) + +require Vagrant.source_root.join("plugins/commands/login/command") + +describe VagrantPlugins::LoginCommand::Command do + include_context "unit" + + let(:env) { isolated_environment.create_vagrant_env } + + let(:token_path) { env.data_dir.join("vagrant_login_token") } + + let(:stdout) { StringIO.new } + let(:stderr) { StringIO.new } + + subject { described_class.new(argv, env) } + + before do + stub_env("ATLAS_TOKEN" => "") + end + + describe "#execute" do + context "with no args" do + let(:argv) { [] } + end + + context "with --check" do + let(:argv) { ["--check"] } + + context "when there is a token" do + before do + stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate}) + .to_return(status: 200) + end + + before do + File.open(token_path, "w+") { |f| f.write("abcd1234") } + end + + it "returns 0" do + expect(subject.execute).to eq(0) + end + end + + context "when there is no token" do + it "returns 1" do + expect(subject.execute).to eq(1) + end + end + end + + context "with --logout" do + let(:argv) { ["--logout"] } + + it "returns 0" do + expect(subject.execute).to eq(0) + end + + it "clears the token" do + subject.execute + expect(File.exist?(token_path)).to be(false) + end + end + + context "with --token" do + let(:argv) { ["--token", "efgh5678"] } + + context "when the token is valid" do + before do + stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate}) + .to_return(status: 200) + end + + it "sets the token" do + subject.execute + token = File.read(token_path).strip + expect(token).to eq("efgh5678") + end + + it "returns 0" do + expect(subject.execute).to eq(0) + end + end + + context "when the token is invalid" do + before do + stub_request(:get, %r{^#{Vagrant.server_url}/api/v1/authenticate}) + .to_return(status: 401) + end + + it "returns 1" do + expect(subject.execute).to eq(1) + end + end + end + end +end diff --git a/website/docs/Gemfile.lock b/website/docs/Gemfile.lock index 7e3a024b4..cced2615a 100644 --- a/website/docs/Gemfile.lock +++ b/website/docs/Gemfile.lock @@ -23,7 +23,7 @@ GEM compass-import-once (1.0.5) sass (>= 3.2, < 3.5) daemons (1.1.9) - eventmachine (1.0.3) + eventmachine (1.0.4) execjs (1.4.1) multi_json (~> 1.0) ffi (1.9.6) diff --git a/website/docs/source/v2/cli/login.html.md b/website/docs/source/v2/cli/login.html.md index c8f6ee7d9..1ff6e9c6d 100644 --- a/website/docs/source/v2/cli/login.html.md +++ b/website/docs/source/v2/cli/login.html.md @@ -19,6 +19,7 @@ boxes or [Vagrant Share](/v2/share/index.html) require a login. The reference of available command-line flags to this command is available below. + ## Options * `--check` - This will check if you're logged in. In addition to outputting @@ -28,3 +29,32 @@ is available below. * `--logout` - This will log you out if you're logged in. If you're already logged out, this command will do nothing. It is not an error to call this command if you're already logged out. + +* `--token` - This will set the Atlas login token manually to the provided + string. It is assumed this token is a valid Atlas access token. + + +## Examples + +Securely authenticate to Atlas using a username and password: + +```text +$ vagrant login +# ... +Atlas username: +Atlas password: +``` + +Check if the current user is authenticated: + +```text +$ vagrant login --check +You are already logged in. +``` + +Securely authenticate with Atlas using a token: + +```text +$ vagrant login --token ABCD1234 +The token was successfully saved. +```