def can_access_with_policy( session: boto3.session.Session, bucket: str, key: Optional[str], role_arn: str, policy: dict, ): if not policy: assumed_role_session = assume_role(session, role_arn) else: assumed_role_session = assume_role(session, role_arn, Policy=policy) s3 = assumed_role_session.client("s3") if key: try: s3.head_object(Bucket=bucket, Key=key) return True except ClientError as e: if e.response.get("Error", {}).get("Code") == "403": pass # try the next thing else: raise try: s3.head_bucket(Bucket=bucket) return True except ClientError as e: if e.response.get("Error", {}).get("Code") == "403": pass # continue to default return False else: raise return False
def test_assume_role_policy_deny(session, ids): policy = { "Version": "2012-10-17", "Statement": [{ "Effect": "Deny", "Action": "sns:*", "Resource": "*" }] } assumed_role_session = aws_assume_role_lib.assume_role(session, RoleArn=ids.RoleArn, Policy=policy) response = assumed_role_session.client("sts").get_caller_identity() assumed_role_arn = response["Arn"] assert ids.RoleArn.rsplit("/", 1)[1] == assumed_role_arn.split("/")[1] sns = assumed_role_session.client("sns") message = "2 {}".format(uuid.uuid4()) print("Sending message", repr(message)) try: sns.publish(TopicArn=ids.TopicArn, Message=message) assert False, "Failed to deny" except ClientError as e: if e.response.get('Error', {}).get('Code') != "AuthorizationError": raise
def test_role_session_name(session, ids): session_name = str(uuid.uuid4()) assumed_role_session = aws_assume_role_lib.assume_role( session, RoleArn=ids.RoleArn, RoleSessionName=session_name) response = assumed_role_session.client('sts').get_caller_identity() assert response["Arn"].split("/")[-1] == session_name
def test_parent_session(session, ids): parent_arn_1 = session.client('sts').get_caller_identity()['Arn'] assumed_role_session = aws_assume_role_lib.assume_role(session, RoleArn=ids.RoleArn) parent_arn_2 = assumed_role_session.assume_role_parent_session.client( 'sts').get_caller_identity()['Arn'] assert parent_arn_1 == parent_arn_2
def test_invalid_params(session, ids): # too short duration try: aws_assume_role_lib.assume_role(session, RoleArn=ids.RoleArn, DurationSeconds=5) assert False, "Failed to raise param validation error" except ParamValidationError: pass assumed_role_session = aws_assume_role_lib.assume_role(session, RoleArn=ids.RoleArn, DurationSeconds=5, validate=False) try: assumed_role_session.client("sts").get_caller_identity() assert False, "Failed to raise param validation error" except ParamValidationError: pass
def test_file_cache(session, ids): with tempfile.TemporaryDirectory() as d: file_cache = aws_assume_role_lib.JSONFileCache(d) dir_size = len(list(Path(d).iterdir())) assert dir_size == 0, "Dir is not empty" assumed_role_session = aws_assume_role_lib.assume_role( session, RoleArn=ids.RoleArn, cache=file_cache) assumed_role_session.client('sts').get_caller_identity() dir_size = len(list(Path(d).iterdir())) assert dir_size == 1, "Dir has wrong size({})".format(dir_size)
def test_region(session, ids): parent_region = "us-east-1" session = boto3.Session(region_name=parent_region) assumed_role_session = aws_assume_role_lib.assume_role(session, RoleArn=ids.RoleArn) assert assumed_role_session.region_name == parent_region assumed_role_session.client("ec2").describe_availability_zones() child_region = "us-east-2" assumed_role_session = aws_assume_role_lib.assume_role( session, RoleArn=ids.RoleArn, region_name=child_region) assert assumed_role_session.region_name == child_region try: assumed_role_session.client("ec2").describe_availability_zones() assert False, "Failed to raise authorization error" except ClientError as e: if e.response.get('Error', {}).get('Code') != "UnauthorizedOperation": raise
def test_assume_role(session, ids): assumed_role_session = aws_assume_role_lib.assume_role(session, RoleArn=ids.RoleArn) response = assumed_role_session.client("sts").get_caller_identity() assumed_role_arn = response["Arn"] assert ids.RoleArn.rsplit("/", 1)[1] == assumed_role_arn.split("/")[1] sns = assumed_role_session.client("sns") message = "1 {}".format(uuid.uuid4()) print("Sending message", repr(message)) sns.publish(TopicArn=ids.TopicArn, Message=message)
def test_no_parent_creds(session, ids): botocore_session = botocore.session.Session() botocore_session.register_component( 'credential_provider', botocore.credentials.CredentialResolver([EmptyProvider()])) session = boto3.Session(botocore_session=botocore_session, region_name="us-east-1") assert session.get_credentials() is None try: aws_assume_role_lib.assume_role(session, RoleArn=ids.RoleArn) assert False, "Failed to raise credential validation error" except NoCredentialsError: pass try: aws_assume_role_lib.assume_role(session, RoleArn=ids.RoleArn, validate=False) assert False, "Failed to raise credential validation error" except NoCredentialsError: pass
def get_session(assume_role_arn): """Return boto3 session established using a role arn or AWS profile.""" if not assume_role_arn: return boto3.session.Session() LOG.info({"assumed_role": assume_role_arn}) function_name = os.environ.get("AWS_LAMBDA_FUNCTION_NAME", os.path.basename(__file__)) return assume_role( boto3.Session(), assume_role_arn, RoleSessionName=generate_lambda_session_name(function_name), DurationSeconds=3600, validate=False, )
def test_session_duration(session, ids): duration = datetime.timedelta(minutes=15) assumed_role_session = aws_assume_role_lib.assume_role( session, RoleArn=ids.RoleArn, DurationSeconds=duration) response = assumed_role_session.client('sts').get_caller_identity()
def test_region_bool(session, ids): prev_region_value = os.environ.get("AWS_DEFAULT_REGION") region1 = "us-east-1" session = boto3.Session() os.environ["AWS_DEFAULT_REGION"] = region1 assert session.region_name == region1 # Test for implicit config on session that if we don't change anything, both true and false stay the same assumed_role_session1 = aws_assume_role_lib.assume_role( session, RoleArn=ids.RoleArn, region_name=True) assert assumed_role_session1.region_name == region1 assumed_role_session2 = aws_assume_role_lib.assume_role( session, RoleArn=ids.RoleArn, region_name=False) assert assumed_role_session2.region_name == region1 assumed_role_session1.client("ec2").describe_availability_zones() assumed_role_session2.client("ec2").describe_availability_zones() # Test for implicit config on session that if we create it and later change implicit config # true stays at the original value # false gets the new value region2 = "us-east-2" assumed_role_session1 = aws_assume_role_lib.assume_role( session, RoleArn=ids.RoleArn, region_name=True) assumed_role_session2 = aws_assume_role_lib.assume_role( session, RoleArn=ids.RoleArn, region_name=False) os.environ["AWS_DEFAULT_REGION"] = region2 assert assumed_role_session1.region_name == region1, "Region mismatch: is {} should be {}".format( assumed_role_session1.region_name, region1) assert assumed_role_session2.region_name == region2, "Region mismatch: is {} should be {}".format( assumed_role_session2.region_name, region2) assumed_role_session1.client("ec2").describe_availability_zones() try: assumed_role_session2.client("ec2").describe_availability_zones() assert False, "Failed to raise authorization error" except ClientError as e: if e.response.get('Error', {}).get('Code') != "UnauthorizedOperation": raise # Test for explicit config contrary to implict config # true stays with explicit config # false goes to implict config session = boto3.Session(region_name=region1) assumed_role_session1 = aws_assume_role_lib.assume_role( session, RoleArn=ids.RoleArn, region_name=True) assumed_role_session2 = aws_assume_role_lib.assume_role( session, RoleArn=ids.RoleArn, region_name=False) assert assumed_role_session1.region_name == region1 assert assumed_role_session2.region_name == region2 assumed_role_session1.client("ec2").describe_availability_zones() try: assumed_role_session2.client("ec2").describe_availability_zones() assert False, "Failed to raise authorization error" except ClientError as e: if e.response.get('Error', {}).get('Code') != "UnauthorizedOperation": raise if prev_region_value is None: os.environ.pop("AWS_DEFAULT_REGION") else: os.environ["AWS_DEFAULT_REGION"] = prev_region_value