From 7189d019dfa326978ea4d8006355d1f5ba302c4f Mon Sep 17 00:00:00 2001 From: martynaspaulikas Date: Tue, 27 Nov 2018 11:28:09 +0000 Subject: [PATCH] Implemented get_access_key_last_used Written test that still does not work due to: ParamValidationError: Parameter validation failed: Unknown parameter in input: "UserName", must be one of: AccessKeyId Refactored update_access_key and delete_access_key functions --- IMPLEMENTATION_COVERAGE.md | 2 +- moto/iam/models.py | 32 ++++++++++++++++++++++---------- moto/iam/responses.py | 7 +++++++ tests/test_iam/test_iam.py | 13 +++++++++++++ 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index 7c68c0e31..e3bac1918 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -2257,7 +2257,7 @@ - [X] detach_user_policy - [X] enable_mfa_device - [ ] generate_credential_report -- [ ] get_access_key_last_used +- [X] get_access_key_last_used - [X] get_account_authorization_details - [ ] get_account_password_policy - [ ] get_account_summary diff --git a/moto/iam/models.py b/moto/iam/models.py index 4a5240a08..32e1ea5ee 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -224,6 +224,10 @@ class AccessKey(BaseModel): datetime.utcnow(), "%Y-%m-%dT%H:%M:%SZ" ) + self.last_used = datetime.strftime( + datetime.utcnow(), + "%Y-%m-%dT%H:%M:%SZ" + ) def get_cfn_attribute(self, attribute_name): from moto.cloudformation.exceptions import UnformattedGetAttTemplateException @@ -351,22 +355,25 @@ class User(BaseModel): def get_all_access_keys(self): return self.access_keys + def get_access_key_last_used(self, access_key_id): + key = self.get_access_key_by_id(access_key_id) + return key.last_used + def delete_access_key(self, access_key_id): - for key in self.access_keys: - if key.access_key_id == access_key_id: - self.access_keys.remove(key) - break - else: - raise IAMNotFoundException( - "Key {0} not found".format(access_key_id)) + key = self.get_access_key_by_id(access_key_id) + self.access_keys.remove(key) def update_access_key(self, access_key_id, status): + key = self.get_access_key_by_id(access_key_id) + key.status = status + + def get_access_key_by_id(self, access_key_id): for key in self.access_keys: if key.access_key_id == access_key_id: - key.status = status - break + return key else: - raise IAMNotFoundException("The Access Key with id {0} cannot be found".format(access_key_id)) + raise IAMNotFoundException( + "The Access Key with id {0} cannot be found".format(access_key_id)) def get_cfn_attribute(self, attribute_name): from moto.cloudformation.exceptions import UnformattedGetAttTemplateException @@ -838,6 +845,11 @@ class IAMBackend(BaseBackend): user = self.get_user(user_name) user.update_access_key(access_key_id, status) + def get_access_key_last_used(self, user_name, access_key_id): + user = self.get_user(user_name) + last_used = user.get_access_key_last_used(access_key_id) + return last_used + def get_all_access_keys(self, user_name, marker=None, max_items=None): user = self.get_user(user_name) keys = user.get_all_access_keys() diff --git a/moto/iam/responses.py b/moto/iam/responses.py index 22558f3f6..c3c6f8f8a 100644 --- a/moto/iam/responses.py +++ b/moto/iam/responses.py @@ -454,6 +454,13 @@ class IamResponse(BaseResponse): template = self.response_template(GENERIC_EMPTY_TEMPLATE) return template.render(name='UpdateAccessKey') + def get_access_key_last_used(self): + user_name = self._get_param('UserName') + access_key_id = self._get_param('AccessKeyId') + iam_backend.get_access_key_last_used(user_name, access_key_id) + template = self.response_template(GENERIC_EMPTY_TEMPLATE) + return template.render(name='GetAccessKeyLastUsed') + def list_access_keys(self): user_name = self._get_param('UserName') diff --git a/tests/test_iam/test_iam.py b/tests/test_iam/test_iam.py index bc23ff712..343d42b3a 100644 --- a/tests/test_iam/test_iam.py +++ b/tests/test_iam/test_iam.py @@ -695,6 +695,19 @@ def test_update_access_key(): resp['AccessKeyMetadata'][0]['Status'].should.equal('Inactive') +@mock_iam +def test_get_access_key_last_used(): + iam = boto3.resource('iam', region_name='us-east-1') + client = iam.meta.client + username = 'test-user' + iam.create_user(UserName=username) + with assert_raises(ClientError): + client.get_access_key_last_used(UserName=username, AccessKeyId='non-existent-key') + key = client.create_access_key(UserName=username)['AccessKey'] + resp = client.get_access_key_last_used(UserName=username, AccessKeyId=key['AccessKeyId']) + resp.should.equal(key.last_used) + + @mock_iam def test_get_account_authorization_details(): import json