aptible-cli 0.7.0 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4b335a0f359338d92dff7ff3e0a267c0da5a6790
4
- data.tar.gz: 28fa0a1b6c4129e361df287757fc8436f540fb9f
3
+ metadata.gz: cf860a7c589c2689289068a00ea10b4a2bb8cd10
4
+ data.tar.gz: 30a8504c9fdeddd33c67a23e775e08eae455cae9
5
5
  SHA512:
6
- metadata.gz: e0c6bb5308aa87d7696a6b4cd1ae85923429084b5bfa3c6882114cbc0932c001e60f4e3045f686bc4e7c5827874c9a53e2685bee2268210baee5479395c1fd99
7
- data.tar.gz: 9604c082e3d8a4b47ab0bad5bd1686fcf2dd27cefa0404f2fffd2f685b8c93fb8b3b19a9348a74aba98c4debfe6bfd14d539b16fec2f1dc67dba93b319a2c667
6
+ metadata.gz: 709bfbf15f9a1988a3bdbd7d6c04d88a7ac748c0f15d4550afdcdf80bdd11536cd1735ed7437c8188d3272e9890a265880b010f546367135d85bb1d956df6a81
7
+ data.tar.gz: 96ac24c260b42100c57639dcd8ee10e57ccbef49dcbf070ce3509f255b98835df0c2a10d9a99cbfe729c7a195adfac21b6070d622017f8cc55a5f40bf0980718
data/.travis.yml CHANGED
@@ -1,2 +1,3 @@
1
1
  rvm:
2
2
  - 2.0.0
3
+ - 2.3.0
data/aptible-cli.gemspec CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.require_paths = ['lib']
22
22
 
23
23
  spec.add_dependency 'aptible-api', '~> 0.9.7'
24
- spec.add_dependency 'aptible-auth', '~> 0.11.7'
24
+ spec.add_dependency 'aptible-auth', '~> 0.11.8'
25
25
  spec.add_dependency 'aptible-resource', '~> 0.3.6'
26
26
  spec.add_dependency 'thor', '~> 0.19.1'
27
27
  spec.add_dependency 'git'
@@ -24,8 +24,6 @@ require_relative 'subcommands/backup'
24
24
 
25
25
  module Aptible
26
26
  module CLI
27
- TOKEN_EXPIRY_WITH_OTP = 12 * 60 * 60 # 12 hours
28
-
29
27
  class Agent < Thor
30
28
  include Thor::Actions
31
29
 
@@ -54,6 +52,8 @@ module Aptible
54
52
  desc 'login', 'Log in to Aptible'
55
53
  option :email
56
54
  option :password
55
+ option :lifetime, desc: 'The duration the token should be valid for ' \
56
+ '(example usage: 24h, 1d, 600s, etc.)'
57
57
  option :otp_token, desc: 'A token generated by your second-factor app'
58
58
  def login
59
59
  email = options[:email] || ask('Email: ')
@@ -66,8 +66,16 @@ module Aptible
66
66
  token_options[:otp_token] = otp_token if otp_token
67
67
 
68
68
  begin
69
- token_options[:expires_in] = TOKEN_EXPIRY_WITH_OTP \
70
- if token_options[:otp_token]
69
+ lifetime = '1w'
70
+ lifetime = '12h' if token_options[:otp_token]
71
+ lifetime = options[:lifetime] if options[:lifetime]
72
+
73
+ duration = ChronicDuration.parse(lifetime)
74
+ if duration.nil?
75
+ fail Thor::Error, "Invalid token lifetime requested: #{lifetime}"
76
+ end
77
+
78
+ token_options[:expires_in] = duration
71
79
  token = Aptible::Auth::Token.create(token_options)
72
80
  rescue OAuth2::Error => e
73
81
  if e.code == 'otp_token_required'
@@ -82,6 +90,12 @@ module Aptible
82
90
 
83
91
  save_token(token.access_token)
84
92
  puts "Token written to #{token_file}"
93
+
94
+ lifetime_format = { units: 2, joiner: ', ' }
95
+ token_lifetime = (token.expires_at - token.created_at).round
96
+ expires_in = ChronicDuration.output(token_lifetime, lifetime_format)
97
+ puts "This token will expire after #{expires_in} " \
98
+ '(use --lifetime to customize)'
85
99
  end
86
100
 
87
101
  private
@@ -1,5 +1,5 @@
1
1
  module Aptible
2
2
  module CLI
3
- VERSION = '0.7.0'
3
+ VERSION = '0.7.1'
4
4
  end
5
5
  end
@@ -3,6 +3,7 @@ require 'spec_helper'
3
3
  describe Aptible::CLI::Agent do
4
4
  before { subject.stub(:ask) }
5
5
  before { subject.stub(:save_token) }
6
+ before { allow(subject).to receive(:token_file).and_return 'some.json' }
6
7
 
7
8
  describe '#version' do
8
9
  it 'should print the version' do
@@ -14,13 +15,18 @@ describe Aptible::CLI::Agent do
14
15
 
15
16
  describe '#login' do
16
17
  let(:token) { double('Aptible::Auth::Token') }
18
+ let(:created_at) { Time.now }
19
+ let(:expires_at) { created_at + 1.week }
20
+ let(:output) { [] }
17
21
 
18
22
  before do
19
23
  m = -> (code) { @code = code }
20
24
  OAuth2::Error.send :define_method, :initialize, m
21
25
  end
22
26
  before { token.stub(:access_token) { 'access_token' } }
23
- before { subject.stub(:puts) {} }
27
+ before { token.stub(:created_at) { created_at } }
28
+ before { token.stub(:expires_at) { expires_at } }
29
+ before { allow(subject).to receive(:puts) { |m| output << m } }
24
30
 
25
31
  it 'should save a token to ~/.aptible/tokens' do
26
32
  Aptible::Auth::Token.stub(:create) { token }
@@ -28,6 +34,15 @@ describe Aptible::CLI::Agent do
28
34
  subject.login
29
35
  end
30
36
 
37
+ it 'should output the token location and token lifetime' do
38
+ Aptible::Auth::Token.stub(:create) { token }
39
+ subject.login
40
+ expect(output.size).to eq(3)
41
+ expect(output[0]).to eq('')
42
+ expect(output[1]).to match(/written to some\.json/)
43
+ expect(output[2]).to match(/will expire after 7 days/)
44
+ end
45
+
31
46
  it 'should raise an error if authentication fails' do
32
47
  Aptible::Auth::Token.stub(:create).and_raise(OAuth2::Error, 'foo')
33
48
  expect do
@@ -36,12 +51,31 @@ describe Aptible::CLI::Agent do
36
51
  end
37
52
 
38
53
  it 'should use command line arguments if passed' do
54
+ options = { email: 'test@example.com', password: 'password',
55
+ lifetime: '30 minutes' }
56
+ subject.stub(:options) { options }
57
+ args = { email: options[:email], password: options[:password],
58
+ expires_in: 30.minutes.seconds }
59
+ expect(Aptible::Auth::Token).to receive(:create).with(args) { token }
60
+ subject.login
61
+ end
62
+
63
+ it 'should default to 1 week expiry when OTP is disabled' do
39
64
  options = { email: 'test@example.com', password: 'password' }
40
65
  subject.stub(:options) { options }
41
- expect(Aptible::Auth::Token).to receive(:create).with(options) { token }
66
+ args = options.dup.merge(expires_in: 1.week.seconds)
67
+ expect(Aptible::Auth::Token).to receive(:create).with(args) { token }
42
68
  subject.login
43
69
  end
44
70
 
71
+ it 'should fail if the lifetime is invalid' do
72
+ options = { email: 'test@example.com', password: 'password',
73
+ lifetime: 'this is sparta' }
74
+ subject.stub(:options) { options }
75
+
76
+ expect { subject.login }.to raise_error(/Invalid token lifetime/)
77
+ end
78
+
45
79
  context 'with OTP' do
46
80
  let(:email) { 'foo@example.org' }
47
81
  let(:password) { 'bar' }
@@ -56,7 +90,7 @@ describe Aptible::CLI::Agent do
56
90
  it 'should authenticate without otp_token_required feedback' do
57
91
  expect(Aptible::Auth::Token).to receive(:create)
58
92
  .with(email: email, password: password, otp_token: token,
59
- expires_in: Aptible::CLI::TOKEN_EXPIRY_WITH_OTP)
93
+ expires_in: 12.hours.seconds)
60
94
  .once
61
95
  .and_return(token)
62
96
 
@@ -77,28 +111,44 @@ describe Aptible::CLI::Agent do
77
111
 
78
112
  it 'should prompt for an OTP token and use it' do
79
113
  expect(Aptible::Auth::Token).to receive(:create)
80
- .with(email: email, password: password)
114
+ .with(email: email, password: password, expires_in: 1.week.seconds)
115
+ .once
116
+ .and_raise(OAuth2::Error, 'otp_token_required')
117
+
118
+ expect(Aptible::Auth::Token).to receive(:create)
119
+ .with(email: email, password: password, otp_token: token,
120
+ expires_in: 12.hours.seconds)
121
+ .once
122
+ .and_return(token)
123
+
124
+ subject.login
125
+ end
126
+
127
+ it 'should let the user override the default lifetime' do
128
+ expect(Aptible::Auth::Token).to receive(:create)
129
+ .with(email: email, password: password, expires_in: 1.day.seconds)
81
130
  .once
82
131
  .and_raise(OAuth2::Error, 'otp_token_required')
83
132
 
84
133
  expect(Aptible::Auth::Token).to receive(:create)
85
134
  .with(email: email, password: password, otp_token: token,
86
- expires_in: Aptible::CLI::TOKEN_EXPIRY_WITH_OTP)
135
+ expires_in: 1.day.seconds)
87
136
  .once
88
137
  .and_return(token)
89
138
 
139
+ allow(subject).to receive(:options).and_return(lifetime: '1d')
90
140
  subject.login
91
141
  end
92
142
 
93
143
  it 'should not retry non-OTP errors.' do
94
144
  expect(Aptible::Auth::Token).to receive(:create)
95
- .with(email: email, password: password)
145
+ .with(email: email, password: password, expires_in: 1.week.seconds)
96
146
  .once
97
147
  .and_raise(OAuth2::Error, 'otp_token_required')
98
148
 
99
149
  expect(Aptible::Auth::Token).to receive(:create)
100
150
  .with(email: email, password: password, otp_token: token,
101
- expires_in: Aptible::CLI::TOKEN_EXPIRY_WITH_OTP)
151
+ expires_in: 12.hours.seconds)
102
152
  .once
103
153
  .and_raise(OAuth2::Error, 'foo')
104
154
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aptible-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Frank Macreery
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-20 00:00:00.000000000 Z
11
+ date: 2016-06-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aptible-api
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.11.7
33
+ version: 0.11.8
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.11.7
40
+ version: 0.11.8
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: aptible-resource
43
43
  requirement: !ruby/object:Gem::Requirement