diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index 3bea66408..e91376eda 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -3227,7 +3227,7 @@ - [X] get_group_policy - [X] get_instance_profile - [X] get_login_profile -- [ ] get_open_id_connect_provider +- [X] get_open_id_connect_provider - [ ] get_organizations_access_report - [X] get_policy - [X] get_policy_version diff --git a/moto/iam/models.py b/moto/iam/models.py index 2a7d185a5..b95c37df7 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -104,11 +104,16 @@ class OpenIDConnectProvider(BaseModel): self.url = parsed_url.netloc + parsed_url.path self.thumbprint_list = thumbprint_list self.client_id_list = client_id_list + self.create_date = datetime.utcnow() @property def arn(self): return 'arn:aws:iam::{0}:oidc-provider/{1}'.format(ACCOUNT_ID, self.url) + @property + def created_iso_8601(self): + return iso_8601_datetime_without_milliseconds(self.create_date) + def _validate(self, url, thumbprint_list, client_id_list): if any(len(client_id) > 255 for client_id in client_id_list): self._errors.append(self._format_error( @@ -1347,5 +1352,13 @@ class IAMBackend(BaseBackend): self.open_id_providers[open_id_provider.arn] = open_id_provider return open_id_provider + def get_open_id_connect_provider(self, arn): + open_id_provider = self.open_id_providers.get(arn) + + if not open_id_provider: + raise IAMNotFoundException('OpenIDConnect Provider not found for arn {}'.format(arn)) + + return open_id_provider + iam_backend = IAMBackend() diff --git a/moto/iam/responses.py b/moto/iam/responses.py index a4ed38666..06ad7b7ce 100644 --- a/moto/iam/responses.py +++ b/moto/iam/responses.py @@ -759,11 +759,20 @@ class IamResponse(BaseResponse): open_id_provider_url = self._get_param('Url') thumbprint_list = self._get_multi_param('ThumbprintList.member') client_id_list = self._get_multi_param('ClientIDList.member') + open_id_provider = iam_backend.create_open_id_connect_provider(open_id_provider_url, thumbprint_list, client_id_list) template = self.response_template(CREATE_OPEN_ID_CONNECT_PROVIDER_TEMPLATE) return template.render(open_id_provider=open_id_provider) + def get_open_id_connect_provider(self): + open_id_provider_arn = self._get_param('OpenIDConnectProviderArn') + + open_id_provider = iam_backend.get_open_id_connect_provider(open_id_provider_arn) + + template = self.response_template(GET_OPEN_ID_CONNECT_PROVIDER_TEMPLATE) + return template.render(open_id_provider=open_id_provider) + LIST_ENTITIES_FOR_POLICY_TEMPLATE = """ @@ -1993,3 +2002,24 @@ CREATE_OPEN_ID_CONNECT_PROVIDER_TEMPLATE = """f248366a-4f64-11e4-aefa-bfd6aEXAMPLE """ + + +GET_OPEN_ID_CONNECT_PROVIDER_TEMPLATE = """ + + + {% for thumbprint in open_id_provider.thumbprint_list %} + {{ thumbprint }} + {% endfor %} + + {{ open_id_provider.created_iso_8601 }} + + {% for client_id in open_id_provider.client_id_list %} + {{ client_id }} + {% endfor %} + + {{ open_id_provider.url }} + + + 2c91531b-4f65-11e4-aefa-bfd6aEXAMPLE + +""" diff --git a/tests/test_iam/test_iam.py b/tests/test_iam/test_iam.py index deec15285..ea0434bff 100644 --- a/tests/test_iam/test_iam.py +++ b/tests/test_iam/test_iam.py @@ -9,6 +9,9 @@ import sure # noqa import sys from boto.exception import BotoServerError from botocore.exceptions import ClientError +from dateutil.tz import tzutc +from freezegun import freeze_time + from moto import mock_iam, mock_iam_deprecated from moto.iam.models import aws_managed_policies from nose.tools import assert_raises, assert_equals @@ -1615,11 +1618,10 @@ def test_create_open_id_connect_provider(): @mock_iam def test_create_open_id_connect_provider_errors(): client = boto3.client('iam', region_name='us-east-1') - response = client.create_open_id_connect_provider( + client.create_open_id_connect_provider( Url='https://example.com', ThumbprintList=[] ) - open_id_arn = response['OpenIDConnectProviderArn'] client.create_open_id_connect_provider.when.called_with( Url='https://example.com', @@ -1695,3 +1697,54 @@ def test_create_open_id_connect_provider_errors(): 'Value "{2}" at "url" failed to satisfy constraint: ' 'Member must have length less than or equal to 255'.format([too_long_client_id], [too_long_thumbprint], too_long_url) ) + + +@freeze_time('2019-01-01 00:00:00') +@mock_iam +def test_get_open_id_connect_provider(): + client = boto3.client('iam', region_name='us-east-1') + response = client.create_open_id_connect_provider( + Url='https://example.com', + ThumbprintList=[ + 'b' * 40 + ], + ClientIDList=[ + 'b' + ] + ) + open_id_arn = response['OpenIDConnectProviderArn'] + + response = client.get_open_id_connect_provider( + OpenIDConnectProviderArn=open_id_arn + ) + + response['Url'].should.equal('example.com') + response['ThumbprintList'].should.equal([ + 'b' * 40 + ]) + response['ClientIDList'].should.equal([ + 'b' + ]) + response['CreateDate'].should.equal(datetime.now(tzutc())) + + +@mock_iam +def test_get_open_id_connect_provider_errors(): + client = boto3.client('iam', region_name = 'us-east-1') + response = client.create_open_id_connect_provider( + Url='https://example.com', + ThumbprintList=[ + 'b' * 40 + ], + ClientIDList=[ + 'b' + ] + ) + open_id_arn = response['OpenIDConnectProviderArn'] + + client.get_open_id_connect_provider.when.called_with( + OpenIDConnectProviderArn = open_id_arn + '-not-existing' + ).should.throw( + ClientError, + 'OpenIDConnect Provider not found for arn {}'.format(open_id_arn + '-not-existing') + )