|
| 1 | +# Note/disclosure: This file has been (partially or fully) generated by an AI agent. |
| 2 | + |
| 3 | +import boto3 |
| 4 | +import pytest |
| 5 | +from botocore.exceptions import ClientError |
| 6 | +from localstack.aws.connect import connect_to |
| 7 | +from localstack.utils.sync import retry |
| 8 | + |
| 9 | +from aws_proxy.shared.models import ProxyConfig |
| 10 | + |
| 11 | + |
| 12 | +def _compare_user_pool_lists(user_pools_aws: list, user_pools_proxied: list): |
| 13 | + # Helper to compare user pool lists, ignoring some dynamic attributes |
| 14 | + # We'll need to refine this based on actual Cognito-IDP response structure |
| 15 | + def normalize_user_pool(user_pool): |
| 16 | + normalized = user_pool.copy() |
| 17 | + normalized.pop("LastModifiedDate", None) |
| 18 | + normalized.pop("CreationDate", None) |
| 19 | + return normalized |
| 20 | + |
| 21 | + normalized_aws = sorted([normalize_user_pool(up) for up in user_pools_aws], key=lambda x: x["Id"]) |
| 22 | + normalized_proxied = sorted([normalize_user_pool(up) for up in user_pools_proxied], key=lambda x: x["Id"]) |
| 23 | + |
| 24 | + assert normalized_proxied == normalized_aws |
| 25 | + |
| 26 | + |
| 27 | +def test_cognito_idp_user_pool_operations(start_aws_proxy): |
| 28 | + # Start proxy for cognito-idp service |
| 29 | + config = ProxyConfig(services={"cognito-idp": {"resources": ".*"}}) |
| 30 | + start_aws_proxy(config) |
| 31 | + |
| 32 | + # Create clients |
| 33 | + cognito_client = connect_to().cognito_idp |
| 34 | + cognito_client_aws = boto3.client("cognito-idp") |
| 35 | + |
| 36 | + # List user pools initially to ensure clean state and compare |
| 37 | + user_pools_proxied_initial = cognito_client.list_user_pools(MaxResults=10)["UserPools"] |
| 38 | + user_pools_aws_initial = cognito_client_aws.list_user_pools(MaxResults=10)["UserPools"] |
| 39 | + _compare_user_pool_lists(user_pools_aws_initial, user_pools_proxied_initial) |
| 40 | + |
| 41 | + # Create a user pool |
| 42 | + user_pool_name = "test-user-pool-proxy" |
| 43 | + create_response_proxied = cognito_client.create_user_pool(PoolName=user_pool_name) |
| 44 | + user_pool_id_proxied = create_response_proxied["UserPool"]["Id"] |
| 45 | + |
| 46 | + # List user pools and compare |
| 47 | + user_pools_proxied_after_create = cognito_client.list_user_pools(MaxResults=10)["UserPools"] |
| 48 | + user_pools_aws_after_create = cognito_client_aws.list_user_pools(MaxResults=10)["UserPools"] |
| 49 | + _compare_user_pool_lists(user_pools_aws_after_create, user_pools_proxied_after_create) |
| 50 | + |
| 51 | + # Describe user pool and compare |
| 52 | + describe_proxied = cognito_client.describe_user_pool(UserPoolId=user_pool_id_proxied)["UserPool"] |
| 53 | + describe_aws = cognito_client_aws.describe_user_pool(UserPoolId=user_pool_id_proxied)["UserPool"] |
| 54 | + # Normalize for comparison (remove dynamic fields) |
| 55 | + describe_proxied.pop("LastModifiedDate", None) |
| 56 | + describe_proxied.pop("CreationDate", None) |
| 57 | + describe_aws.pop("LastModifiedDate", None) |
| 58 | + describe_aws.pop("CreationDate", None) |
| 59 | + assert describe_proxied == describe_aws |
| 60 | + |
| 61 | + # Delete the user pool |
| 62 | + cognito_client.delete_user_pool(UserPoolId=user_pool_id_proxied) |
| 63 | + |
| 64 | + def _assert_user_pool_deleted(): |
| 65 | + with pytest.raises(ClientError) as aws_exc: |
| 66 | + cognito_client_aws.describe_user_pool(UserPoolId=user_pool_id_proxied) |
| 67 | + with pytest.raises(ClientError) as proxied_exc: |
| 68 | + cognito_client.describe_user_pool(UserPoolId=user_pool_id_proxied) |
| 69 | + assert aws_exc.value.response["Error"]["Code"] == "ResourceNotFoundException" |
| 70 | + assert proxied_exc.value.response["Error"]["Code"] == "ResourceNotFoundException" |
| 71 | + |
| 72 | + retry(_assert_user_pool_deleted, retries=5, sleep=5) |
| 73 | + |
| 74 | + # Verify that the user pool is no longer in the list |
| 75 | + user_pools_proxied_final = cognito_client.list_user_pools(MaxResults=10)["UserPools"] |
| 76 | + user_pools_aws_final = cognito_client_aws.list_user_pools(MaxResults=10)["UserPools"] |
| 77 | + _compare_user_pool_lists(user_pools_aws_final, user_pools_proxied_final) |
| 78 | + |
| 79 | + |
| 80 | +def test_cognito_idp_user_operations(start_aws_proxy): |
| 81 | + # Start proxy for cognito-idp service |
| 82 | + config = ProxyConfig(services={"cognito-idp": {"resources": ".*"}}) |
| 83 | + start_aws_proxy(config) |
| 84 | + |
| 85 | + # Create clients |
| 86 | + cognito_client = connect_to().cognito_idp |
| 87 | + cognito_client_aws = boto3.client("cognito-idp") |
| 88 | + |
| 89 | + # Create a user pool |
| 90 | + user_pool_name = "test-user-pool-users-proxy" |
| 91 | + user_pool = cognito_client.create_user_pool(PoolName=user_pool_name) |
| 92 | + user_pool_id = user_pool["UserPool"]["Id"] |
| 93 | + |
| 94 | + try: |
| 95 | + # Create a user pool client |
| 96 | + user_pool_client = cognito_client.create_user_pool_client( |
| 97 | + UserPoolId=user_pool_id, |
| 98 | + ClientName="test-client", |
| 99 | + ExplicitAuthFlows=["ADMIN_NO_SRP_AUTH", "USER_PASSWORD_AUTH"], |
| 100 | + ) |
| 101 | + client_id = user_pool_client["UserPoolClient"]["ClientId"] |
| 102 | + |
| 103 | + # Sign up a user |
| 104 | + username = "testuser" |
| 105 | + password = "Password123!" |
| 106 | + cognito_client.sign_up( |
| 107 | + ClientId=client_id, |
| 108 | + Username=username, |
| 109 | + Password=password, |
| 110 | + UserAttributes=[{"Name": "email", "Value": "test@example.com"}], |
| 111 | + ) |
| 112 | + |
| 113 | + # Confirm the user |
| 114 | + cognito_client.admin_confirm_sign_up(UserPoolId=user_pool_id, Username=username) |
| 115 | + |
| 116 | + # Initiate auth |
| 117 | + auth_response_proxied = cognito_client.initiate_auth( |
| 118 | + ClientId=client_id, |
| 119 | + AuthFlow="USER_PASSWORD_AUTH", |
| 120 | + AuthParameters={"USERNAME": username, "PASSWORD": password}, |
| 121 | + ) |
| 122 | + auth_response_aws = cognito_client_aws.initiate_auth( |
| 123 | + ClientId=client_id, |
| 124 | + AuthFlow="USER_PASSWORD_AUTH", |
| 125 | + AuthParameters={"USERNAME": username, "PASSWORD": password}, |
| 126 | + ) |
| 127 | + assert auth_response_proxied["AuthenticationResult"]["AccessToken"] |
| 128 | + assert auth_response_aws["AuthenticationResult"]["AccessToken"] |
| 129 | + |
| 130 | + # Admin delete user |
| 131 | + cognito_client.admin_delete_user(UserPoolId=user_pool_id, Username=username) |
| 132 | + |
| 133 | + # Verify user is deleted |
| 134 | + with pytest.raises(ClientError) as exc_info: |
| 135 | + cognito_client.admin_get_user(UserPoolId=user_pool_id, Username=username) |
| 136 | + assert exc_info.value.response["Error"]["Code"] == "UserNotFoundException" |
| 137 | + |
| 138 | + finally: |
| 139 | + # Clean up resources |
| 140 | + cognito_client.delete_user_pool(UserPoolId=user_pool_id) |
0 commit comments