awskeyring 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e905b5fccdebddbc839f898423c513e8c3c3475
4
- data.tar.gz: da11dceb9c06415e01647a2de7512103df2d951d
3
+ metadata.gz: 8657e757b5569d9712953debdfb94b87cb120a72
4
+ data.tar.gz: 1cbaee2befed2828a571cdea1e8e3ec2e0b02248
5
5
  SHA512:
6
- metadata.gz: 6c6b3db63fda21933153f5eb38be4a24e07701709c3d893b71c5266d8faca9b0385060dbdde6bac3ebad69d42077e8ae1e6199a74996e996be37f12883f299f8
7
- data.tar.gz: d7db72c1d2f8a1d33508c113a5b8866dc48c5fc53017a89b9b14d8e7dae05d48e4ee1d8ac0f69d83d4041e48e3fbadb26f3847824c7240666ae2525018715c1d
6
+ metadata.gz: c7199c75966a60aba45f9c49cef0c9f11fd6fb7b5ba9f42f7740fc1df346fbad277c5d14051e6764afc9282e5bfd35273191aa4d0c305c109fa9513d757dfd0b
7
+ data.tar.gz: 8a842afe5dc7d834dc64c38e78fddf69c64661dd88a1c41dadcdebb48c335c3605184cac55f588fb07b062f01b768fdbbdd8fdeec2b573e42150a016bbb1e9b4
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Change Log
2
2
 
3
+ ## [v0.3.0](https://github.com/vibrato/awskeyring/tree/v0.3.0) (2018-04-12)
4
+ [Full Changelog](https://github.com/vibrato/awskeyring/compare/v0.2.0...v0.3.0)
5
+
6
+ **Implemented enhancements:**
7
+
8
+ - Validate tokens upon adding them to the keychain [\#18](https://github.com/vibrato/awskeyring/issues/18)
9
+ - Generate a token from IAM User credentials using the GetFederationToken API [\#17](https://github.com/vibrato/awskeyring/issues/17)
10
+ - Test creds against AWS API \(optionally\). [\#20](https://github.com/vibrato/awskeyring/pull/20) ([tristanmorgan](https://github.com/tristanmorgan))
11
+ - Allow STS get\_session\_token without role [\#19](https://github.com/vibrato/awskeyring/pull/19) ([tristanmorgan](https://github.com/tristanmorgan))
12
+
3
13
  ## [v0.2.0](https://github.com/vibrato/awskeyring/tree/v0.2.0) (2018-04-05)
4
14
  [Full Changelog](https://github.com/vibrato/awskeyring/compare/v0.1.1...v0.2.0)
5
15
 
@@ -7,6 +7,19 @@ require 'json'
7
7
  module Awskeyring
8
8
  # AWS API methods for Awskeyring
9
9
  module Awsapi # rubocop:disable Metrics/ModuleLength
10
+ # Admin policy as json
11
+ ADMIN_POLICY = {
12
+ Version: '2012-10-17',
13
+ Statement: [{
14
+ Action: '*',
15
+ Resource: '*',
16
+ Effect: 'Allow'
17
+ }]
18
+ }.to_json.freeze
19
+
20
+ TWELVE_HOUR = (60 * 60 * 12)
21
+ ONE_HOUR = (60 * 60 * 1)
22
+
10
23
  # Retrieves a temporary session token from AWS
11
24
  #
12
25
  # @param [Hash] params including
@@ -47,6 +60,12 @@ module Awskeyring
47
60
  serial_number: params[:mfa],
48
61
  token_code: params[:code]
49
62
  )
63
+ else
64
+ sts.get_federation_token(
65
+ name: params[:user],
66
+ policy: ADMIN_POLICY,
67
+ duration_seconds: params[:duration]
68
+ )
50
69
  end
51
70
  rescue Aws::STS::Errors::AccessDenied => err
52
71
  warn err.to_s
@@ -79,6 +98,22 @@ module Awskeyring
79
98
  )
80
99
  end
81
100
 
101
+ # Verify Credentials are active and valid
102
+ #
103
+ # @param [String] key The aws_access_key_id
104
+ # @param [String] secret The aws_secret_access_key
105
+ # @param [String] token The aws_session_token
106
+ def self.verify_cred(key:, secret:)
107
+ begin
108
+ sts = Aws::STS::Client.new(access_key_id: key, secret_access_key: secret)
109
+ sts.get_caller_identity
110
+ rescue Aws::Errors::ServiceError => err
111
+ warn err.to_s
112
+ exit 1
113
+ end
114
+ true
115
+ end
116
+
82
117
  # Retrieves an AWS Console login url
83
118
  #
84
119
  # @param [String] key The aws_access_key_id
@@ -90,14 +125,6 @@ module Awskeyring
90
125
  def self.get_login_url(key:, secret:, token:, path:, user:) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
91
126
  console_url = "https://console.aws.amazon.com/#{path}/home"
92
127
  signin_url = 'https://signin.aws.amazon.com/federation'
93
- policy_json = {
94
- Version: '2012-10-17',
95
- Statement: [{
96
- Action: '*',
97
- Resource: '*',
98
- Effect: 'Allow'
99
- }]
100
- }.to_json
101
128
 
102
129
  if token
103
130
  session_json = {
@@ -110,8 +137,8 @@ module Awskeyring
110
137
  secret_access_key: secret)
111
138
 
112
139
  session = sts.get_federation_token(name: user,
113
- policy: policy_json,
114
- duration_seconds: (60 * 60 * 12))
140
+ policy: ADMIN_POLICY,
141
+ duration_seconds: TWELVE_HOUR)
115
142
  session_json = {
116
143
  sessionId: session.credentials[:access_key_id],
117
144
  sessionKey: session.credentials[:secret_access_key],
@@ -1,4 +1,4 @@
1
1
  module Awskeyring
2
2
  # The Gems version number
3
- VERSION = '0.2.0'.freeze
3
+ VERSION = '0.3.0'.freeze
4
4
  end
data/lib/awskeyring.rb CHANGED
@@ -106,11 +106,11 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
106
106
  all_items.create(label: SESSION_KEY_PREFIX + params[:account],
107
107
  account: params[:key],
108
108
  password: params[:secret],
109
- comment: ROLE_PREFIX + params[:role])
109
+ comment: params[:role].nil? ? '' : ROLE_PREFIX + params[:role])
110
110
  all_items.create(label: SESSION_TOKEN_PREFIX + params[:account],
111
111
  account: params[:expiry],
112
112
  password: params[:token],
113
- comment: ROLE_PREFIX + params[:role])
113
+ comment: params[:role] || '')
114
114
  end
115
115
 
116
116
  # Return an account item by name
@@ -110,8 +110,10 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
110
110
  method_option :key, type: :string, aliases: '-k', desc: 'AWS account key id.'
111
111
  method_option :secret, type: :string, aliases: '-s', desc: 'AWS account secret.'
112
112
  method_option :mfa, type: :string, aliases: '-m', desc: 'AWS virtual mfa arn.'
113
+ method_option :local, type: :boolean, aliases: '-l', desc: 'Only validate locally.', default: false
114
+ method_option :update, type: :boolean, aliases: '-u', desc: 'Update existing.', default: false
113
115
  # Add an Account
114
- def add(account = nil) # rubocop:disable Metrics/MethodLength
116
+ def add(account = nil) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
115
117
  account = ask_check(
116
118
  existing: account, message: 'account name', validator: Awskeyring::Validate.method(:account_name)
117
119
  )
@@ -122,17 +124,27 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
122
124
  existing: options[:secret], message: 'secret access key',
123
125
  secure: true, validator: Awskeyring::Validate.method(:secret_access_key)
124
126
  )
125
- mfa = ask_check(
126
- existing: options[:mfa], message: 'mfa arn', optional: true, validator: Awskeyring::Validate.method(:mfa_arn)
127
- )
128
-
129
- Awskeyring.add_account(
130
- account: account,
131
- key: key,
132
- secret: secret,
133
- mfa: mfa
134
- )
135
- puts "# Added account #{account}"
127
+ if options[:update]
128
+ Awskeyring::Awsapi.verify_cred(key: key, secret: secret) unless options[:local]
129
+ Awskeyring.update_account(
130
+ account: account,
131
+ key: key,
132
+ secret: secret
133
+ )
134
+ puts "# Updated account #{account}"
135
+ else
136
+ mfa = ask_check(
137
+ existing: options[:mfa], message: 'mfa arn', optional: true, validator: Awskeyring::Validate.method(:mfa_arn)
138
+ )
139
+ Awskeyring::Awsapi.verify_cred(key: key, secret: secret) unless options[:local]
140
+ Awskeyring.add_account(
141
+ account: account,
142
+ key: key,
143
+ secret: secret,
144
+ mfa: mfa
145
+ )
146
+ puts "# Added account #{account}"
147
+ end
136
148
  end
137
149
 
138
150
  map 'add-role' => :add_role
@@ -230,15 +242,9 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
230
242
  )
231
243
  end
232
244
  duration = options[:duration]
233
- duration ||= (60 * 60 * 1).to_s if role
234
- duration ||= (60 * 60 * 12).to_s if code
235
-
236
- if !role && !code
237
- warn 'Please use either a role or a code'
238
- exit 2
239
- end
240
-
241
- Awskeyring.delete_token(account: account, message: '# Removing STS credentials')
245
+ duration ||= Awskeyring::Awsapi::ONE_HOUR.to_s if role
246
+ duration ||= Awskeyring::Awsapi::TWELVE_HOUR.to_s if code
247
+ duration ||= Awskeyring::Awsapi::ONE_HOUR.to_s
242
248
 
243
249
  item_hash = Awskeyring.get_account_hash(account: account)
244
250
  role_arn = Awskeyring.get_role_arn(role_name: role) if role
@@ -253,6 +259,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
253
259
  secret: item_hash[:secret],
254
260
  user: ENV['USER']
255
261
  )
262
+ Awskeyring.delete_token(account: account, message: '# Removing STS credentials')
256
263
  rescue Aws::Errors::ServiceError => err
257
264
  warn err.to_s
258
265
  exit 1
@@ -267,7 +274,8 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
267
274
  role: role
268
275
  )
269
276
 
270
- puts "Authentication valid until #{new_creds[:expiry]}"
277
+ puts "# Token saved for account #{account}"
278
+ puts "# Authentication valid until #{Time.at(new_creds[:expiry].to_i)}"
271
279
  end
272
280
 
273
281
  desc 'console ACCOUNT', 'Open the AWS Console for the ACCOUNT'
@@ -304,7 +312,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
304
312
  comp_line = ENV['COMP_LINE']
305
313
  unless comp_line
306
314
  exec_name = File.basename($PROGRAM_NAME)
307
- warn "enable autocomplete with 'complete -C /path-to-command/#{exec_name} #{exec_name}'"
315
+ warn "enable autocomplete with 'complete -C #{$PROGRAM_NAME} #{exec_name}'"
308
316
  exit 1
309
317
  end
310
318
  comp_len = comp_line.split.index(prev)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awskeyring
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tristan Morgan
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-04-05 00:00:00.000000000 Z
11
+ date: 2018-04-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-iam