def test_should_order_by_resource_list_third(): statement1 = Statement(Effect="Allow", Action=[], Resource=["a"]) statement2 = Statement(Effect="Allow", Action=[], Resource=["b"]) assert statement1 < statement2 assert not statement1 > statement2
def test_should_merge_two_statements_with_different_actions_and_resources(): statement1 = Statement(Effect="Allow", Action=[ Action("some-service", "some-action"), ], Resource=[ "some-resource", ]) statement2 = Statement(Effect="Allow", Action=[ Action("some-service", "some-other-action"), ], Resource=[ "some-resource", "some-other-resource", ]) merged = Statement(Effect="Allow", Action=[ Action("some-service", "some-action"), Action("some-service", "some-other-action"), ], Resource=[ "some-other-resource", "some-resource", ]) assert statement1.merge(statement2) == merged
def test_should_guess_only_specific_actions_and_fix_upper_lowercase(): input_policy = PolicyDocument(Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action( 'ec2', 'DetachVolume'), ], Resource=["*"]), ]) expected_output = PolicyDocument( Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action('ec2', 'DetachVolume'), ], Resource=["*"]), Statement(Effect="Allow", Action=[ Action('ec2', 'AttachVolume'), Action('ec2', 'DescribeVolumes'), ], Resource=["*"]), ]) runner = CliRunner() result = runner.invoke( cli.root_group, args=["guess", "--only", "Attach", "--only", "describe"], input=input_policy.to_json()) assert result.exit_code == 0 assert parse_policy_document(result.output) == expected_output
def test_should_group_by_action_and_resource_independent_of_order(): records = [ Record("rds.amazonaws.com", "ListTagsForResource", ["arn:aws:rds:eu-central-1:111111111111:db:some-db"]), Record("rds.amazonaws.com", "SomethingDifferent", ["arn:aws:rds:eu-central-1:111111111111:db:a-third-db"]), Record("rds.amazonaws.com", "ListTagsForResource", ["arn:aws:rds:eu-central-1:111111111111:db:some-other-db"]), ] expected = PolicyDocument( Version="2012-10-17", Statement=[ Statement( Effect="Allow", Action=[ Action("rds", "ListTagsForResource"), ], Resource=[ "arn:aws:rds:eu-central-1:111111111111:db:some-db", "arn:aws:rds:eu-central-1:111111111111:db:some-other-db", ]), Statement( Effect="Allow", Action=[ Action("rds", "SomethingDifferent"), ], Resource=[ "arn:aws:rds:eu-central-1:111111111111:db:a-third-db", ]), ]) actual = generate_policy(records) assert actual == expected
def test_same_statements_have_the_same_order(): statement1 = Statement(Effect="Allow", Action=[], Resource=["a"]) statement2 = Statement(Effect="Allow", Action=[], Resource=["a"]) assert not statement1 < statement2 assert not statement1 > statement2 assert statement1 == statement2
def test_should_order_by_action_list_second(): statement1 = Statement(Effect="Allow", Action=[Action("ec2", "DescribeInstances")], Resource=[]) statement2 = Statement(Effect="Deny", Action=[Action("iam", "PassRole")], Resource=[]) assert statement1 < statement2 assert not statement1 > statement2
def test_should_fail_if_effects_arent_the_same(): statement1 = Statement(Effect="Allow", Action=[], Resource=[]) statement2 = Statement(Effect="Deny", Action=[], Resource=[]) with pytest.raises(ValueError) as e: statement1.merge(statement2) assert str( e.value ) == "Trying to combine two statements with differing effects: Allow Deny"
def _extend_statement(statement, allowed_prefixes): extended_actions = _guess_actions(statement.Action, allowed_prefixes) if extended_actions: return [statement, Statement(Action=extended_actions, Effect=statement.Effect, Resource=["*"])] return [statement]
def test_should_guess_all_matching_statements(): input_policy = PolicyDocument( Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action('autoscaling', 'DescribeLaunchConfigurations'), ], Resource=["*"]), Statement(Effect="Allow", Action=[ Action('sts', 'AssumeRole'), ], Resource=["arn:aws:iam::111111111111:role/someRole"]) ]) expected_output = PolicyDocument( Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action('autoscaling', 'DescribeLaunchConfigurations'), ], Resource=["*"]), Statement(Effect="Allow", Action=[ Action('autoscaling', 'CreateLaunchConfiguration'), Action('autoscaling', 'DeleteLaunchConfiguration'), ], Resource=["*"]), Statement(Effect="Allow", Action=[ Action('sts', 'AssumeRole'), ], Resource=["arn:aws:iam::111111111111:role/someRole"]) ]) runner = CliRunner() result = runner.invoke(cli.root_group, args=["guess"], input=input_policy.to_json()) assert result.exit_code == 0 assert parse_policy_document(result.output) == expected_output
def test_should_merge_deny_statments(): statement1 = Statement(Effect="Deny", Action=[Action("some-service", "some-action")], Resource=["*"]) statement2 = Statement( Effect="Deny", Action=[Action("some-service", "some-other-action")], Resource=["*"]) merged = Statement(Effect="Deny", Action=[ Action("some-service", "some-action"), Action("some-service", "some-other-action"), ], Resource=["*"]) assert statement1.merge(statement2) == merged
def test_json_parses_to_policy_document(): pd = PolicyDocument( Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action('autoscaling', 'DescribeLaunchConfigurations'), ], Resource=["*"]), Statement(Effect="Allow", Action=[ Action('sts', 'AssumeRole'), ], Resource=["arn:aws:iam::111111111111:role/someRole"]) ]) assert parse_policy_document(StringIO( pd.to_json())).to_json() == pd.to_json()
def test_policy_document_renders_to_json(): pd = PolicyDocument( Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action('autoscaling', 'DescribeLaunchConfigurations'), ], Resource=["*"]), Statement(Effect="Allow", Action=[ Action('sts', 'AssumeRole'), ], Resource=["arn:aws:iam::111111111111:role/someRole"]) ]) expected_json = '''\ { "Statement": [ { "Action": [ "autoscaling:DescribeLaunchConfigurations" ], "Effect": "Allow", "Resource": [ "*" ] }, { "Action": [ "sts:AssumeRole" ], "Effect": "Allow", "Resource": [ "arn:aws:iam::111111111111:role/someRole" ] } ], "Version": "2012-10-17" }''' assert json.loads(pd.to_json()) == json.loads(expected_json)
def to_statement(self): """Converts record into a matching IAM Policy Statement""" if self.event_source == "sts.amazonaws.com" and self.event_name == "GetCallerIdentity": return None if self.event_source == "apigateway.amazonaws.com": return self._to_api_gateway_statement() return Statement( Effect="Allow", Action=[Action(self._source_to_iam_prefix(), self._event_name_to_iam_action())], Resource=sorted(self.resource_arns) )
def test_should_convert_api_gateway_events_properly(): record = Record("apigateway.amazonaws.com", "CreateRestApi") expected_statment = Statement( Effect="Allow", Action=[ Action("apigateway", "POST"), ], Resource=["arn:aws:apigateway:*::/restapis"] ) assert record.to_statement() == expected_statment
def test_should_convert_special_event_sources_properly(): record = Record("monitoring.amazonaws.com", "DescribeLogStreams") expected_statment = Statement( Effect="Allow", Action=[ Action("cloudwatch", "DescribeLogStreams"), ], Resource=["*"] ) assert record.to_statement() == expected_statment
def test_should_convert_special_actions_properly(): record = Record("lambda", "ListVersionsByFunction20150331") expected_statment = Statement( Effect="Allow", Action=[ Action("lambda", "ListVersionsByFunction"), ], Resource=["*"] ) assert record.to_statement() == expected_statment
def test_should_convert_api_gateway_events_with_parameters_properly(): record = Record("apigateway.amazonaws.com", "UpdateMethod") expected_statment = Statement( Effect="Allow", Action=[ Action("apigateway", "PATCH"), ], Resource=["arn:aws:apigateway:*::/restapis/*/resources/*/methods/*"] ) assert record.to_statement() == expected_statment
def test_should_convert_into_iam_statement(): record = Record("autoscaling.amazonaws.com", "DescribeLaunchConfigurations") expected_statment = Statement( Effect="Allow", Action=[ Action('autoscaling', 'DescribeLaunchConfigurations'), ], Resource=["*"] ) assert record.to_statement() == expected_statment
def _to_api_gateway_statement(self): op_def = operation_definition("apigateway", self.event_name) http_method = op_def['http']['method'] request_uri = op_def['http']['requestUri'] resource_path = re.compile(r"{[a-zA-Z_]+}").sub("*", request_uri) region = "*" # use proper region from requestParameters return Statement( Effect="Allow", Action=[Action("apigateway", http_method)], Resource=[f"arn:aws:apigateway:{region}::{resource_path}"])
def test_should_group_by_resources(): records = [ Record("ec2.amazonaws.com", "DescribeSecurityGroups"), Record("rds.amazonaws.com", "ListTagsForResource", ["arn:aws:rds:eu-central-1:111111111111:db:some-db"]), Record("ec2.amazonaws.com", "DescribeInstances"), ] assert generate_policy(records) == PolicyDocument( Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action("ec2", "DescribeInstances"), Action("ec2", "DescribeSecurityGroups"), ], Resource=["*"]), Statement( Effect="Allow", Action=[ Action("rds", "ListTagsForResource"), ], Resource=["arn:aws:rds:eu-central-1:111111111111:db:some-db"]) ])
def test_should_remove_duplicate_actions(): records = [ Record("autoscaling.amazonaws.com", "DescribeLaunchConfigurations"), Record("autoscaling.amazonaws.com", "DescribeLaunchConfigurations"), ] assert generate_policy(records) == PolicyDocument( Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action('autoscaling', 'DescribeLaunchConfigurations'), ], Resource=["*"]) ])
def test_should_allow_events_that_dont_map_to_statement(): records = [ Record("autoscaling.amazonaws.com", "DescribeLaunchConfigurations"), Record("sts.amazonaws.com", "GetCallerIdentity") ] assert generate_policy(records) == PolicyDocument( Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action('autoscaling', 'DescribeLaunchConfigurations'), ], Resource=["*"]) ])
def test_should_generate_simple_policy(): records = [ Record("autoscaling.amazonaws.com", "DescribeLaunchConfigurations"), Record("sts.amazonaws.com", "AssumeRole") ] assert generate_policy(records) == PolicyDocument( Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action('autoscaling', 'DescribeLaunchConfigurations'), Action('sts', 'AssumeRole'), ], Resource=["*"]) ])
def test_should_sort_actions_alphabetically(): records = [ Record("ec2.amazonaws.com", "DescribeSecurityGroups"), Record("rds.amazonaws.com", "ListTagsForResource"), Record("ec2.amazonaws.com", "DescribeInstances"), ] assert generate_policy(records) == PolicyDocument( Version="2012-10-17", Statement=[ Statement(Effect="Allow", Action=[ Action("ec2", "DescribeInstances"), Action("ec2", "DescribeSecurityGroups"), Action("rds", "ListTagsForResource"), ], Resource=["*"]) ])
def test_should_group_by_resources_and_combine_statements_with_same_actions_but_different_resources( ): records = [ Record("rds.amazonaws.com", "ListTagsForResource", ["arn:aws:rds:eu-central-1:111111111111:db:some-db"]), Record("rds.amazonaws.com", "ListTagsForResource", ["arn:aws:rds:eu-central-1:111111111111:db:some-other-db"]), ] assert generate_policy(records) == PolicyDocument( Version="2012-10-17", Statement=[ Statement( Effect="Allow", Action=[ Action("rds", "ListTagsForResource"), ], Resource=[ "arn:aws:rds:eu-central-1:111111111111:db:some-db", "arn:aws:rds:eu-central-1:111111111111:db:some-other-db", ]) ])
def test_should_merge_two_identical_statements(): statement1 = Statement(Effect="Allow", Action=[ Action("some-service", "some-action"), ], Resource=[ "some-resource", ]) statement2 = Statement(Effect="Allow", Action=[ Action("some-service", "some-action"), ], Resource=[ "some-resource", ]) assert statement1.merge(statement2) == statement1 assert statement2.merge(statement1) == statement2
def test_should_order_by_effect_first(): statement1 = Statement(Effect="Allow", Action=[], Resource=[]) statement2 = Statement(Effect="Deny", Action=[], Resource=[]) assert statement1 < statement2 assert not statement1 > statement2