def test_propagate_all(self): """Test clean propagation of all ACL entries.""" with factories.single_commit(): person = factories.PersonFactory() task = wf_factories.TaskGroupTaskFactory() audit = factories.AuditFactory() factories.RelationshipFactory( source=audit, destination=audit.program, ) acl_ids = [ factories.AccessControlListFactory( ac_role=self.roles["Program"]["Program Editors"], object=audit.program, person=person, ).id ] factories.AccessControlListFactory( ac_role=self.roles["Workflow"]["Workflow Member"], object=task.workflow, person=person, ) # propagate all non WF entries propagation._propagate(acl_ids) self.assertEqual(all_models.AccessControlList.query.count(), 4) all_models.AccessControlList.query.filter( all_models.AccessControlList.parent_id.isnot(None) ).delete() self.assertEqual(all_models.AccessControlList.query.count(), 2) # propagate all including WF entries propagation.propagate_all() self.assertEqual(all_models.AccessControlList.query.count(), 6)
def test_deep_propagation(self): """Test nested propagation from programs to assessments. Test 3 people with 2 roles on programs to propagate to assessments """ audit_count = 3 with factories.single_commit(): for i in range(audit_count): audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) factories.RelationshipFactory( source=audit.program if i % 2 == 0 else audit, destination=audit.program if i % 2 == 1 else audit, ) factories.RelationshipFactory( source=assessment if i % 2 == 0 else audit, destination=assessment if i % 2 == 1 else audit, ) acl_ids = [acl.id for acl in audit.program._access_control_list] propagation._propagate(acl_ids, self.user_id) assessment_acls = all_models.AccessControlList.query.filter( all_models.AccessControlList.object_type == all_models.Assessment.__name__, all_models.AccessControlList.parent_id.isnot(None), ).all() # one for PR, PE, PM self.assertEqual(len(assessment_acls), 3)
def test_propagate_all(self): """Test clean propagation of all ACL entries.""" with factories.single_commit(): person = factories.PersonFactory() task = wf_factories.TaskGroupTaskFactory() audit = factories.AuditFactory() factories.RelationshipFactory( source=audit, destination=audit.program, ) acl_ids = [ factories.AccessControlListFactory( ac_role=self.roles["Program"]["Program Editors"], object=audit.program, person=person, ).id ] factories.AccessControlListFactory( ac_role=self.roles["Workflow"]["Workflow Member"], object=task.workflow, person=person, ) # propagate all non WF entries propagation._propagate(acl_ids) self.assertEqual(all_models.AccessControlList.query.count(), 4) all_models.AccessControlList.query.filter( all_models.AccessControlList.parent_id.isnot(None)).delete() self.assertEqual(all_models.AccessControlList.query.count(), 2) # propagate all including WF entries propagation.propagate_all() self.assertEqual(all_models.AccessControlList.query.count(), 6)
def test_propagate_all(self): """Test clean propagation of all ACL entries.""" with factories.single_commit(): wf_factories.TaskGroupTaskFactory() audit = factories.AuditFactory() factories.RelationshipFactory( source=audit, destination=audit.program, ) acl_ids = [acl.id for acl in audit.program._access_control_list] propagation._propagate(acl_ids, self.user_id) self.assertEqual(all_models.AccessControlList.query.count(), 17) propagation.propagate_all() self.assertEqual(all_models.AccessControlList.query.count(), 25)
def test_deep_propagation(self): """Test nested propagation from programs to assessments. Test 3 people with 2 roles on programs to propagate to assessments """ audit_count = 3 people_count = 3 program_roles = ["Program Editors", "Program Readers"] with factories.single_commit(): people = [factories.PersonFactory() for _ in range(people_count)] for i in range(audit_count): audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) factories.RelationshipFactory( source=audit.program if i % 2 == 0 else audit, destination=audit.program if i % 2 == 1 else audit, ) factories.RelationshipFactory( source=assessment if i % 2 == 0 else audit, destination=assessment if i % 2 == 1 else audit, ) acl_ids = [] for person in people: for role_name in program_roles: acl_ids.append( factories.AccessControlListFactory( ac_role=self.roles["Program"][role_name], object=audit.program, person=person, ).id, ) propagation._propagate(acl_ids) assessment_acls = all_models.AccessControlList.query.filter( all_models.AccessControlList.object_type == all_models.Assessment.__name__ ).all() self.assertEqual( len(assessment_acls), 3 * 2 # 3 people each with 2 roles on a program that should be # propagated ) for assessment_acl in assessment_acls: self.assertIsNotNone(assessment_acl.parent_id)
def test_deep_propagation(self): """Test nested propagation from programs to assessments. Test 3 people with 2 roles on programs to propagate to assessments """ audit_count = 3 people_count = 3 program_roles = ["Program Editors", "Program Readers"] with factories.single_commit(): people = [factories.PersonFactory() for _ in range(people_count)] for i in range(audit_count): audit = factories.AuditFactory() assessment = factories.AssessmentFactory(audit=audit) factories.RelationshipFactory( source=audit.program if i % 2 == 0 else audit, destination=audit.program if i % 2 == 1 else audit, ) factories.RelationshipFactory( source=assessment if i % 2 == 0 else audit, destination=assessment if i % 2 == 1 else audit, ) acl_ids = [] for person in people: for role_name in program_roles: acl_ids.append( factories.AccessControlListFactory( ac_role=self.roles["Program"][role_name], object=audit.program, person=person, ).id, ) propagation._propagate(acl_ids) assessment_acls = all_models.AccessControlList.query.filter( all_models.AccessControlList.object_type == all_models.Assessment.__name__).all() self.assertEqual( len(assessment_acls), 3 * 2 # 3 people each with 2 roles on a program that should be # propagated ) for assessment_acl in assessment_acls: self.assertIsNotNone(assessment_acl.parent_id)
def test_propagate_all(self): """Test clean propagation of all ACL entries.""" with factories.single_commit(): person = factories.PersonFactory() audit = factories.AuditFactory() factories.RelationshipFactory( source=audit, destination=audit.program, ) acl_ids = [ factories.AccessControlListFactory( ac_role=self.roles["Program"]["Program Editors"], object=audit.program, person=person, ).id ] propagation._propagate(acl_ids) self.assertEqual(all_models.AccessControlList.query.count(), 3) propagation._delete_all_propagated_acls() self.assertEqual(all_models.AccessControlList.query.count(), 1) propagation.propagate_all() self.assertEqual(all_models.AccessControlList.query.count(), 3)
def test_complex_propagation_count(self): """Test multiple object ACL propagation. This test is meant to catch invalid ACL entries for propagation that can not happen. Example for this is propagation control -> relationships -> document. In that propagation rule we should only propagate control acl entries to relationships to documents. But what can happen is; when a control has multiple relationships, some to objects and only one to document, all of those relationships would get an ACL entry even though in some cases that is a propagation dead end. Setup for this test is: Objects: control regulation objective program audit assessment, assessment_2 Relationships: control - regulation control - objective objective - regulations program - control, regulation, objective, audit audit - assessment, assessment_2, audit - control-snapshot, regulation-snapshot, objective-snapshot control_snapshot - regulation_snapshot control_snapshot - objective_snapshot objective_snapshot - regulations_snapshot document - regulation, objective, control evidence - assessment """ # pylint: disable=too-many-locals with factories.single_commit(): person = factories.PersonFactory() control = factories.ControlFactory() regulation = factories.RegulationFactory() objective = factories.ObjectiveFactory() normal_objects = [control, regulation, objective] for obj1, obj2 in itertools.combinations(normal_objects, 2): factories.RelationshipFactory(source=obj1, destination=obj2) assessment = factories.AssessmentFactory() assessment_2 = factories.AssessmentFactory(audit=assessment.audit) factories.RelationshipFactory( source=assessment, destination=assessment.audit, ) factories.RelationshipFactory( source=assessment_2, destination=assessment.audit, ) factories.RelationshipFactory( source=assessment.audit, destination=assessment.audit.program, ) for obj in normal_objects: factories.RelationshipFactory( source=assessment.audit.program, destination=obj, ) snapshots = self._create_snapshots(assessment.audit, normal_objects) for snapshot in snapshots: factories.RelationshipFactory( source=assessment.audit, destination=snapshot, ) for obj1, obj2 in itertools.combinations(snapshots, 2): factories.RelationshipFactory(source=obj1, destination=obj2) for obj in normal_objects: document = factories.DocumentFactory() factories.RelationshipFactory(source=obj, destination=document) evidence = factories.EvidenceUrlFactory() factories.RelationshipFactory(source=evidence, destination=assessment) acl_entry = factories.AccessControlListFactory( person=person, ac_role=self.roles["Control"]["Admin"], object=control, ) propagation._propagate([acl_entry.id]) self.assertEqual( all_models.AccessControlList.query.count(), 3, # 1 for control, 1 for relationship to document and 1 for document. ) acl_entry = factories.AccessControlListFactory( person=person, ac_role=self.roles["Program"]["Program Editors"], object=assessment.audit.program, ) propagation._propagate([acl_entry.id]) self.assertEqual( all_models.AccessControlList.query.count(), 3 + 1 + 2 + 4 + 6 + 2 + 6 + 6 # 3 previous entries for control # 1 original program ACL entry # 2 for audit (relationship + audit propagation) # 4 for assessments (2 assessments and 2 relationships for them) # 6 for snapshots (3 snapshots with relationships) # 2 assessment document with relationships # 6 for normal objects # 6 for normal object documents )
def test_complex_propagation_count(self): """Test multiple object ACL propagation. This test is meant to catch invalid ACL entries for propagation that can not happen. Example for this is propagation control -> relationships -> document. In that propagation rule we should only propagate control acl entries to relationships to documents. But what can happen is; when a control has multiple relationships, some to objects and only one to document, all of those relationships would get an ACL entry even though in some cases that is a propagation dead end. Setup for this test is: Objects: control regulation objective program audit assessment, assessment_2 Relationships: control - regulation control - objective objective - regulations program - control, regulation, objective, audit audit - assessment, assessment_2, audit - control-snapshot, regulation-snapshot, objective-snapshot control_snapshot - regulation_snapshot control_snapshot - objective_snapshot objective_snapshot - regulations_snapshot document - regulation, objective, control evidence - assessment """ # pylint: disable=too-many-locals with factories.single_commit(): control = factories.ControlFactory() regulation = factories.RegulationFactory() objective = factories.ObjectiveFactory() normal_objects = [control, regulation, objective] for obj1, obj2 in itertools.combinations(normal_objects, 2): if control in (obj1, obj2): with mock.patch( 'ggrc.models.relationship.is_external_app_user', return_value=True): factories.RelationshipFactory(source=obj1, destination=obj2, is_external=True) else: factories.RelationshipFactory(source=obj1, destination=obj2) assessment = factories.AssessmentFactory() assessment_2 = factories.AssessmentFactory(audit=assessment.audit) factories.RelationshipFactory( source=assessment, destination=assessment.audit, ) factories.RelationshipFactory( source=assessment_2, destination=assessment.audit, ) factories.RelationshipFactory( source=assessment.audit, destination=assessment.audit.program, ) for obj in normal_objects: factories.RelationshipFactory( source=assessment.audit.program, destination=obj, ) snapshots = self._create_snapshots(assessment.audit, normal_objects) for snapshot in snapshots: factories.RelationshipFactory( source=assessment.audit, destination=snapshot, ) for obj1, obj2 in itertools.combinations(snapshots, 2): factories.RelationshipFactory(source=obj1, destination=obj2) for obj in normal_objects: document = factories.DocumentFactory() factories.RelationshipFactory(source=obj, destination=document) evidence = factories.EvidenceUrlFactory() factories.RelationshipFactory(source=evidence, destination=assessment) acl_entry = control._access_control_list[0] propagation._propagate([acl_entry.id], self.user_id) self.assertEqual( all_models.AccessControlList.query.filter( all_models.AccessControlList.parent_id.isnot(None)).count(), 2, # 1 for relationship to document and 1 for document. ) acl_entry = next( acl for acl in assessment.audit.program._access_control_list if acl.ac_role.name == "Program Editors") propagation._propagate([acl_entry.id], self.user_id) self.assertEqual( all_models.AccessControlList.query.filter( all_models.AccessControlList.parent_id.isnot(None)).count(), 2 + 2 + 4 + 6 + 2 + 6 + 6 # 2 previous entries for control # 2 for audit (relationship + audit propagation) # 4 for assessments (2 assessments and 2 relationships for them) # 6 for snapshots (3 snapshots with relationships) # 2 assessment document with relationships # 6 for normal objects # 6 for normal object documents )
def test_complex_propagation_count(self): """Test multiple object ACL propagation. This test is meant to catch invalid ACL entries for propagation that can not happen. Example for this is propagation control -> relationships -> document. In that propagation rule we should only propagate control acl entries to relationships to documents. But what can happen is; when a control has multiple relationships, some to objects and only one to document, all of those relationships would get an ACL entry even though in some cases that is a propagation dead end. Setup for this test is: Objects: control regulation objective program audit assessment, assessment_2 Relationships: control - regulation control - objective objective - regulations program - control, regulation, objective, audit audit - assessment, assessment_2, audit - control-snapshot, regulation-snapshot, objective-snapshot control_snapshot - regulation_snapshot control_snapshot - objective_snapshot objective_snapshot - regulations_snapshot document - regulation, objective, control evidence - assessment """ with factories.single_commit(): person = factories.PersonFactory() control = factories.ControlFactory() regulation = factories.RegulationFactory() objective = factories.ObjectiveFactory() normal_objects = [control, regulation, objective] for obj1, obj2 in itertools.combinations(normal_objects, 2): factories.RelationshipFactory(source=obj1, destination=obj2) assessment = factories.AssessmentFactory() assessment_2 = factories.AssessmentFactory(audit=assessment.audit) factories.RelationshipFactory( source=assessment, destination=assessment.audit, ) factories.RelationshipFactory( source=assessment_2, destination=assessment.audit, ) factories.RelationshipFactory( source=assessment.audit, destination=assessment.audit.program, ) for obj in normal_objects: factories.RelationshipFactory( source=assessment.audit.program, destination=obj, ) snapshots = self._create_snapshots(assessment.audit, normal_objects) for snapshot in snapshots: factories.RelationshipFactory( source=assessment.audit, destination=snapshot, ) for obj1, obj2 in itertools.combinations(snapshots, 2): factories.RelationshipFactory(source=obj1, destination=obj2) for obj in normal_objects: document = factories.DocumentFactory() factories.RelationshipFactory(source=obj, destination=document) evidence = factories.EvidenceUrlFactory() factories.RelationshipFactory(source=evidence, destination=assessment) acl_entry = factories.AccessControlListFactory( person=person, ac_role=self.roles["Control"]["Admin"], object=control, ) propagation._propagate([acl_entry.id]) self.assertEqual( all_models.AccessControlList.query.count(), 3, # 1 for control, 1 for relationship to document and 1 for document. ) acl_entry = factories.AccessControlListFactory( person=person, ac_role=self.roles["Program"]["Program Editors"], object=assessment.audit.program, ) propagation._propagate([acl_entry.id]) self.assertEqual( all_models.AccessControlList.query.count(), 3 + 1 + 2 + 4 + 6 + 2 + 6 + 6 # 3 previous entries for control # 1 original program ACL entry # 2 for audit (relationship + audit propagation) # 4 for assessments (2 assessments and 2 relationships for them) # 6 for snapshots (3 snapshots with relationships) # 2 assessment document with relationships # 6 for normal objects # 6 for normal object documents )
def test_complex_propagation_count(self): """Test multiple object ACL propagation. This test is meant to catch invalid ACL entries for propagation that can not happen. Example for this is propagation control -> relationships -> document. In that propagation rule we should only propagate control acl entries to relationships to documents. But what can happen is; when a control has multiple relationships, some to objects and only one to document, all of those relationships would get an ACL entry even though in some cases that is a propagation dead end. Setup for this test is: Objects: control regulation objective program audit assessment, assessment_2 Relationships: control - regulation control - objective objective - regulations program - control, regulation, objective, audit audit - assessment, assessment_2, audit - control-snapshot, regulation-snapshot, objective-snapshot control_snapshot - regulation_snapshot control_snapshot - objective_snapshot objective_snapshot - regulations_snapshot document - regulation, objective, control evidence - assessment """ # pylint: disable=too-many-locals with factories.single_commit(): control = factories.ControlFactory() regulation = factories.RegulationFactory() objective = factories.ObjectiveFactory() normal_objects = [control, regulation, objective] for obj1, obj2 in itertools.combinations(normal_objects, 2): if control in (obj1, obj2): with mock.patch('ggrc.models.relationship.is_external_app_user', return_value=True): factories.RelationshipFactory(source=obj1, destination=obj2, is_external=True) else: factories.RelationshipFactory(source=obj1, destination=obj2) assessment = factories.AssessmentFactory() assessment_2 = factories.AssessmentFactory(audit=assessment.audit) factories.RelationshipFactory( source=assessment, destination=assessment.audit, ) factories.RelationshipFactory( source=assessment_2, destination=assessment.audit, ) factories.RelationshipFactory( source=assessment.audit, destination=assessment.audit.program, ) for obj in normal_objects: factories.RelationshipFactory( source=assessment.audit.program, destination=obj, ) snapshots = self._create_snapshots(assessment.audit, normal_objects) for snapshot in snapshots: factories.RelationshipFactory( source=assessment.audit, destination=snapshot, ) for obj1, obj2 in itertools.combinations(snapshots, 2): factories.RelationshipFactory(source=obj1, destination=obj2) for obj in normal_objects: document = factories.DocumentFactory() factories.RelationshipFactory(source=obj, destination=document) evidence = factories.EvidenceUrlFactory() factories.RelationshipFactory(source=evidence, destination=assessment) acl_entry = control._access_control_list[0] propagation._propagate([acl_entry.id], self.user_id) self.assertEqual( all_models.AccessControlList.query.filter( all_models.AccessControlList.parent_id.isnot(None) ).count(), 2, # 1 for relationship to document and 1 for document. ) acl_entry = next( acl for acl in assessment.audit.program._access_control_list if acl.ac_role.name == "Program Editors" ) propagation._propagate([acl_entry.id], self.user_id) self.assertEqual( all_models.AccessControlList.query.filter( all_models.AccessControlList.parent_id.isnot(None) ).count(), 2 + 2 + 4 + 6 + 2 + 6 + 6 # 2 previous entries for control # 2 for audit (relationship + audit propagation) # 4 for assessments (2 assessments and 2 relationships for them) # 6 for snapshots (3 snapshots with relationships) # 2 assessment document with relationships # 6 for normal objects # 6 for normal object documents )