from datetime import datetime import boto3 import pytest from botocore.exceptions import ClientError from moto import mock_aws from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID @mock_aws def test_create_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=[], # even it is required to provide at least one thumbprint, AWS accepts an empty list ) assert ( response["OpenIDConnectProviderArn"] == f"arn:aws:iam::{ACCOUNT_ID}:oidc-provider/example.com" ) response = client.create_open_id_connect_provider( Url="http://example.org", ThumbprintList=["b" * 40], ClientIDList=["b"] ) assert ( response["OpenIDConnectProviderArn"] == f"arn:aws:iam::{ACCOUNT_ID}:oidc-provider/example.org" ) response = client.create_open_id_connect_provider( Url="http://example.org/oidc", ThumbprintList=[] ) assert ( response["OpenIDConnectProviderArn"] == f"arn:aws:iam::{ACCOUNT_ID}:oidc-provider/example.org/oidc" ) response = client.create_open_id_connect_provider( Url="http://example.org/oidc-query?test=true", ThumbprintList=[] ) assert ( response["OpenIDConnectProviderArn"] == f"arn:aws:iam::{ACCOUNT_ID}:oidc-provider/example.org/oidc-query" ) @mock_aws def test_create_open_id_connect_provider_with_tags(): client = boto3.client("iam", region_name="us-east-1") response = client.create_open_id_connect_provider( Url="https://example.com", ThumbprintList=[], Tags=[{"Key": "k1", "Value": "v1"}, {"Key": "k2", "Value": "v2"}], ) open_id_arn = response["OpenIDConnectProviderArn"] response = client.get_open_id_connect_provider(OpenIDConnectProviderArn=open_id_arn) assert len(response["Tags"]) == 2 assert {"Key": "k1", "Value": "v1"} in response["Tags"] assert {"Key": "k2", "Value": "v2"} in response["Tags"] @pytest.mark.parametrize("url", ["example.org", "example"]) @mock_aws def test_create_open_id_connect_provider_invalid_url(url): client = boto3.client("iam", region_name="us-east-1") with pytest.raises(ClientError) as e: client.create_open_id_connect_provider(Url=url, ThumbprintList=[]) msg = e.value.response["Error"]["Message"] assert "Invalid Open ID Connect Provider URL" in msg @mock_aws def test_create_open_id_connect_provider_errors(): client = boto3.client("iam", region_name="us-east-1") client.create_open_id_connect_provider(Url="https://example.com", ThumbprintList=[]) with pytest.raises(ClientError) as exc: client.create_open_id_connect_provider( Url="https://example.com", ThumbprintList=[] ) err = exc.value.response["Error"] assert err["Message"] == "Unknown" @mock_aws def test_create_open_id_connect_provider_too_many_entries(): client = boto3.client("iam", region_name="us-east-1") with pytest.raises(ClientError) as e: client.create_open_id_connect_provider( Url="http://example.org", ThumbprintList=[ "a" * 40, "b" * 40, "c" * 40, "d" * 40, "e" * 40, "f" * 40, ], ) msg = e.value.response["Error"]["Message"] assert "Thumbprint list must contain fewer than 5 entries." in msg @mock_aws def test_create_open_id_connect_provider_quota_error(): client = boto3.client("iam", region_name="us-east-1") too_many_client_ids = [f"{i}" for i in range(101)] with pytest.raises(ClientError) as e: client.create_open_id_connect_provider( Url="http://example.org", ThumbprintList=[], ClientIDList=too_many_client_ids, ) msg = e.value.response["Error"]["Message"] assert "Cannot exceed quota for ClientIdsPerOpenIdConnectProvider: 100" in msg @mock_aws def test_create_open_id_connect_provider_multiple_errors(): client = boto3.client("iam", region_name="us-east-1") too_long_url = "b" * 256 too_long_thumbprint = "b" * 41 too_long_client_id = "b" * 256 with pytest.raises(ClientError) as e: client.create_open_id_connect_provider( Url=too_long_url, ThumbprintList=[too_long_thumbprint], ClientIDList=[too_long_client_id], ) msg = e.value.response["Error"]["Message"] assert "3 validation errors detected:" in msg assert '"clientIDList" failed to satisfy constraint:' in msg assert "Member must have length less than or equal to 255" in msg assert "Member must have length greater than or equal to 1" in msg assert '"thumbprintList" failed to satisfy constraint:' in msg assert "Member must have length less than or equal to 40" in msg assert "Member must have length greater than or equal to 40" in msg assert '"url" failed to satisfy constraint:' in msg assert "Member must have length less than or equal to 255" in msg @mock_aws def test_delete_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=[] ) open_id_arn = response["OpenIDConnectProviderArn"] client.delete_open_id_connect_provider(OpenIDConnectProviderArn=open_id_arn) with pytest.raises(ClientError) as exc: client.get_open_id_connect_provider(OpenIDConnectProviderArn=open_id_arn) err = exc.value.response["Error"] assert err["Message"] == f"OpenIDConnect Provider not found for arn {open_id_arn}" # deleting a non existing provider should be successful client.delete_open_id_connect_provider(OpenIDConnectProviderArn=open_id_arn) @mock_aws 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) assert response["Url"] == "example.com" assert response["ThumbprintList"] == ["b" * 40] assert response["ClientIDList"] == ["b"] assert isinstance(response["CreateDate"], datetime) @mock_aws def test_update_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] ) open_id_arn = response["OpenIDConnectProviderArn"] client.update_open_id_connect_provider_thumbprint( OpenIDConnectProviderArn=open_id_arn, ThumbprintList=["c" * 40, "d" * 40] ) response = client.get_open_id_connect_provider(OpenIDConnectProviderArn=open_id_arn) assert response["Url"] == "example.com" assert len(response["ThumbprintList"]) == 2 assert "c" * 40 in response["ThumbprintList"] assert "d" * 40 in response["ThumbprintList"] @mock_aws 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"] unknown_arn = open_id_arn + "-not-existing" with pytest.raises(ClientError) as exc: client.get_open_id_connect_provider(OpenIDConnectProviderArn=unknown_arn) err = exc.value.response["Error"] assert err["Message"] == f"OpenIDConnect Provider not found for arn {unknown_arn}" @mock_aws def test_list_open_id_connect_providers(): client = boto3.client("iam", region_name="us-east-1") response = client.create_open_id_connect_provider( Url="https://example.com", ThumbprintList=[] ) open_id_arn_1 = response["OpenIDConnectProviderArn"] response = client.create_open_id_connect_provider( Url="http://example.org", ThumbprintList=["b" * 40], ClientIDList=["b"] ) open_id_arn_2 = response["OpenIDConnectProviderArn"] response = client.create_open_id_connect_provider( Url="http://example.org/oidc", ThumbprintList=[] ) open_id_arn_3 = response["OpenIDConnectProviderArn"] response = client.list_open_id_connect_providers() assert sorted(response["OpenIDConnectProviderList"], key=lambda i: i["Arn"]) == [ {"Arn": open_id_arn_1}, {"Arn": open_id_arn_2}, {"Arn": open_id_arn_3}, ] @mock_aws def test_tag_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=[] ) open_id_arn = response["OpenIDConnectProviderArn"] client.tag_open_id_connect_provider( OpenIDConnectProviderArn=open_id_arn, Tags=[{"Key": "k1", "Value": "v1"}, {"Key": "k2", "Value": "v2"}], ) response = client.get_open_id_connect_provider(OpenIDConnectProviderArn=open_id_arn) assert len(response["Tags"]) == 2 assert {"Key": "k1", "Value": "v1"} in response["Tags"] assert {"Key": "k2", "Value": "v2"} in response["Tags"] @mock_aws def test_untag_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=[] ) open_id_arn = response["OpenIDConnectProviderArn"] client.tag_open_id_connect_provider( OpenIDConnectProviderArn=open_id_arn, Tags=[{"Key": "k1", "Value": "v1"}, {"Key": "k2", "Value": "v2"}], ) client.untag_open_id_connect_provider( OpenIDConnectProviderArn=open_id_arn, TagKeys=["k2"] ) response = client.get_open_id_connect_provider(OpenIDConnectProviderArn=open_id_arn) assert len(response["Tags"]) == 1 assert {"Key": "k1", "Value": "v1"} in response["Tags"] @mock_aws def test_list_open_id_connect_provider_tags(): client = boto3.client("iam", region_name="us-east-1") response = client.create_open_id_connect_provider( Url="https://example.com", ThumbprintList=[], Tags=[{"Key": "k1", "Value": "v1"}, {"Key": "k2", "Value": "v2"}], ) open_id_arn = response["OpenIDConnectProviderArn"] response = client.list_open_id_connect_provider_tags( OpenIDConnectProviderArn=open_id_arn ) assert len(response["Tags"]) == 2 assert {"Key": "k1", "Value": "v1"} in response["Tags"] assert {"Key": "k2", "Value": "v2"} in response["Tags"] @mock_aws def test_list_open_id_connect_provider_tags__paginated(): client = boto3.client("iam", region_name="us-east-1") response = client.create_open_id_connect_provider( Url="https://example.com", ThumbprintList=[], Tags=[{"Key": f"k{idx}", "Value": f"v{idx}"} for idx in range(0, 50)], ) open_id_arn = response["OpenIDConnectProviderArn"] client.tag_open_id_connect_provider( OpenIDConnectProviderArn=open_id_arn, Tags=[{"Key": f"k{idx}", "Value": f"v{idx}"} for idx in range(50, 100)], ) client.tag_open_id_connect_provider( OpenIDConnectProviderArn=open_id_arn, Tags=[{"Key": f"k{idx}", "Value": f"v{idx}"} for idx in range(100, 150)], ) response = client.list_open_id_connect_provider_tags( OpenIDConnectProviderArn=open_id_arn ) assert len(response["Tags"]) == 100 response = client.list_open_id_connect_provider_tags( OpenIDConnectProviderArn=open_id_arn, Marker=response["Marker"] ) assert len(response["Tags"]) == 50 assert "Marker" not in response @mock_aws def test_list_open_id_connect_provider_tags__maxitems(): client = boto3.client("iam", region_name="us-east-1") response = client.create_open_id_connect_provider( Url="https://example.com", ThumbprintList=[], Tags=[{"Key": f"k{idx}", "Value": f"v{idx}"} for idx in range(0, 10)], ) open_id_arn = response["OpenIDConnectProviderArn"] response = client.list_open_id_connect_provider_tags( OpenIDConnectProviderArn=open_id_arn, MaxItems=4 ) assert len(response["Tags"]) == 4 response = client.list_open_id_connect_provider_tags( OpenIDConnectProviderArn=open_id_arn, Marker=response["Marker"], MaxItems=4 ) assert len(response["Tags"]) == 4 response = client.list_open_id_connect_provider_tags( OpenIDConnectProviderArn=open_id_arn, Marker=response["Marker"] ) assert len(response["Tags"]) == 2 assert "Marker" not in response