awskeyring 0.2.0 → 0.3.0

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: 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