Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RuboCop and Spec update #68

Merged
merged 2 commits into from
Aug 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ RSpec/ExampleLength:
Enabled: false

AllCops:
TargetRubyVersion: 2.6
Exclude:
- bin/*
2 changes: 2 additions & 0 deletions awskeyring.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ['lib']

spec.required_ruby_version = '>= 2.6.0'

spec.metadata = {
'bug_tracker_uri' => "#{Awskeyring::HOMEPAGE}/issues",
'changelog_uri' => "#{Awskeyring::HOMEPAGE}/blob/master/CHANGELOG.md",
Expand Down
10 changes: 5 additions & 5 deletions lib/awskeyring.rb
Original file line number Diff line number Diff line change
Expand Up @@ -174,26 +174,26 @@ def self.add_token(params = {})

# Return a list account item names
def self.list_account_names
items = list_items.map { |elem| elem.attributes[:label][(ACCOUNT_PREFIX.length)..-1] }
items = list_items.map { |elem| elem.attributes[:label][(ACCOUNT_PREFIX.length)..] }

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

(items + tokens).uniq.sort
end

# Return a list role item names
def self.list_role_names
list_roles.map { |elem| elem.attributes[:label][(ROLE_PREFIX.length)..-1] }.sort
list_roles.map { |elem| elem.attributes[:label][(ROLE_PREFIX.length)..] }.sort
end

# Return a list token item names
def self.list_token_names
list_tokens.map { |elem| elem.attributes[:label][(SESSION_KEY_PREFIX.length)..-1] }.sort
list_tokens.map { |elem| elem.attributes[:label][(SESSION_KEY_PREFIX.length)..] }.sort
end

# Return a list role item names and arns
def self.list_role_names_plus
list_roles.map { |elem| "#{elem.attributes[:label][(ROLE_PREFIX.length)..-1]}\t#{elem.attributes[:account]}" }
list_roles.map { |elem| "#{elem.attributes[:label][(ROLE_PREFIX.length)..]}\t#{elem.attributes[:account]}" }
end

# Return a list of console paths
Expand Down
6 changes: 3 additions & 3 deletions lib/awskeyring/awsapi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,9 @@ def self.get_login_url(key:, secret:, token:, path:, user:)
sessionToken: token
}.to_json

destination_param = '&Destination=' + CGI.escape(console_url)
destination_param = "&Destination=#{CGI.escape(console_url)}"

AWS_SIGNIN_URL + '?Action=login' + token_param(session_json: session_json) + destination_param
"#{AWS_SIGNIN_URL}?Action=login#{token_param(session_json: session_json)}#{destination_param}"
end

# Get the signin token param
Expand All @@ -214,7 +214,7 @@ def self.get_login_url(key:, secret:, token:, path:, user:)
returned_content = request.get(uri).body

signin_token = JSON.parse(returned_content)['SigninToken']
'&SigninToken=' + CGI.escape(signin_token)
"&SigninToken=#{CGI.escape(signin_token)}"
end

# Get the current region
Expand Down
14 changes: 7 additions & 7 deletions lib/awskeyring_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -539,23 +539,23 @@ def ask_missing(existing:, message:, secure: false, optional: false, limited_to:

def ask(message:, secure: false, optional: false, limited_to: nil)
if secure
Awskeyring::Input.read_secret(message.rjust(20) + ': ')
Awskeyring::Input.read_secret("#{message.rjust(20)}: ")
elsif optional
Thor::LineEditor.readline((message + ' (optional)').rjust(20) + ': ')
Thor::LineEditor.readline("#{"#{message} (optional)".rjust(20)}: ")
elsif limited_to
Thor::LineEditor.readline(message.rjust(20) + ': ', limited_to: limited_to)
Thor::LineEditor.readline("#{message.rjust(20)}: ", limited_to: limited_to)
else
Thor::LineEditor.readline(message.rjust(20) + ': ')
Thor::LineEditor.readline("#{message.rjust(20)}: ")
end
end

def unbundle
to_delete = ENV.keys.select { |elem| elem.start_with?('BUNDLER_ORIG_') }
bundled_env = to_delete.map { |elem| elem[('BUNDLER_ORIG_'.length)..-1] }
bundled_env = to_delete.map { |elem| elem[('BUNDLER_ORIG_'.length)..] }
to_delete << 'BUNDLE_GEMFILE'
bundled_env.each do |env_name|
ENV[env_name] = ENV['BUNDLER_ORIG_' + env_name]
to_delete << env_name if ENV['BUNDLER_ORIG_' + env_name].start_with? 'BUNDLER_'
ENV[env_name] = ENV["BUNDLER_ORIG_#{env_name}"]
to_delete << env_name if ENV["BUNDLER_ORIG_#{env_name}"].start_with? 'BUNDLER_'
end
to_delete.each do |env_name|
ENV.delete(env_name)
Expand Down
21 changes: 17 additions & 4 deletions spec/lib/awskeyring/input_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,27 @@
subject(:input) { described_class }

context 'when inputting a secret key' do
before do
allow(STDIN).to receive(:getch).and_return('A', 'B', 'C', '1', '2', '3', "\n")
end

it 'asks for a secret' do
allow($stdin).to receive(:getch).and_return('A', 'B', 'C', '1', '2', '3', "\n")
expect do
input.read_secret(' secret access key: ')
end.to output(" secret access key: ******\n").to_stdout
end

it 'asks for a secret and delete a few characters' do
allow($stdin).to receive(:getch)
.and_return('A', 'B', 'C', '1', 'm', 'i', 's', 's', "\b", "\b", "\b", "\b", '2', '3', "\n")
expect do
input.read_secret(' secret access key: ')
end.to output(" secret access key: ********\b\e[P\b\e[P\b\e[P\b\e[P**\n").to_stdout
end

it 'asks for a secret and canceled the operation' do
allow($stdin).to receive(:getch)
.and_return('A', 'B', 'C', '1', "\u0003")
expect do
input.read_secret(' secret access key: ')
end.to raise_error(SystemExit).and output(' secret access key: ****').to_stdout
end
end
end
53 changes: 35 additions & 18 deletions spec/lib/awskeyring_command_more_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,25 @@
allow(Awskeyring).to receive(:role_exists).and_return('role')
allow(Awskeyring).to receive(:list_account_names).and_return(['test'])
allow(Awskeyring).to receive(:list_role_names).and_return(['role'])
allow(Awskeyring::Awsapi).to receive(:verify_cred)
.and_return(true)
allow(Awskeyring::Awsapi).to receive(:get_credentials_from_file)
.and_return({
account: 'testaccount',
key: 'ASIAEXAMPLE',
secret: 'bigishLongSecret',
token: 'VeryveryVeryLongSecret',
expiry: Time.parse('2017-03-12T07:55:29Z'),
role: nil
})
end

it 'tries to import a valid token without remote tests' do
expect do
described_class.start(['import', 'testaccount', '-r'])
end.to output("# Token saved for account testaccount\n"\
"# Authentication valid until #{Time.at(1_489_305_329)}\n").to_stdout
expect(Awskeyring::Awsapi).not_to have_received(:verify_cred)
end

it 'tries to receive a new token' do
Expand Down Expand Up @@ -279,6 +298,14 @@
expect(Awskeyring::Awsapi).not_to have_received(:verify_cred)
end

it 'tries to import a valid account' do
expect do
described_class.start(%w[import testaccount])
end.to output("# Added account testaccount\n").to_stdout
expect(Awskeyring).to have_received(:add_account)
expect(Awskeyring::Awsapi).to have_received(:verify_cred)
end

it 'tries to import a valid account without remote tests' do
expect do
described_class.start(['import', 'testaccount', '-r'])
Expand Down Expand Up @@ -308,38 +335,28 @@
context 'when we try to add an AWS account and test an mfa' do
let(:access_key) { 'AKIA0123456789ABCDEF' }
let(:secret_access_key) { 'AbCkTEsTAAAi8ni0987ASDFwer23j14FEQW3IUJV' }
let(:mfa_arn) { 'arn:aws:iam::012345678901:mfa/readonly' }
let(:bad_mfa_arn) { 'arn:azure:iamnot::ABCD45678901:Administrators' }

before do
allow(Thor::LineEditor).to receive(:readline).and_return(bad_mfa_arn)
allow(Awskeyring).to receive(:account_not_exists).with('test').and_return('test')
allow(Awskeyring).to receive(:item_by_account).and_return(nil)
allow(Awskeyring).to receive(:add_account).and_return(nil)
allow(Awskeyring::Awsapi).to receive(:verify_cred)
.and_return(true)
allow(Awskeyring).to receive(:update_account)
end

it 'tries to add an invalid mfa' do
allow(Thor::LineEditor).to receive(:readline).and_return(bad_mfa_arn)
expect do
described_class.start(['add', 'test', '-k', access_key, '-s', secret_access_key, '-m', bad_mfa_arn])
end.to raise_error.and output(/Invalid MFA ARN/).to_stderr
end
end

context 'when we try to add an AWS account with white space' do
let(:access_key) { 'AKIA0123456789ABCDEF' }
let(:secret_access_key) { 'AbCkTEsTAAAi8ni0987ASDFwer23j14FEQW3IUJV' }
let(:mfa_arn) { 'arn:aws:iam::012345678901:mfa/readonly' }

before do
it 'tries to add an account with whitespace' do
allow(Thor::LineEditor).to receive(:readline).and_return(" #{access_key} \n")
allow(Awskeyring::Input).to receive(:read_secret).and_return(" #{secret_access_key} \t")
allow(Awskeyring).to receive(:item_by_account).and_return(nil)
allow(Awskeyring).to receive(:account_not_exists).with('test').and_return('test')
allow(Awskeyring).to receive(:add_account).and_return(nil)
allow(Awskeyring::Awsapi).to receive(:verify_cred)
.and_return(true)
allow(Awskeyring).to receive(:update_account)
end

it 'tries to add an account with whitespace' do
expect do
described_class.start(['add', 'test', '-m', mfa_arn])
end.to output("# Added account test\n").to_stdout
Expand All @@ -355,7 +372,6 @@

before do
allow(Awskeyring).to receive(:add_role).and_return(nil)
allow(Thor::LineEditor).to receive(:readline).and_return(bad_role_arn)
allow(Awskeyring).to receive(:item_by_account).and_return(nil)
allow(Awskeyring).to receive(:role_not_exists).and_return('readonly')
end
Expand All @@ -367,6 +383,7 @@
end

it 'tries to add an invalid role arn' do
allow(Thor::LineEditor).to receive(:readline).and_return(bad_role_arn)
expect do
described_class.start(['add-role', 'readonly', '-a', bad_role_arn])
end.to raise_error.and output(/Invalid Role ARN/).to_stderr
Expand Down
23 changes: 19 additions & 4 deletions spec/lib/awskeyring_command_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
allow(Awskeyring).to receive(:list_role_names_plus)
.and_return(%W[admin\tarn1 minion\tarn2 readonly\tarn3])
allow(Awskeyring).to receive(:list_console_path).and_return(%w[iam cloudformation vpc])
allow(Awskeyring).to receive(:prefs).and_return('{"awskeyring": "awskeyringtest"}')
end

it 'list keychain items' do
Expand All @@ -92,8 +93,8 @@
end

it 'lists roles with autocomplete' do
ENV['COMP_LINE'] = 'awskeyring token servian min'
expect { described_class.start(%w[awskeyring min servian]) }
ENV['COMP_LINE'] = 'awskeyring remove-role min'
expect { described_class.start(%w[awskeyring min remove-role]) }
.to output("minion\n").to_stdout
ENV['COMP_LINE'] = nil
end
Expand All @@ -105,6 +106,13 @@
ENV['COMP_LINE'] = nil
end

it 'lists commands with autocomplete for help' do
ENV['COMP_LINE'] = 'awskeyring help con'
expect { described_class.start(%w[awskeyring con help]) }
.to output("console\n").to_stdout
ENV['COMP_LINE'] = nil
end

it 'lists flags with autocomplete' do
ENV['COMP_LINE'] = 'awskeyring token servian minion --dura'
expect { described_class.start(%w[awskeyring --dura minion]) }
Expand All @@ -125,6 +133,13 @@
.to output("servian\n").to_stdout
ENV['COMP_LINE'] = nil
end

it 'doesnt try to re-initialises the keychain' do
expect do
described_class.start(%w[initialise])
end.to raise_error(SystemExit)
.and output(%r{# .+/\.awskeyring exists\. no need to initialise\.\n}).to_stdout
end
end

context 'when there is an account and a role' do
Expand Down Expand Up @@ -268,13 +283,13 @@

it 'provides JSON for use with credential_process' do
expect { described_class.start(%w[json test]) }
.to output(JSON.pretty_generate(
.to output("#{JSON.pretty_generate(
Version: 1,
AccessKeyId: 'ASIATESTTEST',
SecretAccessKey: 'bigerlongbase64',
SessionToken: 'evenlongerbase64token',
Expiration: Time.at(Time.parse('2011-07-11T19:55:29.611Z').to_i).iso8601
) + "\n").to_stdout
)}\n").to_stdout
expect(Awskeyring).to have_received(:account_exists).with('test')
expect(Awskeyring).to have_received(:get_valid_creds).with(account: 'test', no_token: false)
end
Expand Down