awskeyring 1.11.0 → 1.12.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
  SHA256:
3
- metadata.gz: dc910795f877ae9b6a82106d0abb6aa98a1ac41e3b23e995effe1ea5dc8e8ffd
4
- data.tar.gz: 8e6651afc8b0320b9ed9e3d7b32274d6cf473ef36f7d8bf393f4e0115072aed4
3
+ metadata.gz: 73c6d89c7a836a7f9b8d75bbb1bde93a27792dbfbdc4c8cc563b0f1b4127f811
4
+ data.tar.gz: fe93e67911337c48cd21c8207bec071de5c5991bbbcccb96fdfc36b2728c346c
5
5
  SHA512:
6
- metadata.gz: 56112939c5730e6e72812b0e85845018ae762dddc1e8df8c9308c72a8458c010ce6898c1cd957d91f22a2dc3bffcc5504d933c03e711073adea294e218043e9a
7
- data.tar.gz: 60b525d9b832477409eaaa8b59ef4cb34d8ffac239b9ab26011214a8a8e182d1cc9a304ab35ca3ca4b7b128377c019eb6337bac468ed899bfd067fdac677ada0
6
+ metadata.gz: e91c2c5df102632b00cb823943381c4b1548c2baec16bb72c58724b5e0f790cc2eddac774e96efcc072bd8283efdc356e3ef77a39374659030f1fb4ff4c58ce4
7
+ data.tar.gz: 70cb85135e88d82902dd3f30e2cd8428f6534480d49c75dfb79001525b31c687bfb11c0df3cc35afe97f41a88e9aa32fc48626539c6788cff0c1c607efbf0a33
data/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  ![Awskeyring](https://raw.githubusercontent.com/tristanmorgan/awskeyring/main/awskeyring-144.png)
4
4
 
5
- * [![Build Status](https://app.travis-ci.com/tristanmorgan/awskeyring.svg?branch=main)](https://app.travis-ci.com/github/tristanmorgan/awskeyring)
6
5
  * [![Gem Version](https://img.shields.io/gem/v/awskeyring)](https://badge.fury.io/rb/awskeyring)
7
6
  * [![license MIT](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://opensource.org/licenses/MIT)
8
7
  * [![All Downloads](https://img.shields.io/gem/dt/awskeyring)](https://rubygems.org/gems/awskeyring)
data/exe/awskeyring CHANGED
@@ -11,6 +11,6 @@ end
11
11
  begin
12
12
  AwskeyringCommand.start
13
13
  rescue Keychain::UserCancelledError => e
14
- warn e.to_s
14
+ warn e
15
15
  exit 1
16
16
  end
data/i18n/en.yml CHANGED
@@ -5,6 +5,7 @@ en:
5
5
  add_role_desc: Adds a ROLE to the keyring
6
6
  awskeyring_desc: Autocompletion for bourne shells
7
7
  console_desc: Open the AWS Console for the ACCOUNT
8
+ decode_desc: Decode an account id from a KEY
8
9
  default_desc: Run default help or initialise if needed.
9
10
  env_desc: Outputs bourne shell environment exports for an ACCOUNT
10
11
  exec_desc: Execute a COMMAND with the environment set for an ACCOUNT
@@ -25,6 +25,7 @@ module Awskeyring
25
25
  # AWS Env vars
26
26
  AWS_ENV_VARS = %w[
27
27
  AWS_ACCOUNT_NAME
28
+ AWS_ACCOUNT_ID
28
29
  AWS_ACCESS_KEY_ID
29
30
  AWS_ACCESS_KEY
30
31
  AWS_CREDENTIAL_EXPIRATION
@@ -85,7 +86,7 @@ module Awskeyring
85
86
  )
86
87
  end
87
88
  rescue Aws::STS::Errors::AccessDenied => e
88
- warn e.to_s
89
+ warn e
89
90
  exit 1
90
91
  end
91
92
 
@@ -123,14 +124,16 @@ module Awskeyring
123
124
  # [String] secret The aws_secret_access_key
124
125
  # [String] token The aws_session_token
125
126
  # @return [Hash] env_var hash
126
- def self.get_env_array(params = {})
127
+ def self.get_env_array(params = {}) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
127
128
  env_var = {}
128
129
  env_var['AWS_DEFAULT_REGION'] = 'us-east-1' unless region
129
130
 
130
131
  params[:expiration] = Time.at(params[:expiry]).iso8601 unless params[:expiry].nil?
132
+ params[:account_name] = params.delete(:account)
133
+ params[:account_id] = get_account_id(key: params[:key]) unless params[:key].nil?
131
134
 
132
- params.each_key do |param_name|
133
- AWS_ENV_VARS.each do |var_name|
135
+ AWS_ENV_VARS.each do |var_name|
136
+ params.each_key do |param_name|
134
137
  if var_name.include?(param_name.to_s.upcase) && !params[param_name].nil?
135
138
  env_var[var_name] = params[param_name]
136
139
  end
@@ -151,7 +154,7 @@ module Awskeyring
151
154
  sts = Aws::STS::Client.new(access_key_id: key, secret_access_key: secret, session_token: token)
152
155
  sts.get_caller_identity
153
156
  rescue Aws::Errors::ServiceError => e
154
- warn e.to_s
157
+ warn e
155
158
  exit 1
156
159
  end
157
160
  true
@@ -229,6 +232,30 @@ module Awskeyring
229
232
  region || Aws.shared_config.region(profile: 'default')
230
233
  end
231
234
 
235
+ # Get the account number from an access key
236
+ #
237
+ # @param [String] key The aws_access_key_id
238
+ # @return [String] Account number
239
+ def self.get_account_id(key:)
240
+ padded_no = key[3..12]
241
+ mask = (2 << 39) - 1
242
+ decimal = (decode(padded_no) >> 4) & mask
243
+ decimal.to_s.rjust(12, '0')
244
+ end
245
+
246
+ # base32 decode function
247
+ # returns 0 on failure
248
+ private_class_method def self.decode(str)
249
+ aws_table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'
250
+ bytes = str.bytes
251
+ bytes.inject do |m, o|
252
+ i = aws_table.index(o.chr)
253
+ return 0 if i.nil?
254
+
255
+ (m << 5) + i
256
+ end
257
+ end
258
+
232
259
  # Rotates the AWS access keys
233
260
  #
234
261
  # @param [String] key The aws_access_key_id
@@ -6,7 +6,7 @@ require 'json'
6
6
  # Version const and query of latest.
7
7
  module Awskeyring
8
8
  # The Gem's version number
9
- VERSION = '1.11.0'
9
+ VERSION = '1.12.0'
10
10
  # The Gem's homepage
11
11
  HOMEPAGE = 'https://github.com/tristanmorgan/awskeyring'
12
12
 
data/lib/awskeyring.rb CHANGED
@@ -4,6 +4,7 @@ require 'i18n'
4
4
  require 'json'
5
5
  require 'keychain'
6
6
  require 'awskeyring/validate'
7
+ require 'awskeyring/awsapi'
7
8
 
8
9
  # Awskeyring Module,
9
10
  # gives you an interface to access keychains and items.
@@ -195,6 +196,19 @@ module Awskeyring # rubocop:disable Metrics/ModuleLength
195
196
  (items + tokens).uniq.sort
196
197
  end
197
198
 
199
+ # Return a list account item names plus account ids
200
+ def self.list_account_names_plus # rubocop:disable Metrics/AbcSize
201
+ list_items.concat(list_tokens).map do |elem|
202
+ account_id = Awskeyring::Awsapi.get_account_id(key: elem.attributes[:account])
203
+ account_name = if elem.attributes[:label].start_with?(ACCOUNT_PREFIX)
204
+ elem.attributes[:label][(ACCOUNT_PREFIX.length)..]
205
+ else
206
+ elem.attributes[:label][(SESSION_KEY_PREFIX.length)..]
207
+ end
208
+ "#{account_name}\t#{account_id}"
209
+ end.uniq.sort
210
+ end
211
+
198
212
  # Return a list role item names
199
213
  def self.list_role_names
200
214
  list_roles.map { |elem| elem.attributes[:label][(ROLE_PREFIX.length)..] }.sort
@@ -77,13 +77,18 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
77
77
  end
78
78
 
79
79
  desc 'list', I18n.t('list_desc')
80
+ method_option :detail, type: :boolean, aliases: '-d', desc: I18n.t('method_option.detail'), default: false
80
81
  # list the accounts
81
82
  def list
82
83
  if Awskeyring.list_account_names.empty?
83
84
  warn I18n.t('message.missing_account', bin: File.basename($PROGRAM_NAME))
84
85
  exit 1
85
86
  end
86
- puts Awskeyring.list_account_names.join("\n")
87
+ if options[:detail]
88
+ puts Awskeyring.list_account_names_plus.join("\n")
89
+ else
90
+ puts Awskeyring.list_account_names.join("\n")
91
+ end
87
92
  end
88
93
 
89
94
  desc 'list-role', I18n.t('list_role_desc')
@@ -198,7 +203,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
198
203
  Process.wait pid
199
204
  exit 1 if Process.last_status.exitstatus.positive?
200
205
  rescue Errno::ENOENT => e
201
- warn e.to_s
206
+ warn e
202
207
  exit 1
203
208
  end
204
209
  end
@@ -330,7 +335,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
330
335
  key_message: I18n.t('message.rotate', account: account)
331
336
  )
332
337
  rescue Aws::Errors::ServiceError => e
333
- warn e.to_s
338
+ warn e
334
339
  exit 1
335
340
  end
336
341
 
@@ -426,6 +431,16 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
426
431
  end
427
432
  end
428
433
 
434
+ desc 'decode KEY', I18n.t('decode_desc'), hide: true
435
+ # decode account numbers
436
+ def decode(key = nil)
437
+ key = ask_check(
438
+ existing: key, message: I18n.t('message.key'), validator: Awskeyring::Validate.method(:access_key)
439
+ )
440
+
441
+ puts Awskeyring::Awsapi.get_account_id(key: key)
442
+ end
443
+
429
444
  desc "#{File.basename($PROGRAM_NAME)} CURR PREV", I18n.t('awskeyring_desc'), hide: true
430
445
  map File.basename($PROGRAM_NAME) => :autocomplete
431
446
  # autocomplete
@@ -522,7 +537,7 @@ class AwskeyringCommand < Thor # rubocop:disable Metrics/ClassLength
522
537
  # list command names
523
538
  def list_commands
524
539
  commands = self.class.all_commands.keys.map { |elem| elem.tr('_', '-') }
525
- commands.reject! { |elem| %w[autocomplete default].include?(elem) }
540
+ commands.reject! { |elem| %w[autocomplete default decode].include?(elem) }
526
541
  end
527
542
 
528
543
  # list flags for a command
data/man/awskeyring.5 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "AWSKEYRING" "5" "February 2023" "" ""
4
+ .TH "AWSKEYRING" "5" "December 2023" "" ""
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBAwskeyring\fR \- is a small tool to manage AWS account keys in the macOS Keychain
@@ -159,6 +159,9 @@ list:
159
159
  .IP
160
160
  Prints a list of accounts in the keyring
161
161
  .
162
+ .IP
163
+ \-d, \-\-detail, \-\-no\-detail: Show more detail\.
164
+ .
162
165
  .TP
163
166
  list\-role:
164
167
  .
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: 1.11.0
4
+ version: 1.12.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: 2023-02-21 00:00:00.000000000 Z
11
+ date: 2023-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-sdk-iam
@@ -92,9 +92,9 @@ licenses:
92
92
  metadata:
93
93
  bug_tracker_uri: https://github.com/tristanmorgan/awskeyring/issues
94
94
  changelog_uri: https://github.com/tristanmorgan/awskeyring/blob/main/CHANGELOG.md
95
- documentation_uri: https://rubydoc.info/gems/awskeyring/1.11.0
95
+ documentation_uri: https://rubydoc.info/gems/awskeyring/1.12.0
96
96
  rubygems_mfa_required: 'true'
97
- source_code_uri: https://github.com/tristanmorgan/awskeyring/tree/v1.11.0
97
+ source_code_uri: https://github.com/tristanmorgan/awskeyring/tree/v1.12.0
98
98
  wiki_uri: https://github.com/tristanmorgan/awskeyring/wiki
99
99
  post_install_message:
100
100
  rdoc_options: []