Add access_keys method to aws_iam_user (#44)

* Add access_keys method to aws_iam_user

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Fix unit test that accessed AWS

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Incorporate PR feedback

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Fix unit tests

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Update tests based on PR feedback

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>

* Rebase to master

Signed-off-by: Chris Redekop <chris.redekop@d2l.com>
This commit is contained in:
Chris Redekop 2017-06-13 01:36:43 -04:00 committed by Christoph Hartmann
parent faa2840c1f
commit 15459ca295
8 changed files with 123 additions and 26 deletions

View file

@ -12,7 +12,10 @@ class AwsIamAccessKey < Inspec.resource(1)
"
def initialize(opts, decorator = IamClientDecorator.new)
@opts = opts
@access_key = opts[:access_key]
@username = opts[:username]
@id = @access_key ? @access_key.access_key_id : opts[:id]
@decorator = decorator
end
@ -39,7 +42,7 @@ class AwsIamAccessKey < Inspec.resource(1)
end
def to_s
"IAM Access-Key #{@opts[:id]}"
"IAM Access-Key #{@id}"
end
class AccessKeyNotFoundError < StandardError
@ -92,10 +95,10 @@ class AwsIamAccessKey < Inspec.resource(1)
private
def access_key
@access_key ||= @decorator.get_access_key(@opts[:username], @opts[:id])
@access_key ||= @decorator.get_access_key(@username, @id)
end
def access_key_last_used
@access_key_last_used ||= @decorator.get_access_key_last_used(@opts[:id])
@access_key_last_used ||= @decorator.get_access_key_last_used(@id)
end
end

View file

@ -1,6 +1,8 @@
# author: Alex Bedley
# author: Steffanie Freeman
# author: Simon Varlow
# author: Chris Redekop
class AwsIamUser < Inspec.resource(1)
name 'aws_iam_user'
desc 'Verifies settings for AWS IAM user'
@ -10,9 +12,12 @@ class AwsIamUser < Inspec.resource(1)
its('has_console_password?') { should be true }
end
"
def initialize(name, aws_user_provider = AwsIam::UserProvider.new)
def initialize(name, aws_user_provider = AwsIam::UserProvider.new,
access_key_factory = AwsIamAccessKeyFactory.new)
@name = name
@user = aws_user_provider.user(name)
@access_key_factory = access_key_factory
end
def has_mfa_enabled?
@ -22,4 +27,16 @@ class AwsIamUser < Inspec.resource(1)
def has_console_password?
@user[:has_console_password?]
end
def access_keys
@user[:access_keys].map { |access_key|
@access_key_factory.create_access_key(access_key)
}
end
class AwsIamAccessKeyFactory
def create_access_key(access_key)
AwsIamAccessKey.new({ access_key: access_key })
end
end
end

View file

@ -30,10 +30,15 @@ module AwsIam
return false
end
def access_keys(aws_user)
aws_user.access_keys
end
def convert(aws_user)
{
has_mfa_enabled?: has_mfa_enabled?(aws_user),
has_console_password?: has_console_password?(aws_user),
access_keys: access_keys(aws_user),
}
end
end

View file

@ -19,11 +19,20 @@ resource "aws_iam_user" "console_password_enabled_user" {
force_destroy = true
}
resource "aws_iam_user_login_profile" "u" {
resource "aws_iam_user_login_profile" "user_login_profile" {
user = "${aws_iam_user.console_password_enabled_user.name}"
pgp_key = "${var.login_profile_pgp_key}"
}
resource "aws_iam_user" "access_key_user" {
name = "${terraform.env}.access_key_user"
}
resource "aws_iam_access_key" "access_key" {
user = "${aws_iam_user.access_key_user.name}"
pgp_key = "${var.login_profile_pgp_key}"
}
output "mfa_not_enabled_user" {
value = "${aws_iam_user.mfa_not_enabled_user.name}"
}
@ -32,6 +41,10 @@ output "console_password_enabled_user" {
value = "${aws_iam_user.console_password_enabled_user.name}"
}
output "access_key_user" {
value = "${aws_iam_user.access_key_user.name}"
}
output "example_ec2_name" {
value = "${aws_instance.example.tags.Name}"
}

View file

@ -8,11 +8,22 @@ console_password_enabled_user = attribute(
default: 'default.console_password_enabled_user',
description: 'Name of IAM user console_password_enabled_user')
access_key_user = attribute(
'access_key_user',
default: 'default.access_key_user',
description: 'Name of IAM user access_key_user')
describe aws_iam_user(mfa_not_enabled_user) do
its('has_mfa_enabled?') { should be false }
its('has_console_password?') { should be false }
it { should_not have_mfa_enabled }
it { should_not have_console_password }
end
describe aws_iam_user(console_password_enabled_user) do
its('has_console_password?') { should be true }
it { should have_console_password }
end
aws_iam_user(access_key_user).access_keys.each { |access_key|
describe access_key do
it { should be_active }
end
}

View file

@ -32,6 +32,32 @@ class AwsIamAccessKeyTest < Minitest::Test
include AccessKeyFactory
def test_initialize_accepts_fields
assert_equal(
Id,
AwsIamAccessKey.new({id: Id, username: Username}, nil)
.instance_variable_get('@id')
);
end
def test_initialize_accepts_access_key
assert_equal(
Id,
AwsIamAccessKey.new({access_key: OpenStruct.new(access_key_id: Id)}, nil)
.instance_variable_get('@id')
);
end
def test_initialize_prefers_access_key
assert_equal(
Id,
AwsIamAccessKey.new({
id: 'foo',
access_key: OpenStruct.new(access_key_id: Id)
}, nil).instance_variable_get('@id')
);
end
def test_exists_returns_true_when_access_key_exists
assert aws_iam_access_key.exists?
end

View file

@ -24,7 +24,7 @@ class AwsIamUserProviderTest < Minitest::Test
def test_list_users
@mock_iam_resource.expect :users, [create_mock_user, create_mock_user, create_mock_user]
mock_user_output = {has_mfa_enabled?: true, has_console_password?: true}
mock_user_output = {has_mfa_enabled?: true, has_console_password?: true, access_keys: []}
assert @user_provider.list_users == [mock_user_output, mock_user_output, mock_user_output]
end
@ -67,27 +67,35 @@ class AwsIamUserProviderTest < Minitest::Test
end
end
def test_access_keys_returns_access_keys
access_key = Object.new
@mock_iam_resource.expect :user, create_mock_user(access_keys: [access_key]), [Username]
assert_equal [access_key], @user_provider.user(Username)[:access_keys]
end
private
def create_mock_user(has_console_password: true, has_mfa_enabled: true)
mock_user = Minitest::Mock.new
def create_mock_user(has_console_password: true, has_mfa_enabled: true, access_keys: [])
mock_login_profile = Minitest::Mock.new
mock_user.expect :mfa_devices, has_mfa_enabled ? ['device'] : []
mock_login_profile.expect :create_date, has_console_password ? 'date' : nil
mock_user = Minitest::Mock.new
mock_user.expect :mfa_devices, has_mfa_enabled ? ['device'] : []
mock_user.expect :login_profile, mock_login_profile
mock_user.expect :access_keys, access_keys
end
def create_mock_user_throw(exception)
mock_user = Minitest::Mock.new
mock_login_profile = Minitest::Mock.new
mock_user.expect :mfa_devices, []
mock_login_profile.expect :create_date, nil do |args|
raise exception
end
mock_user = Minitest::Mock.new
mock_user.expect :mfa_devices, []
mock_user.expect :login_profile, mock_login_profile
mock_user.expect :access_keys, []
end
end

View file

@ -18,7 +18,7 @@ Username = "test"
def test_that_MFA_enable_returns_false_if_MFA_is_not_Enabled
@mock_user_provider.expect :user, {has_mfa_enabled?: false}, [Username]
assert !AwsIamUser.new(Username, @mock_user_provider).has_mfa_enabled?
refute AwsIamUser.new(Username, @mock_user_provider).has_mfa_enabled?
end
def test_that_console_Password_returns_true_if_console_Password_has_been_set
@ -28,6 +28,20 @@ Username = "test"
def test_that_console_Password_returns_false_if_console_Password_has_not_been_set
@mock_user_provider.expect :user, {has_console_password?: false}, [Username]
assert !AwsIamUser.new(Username, @mock_user_provider).has_console_password?
refute AwsIamUser.new(Username, @mock_user_provider).has_console_password?
end
def test_that_access_keys_returns_aws_iam_access_key_resources
stub_aws_access_key = Object.new
stub_access_key_resource = Object.new
mock_access_key_factory = Minitest::Mock.new
@mock_user_provider.expect :user, {access_keys: [stub_aws_access_key]}, [Username]
mock_access_key_factory.expect :create_access_key, stub_access_key_resource, [stub_aws_access_key]
assert_equal(stub_access_key_resource,
AwsIamUser.new(Username, @mock_user_provider, mock_access_key_factory).access_keys[0])
mock_access_key_factory.verify
end
end