"""Integration test helper methods.""" import re from subprocess import PIPE, STDOUT, Popen, TimeoutExpired from typing import Any, Dict, List, Optional, Tuple from jwtauth.testing import ( get_bearer_token_identity_uuid as jwtauth_get_bearer_token_identity_uuid, ) from mypy_boto3_dynamodb import DynamoDBClient from pdp.config import DYNAMODB_TABLE_IDENTITY APPLICATION = "pdp-integration-test" STRESS_TEST_APPLICATION = "ows-pdp-stress-test" AUTH_URL = "https://qa-orchard.auth0.com/oauth/token" AUTH_AUDIENCE = "https://workstation.qaorch.com/api" PDP_TEST_USER_UUID = "4d5f24f5-83f9-4989-9f82-0924a5feaf88" ##### jwtauth.testing constants ###### # Test user in auth0 PDP_TEST_APP_AUTH0_CREDENTIALS = "PDP_TEST_APP_AUTH0_CREDENTIALS" PDP_TEST_USER_CREDENTIALS = "PDP_TEST_USER_CREDENTIALS" # Rap admin test users in auth0 PDP_TEST_RAP_ADMIN_USER_CREDENTIALS = "PDP_TEST_RAP_ADMIN_USER_CREDENTIALS" PDP_TEST_NOT_RAP_ADMIN_USER_CREDENTIALS = "PDP_TEST_NOT_RAP_ADMIN_USER_CREDENTIALS" PDP_TEST_RAP_ADMIN_D3_USER_CREDENTIALS = "PDP_TEST_RAP_ADMIN_D3_USER_CREDENTIALS" PDP_TEST_SEAT_RAP_ADMIN_USER_CREDENTIALS = "PDP_TEST_SEAT_RAP_ADMIN_USER_CREDENTIALS" # Stress test users in auth0 COMPLICATED_IDENTITY_USER_CREDENTIALS = "COMPLICATED_IDENTITY_USER_CREDENTIALS" SIMPLE_IDENTITY_USER_CREDENTIALS = "SIMPLE_IDENTITY_USER_CREDENTIALS" ###################################### def get_bearer_token_identity_uuid(bearer_token: str) -> Optional[str]: """Extract identity_uuid from bearer_token.""" return jwtauth_get_bearer_token_identity_uuid(bearer_token, environment="qa") def run_command( cmd: List[str], timeout: int = 10, expected_returncode: int = 0 ) -> Tuple[str, str]: """Execute a CLI command.""" proc = Popen(cmd, stderr=STDOUT, stdout=PIPE) try: stdout, stderr = proc.communicate(timeout=timeout) except TimeoutExpired: proc.kill() stdout, stderr = proc.communicate() assert proc.returncode == expected_returncode # remove the extra characters printed by Typer to stdout/stderr. stdout = stdout.decode("ascii", "ignore") # type: ignore[assignment] stdout = re.sub(r"[\s\n]+", " ", str(stdout)) # type: ignore[assignment] return str(stdout), str(stderr) def fetch_tombstone_records(boto_client: DynamoDBClient) -> Dict[str, Any]: """Fetch tombstone records. Returns a dictionary that maps a `tenant_uuid` to a tombstone record. Ex: {'573d0372-7f2f-48a6-8deb-c9a6558f9549': { 'expires_at': {'N': '1737833296'}, 'identity_uuid': {'S': 'TOMBSTONE:61a3ea68-8c51-4ca2-beac-...'}, 'updated_at': {'S': '2025-01-24T19:28:16.379880+00:00'}, 'tenant_uuid': {'S': 'TOMBSTONE:573d0372-7f2f-48a6-8deb-c9a6558f9549'}, 'roles': {'L': []}, 'updated_by': {'S': 'd7fac0ab-184a-4f76-ab2f-2acdcdf14ba0'}, 'created_at': {'S': '2025-01-24T19:28:16.379880+00:00'}, 'tenant_type': {'S': 'account'}, 'is_tombstone': {'BOOL': True}, 'version': {'S': '0'}, 'created_by': {'S': 'd7fac0ab-184a-4f76-ab2f-2acdcdf14ba0'}}} """ result = boto_client.scan( TableName=DYNAMODB_TABLE_IDENTITY, FilterExpression="is_tombstone = :true", ExpressionAttributeValues={":true": {"BOOL": True}}, ) tombstone_by_tenant_uuid = {} for row in result["Items"]: _, tenant_uuid = row["tenant_uuid"]["S"].split(":") tombstone_by_tenant_uuid[tenant_uuid] = row return tombstone_by_tenant_uuid