def test_can_compose_scanner_summary(self):
        """Test that the scan summary is built correctly."""
        email_pipeline = (
            email_scanner_summary_pipeline.EmailScannerSummaryPipeline(111111))

        members = [
            iam_policy.IamPolicyMember.create_from(u)
            for u in ['user:[email protected]', 'group:[email protected]', 'serviceAccount:[email protected]']
        ]
        all_violations = [
            audit_rules.RuleViolation(
                resource_type='organization',
                resource_id='abc111',
                rule_name='Abc 111',
                rule_index=0,
                violation_type=audit_rules.VIOLATION_TYPE['whitelist'],
                role='role1',
                members=tuple(members)),
            audit_rules.RuleViolation(
                resource_type='project',
                resource_id='def222',
                rule_name='Def 123',
                rule_index=1,
                violation_type=audit_rules.VIOLATION_TYPE['blacklist'],
                role='role2',
                members=tuple(members)),
        ]
        total_resources = {
            resource.ResourceType.ORGANIZATION: 1,
            resource.ResourceType.PROJECT: 1,
        }

        actual = email_pipeline._compose(all_violations, total_resources)

        expected_summaries = {
            resource.ResourceType.ORGANIZATION: {
                'pluralized_resource_type': 'Organizations',
                'total': 1,
                'violations': {
                    'abc111': len(members)
                }
            },
            resource.ResourceType.PROJECT: {
                'pluralized_resource_type': 'Projects',
                'total': 1,
                'violations': {
                    'def222': len(members)
                }
            },
        }
        expected_totals = sum([
            v for t in expected_summaries.values()
            for v in t['violations'].values()
        ])
        expected = (expected_totals, expected_summaries)

        self.assertEqual(expected, actual)
コード例 #2
0
    def _check_whitelistblacklist_rules(self, resource, rule, policy_bindings):
        """Check whitelist and blacklist rules.

        Args:
            resource (Resource): The resource that the policy belongs to.
            rule (Rule): The rule to check.
            policy_bindings (list): The list of IamPolicyBindings.

        Yields:
            iterable: A generator of RuleViolations.
        """
        violation_type = scanner_rules.VIOLATION_TYPE.get(
            rule.mode, scanner_rules.VIOLATION_TYPE['UNSPECIFIED'])
        for policy_binding in policy_bindings:
            for rule_binding in rule.bindings:
                # If the rule's role pattern matches the policy binding's
                # role pattern, then check the members to see whether they
                # match, according to the rule mode.
                violating_members = None
                if rule_binding.role_pattern.match(policy_binding.role_name):
                    violating_members = (self._dispatch_rule_mode_check(
                        mode=rule.mode,
                        rule_members=rule_binding.members,
                        policy_members=policy_binding.members))
                if violating_members:
                    yield scanner_rules.RuleViolation(
                        resource_type=resource.type,
                        resource_id=resource.id,
                        rule_name=rule.rule_name,
                        rule_index=rule.rule_index,
                        violation_type=violation_type,
                        role=policy_binding.role_name,
                        members=tuple(violating_members))
コード例 #3
0
    def test_org_project_inherit_org_rule_violation(self):
        """Test org with blacklist and child with whitelist, no inherit.

        Test that the project whitelist rule overrides the org blacklist rule
        when the project does not inherit from parent.

        Setup:
            * Create a RulesEngine with RULES5 rule set.
            * Create policy.

        Expected result:
            * Find 1 rule violation.
        """
        # actual
        rules_local_path = get_datafile_path(__file__, 'test_rules_1.yaml')
        rules_engine = ire.IamRulesEngine(rules_local_path)
        rules5 = copy.deepcopy(test_rules.RULES5)
        rules5['rules'][1]['inherit_from_parents'] = True
        rules_engine.rule_book = ire.IamRuleBook(rules5, self.fake_timestamp)
        rules_engine.rule_book.org_res_rel_dao = mock.MagicMock()
        find_ancestor_mock = mock.MagicMock(
            side_effect=[[self.org789]])
        rules_engine.rule_book.org_res_rel_dao.find_ancestors = \
            find_ancestor_mock

        project_policy = {
            'bindings': [
                {
                    'role': 'roles/owner',
                    'members': [
                        'user:[email protected]',
                    ]
                }
            ]
        }

        actual_violations = set(
            rules_engine.find_policy_violations(self.project1, project_policy)
        )

        # expected
        expected_outstanding_proj = {
            'roles/owner': [
                IamPolicyMember.create_from('user:[email protected]')
            ]
        }

        expected_violations = set([
            scanner_rules.RuleViolation(
                rule_index=0,
                rule_name='org blacklist',
                resource_id=self.project1.id,
                resource_type=self.project1.type,
                violation_type='ADDED',
                role=project_policy['bindings'][0]['role'],
                members=tuple(expected_outstanding_proj['roles/owner'])),
        ])

        self.assertItemsEqual(expected_violations, actual_violations)
コード例 #4
0
    def test_one_member_mismatch(self):
        """Test a policy where one member mismatches the whitelist.

        Setup:
            * Create a RulesEngine and add test_rules.RULES1.
            * Create the policy binding.
            * Create the Rule and rule bindings.
            * Create the resource association for the Rule.

        Expected results:
            One policy binding member missing from the whitelist.
        """
        # actual
        rules_local_path = get_datafile_path(__file__, 'test_rules_1.yaml')
        rules_engine = ire.IamRulesEngine(rules_local_path)
        rules_engine.rule_book = ire.IamRuleBook(test_rules.RULES1,
                                                 self.fake_timestamp)
        rules_engine.rule_book.org_res_rel_dao = mock.MagicMock()
        find_ancestor_mock = mock.MagicMock(side_effect=[[self.org789]])
        rules_engine.rule_book.org_res_rel_dao.find_ancestors = \
            find_ancestor_mock

        policy = {
            'bindings': [{
                'role':
                'roles/editor',
                'members': ['user:[email protected]', 'user:[email protected]']
            }]
        }

        actual_violations = set(
            rules_engine.find_policy_violations(self.project1, policy))

        # expected
        rule_bindings = [{
            'role': 'roles/*',
            'members': ['user:*@company.com']
        }]
        rule = scanner_rules.Rule(
            'my rule',
            0, [IamPolicyBinding.create_from(b) for b in rule_bindings],
            mode='whitelist')
        expected_outstanding = {
            'roles/editor':
            [IamPolicyMember.create_from('user:[email protected]')]
        }
        expected_violations = set([
            scanner_rules.RuleViolation(
                resource_type=self.project1.type,
                resource_id=self.project1.id,
                rule_name=rule.rule_name,
                rule_index=rule.rule_index,
                role='roles/editor',
                violation_type=scanner_rules.VIOLATION_TYPE.get(rule.mode),
                members=tuple(expected_outstanding['roles/editor']))
        ])

        self.assertEqual(expected_violations, actual_violations)
コード例 #5
0
    def test_org_2_child_rules_report_violation(self):
        """Test org "children" whitelist works with org "children" blacklist.

        Test that org children whitelist with org children blacklist rules
        report violation.

        Setup:
            * Create a RulesEngine with RULES6 rule set.
            * Create policy.

        Expected result:
            * Find 1 rule violation.
        """
        # actual
        rules_local_path = get_datafile_path(__file__, 'test_rules_1.yaml')
        rules_engine = ire.IamRulesEngine(rules_local_path)
        rules_engine.rule_book = ire.IamRuleBook(
            test_rules.RULES6, self.fake_timestamp)
        rules_engine.rule_book.org_res_rel_dao = mock.MagicMock()
        find_ancestor_mock = mock.MagicMock(
            side_effect=[[self.org789]])
        rules_engine.rule_book.org_res_rel_dao.find_ancestors = \
            find_ancestor_mock

        project_policy = {
            'bindings': [
                {
                    'role': 'roles/owner',
                    'members': [
                        'user:[email protected]',
                    ]
                }
            ]
        }

        actual_violations = set(
            rules_engine.find_policy_violations(self.project1, project_policy)
        )

        # expected
        expected_outstanding_proj = {
            'roles/owner': [
                IamPolicyMember.create_from('user:[email protected]')
            ]
        }

        expected_violations = set([
            scanner_rules.RuleViolation(
                rule_index=1,
                rule_name='project blacklist',
                resource_id=self.project1.id,
                resource_type=self.project1.type,
                violation_type='ADDED',
                role=project_policy['bindings'][0]['role'],
                members=tuple(expected_outstanding_proj['roles/owner'])),
        ])

        self.assertItemsEqual(expected_violations, actual_violations)
コード例 #6
0
    def test_folder_rule_whitelist(self):
        """Test a simple folder whitelist rule."""
        rules_local_path = get_datafile_path(__file__, 'test_rules_1.yaml')
        rules_engine = ire.IamRulesEngine(rules_local_path)
        rules_engine.rule_book = ire.IamRuleBook({}, test_rules.FOLDER_RULES1,
                                                 self.fake_timestamp)
        rules_engine.rule_book.org_res_rel_dao = mock.MagicMock()
        find_ancestor_mock = mock.MagicMock(
            side_effect=[[self.org789], [self.folder1, self.org789]])
        rules_engine.rule_book.org_res_rel_dao.find_ancestors = \
            find_ancestor_mock

        # one violation for folder because of organization 778899
        # one violation for project because of project3's parent
        folder_policy = {
            'bindings': [{
                'role': 'roles/editor',
                'members': [
                    'user:[email protected]',
                ]
            }]
        }

        project_policy = {
            'bindings': [{
                'role': 'roles/editor',
                'members': [
                    'user:[email protected]',
                ]
            }]
        }

        actual_violations = set(
            itertools.chain(
                rules_engine.find_policy_violations(self.folder1,
                                                    folder_policy),
                rules_engine.find_policy_violations(self.project3,
                                                    project_policy)))

        # expected
        expected_outstanding = {
            'roles/editor':
            [IamPolicyMember.create_from('user:[email protected]')]
        }

        expected_violations = set([
            scanner_rules.RuleViolation(
                rule_index=0,
                rule_name='folder rule 1',
                resource_id=self.folder1.id,
                resource_type=self.folder1.type,
                violation_type='ADDED',
                role=project_policy['bindings'][0]['role'],
                members=tuple(expected_outstanding['roles/editor'])),
        ])
        self.assertItemsEqual(expected_violations, actual_violations)
コード例 #7
0
    def setUp(self, mock_db_connector):
        mock_db_connector.return_value = None
        self.resource_name = 'violations'
        self.dao = violation_dao.ViolationDao()
        self.fake_snapshot_timestamp = '12345'
        self.fake_table_name = (
            '%s_%s' % (self.resource_name, self.fake_snapshot_timestamp))
        self.fake_violations = [
            rules.RuleViolation(
                resource_type='x',
                resource_id='1',
                rule_name='rule name',
                rule_index=0,
                violation_type='ADDED',
                role='roles/editor',
                members=[
                    iam.IamPolicyMember.create_from(m)
                    for m in ['user:[email protected]', 'user:[email protected]']
                ],
            ),
            rules.RuleViolation(
                resource_type='%sb' % ('a' * 300),
                resource_id='1',
                rule_name='%sd' % ('c' * 300),
                rule_index=1,
                violation_type='REMOVED',
                role='%s' % ('e' * 300),
                members=[
                    iam.IamPolicyMember.create_from('user:%sh' % ('g' * 300))
                ],
            ),
        ]

        self.expected_fake_violations = [
            ('x', '1', 'rule name', 0, 'ADDED', 'roles/editor',
             'user:[email protected]'),
            ('x', '1', 'rule name', 0, 'ADDED', 'roles/editor',
             'user:[email protected]'),
            ('a' * 255, '1', 'c' * 255, 1, 'REMOVED', 'e' * 255,
             ('user:%s' % ('g' * 300))[:255]),
        ]
コード例 #8
0
    def _check_required_rules(self, resource, rule, policy_bindings):
        """Check required rule.

        Args:
            resource (Resource): The resource that the policy belongs to.
            policy_bindings (list): The list of IamPolicyBindings.
            rule (Rule): The rule to check.

        Yields:
            iterable: A generator of RuleViolations.
        """
        violation_type = scanner_rules.VIOLATION_TYPE.get(
            rule.mode, scanner_rules.VIOLATION_TYPE['UNSPECIFIED'])
        found_role = False
        violating_bindings = {}
        # If the rule's binding role is found in the policy,
        # check the policy members to see if all rule binding
        # members are found.
        # Any outstanding rule bindings (role => members) should be reported.
        for rule_binding in rule.bindings:
            for policy_binding in policy_bindings:
                violating_members = None
                if rule_binding.role_pattern.match(policy_binding.role_name):
                    found_role = True
                    violating_members = (self._dispatch_rule_mode_check(
                        mode=rule.mode,
                        rule_members=rule_binding.members,
                        policy_members=policy_binding.members))
                if violating_members:
                    violating_bindings[
                        rule_binding.role_name] = violating_members

        if not found_role:
            violating_bindings = {
                b.role_name: b.members
                for b in rule.bindings
            }

        if violating_bindings:
            for (role_name, members) in violating_bindings.iteritems():
                yield scanner_rules.RuleViolation(
                    resource_type=resource.type,
                    resource_id=resource.id,
                    rule_name=rule.rule_name,
                    rule_index=rule.rule_index,
                    violation_type=violation_type,
                    role=role_name,
                    members=tuple(members))
コード例 #9
0
    def find_mismatches(self, policy_resource, binding_to_match):
        """Determine if the policy binding matches this rule's criteria.

        How the member matching operates:

        1. Whitelist: policy members match at least one rule member
        2. Blacklist: policy members must not match any rule members
        3. Require: rule members must all match policy members

        Args:
            policy_resource (Resource): The resource that the policy belongs to.
            binding_to_match (IamPolicyBinding): The IamPolicyBinding binding
                to compare to this rule's bindings.

        Yields:
            iterable: A generator of RuleViolations.
        """
        policy_binding = iam_policy.IamPolicyBinding.create_from(
            binding_to_match)

        for rule in self.rules:
            found_role = False
            for binding in rule.bindings:
                policy_role_name = policy_binding.role_name
                if not policy_binding.role_name.startswith('roles'):
                    policy_role_name = 'roles/{}'.format(
                        policy_binding.role_name)

                # If the rule's role pattern matches the policy binding's role
                # pattern, then check the members to see whether they match,
                # according to the rule mode.
                if binding.role_pattern.match(policy_role_name):
                    if rule.mode == scanner_rules.RuleMode.REQUIRED:
                        role_name = binding.role_name
                    else:
                        role_name = policy_role_name
                    found_role = True
                    violating_members = (self._dispatch_rule_mode_check(
                        mode=rule.mode,
                        rule_members=binding.members,
                        policy_members=policy_binding.members))
                    if violating_members:
                        yield scanner_rules.RuleViolation(
                            resource_type=policy_resource.type,
                            resource_id=policy_resource.id,
                            rule_name=rule.rule_name,
                            rule_index=rule.rule_index,
                            violation_type=scanner_rules.VIOLATION_TYPE.get(
                                rule.mode,
                                scanner_rules.VIOLATION_TYPE['UNSPECIFIED']),
                            role=role_name,
                            members=tuple(violating_members))

            # Extra check if the role did not match in the REQUIRED case.
            if not found_role and rule.mode == scanner_rules.RuleMode.REQUIRED:
                for binding in rule.bindings:
                    yield scanner_rules.RuleViolation(
                        resource_type=policy_resource.type,
                        resource_id=policy_resource.id,
                        rule_name=rule.rule_name,
                        rule_index=rule.rule_index,
                        violation_type=scanner_rules.VIOLATION_TYPE.get(
                            rule.mode,
                            scanner_rules.VIOLATION_TYPE['UNSPECIFIED']),
                        role=binding.role_name,
                        members=tuple(binding.members))
コード例 #10
0
    def setUp(self, mock_db_connector):
        mock_db_connector.return_value = None
        self.resource_name = 'violations'
        self.dao = violation_dao.ViolationDao()
        self.fake_snapshot_timestamp = '12345'
        self.fake_table_name = (
            '%s_%s' % (self.resource_name, self.fake_snapshot_timestamp))
        self.fake_violations = [
            rules.RuleViolation(
                resource_type='x',
                resource_id='1',
                rule_name='rule name',
                rule_index=0,
                violation_type='ADDED',
                role='roles/editor',
                members=[
                    iam.IamPolicyMember.create_from(m)
                    for m in ['user:[email protected]', 'user:[email protected]']
                ],
            ),
            rules.RuleViolation(
                resource_type='%se' % ('a' * 300),
                resource_id='1',
                rule_name='%sh' % ('b' * 300),
                rule_index=1,
                violation_type='REMOVED',
                role='%s' % ('c' * 300),
                members=[
                    iam.IamPolicyMember.create_from('user:%s' % ('d' * 300))
                ],
            ),
        ]
        long_string = '{"member": "user:%s", "role": "%s"}' % (('d' * 300),
                                                               ('c' * 300))

        self.fake_flattened_violations = [
            {
                'resource_id': '1',
                'resource_type': self.fake_violations[0].resource_type,
                'rule_index': 0,
                'rule_name': self.fake_violations[0].rule_name,
                'violation_type': self.fake_violations[0].violation_type,
                'violation_data': {
                    'role': self.fake_violations[0].role,
                    'member': 'user:[email protected]'
                }
            },
            {
                'resource_id': '1',
                'resource_type': self.fake_violations[0].resource_type,
                'rule_index': 0,
                'rule_name': self.fake_violations[0].rule_name,
                'violation_type': self.fake_violations[0].violation_type,
                'violation_data': {
                    'role': self.fake_violations[0].role,
                    'member': 'user:[email protected]'
                }
            },
            {
                'resource_id': '1',
                'resource_type': self.fake_violations[1].resource_type,
                'rule_index': 1,
                'rule_name': self.fake_violations[1].rule_name,
                'violation_type': self.fake_violations[1].violation_type,
                'violation_data': {
                    'role': self.fake_violations[1].role,
                    'member': 'user:%s' % ('d' * 300)
                }
            },
        ]

        self.expected_fake_violations = [
            ('x', '1', 'rule name', 0, 'ADDED',
             '{"member": "user:[email protected]", "role": "roles/editor"}'),
            ('x', '1', 'rule name', 0, 'ADDED',
             '{"member": "user:[email protected]", "role": "roles/editor"}'),
            ('a' * 255, '1', 'b' * 255, 1, 'REMOVED', long_string),
        ]
コード例 #11
0
    def test_org_self_rules_work_with_org_child_rules(self):
        """Test org "self" whitelist works with org "children" whitelist

        Test hierarchical rules.

        Setup:
            * Create a RulesEngine with RULES4 rule set.
            * Create policy.

        Expected result:
            * Find 3 rule violations.
        """
        # actual
        rules_local_path = get_datafile_path(__file__, 'test_rules_1.yaml')
        rules_engine = ire.IamRulesEngine(rules_local_path)
        rules_engine.rule_book = ire.IamRuleBook(test_rules.RULES4,
                                                 self.fake_timestamp)
        rules_engine.rule_book.org_res_rel_dao = mock.MagicMock()
        find_ancestor_mock = mock.MagicMock(side_effect=[[], [self.org789]])
        rules_engine.rule_book.org_res_rel_dao.find_ancestors = \
            find_ancestor_mock

        org_policy = {
            'bindings': [{
                'role':
                'roles/owner',
                'members': [
                    'user:[email protected]',
                    'user:[email protected]',
                ]
            }]
        }

        project_policy = {
            'bindings': [{
                'role':
                'roles/editor',
                'members': [
                    'user:[email protected]',
                    'user:[email protected]',
                ]
            }]
        }

        actual_violations = set(
            itertools.chain(
                rules_engine.find_policy_violations(self.org789, org_policy),
                rules_engine.find_policy_violations(self.project1,
                                                    project_policy)))

        # expected
        expected_outstanding_org = {
            'roles/owner':
            [IamPolicyMember.create_from('user:[email protected]')]
        }
        expected_outstanding_proj = {
            'roles/editor':
            [IamPolicyMember.create_from('user:[email protected]')]
        }

        expected_violations = set([
            scanner_rules.RuleViolation(
                rule_index=0,
                rule_name='org whitelist',
                resource_id=self.org789.id,
                resource_type=self.org789.type,
                violation_type='ADDED',
                role=org_policy['bindings'][0]['role'],
                members=tuple(expected_outstanding_org['roles/owner'])),
            scanner_rules.RuleViolation(
                rule_index=1,
                rule_name='project whitelist',
                resource_id=self.project1.id,
                resource_type=self.project1.type,
                violation_type='ADDED',
                role=project_policy['bindings'][0]['role'],
                members=tuple(expected_outstanding_proj['roles/editor'])),
        ])

        self.assertItemsEqual(expected_violations, actual_violations)
コード例 #12
0
    def test_org_proj_rules_vs_policy_has_violations(self):
        """Test rules on org and project with whitelist, blacklist, required.

        Test whitelist, blacklist, and required rules against an org that has
        1 blacklist violation and a project that has 1 whitelist violation and
        1 required violation.

        Setup:
            * Create a RulesEngine with RULES3 rule set.
            * Create policy.

        Expected result:
            * Find 3 rule violations.
        """
        # actual
        rules_local_path = get_datafile_path(__file__, 'test_rules_1.yaml')
        rules_engine = ire.IamRulesEngine(rules_local_path)
        rules_engine.rule_book = ire.IamRuleBook(test_rules.RULES3,
                                                 self.fake_timestamp)
        rules_engine.rule_book.org_res_rel_dao = mock.MagicMock()
        find_ancestor_mock = mock.MagicMock(side_effect=[[], [self.org789]])
        rules_engine.rule_book.org_res_rel_dao.find_ancestors = \
            find_ancestor_mock

        org_policy = {
            'bindings': [{
                'role':
                'roles/editor',
                'members': [
                    'user:[email protected]',
                    'user:[email protected]',
                ]
            }]
        }

        project_policy = {
            'bindings': [{
                'role':
                'roles/editor',
                'members': [
                    'user:[email protected]',
                    'user:[email protected]',
                ]
            }]
        }

        actual_violations = set(
            itertools.chain(
                rules_engine.find_policy_violations(self.org789, org_policy),
                rules_engine.find_policy_violations(self.project1,
                                                    project_policy),
            ))

        # expected
        expected_outstanding_org = {
            'roles/editor':
            [IamPolicyMember.create_from('user:[email protected]')]
        }
        expected_outstanding_project = {
            'roles/editor':
            [IamPolicyMember.create_from('user:[email protected]')],
            'roles/viewer':
            [IamPolicyMember.create_from('user:[email protected]')]
        }

        expected_violations = set([
            scanner_rules.RuleViolation(
                rule_index=1,
                rule_name='my blacklist rule',
                resource_id=self.org789.id,
                resource_type=self.org789.type,
                violation_type='ADDED',
                role=org_policy['bindings'][0]['role'],
                members=tuple(expected_outstanding_org['roles/editor'])),
            scanner_rules.RuleViolation(
                rule_index=0,
                rule_name='my whitelist rule',
                resource_id=self.project1.id,
                resource_type=self.project1.type,
                violation_type='ADDED',
                role=project_policy['bindings'][0]['role'],
                members=tuple(expected_outstanding_project['roles/editor'])),
            scanner_rules.RuleViolation(
                rule_index=2,
                rule_name='my required rule',
                resource_id=self.project1.id,
                resource_type=self.project1.type,
                violation_type='REMOVED',
                role='roles/viewer',
                members=tuple(expected_outstanding_project['roles/viewer'])),
        ])

        self.assertItemsEqual(expected_violations, actual_violations)
コード例 #13
0
    def test_whitelist_blacklist_rules_vs_policy_has_violations(self):
        """Test a ruleset with whitelist and blacklist violating rules.

        Setup:
            * Mock find_ancestors().
            * Create a RulesEngine with RULES2 rule set.
            * Create policy.

        Expected result:
            * Find 1 rule violation.
        """
        # actual
        rules_local_path = get_datafile_path(__file__, 'test_rules_1.yaml')
        rules_engine = ire.IamRulesEngine(rules_local_path,
                                          self.fake_timestamp)
        # TODO: mock the rules local path to return RULES2
        rules_engine.rule_book = ire.IamRuleBook(test_rules.RULES2,
                                                 self.fake_timestamp)
        rules_engine.rule_book.org_res_rel_dao = mock.MagicMock()
        find_ancestor_mock = mock.MagicMock(side_effect=[[self.org789], []])
        rules_engine.rule_book.org_res_rel_dao.find_ancestors = \
            find_ancestor_mock

        policy = {
            'bindings': [{
                'role':
                'roles/editor',
                'members': [
                    'user:[email protected]', 'user:[email protected]',
                    'user:[email protected]'
                ]
            }]
        }

        actual_violations = set(
            itertools.chain(
                rules_engine.find_policy_violations(self.project1, policy),
                rules_engine.find_policy_violations(self.project2, policy)))

        # expected
        expected_outstanding1 = {
            'roles/editor':
            [IamPolicyMember.create_from('user:[email protected]')]
        }
        expected_outstanding2 = {
            'roles/editor':
            [IamPolicyMember.create_from('user:[email protected]')]
        }

        expected_violations = set([
            scanner_rules.RuleViolation(
                rule_index=0,
                rule_name='my rule',
                resource_id=self.project1.id,
                resource_type=self.project1.type,
                violation_type='ADDED',
                role=policy['bindings'][0]['role'],
                members=tuple(expected_outstanding1['roles/editor'])),
            scanner_rules.RuleViolation(
                rule_index=0,
                rule_name='my rule',
                resource_type=self.project2.type,
                resource_id=self.project2.id,
                violation_type='ADDED',
                role=policy['bindings'][0]['role'],
                members=tuple(expected_outstanding1['roles/editor'])),
            scanner_rules.RuleViolation(
                rule_index=1,
                rule_name='my other rule',
                resource_type=self.project2.type,
                resource_id=self.project2.id,
                violation_type='ADDED',
                role=policy['bindings'][0]['role'],
                members=tuple(expected_outstanding2['roles/editor'])),
            scanner_rules.RuleViolation(
                rule_index=2,
                rule_name='required rule',
                resource_id=self.project1.id,
                resource_type=self.project1.type,
                violation_type='REMOVED',
                role='roles/viewer',
                members=tuple([
                    IamPolicyMember.create_from(
                        'user:[email protected]')
                ]))
        ])

        self.assertItemsEqual(expected_violations, actual_violations)
コード例 #14
0
    def test_wildcard_resources_with_project_whitelist(self):
        """Test whitelisted wildcard resources.

        Setup:
            * Create a RulesEngine with RULES9 rule set.
            * Create policy.

        Expected result:
            * Find 2 rule violations:
               - A policy binding that violates the org whitelist.
               - A policy binding that violates the org whitelist, even though
                 the project whitelist allows it.
        """
        # actual
        rules_local_path = get_datafile_path(__file__, 'test_rules_1.yaml')
        rules_engine = ire.IamRulesEngine(rules_local_path)
        rules_engine.rule_book = ire.IamRuleBook({}, test_rules.RULES9,
                                                 self.fake_timestamp)
        rules_engine.rule_book.org_res_rel_dao = mock.MagicMock()
        # have to return 2 [self.org789] because the find_ancestors() call is
        # called twice, once for each find_violations().
        find_ancestor_mock = mock.MagicMock(
            side_effect=[[self.org789], [self.org789]])
        rules_engine.rule_book.org_res_rel_dao.find_ancestors = \
            find_ancestor_mock

        project_policy = {
            'bindings': [
                {
                    'role':
                    'roles/owner',
                    'members': [
                        'user:[email protected]',
                        'user:[email protected]',
                        'user:[email protected]',
                    ]
                },
                {
                    'role': 'roles/editor',
                    'members': [
                        'user:[email protected]',
                    ]
                },
            ]
        }

        actual_violations = set(
            rules_engine.find_policy_violations(self.project1, project_policy))

        # expected
        # [email protected] not in any whitelists
        # [email protected] is allowed by the project whitelist
        # but we still alert due to the org whitelist.
        expected_outstanding_proj = {
            'roles/owner': [
                IamPolicyMember.create_from('user:[email protected]'),
                IamPolicyMember.create_from(
                    'user:[email protected]'),
            ],
            'roles/editor':
            [IamPolicyMember.create_from('user:[email protected]')]
        }

        expected_violations = set([
            scanner_rules.RuleViolation(
                rule_index=0,
                rule_name='org whitelist',
                resource_id=self.project1.id,
                resource_type=self.project1.type,
                violation_type='ADDED',
                role=project_policy['bindings'][0]['role'],
                members=tuple(expected_outstanding_proj['roles/owner'])),
            scanner_rules.RuleViolation(
                rule_index=0,
                rule_name='org whitelist',
                resource_id=self.project1.id,
                resource_type=self.project1.type,
                violation_type='ADDED',
                role=project_policy['bindings'][1]['role'],
                members=tuple(expected_outstanding_proj['roles/editor'])),
        ])

        self.assertItemsEqual(expected_violations, actual_violations)
コード例 #15
0
    def setUp(self, mock_db_connector):
        mock_db_connector.return_value = None
        self.resource_name = 'violations'
        self.dao = violation_dao.ViolationDao()
        self.fake_snapshot_timestamp = '12345'
        self.fake_table_name = ('%s_%s' %
            (self.resource_name, self.fake_snapshot_timestamp))
        self.fake_violations = [
            rules.RuleViolation(
                resource_type='x',
                resource_id='1',
                rule_name='rule name',
                rule_index=0,
                violation_type='ADDED',
                role='roles/editor',
                members=[iam.IamPolicyMember.create_from(m)
                    for m in ['user:[email protected]', 'user:[email protected]']],
            ),
            rules.RuleViolation(
                resource_type='%se' % ('a'*300),
                resource_id='1',
                rule_name='%sh' % ('b'*300),
                rule_index=1,
                violation_type='REMOVED',
                role='%s' % ('c'*300),
                members=[iam.IamPolicyMember.create_from(
                    'user:%s' % ('d'*300))],
            ),
        ]
        long_string = '{"member": "user:%s", "role": "%s"}' % (('d'*300),('c'*300))

        self.fake_flattened_violations = [
            {
                'resource_id': '1',
                'resource_type':
                    self.fake_violations[0].resource_type,
                'rule_index': 0,
                'rule_name': self.fake_violations[0].rule_name,
                'violation_type': self.fake_violations[0].violation_type,
                'violation_data': {
                    'role': self.fake_violations[0].role,
                    'member': 'user:[email protected]'
                }
            },
            {
                'resource_id': '1',
                'resource_type':
                    self.fake_violations[0].resource_type,
                'rule_index': 0,
                'rule_name': self.fake_violations[0].rule_name,
                'violation_type': self.fake_violations[0].violation_type,
                'violation_data': {
                    'role': self.fake_violations[0].role,
                    'member': 'user:[email protected]'
                }
            },
            {
                'resource_id': '1',
                'resource_type':
                    self.fake_violations[1].resource_type,
                'rule_index': 1,
                'rule_name': self.fake_violations[1].rule_name,
                'violation_type': self.fake_violations[1].violation_type,
                'violation_data': {
                    'role': self.fake_violations[1].role,
                    'member': 'user:%s' % ('d'*300)
                }
            },
        ]

        self.expected_fake_violations = [
            ('2e598a34bf36b5ad577f6e8eec47acf0ffe71143e82bc78c9cfaac8f553a4fa4f09078ebe0769639d9dc9fffc2dffb94345ae6696fbe4e646e8b9bb723fd3ab0',
             'x', '1', 'rule name', 0, 'ADDED',
             '{"member": "user:[email protected]", "role": "roles/editor"}',
             '2020-08-28 10:20:30'),
            ('5420235c547006300e7842c45c9b0419bc1c5590fd4200607e9925010123f5905f374c2b182420f6ecb161146c8d18c6683045026c810009154b03a56f5a94f5',
             'x', '1', 'rule name', 0, 'ADDED',
             '{"member": "user:[email protected]", "role": "roles/editor"}',
             '2010-08-28 10:20:30'),
            ('i'*255,
             'a'*255, '1', 'b'*255, 1, 'REMOVED', long_string,
             '2030-08-28 10:20:30'),
        ]