module Awskeyring

Awskeyring Module, gives you an interface to access keychains and items.

Awskeyring Module, gives you an interface to access keychains and items.

Awskeyring Module,

Awskeyring Module, gives you an interface to access keychains and items.

Awskeyring Module, Version const and query of latest.

Constants

ACCOUNT_PREFIX

Prefix for Accounts

DEFAULT_BROWSER_LIST

Default Browsers

DEFAULT_CONSOLE_LIST

Default Console Paths

DEFAULT_KEY_AGE

Default warning of key age in days.

FIVE_MINUTES

Default keychain Lock period

GEM_VERSION_URL

RubyGems Version url

HOMEPAGE

The Gem's homepage

PREFS_FILE

Default rpeferences fole path

ROLE_PREFIX

Prefix for Roles

SESSION_KEY_PREFIX

Prefix for Session Keys

SESSION_TOKEN_PREFIX

Prefix for Session Tokens

VERSION

The Gem's version number

Public Class Methods

access_key_not_exists(access_key) click to toggle source

Validate access key does not exists

@param [String] access_key the associated access key.

# File lib/awskeyring.rb, line 349
def self.access_key_not_exists(access_key)
  Awskeyring::Validate.access_key(access_key)
  raise 'Access KEY already exists' if item_by_account(access_key)

  access_key
end
account_exists(account_name) click to toggle source

Validate account exists

@param [String] account_name the associated account name.

# File lib/awskeyring.rb, line 329
def self.account_exists(account_name)
  Awskeyring::Validate.account_name(account_name)
  raise 'Account does not exist' unless (account_name = solo_select(list_account_names, account_name))

  account_name
end
account_not_exists(account_name) click to toggle source

Validate account does not exists

@param [String] account_name the associated account name.

# File lib/awskeyring.rb, line 339
def self.account_not_exists(account_name)
  Awskeyring::Validate.account_name(account_name)
  raise 'Account already exists' if list_account_names.include?(account_name)

  account_name
end
add_account(account:, key:, secret:, mfa:) click to toggle source

Add an account item

@param [String] account The account name to create @param [String] key The aws_access_key_id @param [String] secret The aws_secret_key @param [String] mfa The arn of the MFA device

# File lib/awskeyring.rb, line 117
def self.add_account(account:, key:, secret:, mfa:)
  all_items.create(
    label: ACCOUNT_PREFIX + account,
    account: key,
    password: secret,
    comment: mfa
  )
end
add_role(role:, arn:) click to toggle source

Add a Role item

@param [String] role The role name to add @param [String] arn The arn of the role

# File lib/awskeyring.rb, line 142
def self.add_role(role:, arn:)
  all_items.create(
    label: ROLE_PREFIX + role,
    account: arn,
    password: '',
    comment: ''
  )
end
add_token(params = {}) click to toggle source

add a session token pair of items

@param [Hash] params including

account The name of the accont
key The aws_access_key_id
secret The aws_secret_access_key
token The aws_sesson_token
expiry time of expiry
role The role used
# File lib/awskeyring.rb, line 160
def self.add_token(params = {})
  all_items.create(label: SESSION_KEY_PREFIX + params[:account],
                   account: params[:key],
                   password: params[:secret],
                   comment: params[:role].nil? ? '' : ROLE_PREFIX + params[:role])
  all_items.create(label: SESSION_TOKEN_PREFIX + params[:account],
                   account: params[:expiry],
                   password: params[:token],
                   comment: params[:role] || '')
end
delete_account(account:, message:) click to toggle source

Delete an Account

@param [String] account The account to delete @param [String] message The message to display

# File lib/awskeyring.rb, line 305
def self.delete_account(account:, message:)
  delete_token(account: account, message: I18n.t('message.delexpired'))
  cred = get_item(account: account)
  return unless cred

  puts message if message
  cred.delete
end
delete_role(role_name:, message:) click to toggle source

Delete a role

@param [String] role_name The role to delete @param [String] message The message to display

# File lib/awskeyring.rb, line 318
def self.delete_role(role_name:, message:)
  role = get_role(role_name: role_name)
  return unless role

  puts message if message
  role.delete
end
delete_token(account:, message:) click to toggle source

Delete a session token

@param [String] account The account to delete a token for @param [String] message The message to display

# File lib/awskeyring.rb, line 296
def self.delete_token(account:, message:)
  session_key, session_token = get_token_pair(account: account)
  delete_pair(key: session_key, token: session_token, message: message)
end
get_role_arn(role_name:) click to toggle source

get the ARN for a role

@param [String] role_name The role name to retrieve

# File lib/awskeyring.rb, line 267
def self.get_role_arn(role_name:)
  role_item = get_role(role_name: role_name)
  role_item.attributes[:account] if role_item
end
get_valid_creds(account:, no_token: false) click to toggle source

Return valid creds for account

@param [String] account The account to retrieve @param [Boolean] no_token Flag to skip tokens

# File lib/awskeyring.rb, line 249
def self.get_valid_creds(account:, no_token: false)
  cred, temp_cred = get_valid_item_pair(account: account, no_token: no_token)
  token = temp_cred.password unless temp_cred.nil?
  expiry = temp_cred.attributes[:account].to_i unless temp_cred.nil?
  {
    account: account,
    expiry: expiry,
    key: cred.attributes[:account],
    mfa: no_token ? cred.attributes[:comment] : nil,
    secret: cred.password,
    token: token,
    updated: cred.attributes[:updated_at]
  }
end
init_keychain(awskeyring:) click to toggle source

Create a new Keychain

@param [String] awskeyring The keychain name to create

# File lib/awskeyring.rb, line 47
def self.init_keychain(awskeyring:)
  keychain = Keychain.create(awskeyring)
  keychain.lock_interval = FIVE_MINUTES
  keychain.lock_on_sleep = true

  prefs = {
    awskeyring: awskeyring,
    keyage: DEFAULT_KEY_AGE,
    console: DEFAULT_CONSOLE_LIST
  }
  File.new(Awskeyring::PREFS_FILE, 'w').write JSON.dump(prefs)
end
key_age() click to toggle source

Return Key age warning number

# File lib/awskeyring.rb, line 223
def self.key_age
  prefs.key?('keyage') ? prefs['keyage'] : DEFAULT_KEY_AGE
end
latest_version() click to toggle source

Retrieve the latest version from RubyGems

# File lib/awskeyring/version.rb, line 18
def self.latest_version
  uri       = URI(GEM_VERSION_URL)
  request   = Net::HTTP.new(uri.host, uri.port)
  request.use_ssl = true
  JSON.parse(request.get(uri).body)['version']
end
list_account_names() click to toggle source

Return a list account item names

# File lib/awskeyring.rb, line 189
def self.list_account_names
  items = list_items.map { |elem| elem.attributes[:label][(ACCOUNT_PREFIX.length)..] }

  tokens = list_tokens.map { |elem| elem.attributes[:label][(SESSION_KEY_PREFIX.length)..] }

  (items + tokens).uniq.sort
end
list_browsers() click to toggle source

Return a list of browserss

# File lib/awskeyring.rb, line 218
def self.list_browsers
  prefs.key?('browser') ? prefs['browser'] : DEFAULT_BROWSER_LIST
end
list_console_path() click to toggle source

Return a list of console paths

# File lib/awskeyring.rb, line 213
def self.list_console_path
  prefs.key?('console') ? prefs['console'] : DEFAULT_CONSOLE_LIST
end
list_role_names() click to toggle source

Return a list role item names

# File lib/awskeyring.rb, line 198
def self.list_role_names
  list_roles.map { |elem| elem.attributes[:label][(ROLE_PREFIX.length)..] }.sort
end
list_role_names_plus() click to toggle source

Return a list role item names and arns

# File lib/awskeyring.rb, line 208
def self.list_role_names_plus
  list_roles.map { |elem| "#{elem.attributes[:label][(ROLE_PREFIX.length)..]}\t#{elem.attributes[:account]}" }
end
list_token_names() click to toggle source

Return a list token item names

# File lib/awskeyring.rb, line 203
def self.list_token_names
  list_tokens.map { |elem| elem.attributes[:label][(SESSION_KEY_PREFIX.length)..] }.sort
end
prefs() click to toggle source

Retrieve the preferences

@return [Hash] prefs of the gem

# File lib/awskeyring.rb, line 36
def self.prefs
  if File.exist? PREFS_FILE
    JSON.parse(File.read(PREFS_FILE))
  else
    {}
  end
end
role_arn_not_exists(role_arn) click to toggle source

Validate role arn not exists

@param [String] role_arn the associated role arn.

# File lib/awskeyring.rb, line 389
def self.role_arn_not_exists(role_arn)
  Awskeyring::Validate.role_arn(role_arn)
  raise 'Role ARN already exists' if item_by_account(role_arn)

  role_arn
end
role_exists(role_name) click to toggle source

Validate role exists

@param [String] role_name the associated role name.

# File lib/awskeyring.rb, line 359
def self.role_exists(role_name)
  Awskeyring::Validate.role_name(role_name)
  raise 'Role does not exist' unless (role_name = solo_select(list_role_names, role_name))

  role_name
end
role_not_exists(role_name) click to toggle source

Validate role does not exists

@param [String] role_name the associated role name.

# File lib/awskeyring.rb, line 369
def self.role_not_exists(role_name)
  Awskeyring::Validate.role_name(role_name)
  raise 'Role already exists' if list_role_names.include?(role_name)

  role_name
end
solo_select(list, prefix) click to toggle source

return item that matches a prefix if only one.

# File lib/awskeyring.rb, line 101
def self.solo_select(list, prefix)
  return prefix if list.include?(prefix)

  list.select! { |elem| elem.start_with?(prefix) }

  return list.first if list.length == 1

  nil
end
token_exists(token_name) click to toggle source

Validate token exists

@param [String] token_name the associated account name.

# File lib/awskeyring.rb, line 379
def self.token_exists(token_name)
  Awskeyring::Validate.account_name(token_name)
  raise 'Token does not exist' unless (token_name = solo_select(list_token_names, token_name))

  token_name
end
update_account(account:, key:, secret:) click to toggle source

update and account item

@param [String] account The account to update @param [String] key The aws_access_key_id @param [String] secret The aws_secret_key

# File lib/awskeyring.rb, line 131
def self.update_account(account:, key:, secret:)
  item = get_item(account: account)
  item.attributes[:account] = key
  item.password = secret
  item.save!
end

Private Class Methods

all_items() click to toggle source

Return all keychain items

# File lib/awskeyring.rb, line 91
                     def self.all_items
  load_keychain.generic_passwords
end
delete_expired(key:, token:) click to toggle source

Delete session token items if expired

# File lib/awskeyring.rb, line 273
                     def self.delete_expired(key:, token:)
  expires_at = Time.at(token.attributes[:account].to_i)
  if expires_at < Time.new
    delete_pair(key: key, token: token, message: I18n.t('message.delexpired'))
    key = nil
    token = nil
  end
  [key, token]
end
delete_pair(key:, token:, message:) click to toggle source

Delete session token items

# File lib/awskeyring.rb, line 284
                     def self.delete_pair(key:, token:, message:)
  return unless key

  puts message if message
  token.delete if token
  key.delete
end
get_item(account:) click to toggle source

Return an account item by name

# File lib/awskeyring.rb, line 172
                     def self.get_item(account:)
  all_items.where(label: ACCOUNT_PREFIX + account).first
end
get_role(role_name:) click to toggle source

Return a role item by name

# File lib/awskeyring.rb, line 177
                     def self.get_role(role_name:)
  all_items.where(label: ROLE_PREFIX + role_name).first
end
get_token_pair(account:) click to toggle source

Return a session token pair of items by name

# File lib/awskeyring.rb, line 182
                     def self.get_token_pair(account:)
  session_key = all_items.where(label: SESSION_KEY_PREFIX + account).first
  session_token = all_items.where(label: SESSION_TOKEN_PREFIX + account).first if session_key
  [session_key, session_token]
end
get_valid_item_pair(account:, no_token: false) click to toggle source

Return a session token if available or a static key

# File lib/awskeyring.rb, line 228
                     def self.get_valid_item_pair(account:, no_token: false)
  session_key, session_token = get_token_pair(account: account)
  session_key, session_token = delete_expired(key: session_key, token: session_token) if session_key

  if session_key && session_token && !no_token
    puts I18n.t('message.temporary')
    return session_key, session_token
  end

  item = get_item(account: account)
  if item.nil?
    warn I18n.t('message.notfound', account: account)
    exit 2
  end
  [item, nil]
end
item_by_account(account) click to toggle source

return an item by accout

# File lib/awskeyring.rb, line 96
                     def self.item_by_account(account)
  all_items.where(account: account).first
end
list_items() click to toggle source

Return a list of all acount items

# File lib/awskeyring.rb, line 76
                     def self.list_items
  all_items.all.select { |elem| elem.attributes[:label].start_with?(ACCOUNT_PREFIX) }
end
list_roles() click to toggle source

Return a list of all role items

# File lib/awskeyring.rb, line 81
                     def self.list_roles
  all_items.all.select { |elem| elem.attributes[:label].start_with?(ROLE_PREFIX) }
end
list_tokens() click to toggle source

Return a list of all acount items

# File lib/awskeyring.rb, line 86
                     def self.list_tokens
  all_items.all.select { |elem| elem.attributes[:label].start_with?(SESSION_KEY_PREFIX) }
end
load_keychain() click to toggle source

Load the keychain for access

@return [Keychain] keychain ready for use.

# File lib/awskeyring.rb, line 63
                     def self.load_keychain
  unless File.exist?(Awskeyring::PREFS_FILE) && !prefs.empty?
    warn I18n.t('message.missing', bin: File.basename($PROGRAM_NAME))
    exit 1
  end

  keychain = Keychain.open(prefs['awskeyring'])
  warn I18n.t('message.timeout') if keychain && keychain.lock_interval > FIVE_MINUTES

  keychain
end