コード例 #1
0
  def test_create_from_ggrcq(self, definition_type, title):
    """Test create definition only for GGRCQ."""
    api = Api()
    payload = [
        {
            "custom_attribute_definition": {
                "attribute_type": "Text",
                "context": {"id": None},
                "definition_type": definition_type,
                "helptext": "",
                "mandatory": False,
                "modal_title": "Title",
                "placeholder": "",
                "title": title
            }
        }
    ]

    with api.as_external():
      response = api.post(all_models.CustomAttributeDefinition, payload)
      self.assertEqual(response.status_code, 200)
コード例 #2
0
    def test_create_from_ggrcq(self, definition_type, title):
        """Test create definition only for GGRCQ."""
        api = Api()
        payload = [{
            "custom_attribute_definition": {
                "attribute_type": "Text",
                "context": {
                    "id": None
                },
                "definition_type": definition_type,
                "helptext": "",
                "mandatory": False,
                "modal_title": "Title",
                "placeholder": "",
                "title": title
            }
        }]

        with api.as_external():
            response = api.post(all_models.CustomAttributeDefinition, payload)
            self.assertEqual(response.status_code, 200)
コード例 #3
0
class TestAccessControlRole(TestCase):
    """TestAccessControlRole"""
    def setUp(self):
        self.clear_data()
        super(TestAccessControlRole, self).setUp()
        self.api = Api()
        self.object_generator = ObjectGenerator()
        self.people = {}
        for name in ["Creator", "Reader", "Editor"]:
            _, user = self.object_generator.generate_person(
                data={"name": name}, user_role=name)
            self.people[name] = user

    def _post_role(self, name=None, object_type="Control"):
        """Helper function for POSTing roles"""
        if name is None:
            name = random_str(prefix="Access Control Role - ")
        return self.api.post(
            AccessControlRole, {
                "access_control_role": {
                    "name": name,
                    "object_type": object_type,
                    "context": None,
                    "read": True
                },
            })

    def test_create_after_objects(self):
        """Test eager creation of ACLs on existing objects with new ACR."""
        program_id = factories.ProgramFactory().id
        role_name = "New Custom Role"
        self._post_role(name=role_name, object_type="Program")
        program = all_models.Program.query.get(program_id)
        self.assertIn(role_name, program.acr_name_acl_map.keys())
        self.assertIsNotNone(program.acr_name_acl_map[role_name])

    def test_create(self):
        """Test Access Control Role creation"""
        response = self._post_role(object_type="Program")
        assert response.status_code == 201, \
            "Failed to create a new access control role, response was {}".format(
                response.status)

        id_ = response.json['access_control_role']['id']
        role = AccessControlRole.query.filter(
            AccessControlRole.id == id_).first()
        assert role.read == 1, \
            "Read permission not correctly saved {}".format(role.read)
        assert role.update == 1, \
            "Update permission not correctly saved {}".format(role.update)
        assert role.delete == 1, \
            "Update permission not correctly saved {}".format(role.delete)

    @ddt.data(
        {
            "mandatory": True,
            "exp_response": MANDATORY_ROLE_RESPONSE
        },
        {
            "mandatory": False,
            "exp_response": NON_MANDATORY_ROLE_RESPONSE
        },
    )
    @ddt.unpack
    def test_mandatory_delete(self, mandatory, exp_response):
        """Test set empty field via import if acr mandatory is {mandatory}"""
        role = factories.AccessControlRoleFactory(
            name=ROLE_NAME,
            object_type="Program",
            mandatory=mandatory,
        )
        with factories.single_commit():
            user = factories.PersonFactory()
            program = factories.ProgramFactory()
            role_id = role.id
            factories.AccessControlPersonFactory(
                ac_list=program.acr_name_acl_map[ROLE_NAME],
                person=user,
            )
        response = self.import_data(
            OrderedDict([
                ("object_type", "Program"),
                ("Code*", program.slug),
                (ROLE_NAME, "--"),
            ]))
        self._check_csv_response(response, exp_response)
        db_data = defaultdict(set)
        program = all_models.Program.query.get(program.id)
        for person, acl in program.access_control_list:
            db_data[acl.ac_role_id].add(person.id)
        if mandatory:
            cur_user = all_models.Person.query.filter_by(
                email="*****@*****.**").first()
            self.assertEqual(set([cur_user.id]), db_data[role_id])
        else:
            self.assertFalse(db_data[role_id])

    def test_only_admin_can_post(self):
        """Only admin users should be able to POST access control roles"""
        for name in ("Creator", "Reader", "Editor"):
            person = self.people.get(name)
            self.api.set_user(person)
            response = self._post_role()
            assert response.status_code == 403, \
                "Non admins should get forbidden error when POSTing role. {}".format(
                    response.status)

    @ddt.data(
        ("name", "New ACR"),
        ("read", False),
        ("mandatory", False),
        ("non_editable", False),
    )
    @ddt.unpack
    def test_modify_non_editable_role(self, field_name, field_value):
        """Test if user can modify non-editable role"""
        # Primary Contacts role of Control is non-editable
        ac_role = AccessControlRole.query.filter_by(
            object_type="Control",
            name="Control Operators",
        ).first()

        response = self.api.put(ac_role, {field_name: field_value})
        assert response.status_code == 403, \
            "Forbidden error should be thrown when non-editable " \
            "role {} updated.".format(ac_role.name)

    def test_delete_non_editable_role(self):
        """Test if user can delete non-editable role"""
        # Primary Contacts role of Control is non-editable
        ac_role = AccessControlRole.query.filter_by(
            object_type="Control",
            name="Control Operators",
        ).first()

        response = self.api.delete(ac_role)
        assert response.status_code == 403, \
            "Forbidden error should be thrown when non-editable " \
            "role {} deleted.".format(ac_role.name)

    @ddt.data("Control")
    def test_create_from_ggrcq(self, object_type):
        """Test that create action only for GGRCQ."""
        with self.api.as_external():
            response = self._post_role(object_type=object_type)
            self.assertEqual(response.status_code, 201)

    @ddt.data("Control")
    def test_create_from_ggrc(self, object_type):
        """Test create action not allowed for GGRC."""
        response = self._post_role(object_type=object_type)
        self.assertEqual(response.status_code, 405)

    @ddt.data("Control")
    def test_modify_from_ggrcq(self, object_type):
        """Test that modify action only for GGRCQ."""
        with factories.single_commit():
            acr_id = factories.AccessControlRoleFactory(
                object_type=object_type).id

        with self.api.as_external():
            acr = all_models.AccessControlRole.query.get(acr_id)
            response = self.api.put(acr, {"name": "new acr"})
            self.assertEqual(response.status_code, 200)

    @ddt.data("Control")
    def test_modify_from_ggrc(self, object_type):
        """Test modify action not allowed for GGRC."""
        with factories.single_commit():
            acr = factories.AccessControlRoleFactory(object_type=object_type)

        response = self.api.put(acr, {"name": "new acr"})
        self.assertEqual(response.status_code, 405)

    @ddt.data("Control")
    def test_delete_from_ggrcq(self, object_type):
        """Test that modify action only for GGRCQ."""
        with factories.single_commit():
            acr_id = factories.AccessControlRoleFactory(
                object_type=object_type).id

        with self.api.as_external():
            acr = all_models.AccessControlRole.query.get(acr_id)
            response = self.api.delete(acr)
            self.assertEqual(response.status_code, 200)

    @ddt.data("Control")
    def test_delete_from_ggrc(self, object_type):
        """Test modify action not allowed for GGRC."""
        with factories.single_commit():
            acr = factories.AccessControlRoleFactory(object_type=object_type)

        response = self.api.delete(acr)
        self.assertEqual(response.status_code, 405)

    @ddt.data(
        {
            "name": "Test 1",
            "update": False,
            "read": False,
            "delete": True
        },
        {
            "name": "Test 2",
            "update": True,
            "read": False,
            "delete": False
        },
        {
            "name": "Test 3",
            "update": True,
            "read": False,
            "delete": True
        },
    )
    @ddt.unpack
    def test_create_with_wrong_options(self, name, update, read, delete):
        """ Test if user create ACR with wrong options."""
        options = [{
            'access_control_role': {
                'modal_title': 'Add Custom Role to type Regulation',
                'object_type': 'Regulation',
                'parent_type': 'Regulation',
                'context': {
                    'id': None
                },
                'delete': delete,
                'update': update,
                'read': read,
                'name': name
            }
        }]
        response = self.api.post(AccessControlRole, options)
        self.assert400(response)
コード例 #4
0
class TestAccessControlRole(TestCase):
  """TestAccessControlRole"""

  def setUp(self):
    self.clear_data()
    super(TestAccessControlRole, self).setUp()
    self.api = Api()
    self.object_generator = ObjectGenerator()
    self.people = {}
    for name in ["Creator", "Reader", "Editor"]:
      _, user = self.object_generator.generate_person(
          data={"name": name}, user_role=name)
      self.people[name] = user

  def _post_role(self, name=None, object_type="Control"):
    """Helper function for POSTing roles"""
    if name is None:
      name = random_str(prefix="Access Control Role - ")
    return self.api.post(AccessControlRole, {
        "access_control_role": {
            "name": name,
            "object_type": object_type,
            "context": None,
            "read": True
        },
    })

  def test_create_after_objects(self):
    """Test eager creation of ACLs on existing objects with new ACR."""
    risk_id = factories.RiskFactory().id
    role_name = "New Custom Role"
    self._post_role(name=role_name, object_type="Risk")
    risk = all_models.Risk.query.get(risk_id)
    self.assertIn(role_name, risk.acr_name_acl_map.keys())
    self.assertIsNotNone(risk.acr_name_acl_map[role_name])

  def test_create(self):
    """Test Access Control Role creation"""
    response = self._post_role(object_type="Risk")
    assert response.status_code == 201, \
        "Failed to create a new access control role, response was {}".format(
            response.status)

    id_ = response.json['access_control_role']['id']
    role = AccessControlRole.query.filter(AccessControlRole.id == id_).first()
    assert role.read == 1, \
        "Read permission not correctly saved {}".format(role.read)
    assert role.update == 1, \
        "Update permission not correctly saved {}".format(role.update)
    assert role.delete == 1, \
        "Update permission not correctly saved {}".format(role.delete)

  @ddt.data(
      {"mandatory": True, "exp_response": MANDATORY_ROLE_RESPONSE},
      {"mandatory": False, "exp_response": NON_MANDATORY_ROLE_RESPONSE},
  )
  @ddt.unpack
  def test_mandatory_delete(self, mandatory, exp_response):
    """Test set empty field via import if acr mandatory is {mandatory}"""
    role = factories.AccessControlRoleFactory(
        name=ROLE_NAME,
        object_type="Risk",
        mandatory=mandatory,
    )
    with factories.single_commit():
      user = factories.PersonFactory()
      risk = factories.RiskFactory()
      role_id = role.id
      factories.AccessControlPersonFactory(
          ac_list=risk.acr_name_acl_map[ROLE_NAME],
          person=user,
      )
    response = self.import_data(OrderedDict([
        ("object_type", "Risk"),
        ("Code*", risk.slug),
        (ROLE_NAME, "--"),
    ]))
    self._check_csv_response(response, exp_response)
    db_data = defaultdict(set)
    risk = all_models.Risk.query.get(risk.id)
    for person, acl in risk.access_control_list:
      db_data[acl.ac_role_id].add(person.id)
    if mandatory:
      cur_user = all_models.Person.query.filter_by(
          email="*****@*****.**").first()
      self.assertEqual(set([cur_user.id]), db_data[role_id])
    else:
      self.assertFalse(db_data[role_id])

  def test_only_admin_can_post(self):
    """Only admin users should be able to POST access control roles"""
    for name in ("Creator", "Reader", "Editor"):
      person = self.people.get(name)
      self.api.set_user(person)
      response = self._post_role()
      assert response.status_code == 403, \
          "Non admins should get forbidden error when POSTing role. {}".format(
              response.status)

  @ddt.data(
      ("name", "New ACR"),
      ("read", False),
      ("mandatory", False),
      ("non_editable", False),
  )
  @ddt.unpack
  def test_modify_non_editable_role(self, field_name, field_value):
    """Test if user can modify non-editable role"""
    # Primary Contacts role of Control is non-editable
    ac_role = AccessControlRole.query.filter_by(
        object_type="Control",
        name="Control Operators",
    ).first()

    response = self.api.put(ac_role, {field_name: field_value})
    assert response.status_code == 403, \
        "Forbidden error should be thrown when non-editable " \
        "role {} updated.".format(ac_role.name)

  def test_delete_non_editable_role(self):
    """Test if user can delete non-editable role"""
    # Primary Contacts role of Control is non-editable
    ac_role = AccessControlRole.query.filter_by(
        object_type="Control",
        name="Control Operators",
    ).first()

    response = self.api.delete(ac_role)
    assert response.status_code == 403, \
        "Forbidden error should be thrown when non-editable " \
        "role {} deleted.".format(ac_role.name)

  @ddt.data("Control")
  def test_create_from_ggrcq(self, object_type):
    """Test that create action only for GGRCQ."""
    with self.api.as_external():
      response = self._post_role(object_type=object_type)
      self.assertEqual(response.status_code, 201)

  @ddt.data("Control")
  def test_create_from_ggrc(self, object_type):
    """Test create action not allowed for GGRC."""
    response = self._post_role(object_type=object_type)
    self.assertEqual(response.status_code, 405)

  @ddt.data("Control")
  def test_modify_from_ggrcq(self, object_type):
    """Test that modify action only for GGRCQ."""
    with factories.single_commit():
      acr_id = factories.AccessControlRoleFactory(object_type=object_type).id

    with self.api.as_external():
      acr = all_models.AccessControlRole.query.get(acr_id)
      response = self.api.put(acr, {"name": "new acr"})
      self.assertEqual(response.status_code, 200)

  @ddt.data("Control")
  def test_modify_from_ggrc(self, object_type):
    """Test modify action not allowed for GGRC."""
    with factories.single_commit():
      acr = factories.AccessControlRoleFactory(object_type=object_type)

    response = self.api.put(acr, {"name": "new acr"})
    self.assertEqual(response.status_code, 405)

  @ddt.data("Control")
  def test_delete_from_ggrcq(self, object_type):
    """Test that modify action only for GGRCQ."""
    with factories.single_commit():
      acr_id = factories.AccessControlRoleFactory(object_type=object_type).id

    with self.api.as_external():
      acr = all_models.AccessControlRole.query.get(acr_id)
      response = self.api.delete(acr)
      self.assertEqual(response.status_code, 200)

  @ddt.data("Control")
  def test_delete_from_ggrc(self, object_type):
    """Test modify action not allowed for GGRC."""
    with factories.single_commit():
      acr = factories.AccessControlRoleFactory(object_type=object_type)

    response = self.api.delete(acr)
    self.assertEqual(response.status_code, 405)
コード例 #5
0
class TestAccessControlList(TestCase):
    """TestAccessControlList"""
    @classmethod
    def setUpClass(cls):
        """Sets objects common for all tests in TestCase."""
        super(TestAccessControlList, cls).setUpClass()
        cls.api = Api()

    def setUp(self):
        super(TestAccessControlList, self).setUp()
        self.api = Api()

        self.person = factories.PersonFactory(name="My Person")
        self.acr = factories.AccessControlRoleFactory(object_type="Control",
                                                      read=True)
        self.second_acr = factories.AccessControlRoleFactory(
            object_type="Control", read=True)
        self.control = factories.ControlFactory()
        factories.AccessControlPersonFactory(
            ac_list=self.control.acr_acl_map[self.acr],
            person=self.person,
        )

    def _acl_asserts(self, acl, acr_id, person_id):
        """Run asserts on a given acl list"""
        self.assertEqual(
            len(acl), 1,
            "Access control list did not get saved {}".format(acl))
        self.assertTrue(acl[0]["id"] > 0,
                        "Acces control list did not set an id")
        self.assertEqual(
            acl[0]["ac_role_id"], acr_id,
            "Access control list does not include the saved role id")
        self.assertEqual(
            acl[0]["person_id"], person_id,
            "Access control list does not include person id {}".format(acl[0]))

    def _post_control(self, acr_id, person_id, assertion, collection=False):
        """Helper function for posting a control"""
        title = factories.random_str(prefix="Control - ")
        control = {
            "control": {
                "title": title,
                "type": "Control",
                "context": None,
                "access_control_list":
                [acl_helper.get_acl_json(acr_id, person_id)],
                "assertions": '["{}"]'.format(assertion),
                "external_id": factories.SynchronizableExternalId.next(),
                "external_slug": factories.random_str(),
                "review_status": all_models.Review.STATES.UNREVIEWED,
                "review_status_display_name": "some status",
            },
        }
        with self.api.as_external():
            response = self.api.post(all_models.Control,
                                     [control] if collection else control)

        self.assertTrue(
            response.status_code == 200 or response.status_code == 201,
            "Control not created successfully {}".format(response.status))

        if collection:
            return response.json[0][1]
        return response.json

    def test_object_roles(self):
        """Test if roles are fetched with the object"""
        acr_id, person_id = self.acr.id, self.person.id
        response = self.api.get(all_models.Control, self.control.id)
        self.assert200(
            response,
            "Failed to fetch created control {}".format(response.status))
        self.assertIn(
            "access_control_list", response.json["control"],
            "Access Control List not present in {}".format(
                response.json["control"].keys()))

        acl = response.json["control"]["access_control_list"]
        self._acl_asserts(acl, acr_id, person_id)

    def test_post_object_roles(self):
        """Test if roles are stored correctly when POSTed with the object"""
        acr_id, person_id = self.acr.id, self.person.id
        response = self._post_control(acr_id, person_id, "test assertion")
        acl = response["control"]["access_control_list"]
        self._acl_asserts(acl, acr_id, person_id)

    def test_acl_revision_content(self):
        """Test if the access control list is added to revisions"""
        acr_id, person_id = self.acr.id, self.person.id
        response = self._post_control(acr_id, person_id, "test assertion")
        control_id = response["control"]["id"]
        rev = all_models.Revision.query.filter(
            all_models.Revision.resource_id == control_id,
            all_models.Revision.resource_type == "Control").first()

        acl = rev.content["access_control_list"]
        self._acl_asserts(acl, acr_id, person_id)

    def test_put_object_roles(self):
        """Test if PUTing object roles saves them correctly"""
        second_acr_id, person_id = self.second_acr.id, self.person.id
        response = self.api.get(all_models.Control, self.control.id)
        self.assert200(
            response,
            "Failed to fetch created control {}".format(response.status))

        control = response.json['control']
        control['access_control_list'].append(
            acl_helper.get_acl_json(second_acr_id, person_id))
        with self.api.as_external():
            response = self.api.put(self.control, {"control": control})
        self.assert200(response,
                       "PUTing control failed {}".format(response.status))

        acl = response.json['control']['access_control_list']
        self.assertEqual(len(acl), 2,
                         "Access control list not updated {}".format(acl))

    def test_put_removing_roles(self):
        """Test if PUTing an empty list removes object roles correct"""
        response = self.api.get(all_models.Control, self.control.id)
        self.assert200(
            response,
            "Failed to fetch created control {}".format(response.status))

        control = response.json['control']
        control['access_control_list'] = []
        with self.api.as_external():
            response = self.api.put(self.control, {"control": control})
        self.assert200(response,
                       "PUTing control failed {}".format(response.status))

        acl = response.json['control']['access_control_list']
        self.assertEqual(len(acl), 0,
                         "Access control list not empty {}".format(acl))

    def test_acl_indexing_on_post(self):
        """Test if roles are stored correctly when POSTed with the object"""
        acr_id, person_id = self.acr.id, self.person.id
        response = self._post_control(acr_id, person_id, "test assertion")
        control = response["control"]
        res = mysql.MysqlRecordProperty.query.filter(
            mysql.MysqlRecordProperty.type == "Control",
            mysql.MysqlRecordProperty.key == control["id"],
            mysql.MysqlRecordProperty.property == self.acr.name).all()

        self.assertTrue(
            len(res) > 0,
            "Full text record index not created for {}".format(self.acr.name))

        # email is presented in __sort__ subproperty as well
        self.assertEqual(
            len([r for r in res if r.content == self.person.email]), 2,
            "Person email not indexed {}".format(self.person.email))

        self.assertEqual(
            len([r for r in res if r.content == self.person.name]), 1,
            "Person name not indexed {}".format(self.person.name))

    def test_acl_revision_count(self):
        """Test if acl revision is created when object POSTed and PUTed"""
        acr_id, person_id = self.acr.id, self.person.id

        response = self._post_control(acr_id, person_id, "test assertion")
        # One ACL and Control created in setUp and on by POST
        self.assertEqual(
            all_models.Revision.query.filter_by(
                resource_type="AccessControlPerson").count(), 3)
        self.assertEqual(
            all_models.Revision.query.filter_by(
                resource_type="Control").count(), 2)

        # If content of "access_control_list" is changed,
        # new revision should be created for ACL
        control = response["control"]
        control["access_control_list"] = []
        with self.api.as_external():
            self.api.put(all_models.Control.query.get(control["id"]),
                         {"control": control})
        self.assertEqual(
            all_models.Revision.query.filter_by(
                resource_type="AccessControlPerson").count(), 4)
        self.assertEqual(
            all_models.Revision.query.filter_by(
                resource_type="Control").count(), 3)