예제 #1
0
    def test_acl_definitions(self, model):
        """Test ACL column definitions."""
        with factories.single_commit():
            factory = factories.AccessControlRoleFactory
            factories.AccessControlRoleFactory(object_type="Control",
                                               read=True)
            role_names = {
                factory(object_type=model.__name__).name
                for _ in range(2)
            }

        expected_names = set()
        if issubclass(model, roleable.Roleable):
            expected_names = role_names

        definitions = get_object_column_definitions(model)
        definition_names = {d["display_name"]: d for d in definitions.values()}
        self.assertLessEqual(expected_names, set(definition_names.keys()))
예제 #2
0
 def test_get_mandatory_acrs(self, mandatory):
   """ACR and mandatory meta info if mandatory flag is {0}."""
   control_id = self.control.id
   acr = factories.AccessControlRoleFactory(name="test_name",
                                            object_type=self.control.type,
                                            mandatory=mandatory)
   acr_id = acr.id
   resp = self.api.client.get(
       "/api/revisions"
       "?resource_type=Control&resource_id={}".format(control_id)
   )
   collection = resp.json["revisions_collection"]["revisions"]
   self.assertTrue(collection)
   self.assertIn("meta", collection[0])
   self.assertIn("mandatory", collection[0]["meta"])
   self.assertIn("access_control_roles", collection[0]["meta"]["mandatory"])
   mandatory_acrs = collection[0]["meta"]["mandatory"]["access_control_roles"]
   self.assertEqual(mandatory, acr_id in mandatory_acrs)
예제 #3
0
 def test_acl_filter(self, test_role_name):
     """Control Snapshots are filtered and sorted by ACL Role."""
     with factories.single_commit():
         program = factories.ProgramFactory()
         person1 = factories.PersonFactory(name="Ann",
                                           email="*****@*****.**")
         control1 = factories.ControlFactory()
         control2 = factories.ControlFactory()
         program_id = program.id
         control1_id = control1.id
         control2_id = control2.id
         factories.RelationshipFactory(source=program, destination=control1)
         factories.RelationshipFactory(source=program, destination=control2)
         factories.AccessControlListFactory(
             ac_role=factories.AccessControlRoleFactory(
                 name=test_role_name, object_type="Control"),
             person=person1,
             object_id=control1_id,
             object_type="Control",
         )
     revision = all_models.Revision.query.filter(
         all_models.Revision.resource_type == "Control",
         all_models.Revision.resource_id == control1_id).order_by(
             all_models.Revision.updated_at.desc()).first()
     revision.content = control1.log_json()
     db.session.add(revision)
     db.session.commit()
     program = models.Program.query.filter_by(id=program_id).one()
     self._create_audit(program=program, title="some title")
     control_user1_result = self._get_first_result_set(
         self._make_snapshot_query_dict(
             "Control",
             expression=['{}'.format(test_role_name), "=", "Ann"]),
         "Snapshot",
     )
     self.assertEqual(control_user1_result["count"], 1)
     snaps_dict = dict(
         all_models.Snapshot.query.filter(
             all_models.Snapshot.child_type == "Control").values(
                 "child_id", "id"))
     self.assertIn(snaps_dict[control1_id],
                   [i["id"] for i in control_user1_result["values"]])
     self.assertNotIn(snaps_dict[control2_id],
                      [i["id"] for i in control_user1_result["values"]])
    def test_proposal_apply_review_status(self, notification_type,
                                          num_notifications_expected):
        """Change via proposal with ignorable attrs review status not change"""
        with factories.single_commit():
            risk = factories.RiskFactory()
            review = factories.ReviewFactory(
                status=all_models.Review.STATES.REVIEWED,
                reviewable=risk,
                notification_type=notification_type)
            review_id = review.id

            user = factories.PersonFactory()
            acl = factories.AccessControlListFactory(
                ac_role=factories.AccessControlRoleFactory(object_type="Risk"),
                object=risk)

            proposal_content = {
                "access_control_list": {
                    acl.ac_role_id: {
                        "added": [{
                            "id": user.id,
                            "email": user.email
                        }],
                        "deleted": []
                    }
                }
            }

            proposal = factories.ProposalFactory(instance=risk,
                                                 content=proposal_content,
                                                 agenda="agenda content")

        self.api.modify_object(proposal, {"status": proposal.STATES.APPLIED})
        review = all_models.Review.query.get(review_id)
        self.assertEqual(review.status, all_models.Review.STATES.REVIEWED)

        review_notif_types = all_models.Review.NotificationObjectTypes
        notif_unreviewed_type = all_models.Notification.query.join(
            all_models.NotificationType).filter(
                all_models.NotificationType.name ==
                review_notif_types.STATUS_UNREVIEWED).all()

        self.assertEqual(num_notifications_expected,
                         len(notif_unreviewed_type))
    def test_export_deleted_acr(self):
        """Test exporting snapshots with ACL entries for deleted ACRs."""
        # pylint: disable=too-many-locals
        with factories.single_commit():
            # Create one more custom role
            ac_role = factories.AccessControlRoleFactory(
                object_type="Control",
                name="Custom Role",
            )
            control = factories.ControlFactory(slug="Control 1")
            person = factories.PersonFactory()
            factories.AccessControlListFactory(
                ac_role=ac_role,
                person=person,
                object=control,
            )
            audit = factories.AuditFactory()

        # pylint: disable=protected-access
        # This is used to update control revision data with the new ACL entry
        # without making a put request to that control.
        factories.ModelFactory._log_event(control)
        self._create_snapshots(audit, [control])

        db.session.delete(ac_role)
        db.session.commit()

        search_request = [{
            "object_name": "Snapshot",
            "filters": {
                "expression": {
                    "left": "child_type",
                    "op": {
                        "name": "="
                    },
                    "right": "Control",
                },
            },
        }]
        parsed_data = self.export_parsed_csv(
            search_request)["Control Snapshot"][0]

        self.assertNotIn("Custom Role", parsed_data)
예제 #6
0
    def test_single_acl_entry(self):
        """Test ACL column import with single email."""
        role = factories.AccessControlRoleFactory(object_type="Market")
        role_id = role.id

        response = self.import_data(
            OrderedDict([
                ("object_type", "Market"),
                ("code", "market-1"),
                ("title", "Title"),
                ("Admin", "*****@*****.**"),
                (role.name, "*****@*****.**"),
            ]))
        self._check_csv_response(response, {})
        market = models.Market.query.first()
        self.assertEqual(len(market.access_control_list), 1)
        self.assertEqual(market.access_control_list[0].ac_role_id, role_id)
        self.assertEqual(market.access_control_list[0].person.email,
                         "*****@*****.**")
예제 #7
0
    def test_proposal_delete_acl(self):
        """Test simple delete acl proposal."""
        with factories.single_commit():
            control = factories.ControlFactory(title="1")
            role = factories.AccessControlRoleFactory(name="role")
            person = factories.PersonFactory()
            factories.AccessControlListFactory(
                person=person,
                ac_role=role,
                object=control,
            )
        with factories.single_commit():
            latest_revision = all_models.Revision.query.filter(
                all_models.Revision.resource_id == control.id,
                all_models.Revision.resource_type == control.type).order_by(
                    all_models.Revision.created_at.desc()).first()
            latest_revision.content = control.log_json()

        control_id = control.id
        role_id = unicode(role.id)
        person_id = person.id
        control_content = control.log_json()
        control_content["access_control_list"] = []
        self.create_proposal(control,
                             full_instance_content=control_content,
                             agenda="delete access control roles",
                             context=None)
        control = all_models.Control.query.get(control_id)
        self.assertEqual(1, len(control.proposals))
        self.assertIn("access_control_list", control.proposals[0].content)
        acl = control.proposals[0].content["access_control_list"]
        self.assertIn(role_id, acl)
        role = control.proposals[0].content["access_control_list"][role_id]
        person = all_models.Person.query.get(person_id)
        self.assertEqual(
            {
                "added": [],
                "deleted": [{
                    "id": person_id,
                    "email": person.email
                }],
            }, role)
        self.assertEqual(1, len(control.comments))
예제 #8
0
    def test_acl_multiple_entries(self):
        """Test ACL column import with multiple emails."""
        role = factories.AccessControlRoleFactory(object_type="Market")
        emails = {factories.PersonFactory().email for _ in range(3)}

        response = self.import_data(
            OrderedDict([
                ("object_type", "Market"),
                ("code", "market-1"),
                ("title", "Title"),
                ("Admin", "*****@*****.**"),
                (role.name, "\n".join(emails)),
            ]))
        self._check_csv_response(response, {})
        market = models.Market.query.first()
        self.assertEqual(
            {acl.person.email
             for acl in market.access_control_list},
            emails,
        )
    def test_admin_has_access(self):
        """Ensure that global creator has access to created proposal by him"""
        role_creator = all_models.Role.query.filter(
            all_models.Role.name == "Creator").one()

        # prepare - create program, assign roles
        factories.AccessControlRoleFactory(name="ACL_Reader",
                                           update=0,
                                           object_type="Program")
        with factories.single_commit():
            program = factories.ProgramFactory()
            person = factories.PersonFactory()
            rbac_factories.UserRoleFactory(role=role_creator, person=person)
            factories.AccessControlPersonFactory(
                ac_list=program.acr_name_acl_map["ACL_Reader"],
                person=person,
            )
            program_id = program.id

        # make query to create proposal
        self.api.set_user(person)
        self.client.get("/login")

        acr_class = all_models.AccessControlRole
        acr = acr_class.query.filter(
            acr_class.name == 'ProposalEditor',
            acr_class.object_type == 'Proposal').one()

        create_data = self._get_create_proposal_request(
            program_id, acr.id, person.id)
        self.api.post(all_models.Proposal, create_data)

        query_data = _get_query_proposal_request(program_id)
        headers = {
            "Content-Type": "application/json",
        }
        resp = self.api.client.post("/query",
                                    data=json.dumps(query_data),
                                    headers=headers).json
        self.assertEqual(1, len(resp))
        self.assertEqual(resp[0]["Proposal"]["count"], 1)
예제 #10
0
    def test_import_control_duplicate_slugs(self):
        """Test import does not fail when two objects with the same slug are
    imported."""
        with factories.single_commit():
            role_name = factories.AccessControlRoleFactory(
                object_type="Control").name
            emails = [factories.PersonFactory().email for _ in range(2)]

        control = factories.ControlFactory()
        self.import_data(
            collections.OrderedDict([
                ("object_type", "Control"),
                ("code", control.slug),
                ("title", "Title"),
                ("Admin", "*****@*****.**"),
                (role_name, "\n".join(emails)),
            ]))

        import_dicts = [
            collections.OrderedDict([
                ("object_type", "Control"),
                ("code", control.slug),
                ("title", "Title"),
                ("Admin", "*****@*****.**"),
                (role_name, "\n".join(emails)),
            ]),
            collections.OrderedDict([
                ("object_type", "Control"),
                ("code", control.slug),
                ("title", "Title"),
                ("Admin", "*****@*****.**"),
                (role_name, "\n".join(emails)),
            ]),
        ]
        response = self.import_data(*import_dicts)
        fail_response = {
            u'message': u'Import failed due to server error.',
            u'code': 400
        }
        self.assertNotEqual(response, fail_response)
예제 #11
0
 def test_proposal_for_acl(self):
   """Test simple add acl proposal."""
   with factories.single_commit():
     control = factories.ControlFactory(title="1")
     role = factories.AccessControlRoleFactory(name="role")
     person = factories.PersonFactory()
   control_id = control.id
   role_id = unicode(role.id)
   person_id = person.id
   control_content = control.log_json()
   control_content["access_control_list"] = [
       {"ac_role_id": role_id, "person": {"type": "Person", "id": person.id}}
   ]
   resp = self.api.post(
       all_models.Proposal,
       {"proposal": {
           "instance": {
               "id": control.id,
               "type": control.type,
           },
           # "content": {"123": 123},
           "full_instance_content": control_content,
           "agenda": "update access control roles",
           "context": None,
       }})
   self.assertEqual(201, resp.status_code)
   control = all_models.Control.query.get(control_id)
   self.assertEqual(1, len(control.proposals))
   self.assertIn("access_control_list", control.proposals[0].content)
   acl = control.proposals[0].content["access_control_list"]
   self.assertIn(role_id, acl)
   role = control.proposals[0].content["access_control_list"][role_id]
   person = all_models.Person.query.get(person_id)
   self.assertEqual(
       {
           "added": [{"id": person_id, "email": person.email}],
           "deleted": [],
       },
       role)
   self.assertEqual(1, len(control.comments))
예제 #12
0
 def test_proposal_for_acl(self):
     """Test simple add acl proposal."""
     with factories.single_commit():
         control = factories.ControlFactory(title="1")
         role = factories.AccessControlRoleFactory(name="role",
                                                   object_type=control.type,
                                                   internal=False)
         person = factories.PersonFactory()
     control_id = control.id
     role_id = unicode(role.id)
     person_id = person.id
     control_content = control.log_json()
     control_content["access_control_list"] = [{
         "ac_role_id": role_id,
         "person": {
             "type": "Person",
             "id": person.id
         }
     }]
     self.create_proposal(control,
                          full_instance_content=control_content,
                          agenda="update access control roles",
                          context=None)
     control = all_models.Control.query.get(control_id)
     self.assertEqual(1, len(control.proposals))
     self.assertIn("access_control_list", control.proposals[0].content)
     acl = control.proposals[0].content["access_control_list"]
     self.assertIn(role_id, acl)
     role = control.proposals[0].content["access_control_list"][role_id]
     person = all_models.Person.query.get(person_id)
     self.assertEqual(
         {
             "added": [{
                 "id": person_id,
                 "email": person.email
             }],
             "deleted": [],
         }, role)
     self.assertEqual(1, len(control.comments))
예제 #13
0
    def test_autogenerated_no_acl_in_snapshot(self, field, role_name):
        """Test autogenerated assessment assignees base on template settings

    and no ACL list in snapshot."""
        email = "{}@example.com".format(field)
        with factories.single_commit():
            person = factories.PersonFactory(email=email, name=field)
            factories.AccessControlRoleFactory(
                name=role_name,
                object_type=self.snapshot.child_type,
            )
            template = factories.AssessmentTemplateFactory(
                test_plan_procedure=False,
                procedure_description="Assessment Template Test Plan",
                default_people={"assessors": role_name})
            content = self.control.log_json()
            content.pop("access_control_list")
            content[field] = {"id": person.id}
            self.snapshot.revision.content = content
            db.session.add(self.snapshot.revision)
        response = self.assessment_post(template)
        self.assert_assignees("Assessor", response, email)
    def test_multiple_acl_roles_update(self, first_roles, edited_roles):
        """Test updating objects via import with multiple ACL roles."""
        with factories.single_commit():
            for email in self._random_emails:
                factories.PersonFactory(email=email)

            for role_name in first_roles.keys():
                factories.AccessControlRoleFactory(
                    object_type="Market",
                    name=role_name,
                )

        import_dict = self._generate_role_import_dict(first_roles)
        self.import_data(import_dict)
        market = models.Market.query.first()

        stored_roles = {}
        for role_name in first_roles.keys():
            stored_roles[role_name] = {
                acl.person.email
                for acl in market.access_control_list
                if acl.ac_role.name == role_name
            }

        self.assertEqual(stored_roles, first_roles)

        import_dict = self._generate_role_import_dict(edited_roles)
        self.import_data(import_dict)
        market = models.Market.query.first()

        stored_roles = {}
        for role_name in edited_roles.keys():
            stored_roles[role_name] = {
                acl.person.email
                for acl in market.access_control_list
                if acl.ac_role.name == role_name
            }

        self.assertEqual(stored_roles, edited_roles)
예제 #15
0
 def test_index_deleted_acr(self):
   """Test index by removed ACR."""
   role_name = "Test name"
   with factories.single_commit():
     acr = factories.AccessControlRoleFactory(
         name=role_name,
         object_type="Control"
     )
     person = factories.PersonFactory(email="*****@*****.**", name='test')
     control = factories.ControlFactory()
     factories.AccessControlListFactory(
         ac_role=acr,
         person=person,
         object=control
     )
   revision = all_models.Revision.query.filter(
       all_models.Revision.resource_id == control.id,
       all_models.Revision.resource_type == control.type,
   ).one()
   revision.content = control.log_json()
   db.session.add(revision)
   with factories.single_commit():
     snapshot = factories.SnapshotFactory(
         child_id=control.id,
         child_type=control.type,
         revision=revision)
   db.session.expire_all()
   db.session.delete(acr)
   db.session.commit()
   snapshot_id = snapshot.id
   self.client.post("/admin/full_reindex")
   snapshot = all_models.Snapshot.query.get(snapshot_id)
   all_found_records = dict(Record.query.filter(
       Record.key == snapshot.id,
       Record.type == snapshot.type,
       Record.property == role_name.lower()
   ).values("subproperty", "content"))
   self.assertFalse(all_found_records)
  def test_duplicated_acr_import(self):
    """Test import of LCAD with same name as GCAD."""
    acr_name = "Test ACR"
    with factories.single_commit():
      factories.AccessControlRoleFactory(
          object_type="Assessment",
          name=acr_name,
      )
      audit = factories.AuditFactory()

    response = self.import_data(OrderedDict([
        ("object_type", "Assessment_Template"),
        ("Code*", ""),
        ("Audit*", audit.slug),
        ("Default Assignees", "*****@*****.**"),
        ("Default Verifiers", "*****@*****.**"),
        ("Title", "Title"),
        ("Object Under Assessment", "Control"),
        ("Custom Attributes", "Text, {}".format(acr_name)),
    ]))

    expected_messages = {
        "Assessment Template": {
            "rows": 1,
            "updated": 0,
            "created": 0,
            "row_warnings": set(),
            "row_errors": {
                errors.ERROR_TEMPLATE.format(
                    line=3,
                    message=common_errors.DUPLICATE_CUSTOM_ROLE.format(
                        role_name=acr_name
                    ),
                )
            },
        }
    }
    self._check_csv_response(response, expected_messages)
예제 #17
0
    def test_single_acl_entry(self):
        """Test ACL column import with single email."""
        role = factories.AccessControlRoleFactory(object_type="Market")
        role_id = role.id

        response = self.import_data(
            OrderedDict([
                ("object_type", "Market"),
                ("code", "market-1"),
                ("title", "Title"),
                ("Admin", "*****@*****.**"),
                ("Assignee", "*****@*****.**"),
                ("Verifier", "*****@*****.**"),
                (role.name, "*****@*****.**"),
            ]))
        self._check_csv_response(response, {})
        market = models.Market.query.first()
        acl = models.AccessControlList.query.filter_by(ac_role_id=role_id,
                                                       object_id=market.id,
                                                       object_type="Market")
        self.assertEqual(acl.count(), 1)
        self.assertEqual(acl.first().ac_role_id, role_id)
        self.assertEqual(acl.first().person.email, "*****@*****.**")
예제 #18
0
 def test_index_by_acr(self):
   """Test index by ACR."""
   role_name = "Test name"
   with factories.single_commit():
     acr = factories.AccessControlRoleFactory(
         name=role_name,
         object_type="Control"
     )
     person = factories.PersonFactory(email="*****@*****.**", name='test')
     control = factories.ControlFactory()
     factories.AccessControlListFactory(
         ac_role=acr,
         person=person,
         object=control
     )
   revision = all_models.Revision.query.filter(
       all_models.Revision.resource_id == control.id,
       all_models.Revision.resource_type == control.type,
   ).one()
   revision.content = control.log_json()
   db.session.add(revision)
   with factories.single_commit():
     snapshot = factories.SnapshotFactory(
         child_id=control.id,
         child_type=control.type,
         revision=revision)
   db.session.expire_all()
   person_id = person.id
   snapshot_id = snapshot.id
   self.client.post("/admin/full_reindex")
   person = all_models.Person.query.get(person_id)
   snapshot = all_models.Snapshot.query.get(snapshot_id)
   self.assert_indexed_fields(snapshot, role_name, {
       "{}-email".format(person.id): person.email,
       "{}-name".format(person.id): person.name,
       "__sort__": person.email,
   })
예제 #19
0
    def test_acl_update(self):
        """Test ACL column import with multiple emails."""
        with factories.single_commit():
            role_name = factories.AccessControlRoleFactory(
                object_type="Market").name
            emails = {factories.PersonFactory().email for _ in range(4)}

        update_emails = set(list(emails)[:2]) | {"*****@*****.**"}

        response = self.import_data(
            collections.OrderedDict([
                ("object_type", "Market"),
                ("code", ""),
                ("title", "Title"),
                ("Admin", "*****@*****.**"),
                ("Assignee", "*****@*****.**"),
                ("Verifier", "*****@*****.**"),
                (role_name, "\n".join(emails)),
            ]))
        self._check_csv_response(response, {})

        market = all_models.Market.query.filter_by(title="Title").first()
        response = self.import_data(
            collections.OrderedDict([
                ("object_type", "Market"),
                ("code", market.slug),
                ("title", "Title"),
                ("Admin", "*****@*****.**"),
                (role_name, "\n".join(update_emails)),
            ]))
        self._check_csv_response(response, {})
        market = models.Market.query.first()
        self.assertEqual(
            {person.email
             for person, _ in market.access_control_list},
            update_emails,
        )
예제 #20
0
  def test_acl_people(self, my_work_flags, should_return):
    """Owned returns objects where person has role with my_work set."""
    with factories.single_commit():
      for my_work in my_work_flags:
        role = factories.AccessControlRoleFactory(object_type="Control",
                                                  my_work=my_work)
        acl = factories.AccessControlListFactory(
            ac_role=role,
            object=self.control,
        )
        factories.AccessControlPersonFactory(
            ac_list=acl,
            person=self.person,
        )

    control_id = self.control.id

    ids = self._get_first_result_set(
        {
            "object_name": "Control",
            "type": "ids",
            "filters": {
                "expression": {
                    "object_name": "Person",
                    "op": {"name": "owned"},
                    "ids": [self.person.id]
                }
            }
        },
        "Control", "ids"
    )

    if should_return:
      self.assertEqual(ids, [control_id])
    else:
      self.assertEqual(ids, [])
예제 #21
0
    def test_multiple_acl_roles_add(self, roles):
        """Test importing new object with multiple ACL roles."""
        for email in self._random_emails:
            factories.PersonFactory(email=email)

        for role_name in roles.keys():
            factories.AccessControlRoleFactory(
                object_type="Market",
                name=role_name + "  ",
            )

        import_dict = self._generate_role_import_dict(roles)
        self.import_data(import_dict)
        market = models.Market.query.first()

        stored_roles = {}
        for role_name in roles.keys():
            stored_roles[role_name] = {
                acl.person.email
                for acl in market.access_control_list
                if acl.ac_role.name == role_name
            }

        self.assertEqual(stored_roles, roles)
예제 #22
0
    def test_acr_control_export(self):
        """Test exporting of a AC roles with linked users."""
        # pylint: disable=too-many-locals
        ac_roles = models.AccessControlRole.query.filter(
            models.AccessControlRole.object_type == "Control",
            models.AccessControlRole.internal == 0,
        ).all()
        control_acr_people = collections.defaultdict(dict)
        with factories.single_commit():
            # Create one more custom role
            ac_roles.append(
                factories.AccessControlRoleFactory(object_type="Control"))
            controls = [
                factories.ControlFactory(slug="Control {}".format(i))
                for i in range(3)
            ]
            for control in controls:
                for ac_role in ac_roles:
                    person = factories.PersonFactory()
                    factories.AccessControlPersonFactory(
                        ac_list=control.acr_acl_map[ac_role],
                        person=person,
                    )
                    control_acr_people[control.slug][
                        ac_role.name] = person.email
            audit = factories.AuditFactory()
            snapshots = self._create_snapshots(audit, controls)

        control_dicts = {}
        for snapshot, control in zip(snapshots, controls):
            # As revisions for snapshot are created using factories need to
            # update their content and rewrite acl
            snapshot.revision.content = control.log_json()
            for acl in snapshot.revision.content["access_control_list"]:
                acl["person"] = {
                    "id": acl["person_id"],
                    "type": "Person",
                }
            db.session.add(snapshot.revision)
            db.session.commit()

            control_dicts[control.slug] = {
                "Code":
                "*" + control.slug,
                "Revision Date":
                snapshot.revision.created_at.strftime(DATE_FORMAT_US),
                "Description":
                u"",
                "Effective Date":
                u"",
                "Fraud Related":
                u"",
                "Frequency":
                u"",
                "Kind/Nature":
                u"",
                "Notes":
                u"",
                "Reference URL":
                u"",
                "Review Status":
                u"some status",
                "Significance":
                u"",
                "State":
                u"Draft",
                "Last Assessment Date":
                u"",
                "Last Deprecated Date":
                u"",
                "Assessment Procedure":
                u"",
                "Title":
                control.title,
                "Type/Means":
                u"",
                "Audit":
                audit.slug,
                "Assertions":
                u",".join(json.loads(control.assertions)),
                "Categories":
                u"",
                "Document File":
                u"",
                'Created Date':
                control.created_at.strftime(DATE_FORMAT_US),
                'Last Updated Date':
                control.updated_at.strftime(DATE_FORMAT_US),
                'Last Updated By':
                "",
                "Folder":
                u"",
                "Archived":
                u"yes" if audit.archived else u"no",
            }
            control_dicts[control.slug].update(
                **control_acr_people[control.slug])

        search_request = [{
            "object_name": "Snapshot",
            "filters": {
                "expression": {
                    "left": "child_type",
                    "op": {
                        "name": "="
                    },
                    "right": "Control",
                },
            },
        }]
        parsed_data = self.export_parsed_csv(
            search_request)["Control Snapshot"]
        parsed_dict = {line["Code"]: line for line in parsed_data}

        for i, _ in enumerate(controls):
            self.assertEqual(
                parsed_dict["*Control {}".format(i)],
                control_dicts["Control {}".format(i)],
            )
예제 #23
0
    def test_acr_control_export(self):
        """Test exporting of a AC roles with linked users."""
        # pylint: disable=too-many-locals
        ac_roles = models.AccessControlRole.query.filter(
            models.AccessControlRole.object_type == "Control",
            models.AccessControlRole.internal == 0,
        ).all()
        control_acr_people = collections.defaultdict(dict)
        with factories.single_commit():
            # Create one more custom role
            ac_roles.append(
                factories.AccessControlRoleFactory(object_type="Control"))
            controls = [
                factories.ControlFactory(slug="Control {}".format(i))
                for i in range(3)
            ]
            for control in controls:
                for ac_role in ac_roles:
                    person = factories.PersonFactory()
                    factories.AccessControlPersonFactory(
                        ac_list=control.acr_acl_map[ac_role],
                        person=person,
                    )
                    control_acr_people[control.slug][
                        ac_role.name] = person.email
            audit = factories.AuditFactory()
            snapshots = self._create_snapshots(audit, controls)

        control_dicts = {}
        for snapshot, control in zip(snapshots, controls):
            # As revisions for snapshot are created using factories need to
            # update their content and rewrite acl
            snapshot.revision.content = control.log_json()
            for acl in snapshot.revision.content["access_control_list"]:
                acl["person"] = {
                    "id": acl["person_id"],
                    "type": "Person",
                }
            db.session.add(snapshot.revision)
            db.session.commit()

            control_dicts[control.slug] = self._control_dict({
                "Code":
                "*" + control.slug,
                "Revision Date":
                snapshot.revision.created_at.strftime(DATE_FORMAT_US),
                "Title":
                control.title,
                "Audit":
                audit.slug,
                "Assertions":
                u",".join(json.loads(control.assertions)),
                'Created Date':
                control.created_at.strftime(DATE_FORMAT_US),
                'Last Updated Date':
                control.updated_at.strftime(DATE_FORMAT_US),
                "Archived":
                u"yes" if audit.archived else u"no",
            })
            control_dicts[control.slug].update(
                **control_acr_people[control.slug])

        parsed_data = self.export_parsed_csv(
            self.search_request)["Control Snapshot"]
        parsed_dict = {line["Code"]: line for line in parsed_data}

        for i, _ in enumerate(controls):
            self.assertEqual(
                parsed_dict["*Control {}".format(i)],
                control_dicts["Control {}".format(i)],
            )
예제 #24
0
 def setUp(self):
     super(TestPermissions, self).setUp()
     self.api = Api()
     roles = {r.name: r for r in all_models.Role.query.all()}
     ac_roles = {
         r.name: r
         for r in all_models.AccessControlRole.query.all()
     }
     with factories.single_commit():
         self.control = factories.ControlFactory()
         acrs = {
             "ACL_Reader":
             factories.AccessControlRoleFactory(name="ACL_Reader",
                                                object_type="Control",
                                                update=0),
             "ACL_Editor":
             factories.AccessControlRoleFactory(name="ACL_Editor",
                                                object_type="Control"),
             "ACL_Nobody":
             factories.AccessControlRoleFactory(
                 name="ACL_Nobody",
                 object_type="Control",
                 read=0,
                 update=0,
                 delete=0,
             ),
         }
         self.program = factories.ProgramFactory()
         self.program.context.related_object = self.program
         self.relationship = factories.RelationshipFactory(
             source=self.program,
             destination=self.control,
             context=self.program.context,
         )
         self.people = {
             "Creator": factories.PersonFactory(),
             "Reader": factories.PersonFactory(),
             "Editor": factories.PersonFactory(),
             "Administrator": factories.PersonFactory(),
             "ACL_Reader": factories.PersonFactory(),
             "ACL_Editor": factories.PersonFactory(),
             "ACL_Nobody": factories.PersonFactory(),
             "Program Editors": factories.PersonFactory(),
             "Program Managers": factories.PersonFactory(),
             "Program Readers": factories.PersonFactory(),
         }
         for role_name in ["Creator", "Reader", "Editor", "Administrator"]:
             rbac_factories.UserRoleFactory(role=roles[role_name],
                                            person=self.people[role_name])
         for role_name in [
                 "Program Editors", "Program Managers", "Program Readers"
         ]:
             person = self.people[role_name]
             rbac_factories.UserRoleFactory(role=roles["Creator"],
                                            person=person)
             factories.AccessControlListFactory(ac_role=ac_roles[role_name],
                                                object=self.program,
                                                person=person)
         self.proposal = factories.ProposalFactory(
             instance=self.control,
             content={
                 "access_control_list": {},
                 "custom_attribute_values": {},
                 "fields": {},
                 "mapping_fields": {},
                 "mapping_list_fields": {},
             })
         for role_name in ["ACL_Reader", "ACL_Editor", "ACL_Nobody"]:
             person = self.people[role_name]
             rbac_factories.UserRoleFactory(role=roles["Creator"],
                                            person=person)
             factories.AccessControlListFactory(ac_role=acrs[role_name],
                                                object=self.control,
                                                person=person)
     with factories.single_commit():
         proposal_model.set_acl_to_all_proposals_for(self.control)
예제 #25
0
  def test_apply_acl(self):  # pylint: disable=too-many-locals
    """Test simple apply acl proposal."""
    with factories.single_commit():
      role_1 = factories.AccessControlRoleFactory(
          name="role_1", object_type="Control")
      role_2 = factories.AccessControlRoleFactory(
          name="role_2", object_type="Control")
      role_3 = factories.AccessControlRoleFactory(
          name="role_3", object_type="Control")
      role_4 = factories.AccessControlRoleFactory(
          name="role_4", object_type="Control")
      role_5 = factories.AccessControlRoleFactory(
          name="role_5", object_type="Control")
    with factories.single_commit():
      control = factories.ControlFactory(title="1")
      person_1 = factories.PersonFactory()
      person_2 = factories.PersonFactory()
      person_3 = factories.PersonFactory()
      acl_1 = control.acr_acl_map[role_1]
      acl_2 = control.acr_acl_map[role_2]
      acl_3 = control.acr_acl_map[role_3]
      acl_4 = control.acr_acl_map[role_4]
      factories.AccessControlPersonFactory(
          ac_list=acl_1,
          person=person_1,
      )
      factories.AccessControlPersonFactory(
          ac_list=acl_2,
          person=person_2,
      )
      factories.AccessControlPersonFactory(
          ac_list=acl_3,
          person=person_3,
      )
      for person in [person_1, person_2, person_3]:
        factories.AccessControlPersonFactory(
            ac_list=acl_4,
            person=person,
        )

    with factories.single_commit():
      proposal = factories.ProposalFactory(
          instance=control,
          content={
              "access_control_list": {
                  role_1.id: {
                      "added": [{"id": person_2.id, "email": person_2.email}],
                      "deleted": []
                  },
                  role_2.id: {
                      "added": [{"id": person_1.id, "email": person_1.email}],
                      "deleted": [{"id": person_2.id, "email": person_2.email}]
                  },
                  role_3.id: {
                      "added": [{"id": person_3.id, "email": person_3.email}],
                      "deleted": [{"id": person_2.id, "email": person_2.email}]
                  },
                  role_4.id: {
                      "added": [],
                      "deleted": [{"id": person_1.id, "email": person_1.email},
                                  {"id": person_2.id, "email": person_2.email},
                                  {"id": person_3.id, "email": person_3.email}]
                  },
                  role_5.id: {
                      "added": [{"id": person_1.id, "email": person_1.email},
                                {"id": person_2.id, "email": person_2.email},
                                {"id": person_3.id, "email": person_3.email}],
                      "deleted": [],
                  },
              }
          },
          agenda="agenda content")
    control_id = control.id
    person_1_id = person_1.id
    person_2_id = person_2.id
    person_3_id = person_3.id
    role_1_id = role_1.id
    role_2_id = role_2.id
    role_3_id = role_3.id
    role_4_id = role_4.id
    role_5_id = role_5.id
    self.assertEqual(proposal.STATES.PROPOSED, proposal.status)
    revisions = all_models.Revision.query.filter(
        all_models.Revision.resource_type == control.type,
        all_models.Revision.resource_id == control.id
    ).all()
    self.assertEqual(1, len(revisions))
    resp = self.api.put(
        proposal, {"proposal": {"status": proposal.STATES.APPLIED}})
    self.assert200(resp)
    control = all_models.Control.query.get(control_id)
    result_dict = collections.defaultdict(set)
    for person, acl in control.access_control_list:
      result_dict[acl.ac_role_id].add(person.id)
    self.assertEqual({person_1_id, person_2_id}, result_dict[role_1_id])
    self.assertEqual({person_1_id}, result_dict[role_2_id])
    self.assertEqual({person_3_id}, result_dict[role_3_id])
    self.assertEqual(set([]), result_dict[role_4_id])
    self.assertEqual({person_1_id, person_2_id, person_3_id},
                     result_dict[role_5_id])
예제 #26
0
    def test_proposal_delete_acl(self, roles, deleted):
        """Test delete acl proposal for ACRs with internal flags as {roles}."""
        role_person_list = []
        with factories.single_commit():
            risk = factories.RiskFactory(title="1")
            for idx, role_internal_flag in enumerate(roles):
                role = factories.AccessControlRoleFactory(
                    name="role_{}".format(idx),
                    object_type="Risk",
                    internal=role_internal_flag)
                person = factories.PersonFactory()
                role_person_list.append((role, person))
                acl = factories.AccessControlListFactory(
                    ac_role=role,
                    object=risk,
                )
                factories.AccessControlPersonFactory(
                    ac_list=acl,
                    person=person,
                )
        with factories.single_commit():
            latest_revision = all_models.Revision.query.filter(
                all_models.Revision.resource_id == risk.id,
                all_models.Revision.resource_type == risk.type).order_by(
                    all_models.Revision.created_at.desc()).first()
            latest_revision.content = risk.log_json()

        risk_id = risk.id
        risk_content = risk.log_json()
        risk_content["access_control_list"] = []
        expected_result = {}
        for idx, (role, person) in enumerate(role_person_list):
            if deleted[idx]:
                expected_result[str(role.id)] = {
                    "added": [],
                    "deleted": [{
                        "id": person.id,
                        "email": person.email
                    }],
                }
        resp = self.api.post(
            all_models.Proposal,
            {
                "proposal": {
                    "instance": {
                        "id": risk.id,
                        "type": risk.type,
                    },
                    # "content": {"123": 123},
                    "full_instance_content": risk_content,
                    "agenda": "delete access control roles",
                    "context": None,
                }
            })
        self.assertEqual(201, resp.status_code)
        risk = all_models.Risk.query.get(risk_id)
        self.assertEqual(1, len(risk.proposals))
        self.assertIn("access_control_list", risk.proposals[0].content)
        acl = risk.proposals[0].content["access_control_list"]
        self.assertEqual(expected_result, acl)
        self.assertEqual(1, len(risk.comments))
예제 #27
0
  def test_roleable_eager_query(self):
    """Test eager query on roleable object.

    This test compares the query counts while accessing an object with a single
    user role on it with an object with multiple users.
    """
    with factories.single_commit():
      people = [factories.PersonFactory() for _ in range(5)]
      emails = {person.email for person in people}
      control = factories.ControlFactory()
      control.add_person_with_role_name(people[0], "Admin")
      control_id = control.id

    db.session.expire_all()
    with utils.QueryCounter() as counter:
      control = all_models.Control.eager_query().filter_by(
          id=control_id
      ).one()
      eager_query_count = counter.get
      self.assertEqual(len(control.access_control_list), 1)
      self.assertEqual(eager_query_count, counter.get)
      self.assertEqual(
          control.access_control_list[0][1].ac_role.name,
          "Admin",
      )
      self.assertEqual(eager_query_count, counter.get)
      self.assertEqual(
          control.access_control_list[0][0].email,
          people[0].email,
      )
      self.assertEqual(eager_query_count, counter.get)

    factories.AccessControlRoleFactory(object_type="Control", name="custom")

    with factories.single_commit():
      control_multi = factories.ControlFactory()
      for person in people:
        control_multi.add_person_with_role_name(person, "Admin")
        control_multi.add_person_with_role_name(person, "custom")
      control_multi_id = control_multi.id

    db.session.expire_all()
    with utils.QueryCounter() as counter:
      control_multi = all_models.Control.eager_query().filter_by(
          id=control_multi_id
      ).one()
      self.assertEqual(eager_query_count, counter.get)
      self.assertEqual(
          len(control_multi.access_control_list),
          len(people) * 2,
      )
      self.assertEqual(eager_query_count, counter.get)
      admins = {
          person.email
          for person in control_multi.get_persons_for_rolename("Admin")
      }
      self.assertEqual(admins, emails)
      self.assertEqual(eager_query_count, counter.get)
      custom_role_users = {
          person.email
          for person in control_multi.get_persons_for_rolename("custom")
      }
      self.assertEqual(custom_role_users, emails)
      self.assertEqual(eager_query_count, counter.get)
예제 #28
0
 def setUp(self):
   super(TestAccessControlRoleable, self).setUp()
   with factories.single_commit():
     self.role = factories.AccessControlRoleFactory(object_type="Control")
     self.person = factories.PersonFactory()
예제 #29
0
 def test_email_sending(self):
     """Test sending emails about proposals."""
     role_1 = factories.AccessControlRoleFactory(object_type="Program",
                                                 notify_about_proposal=True)
     role_2 = factories.AccessControlRoleFactory(object_type="Program",
                                                 notify_about_proposal=True)
     role_3 = factories.AccessControlRoleFactory(
         object_type="Program", notify_about_proposal=False)
     with factories.single_commit():
         program = factories.ProgramFactory()
         person_1 = factories.PersonFactory()  # has 1 role
         person_2 = factories.PersonFactory()  # has no roles
         person_3 = factories.PersonFactory()  # has 2 roles
         factories.PersonFactory()  # not related to program at all
         factories.AccessControlPersonFactory(
             ac_list=program.acr_acl_map[role_1], person=person_1)
         factories.AccessControlPersonFactory(
             ac_list=program.acr_acl_map[role_1], person=person_3)
         factories.AccessControlPersonFactory(
             ac_list=program.acr_acl_map[role_2], person=person_3)
         factories.AccessControlPersonFactory(
             ac_list=program.acr_acl_map[role_3], person=person_2)
         proposal_1 = factories.ProposalFactory(
             instance=program,
             content={
                 "fields": {
                     "title": "a"
                 },
                 "access_control_list": {},
                 "custom_attribute_values": {},
                 "mapping_fields": {},
                 "mapping_list_fields": {},
             },
             agenda="agenda 1")
         proposal_2 = factories.ProposalFactory(
             instance=program,
             content={
                 "fields": {
                     "title": "b"
                 },
                 "access_control_list": {},
                 "custom_attribute_values": {},
                 "mapping_fields": {},
                 "mapping_list_fields": {},
             },
             agenda="agenda 2")
     self.assertIsNone(proposal_1.proposed_notified_datetime)
     self.assertIsNone(proposal_2.proposed_notified_datetime)
     with mock.patch("google.appengine.api.mail.send_mail") as mailer_mock:
         with mock.patch.object(fast_digest.DIGEST_TMPL,
                                "render") as bodybuilder_mock:
             fast_digest.send_notification()
     self.assertIsNotNone(proposal_1.proposed_notified_datetime)
     self.assertIsNotNone(proposal_2.proposed_notified_datetime)
     self.assertEqual(2, len(bodybuilder_mock.call_args_list))
     self.assertEqual(2, len(mailer_mock.call_args_list))
     # email to each required person
     self.assertListEqual(
         sorted([person_1.email, person_3.email]),
         sorted([a[1]["to"] for a in mailer_mock.call_args_list]))
     # no matter how many roles each proposal should be otified
     # only once for that person
     self.assertListEqual(
         [2] * 2,
         [len(a[1]["proposals"]) for a in bodybuilder_mock.call_args_list])
예제 #30
0
    def test_apply_acl(self):  # pylint: disable=too-many-locals
        """Test simple apply acl proposal."""
        with factories.single_commit():
            control = factories.ControlFactory(title="1")
            role_1 = factories.AccessControlRoleFactory(name="role_1",
                                                        object_type="Control")
            role_2 = factories.AccessControlRoleFactory(name="role_2",
                                                        object_type="Control")
            role_3 = factories.AccessControlRoleFactory(name="role_3",
                                                        object_type="Control")
            role_4 = factories.AccessControlRoleFactory(name="role_4",
                                                        object_type="Control")
            role_5 = factories.AccessControlRoleFactory(name="role_5",
                                                        object_type="Control")
            person_1 = factories.PersonFactory()
            person_2 = factories.PersonFactory()
            person_3 = factories.PersonFactory()
            factories.AccessControlListFactory(
                person=person_1,
                ac_role=role_1,
                object=control,
            )
            factories.AccessControlListFactory(
                person=person_2,
                ac_role=role_2,
                object=control,
            )
            factories.AccessControlListFactory(
                person=person_3,
                ac_role=role_3,
                object=control,
            )
            for person in [person_1, person_2, person_3]:
                factories.AccessControlListFactory(
                    person=person,
                    ac_role=role_4,
                    object=control,
                )

        with factories.single_commit():
            proposal = factories.ProposalFactory(instance=control,
                                                 content={
                                                     "access_control_list": {
                                                         role_1.id: {
                                                             "added": [{
                                                                 "id":
                                                                 person_2.id,
                                                                 "email":
                                                                 person_2.email
                                                             }],
                                                             "deleted": []
                                                         },
                                                         role_2.id: {
                                                             "added": [{
                                                                 "id":
                                                                 person_1.id,
                                                                 "email":
                                                                 person_1.email
                                                             }],
                                                             "deleted": [{
                                                                 "id":
                                                                 person_2.id,
                                                                 "email":
                                                                 person_2.email
                                                             }]
                                                         },
                                                         role_3.id: {
                                                             "added": [{
                                                                 "id":
                                                                 person_3.id,
                                                                 "email":
                                                                 person_3.email
                                                             }],
                                                             "deleted": [{
                                                                 "id":
                                                                 person_2.id,
                                                                 "email":
                                                                 person_2.email
                                                             }]
                                                         },
                                                         role_4.id: {
                                                             "added": [],
                                                             "deleted": [{
                                                                 "id":
                                                                 person_1.id,
                                                                 "email":
                                                                 person_1.email
                                                             }, {
                                                                 "id":
                                                                 person_2.id,
                                                                 "email":
                                                                 person_2.email
                                                             }, {
                                                                 "id":
                                                                 person_3.id,
                                                                 "email":
                                                                 person_3.email
                                                             }]
                                                         },
                                                         role_5.id: {
                                                             "added": [{
                                                                 "id":
                                                                 person_1.id,
                                                                 "email":
                                                                 person_1.email
                                                             }, {
                                                                 "id":
                                                                 person_2.id,
                                                                 "email":
                                                                 person_2.email
                                                             }, {
                                                                 "id":
                                                                 person_3.id,
                                                                 "email":
                                                                 person_3.email
                                                             }],
                                                             "deleted": [],
                                                         },
                                                     }
                                                 },
                                                 agenda="agenda content")
        control_id = control.id
        person_1_id = person_1.id
        person_2_id = person_2.id
        person_3_id = person_3.id
        role_1_id = role_1.id
        role_2_id = role_2.id
        role_3_id = role_3.id
        role_4_id = role_4.id
        role_5_id = role_5.id
        self.assertEqual(proposal.STATES.PROPOSED, proposal.status)
        with self.number_obj_revisions_for(control):
            self.apply_proposal(proposal)
        control = all_models.Control.query.get(control_id)
        result_dict = collections.defaultdict(set)
        for acl in control.access_control_list:
            result_dict[acl.ac_role_id].add(acl.person_id)
        self.assertEqual({person_1_id, person_2_id}, result_dict[role_1_id])
        self.assertEqual({person_1_id}, result_dict[role_2_id])
        self.assertEqual({person_3_id}, result_dict[role_3_id])
        self.assertEqual(set([]), result_dict[role_4_id])
        self.assertEqual({person_1_id, person_2_id, person_3_id},
                         result_dict[role_5_id])