Beispiel #1
0
class TestBackgroundTask(TestCase):
    """Tests for background task model."""
    def setUp(self):
        """setUp, nothing else to add."""
        super(TestBackgroundTask, self).setUp()
        self.object_generator = ObjectGenerator()
        self.api = api_helper.Api()

    def test_bg_task_from_post(self):
        """Test filtering of GET response for BackgroundTask"""
        from ggrc.models import all_models

        response, _ = self.object_generator.generate_object(
            all_models.Control, with_background_tasks=True)
        self.assertEqual(response.status_code, 201)
        bg_tasks = all_models.BackgroundTask.query.filter(
            all_models.BackgroundTask.name.like("%POST%")).all()
        self.assertEqual(len(bg_tasks), 1)

        content = self.api.client.get("/api/background_tasks")
        self.assert200(content)
        bg_tasks_content = \
            content.json['background_tasks_collection']['background_tasks']
        self.assertEqual(set(bg_tasks_content[0].keys()),
                         {"id", "selfLink", "status", "type"})

        task_id = bg_tasks[0].id
        content = self.api.client.get(
            "/api/background_tasks/{}".format(task_id))
        self.assert200(content)
        bg_task_content = \
            content.json['background_task']
        self.assertEqual(set(bg_task_content.keys()),
                         {"id", "selfLink", "status", "type"})
Beispiel #2
0
class TestBackgroundTask(TestCase):
  """Tests for background task model."""

  def setUp(self):
    """setUp, nothing else to add."""
    super(TestBackgroundTask, self).setUp()
    self.api = api_helper.Api()
    self.object_generator = ObjectGenerator()

  def test_bg_task_from_post(self):
    """Test filtering of GET response for BackgroundTask"""
    from ggrc.models import all_models

    with self.object_generator.api.as_external():
      response, _ = self.object_generator.generate_object(
          all_models.Control, with_background_tasks=True)
    self.assertEqual(response.status_code, 201)
    bg_tasks = all_models.BackgroundTask.query.filter(
        all_models.BackgroundTask.name.like("%POST%")).all()
    self.assertEqual(len(bg_tasks), 1)

    content = self.api.client.get("/api/background_tasks")
    self.assert200(content)
    bg_tasks_content = \
        content.json['background_tasks_collection']['background_tasks']
    self.assertEqual(set(bg_tasks_content[0].keys()),
                     {"id", "selfLink", "status", "type"})

    task_id = bg_tasks[0].id
    content = self.api.client.get("/api/background_tasks/{}".format(task_id))
    self.assert200(content)
    bg_task_content = \
        content.json['background_task']
    self.assertEqual(set(bg_task_content.keys()),
                     {"id", "selfLink", "status", "type"})
Beispiel #3
0
class TestResource(TestCase):
  """
  Test /search REST API
  """

  def setUp(self):
    super(TestResource, self).setUp()
    self.api = Api()
    self.object_generator = ObjectGenerator()
    self.create_objects()

  def create_objects(self):
    """Create objects to be searched.

    Creates five Requirements and makes relationships.
    0   1   2   3   4
    |---|   |---|   |
    |-------|-------|
    """
    self.objects = [
        self.object_generator.generate_object(all_models.Requirement)[1].id
        for _ in xrange(5)
    ]
    self.objects = all_models.Requirement.eager_query().filter(
        all_models.Requirement.id.in_(self.objects)
    ).all()
    for src, dst in [(0, 1), (0, 2), (2, 3), (2, 4)]:
      self.object_generator.generate_relationship(
          self.objects[src], self.objects[dst]
      )

  def search(self, *args, **kwargs):
    res, _ = self.api.search(*args, **kwargs)
    return res.json["results"]["entries"]

  def test_search_all(self):
    """Test search for all objects of a type."""
    res, _ = self.api.search("Requirement")
    self.assertEqual(len(res.json["results"]["entries"]), 5)

  def test_search_query(self):
    """Test search with query by title."""
    entries = self.search("Requirement", query=self.objects[0].title)
    self.assertEqual({entry["id"] for entry in entries},
                     {self.objects[0].id})

  def test_search_relevant(self):
    """Test search with 'relevant to' single object."""
    relevant_objects = "Requirement:{}".format(self.objects[0].id)
    entries = self.search("Requirement", relevant_objects=relevant_objects)
    self.assertEqual({entry["id"] for entry in entries},
                     {self.objects[i].id for i in [1, 2]})

  def test_search_relevant_multi(self):
    """Test search with 'relevant to' multiple objects."""
    ids = ",".join("Requirement:{}".format(self.objects[i].id) for i in (0, 3))
    entries = self.search("Requirement", relevant_objects=ids)
    self.assertEqual({entry["id"] for entry in entries},
                     {self.objects[2].id})
Beispiel #4
0
class TestResource(TestCase):
    """
  Test /search REST API
  """
    def setUp(self):
        super(TestResource, self).setUp()
        self.api = Api()
        self.object_generator = ObjectGenerator()
        self.create_objects()

    def create_objects(self):
        """Create objects to be searched.

    Creates five Requirements and makes relationships.
    0   1   2   3   4
    |---|   |---|   |
    |-------|-------|
    """
        self.objects = [
            self.object_generator.generate_object(all_models.Requirement)[1].id
            for _ in xrange(5)
        ]
        self.objects = all_models.Requirement.eager_query().filter(
            all_models.Requirement.id.in_(self.objects)).all()
        for src, dst in [(0, 1), (0, 2), (2, 3), (2, 4)]:
            self.object_generator.generate_relationship(
                self.objects[src], self.objects[dst])

    def search(self, *args, **kwargs):
        res, _ = self.api.search(*args, **kwargs)
        return res.json["results"]["entries"]

    def test_search_all(self):
        """Test search for all objects of a type."""
        res, _ = self.api.search("Requirement")
        self.assertEqual(len(res.json["results"]["entries"]), 5)

    def test_search_query(self):
        """Test search with query by title."""
        entries = self.search("Requirement", query=self.objects[0].title)
        self.assertEqual({entry["id"]
                          for entry in entries}, {self.objects[0].id})

    def test_search_relevant(self):
        """Test search with 'relevant to' single object."""
        relevant_objects = "Requirement:{}".format(self.objects[0].id)
        entries = self.search("Requirement", relevant_objects=relevant_objects)
        self.assertEqual({entry["id"]
                          for entry in entries},
                         {self.objects[i].id
                          for i in [1, 2]})

    def test_search_relevant_multi(self):
        """Test search with 'relevant to' multiple objects."""
        ids = ",".join("Requirement:{}".format(self.objects[i].id)
                       for i in (0, 3))
        entries = self.search("Requirement", relevant_objects=ids)
        self.assertEqual({entry["id"]
                          for entry in entries}, {self.objects[2].id})
Beispiel #5
0
class TestRiskSnapshotting(TestCase):
    """Risk snapshot tests"""
    def setUp(self):
        """setUp, nothing else to add."""
        super(TestRiskSnapshotting, self).setUp()
        self.api = api_helper.Api()
        self.api.login_as_external()
        self.objgen = ObjectGenerator()

    def test_update_risk_snapshot(self):
        """Update risk snapshot to the latest version"""
        with factories.single_commit():
            program = factories.ProgramFactory(title="P1")
            risk = factories.RiskFactory(title="R1")
            risk_id = risk.id
            factories.RelationshipFactory(source=program, destination=risk)

        # Risk snapshot created for audit during mapping audit to program
        self.objgen.generate_object(
            all_models.Audit, {
                "title": "A1",
                "program": {
                    "id": program.id
                },
                "status": "Planned",
                "snapshots": {
                    "operation": "create",
                }
            })

        # Update risk to get outdated snapshot (new risk revision)
        risk = all_models.Risk.query.get(risk_id)
        self.api.put(risk, {"title": "New risk title"})

        audit = all_models.Audit.query.filter_by(title="A1").one()
        snapshot = all_models.Snapshot.query.first()
        self.assertEquals(audit, snapshot.parent)

        # Update snapshot to the latest revision
        res = self.api.put(snapshot, {"update_revision": "latest"})

        self.assert200(res)
        self.assertTrue(res.json["snapshot"]["is_latest_revision"])
Beispiel #6
0
class TestPermissions(TestCase):
  """Test permissions for background tasks"""

  def setUp(self):
    super(TestPermissions, self).setUp()
    self.api = api_helper.Api()
    self.object_generator = ObjectGenerator()
    self.init_users()

  def init_users(self):
    """ Init users needed by the test cases """
    users = [("reader", "Reader"),
             ("admin", "Administrator"),
             ("creator", "Creator")]
    self.users = {}
    for (name, role) in users:
      _, user = self.object_generator.generate_person(
          data={"name": name}, user_role=role)
      self.users[name] = user

  def test_bg_tasks_access(self):
    """Only admin can use admin requirement"""
    from ggrc.models import all_models

    with self.object_generator.api.as_external():
      response, _ = self.object_generator.generate_object(
          all_models.Control, with_background_tasks=True)
    self.assertEqual(response.status_code, 201)

    for role in ("reader", "creator", "admin"):
      self.api.set_user(self.users[role])
      content = self.api.client.get("/api/background_tasks")
      self.assert200(content)
      bg_tasks_content = \
          content.json['background_tasks_collection']['background_tasks']
      for bg_task_content in bg_tasks_content:
        self.assertEqual(set(bg_task_content.keys()),
                         {"id", "selfLink", "status", "type"})
      self.assertTrue(len(bg_tasks_content) >= 1)
class TestPermissions(TestCase):
  """Test permissions for background tasks"""

  def setUp(self):
    super(TestPermissions, self).setUp()
    self.api = api_helper.Api()
    self.object_generator = ObjectGenerator()
    self.init_users()

  def init_users(self):
    """ Init users needed by the test cases """
    users = [("reader", "Reader"),
             ("admin", "Administrator"),
             ("creator", "Creator")]
    self.users = {}
    for (name, role) in users:
      _, user = self.object_generator.generate_person(
          data={"name": name}, user_role=role)
      self.users[name] = user

  def test_bg_tasks_access(self):
    """Only admin can use admin requirement"""
    from ggrc.models import all_models

    response, _ = self.object_generator.generate_object(
        all_models.Control, with_background_tasks=True)
    self.assertEqual(response.status_code, 201)

    for role in ("reader", "creator", "admin"):
      self.api.set_user(self.users[role])
      content = self.api.client.get("/api/background_tasks")
      self.assert200(content)
      bg_tasks_content = \
          content.json['background_tasks_collection']['background_tasks']
      for bg_task_content in bg_tasks_content:
        self.assertEqual(set(bg_task_content.keys()),
                         {"id", "selfLink", "status", "type"})
      self.assertTrue(len(bg_tasks_content) >= 1)
Beispiel #8
0
class TestWithExtCustomAttrsSetter(TestCase):
  """Test WithReadOnlyAccess mixin"""

  def setUp(self):
    super(TestWithExtCustomAttrsSetter, self).setUp()
    self.object_generator = ObjectGenerator()
    self.object_generator.api.login_as_normal()

  @staticmethod
  def _create_cads(obj_type, names=('ATTR1', 'ATTR2', 'ATTR3')):
    """Create custom attribute definitions"""

    ret = dict()

    with factories.single_commit():
      for name in names:
        obj = factories.CustomAttributeDefinitionFactory(
            title=name,
            definition_type=obj_type.lower(),
            attribute_type="Text",
        )
        ret[name] = obj.id

    return ret

  @staticmethod
  def _create_model(obj_type, cad_map, cavs):
    """Create model and assign CAVs"""

    with factories.single_commit():
      obj = factories.get_model_factory(obj_type)()

      for name, value in cavs.iteritems():
        cad = get_model('CustomAttributeDefinition').query.get(cad_map[name])
        factories.CustomAttributeValueFactory(
            custom_attribute=cad,
            attributable=obj,
            attribute_value=value,
        )

      return obj.id

  @staticmethod
  def _get_orig_cav_list(cad_map, name_to_val):
    """Return list of original cav in request json"""
    return list(
        {
            'custom_attribute_id': cad_map[name],
            'attribute_value': val,
            'attribute_object': None,
        } for name, val in name_to_val.iteritems()
    )

  @staticmethod
  def _get_external_cav_list(name_to_val):
    """Return list of external cav in request json"""
    return list(
        {
            'name': name,
            'value': val,
        } for name, val in name_to_val.iteritems()
    )

  @ddt.data('System')
  def test_post_orig_cavs(self, obj_type):
    """Test POST orig cav for {0!r} for normal user"""

    cad_map = self._create_cads(obj_type)

    vals = dict((name, name) for name in cad_map)
    resp, obj = self.object_generator.generate_object(
        get_model(obj_type),
        data={
            'custom_attribute_values': self._get_orig_cav_list(cad_map, vals),
        }
    )

    self.assertStatus(resp, 201)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)

    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_post_orig_cavs_external(self, obj_type):
    """Test POST orig cav for {0!r} for external user"""

    cad_map = self._create_cads(obj_type)

    self.object_generator.api.login_as_external()

    vals = dict((name, name) for name in cad_map)
    resp, obj = self.object_generator.generate_object(
        get_model(obj_type),
        data={
            'custom_attribute_values': self._get_orig_cav_list(cad_map, vals),
        }
    )

    self.assertStatus(resp, 201)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)

    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_post_ext_cavs(self, obj_type):
    """Test POST external cav for {0!r} for normal user"""

    cad_map = self._create_cads(obj_type)

    vals = dict((name, name) for name in cad_map)
    resp, obj = self.object_generator.generate_object(
        get_model(obj_type),
        data={
            'external_custom_attributes': self._get_external_cav_list(vals),
        }
    )

    self.assertStatus(resp, 201)

    exp = dict()
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_post_ext_cavs_external(self, obj_type):
    """Test POST external cav for {0!r} for external user"""

    cad_map = self._create_cads(obj_type)

    self.object_generator.api.login_as_external()

    vals = dict((name, name) for name in cad_map)
    resp, obj = self.object_generator.generate_object(
        get_model(obj_type),
        data={
            'external_custom_attributes': self._get_external_cav_list(vals),
        }
    )

    self.assertStatus(resp, 201)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_post_ext_and_orig_cavs_external(self, obj_type):
    """Test POST external and orig cav for {0!r} are specified for ext user"""

    cad_map = self._create_cads(obj_type)

    self.object_generator.api.login_as_external()

    orig_vals = dict((name, '{}-1'.format(name)) for name in cad_map)
    ext_vals = dict((name, name) for name in cad_map)
    resp, obj = self.object_generator.generate_object(
        get_model(obj_type),
        data={
            'custom_attribute_values': self._get_orig_cav_list(
                cad_map, orig_vals),
            'external_custom_attributes': self._get_external_cav_list(
                ext_vals),
        }
    )

    self.assertStatus(resp, 201)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_post_not_existing_cavs_external(self, obj_type):
    """Test POST missing cav for {0!r} are specified for external user"""

    cad_map = self._create_cads(obj_type)

    self.object_generator.api.login_as_external()

    vals = dict((name, name) for name in cad_map)
    vals['NEW'] = 'NEWVAL'
    resp, obj = self.object_generator.generate_object(
        get_model(obj_type),
        data={
            'external_custom_attributes': self._get_external_cav_list(vals),
        }
    )

    self.assertStatus(resp, 201)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_post_not_all_cavs_external(self, obj_type):
    """Test POST not all cavs for {0!r} are specified for external user"""

    cad_map = self._create_cads(obj_type)

    self.object_generator.api.login_as_external()

    vals = dict((name, name) for name in cad_map if name != "ATTR1")
    resp, obj = self.object_generator.generate_object(
        get_model(obj_type),
        data={
            'external_custom_attributes': self._get_external_cav_list(vals),
        }
    )

    self.assertStatus(resp, 201)

    exp = dict((cad_map[name], name) for name in cad_map if name != "ATTR1")
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_post_not_all_mandatory_cavs_external(self, obj_type):
    """Test POST not all cavs for {0!r} are specified for external user"""

    cad_map = self._create_cads(obj_type)
    factories.CustomAttributeDefinitionFactory(
        title="M-ATTR1",
        definition_type=obj_type.lower(),
        attribute_type="Text",
        mandatory=True
    )

    self.object_generator.api.login_as_external()

    vals = dict((name, name) for name in cad_map)
    resp, obj = self.object_generator.generate_object(
        get_model(obj_type),
        data={
            'external_custom_attributes': self._get_external_cav_list(vals),
        }
    )

    self.assertStatus(resp, 201)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_put_orig_cavs(self, obj_type):
    """Test PUT orig cav for {0!r} for normal user"""

    cad_map = self._create_cads(obj_type)
    orig_cavs = dict(
        (name, '{}-orig'.format(name)) for name in cad_map
    )
    obj_id = self._create_model(obj_type, cad_map, orig_cavs)

    vals = dict((name, name) for name in cad_map)
    obj = get_model(obj_type).query.get(obj_id)
    resp, obj = self.object_generator.modify(
        obj,
        obj_type.lower(),
        data={
            'custom_attribute_values': self._get_orig_cav_list(cad_map, vals),
        }
    )

    self.assert200(resp)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)

    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_put_orig_cavs_external(self, obj_type):
    """Test PUT orig cav for {0!r} for external user"""

    cad_map = self._create_cads(obj_type)
    orig_cavs = dict(
        (name, '{}-orig'.format(name)) for name in cad_map
    )
    obj_id = self._create_model(obj_type, cad_map, orig_cavs)

    self.object_generator.api.login_as_external()

    vals = dict((name, name) for name in cad_map)
    obj = get_model(obj_type).query.get(obj_id)
    resp, obj = self.object_generator.modify(
        obj,
        obj_type.lower(),
        data={
            'custom_attribute_values': self._get_orig_cav_list(cad_map, vals),
        }
    )

    self.assert200(resp)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)

    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_put_ext_cavs(self, obj_type):
    """Test PUT external cav for {0!r} for normal user"""

    cad_map = self._create_cads(obj_type)
    orig_cavs = dict(
        (name, '{}-orig'.format(name)) for name in cad_map
    )
    obj_id = self._create_model(obj_type, cad_map, orig_cavs)

    vals = dict((name, name) for name in cad_map)
    obj = get_model(obj_type).query.get(obj_id)
    resp, obj = self.object_generator.modify(
        obj,
        obj_type.lower(),
        data={
            'external_custom_attributes': self._get_external_cav_list(vals),
        }
    )

    self.assert200(resp)

    exp = dict((cad_map[name], orig_cavs[name]) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_put_ext_cavs_external(self, obj_type):
    """Test PUT external cav for {0!r} for external user"""

    cad_map = self._create_cads(obj_type)
    orig_cavs = dict(
        (name, '{}-orig'.format(name)) for name in cad_map
    )
    obj_id = self._create_model(obj_type, cad_map, orig_cavs)

    self.object_generator.api.login_as_external()

    vals = dict((name, name) for name in cad_map)
    obj = get_model(obj_type).query.get(obj_id)
    resp, obj = self.object_generator.modify(
        obj,
        obj_type.lower(),
        data={
            'external_custom_attributes': self._get_external_cav_list(vals),
        }
    )

    self.assert200(resp)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_put_ext_and_orig_cavs_external(self, obj_type):
    """Test PUT external and orig cav for {0!r} are specified for ext user"""

    cad_map = self._create_cads(obj_type)
    orig_cavs = dict(
        (name, '{}-orig'.format(name)) for name in cad_map
    )
    obj_id = self._create_model(obj_type, cad_map, orig_cavs)

    self.object_generator.api.login_as_external()

    orig_vals = dict((name, '{}-1'.format(name)) for name in cad_map)
    ext_vals = dict((name, name) for name in cad_map)
    obj = get_model(obj_type).query.get(obj_id)
    resp, obj = self.object_generator.modify(
        obj,
        obj_type.lower(),
        data={
            'custom_attribute_values': self._get_orig_cav_list(
                cad_map, orig_vals),
            'external_custom_attributes': self._get_external_cav_list(
                ext_vals),
        }
    )

    self.assert200(resp)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_put_not_existing_cavs_external(self, obj_type):
    """Test PUT missing cav for {0!r} are specified for external user"""

    cad_map = self._create_cads(obj_type)
    orig_cavs = dict(
        (name, '{}-orig'.format(name)) for name in cad_map
    )
    obj_id = self._create_model(obj_type, cad_map, orig_cavs)

    self.object_generator.api.login_as_external()

    vals = dict((name, name) for name in cad_map)
    vals['NEW'] = 'NEWVAL'
    obj = get_model(obj_type).query.get(obj_id)
    resp, obj = self.object_generator.modify(
        obj,
        obj_type.lower(),
        data={
            'external_custom_attributes': self._get_external_cav_list(vals),
        }
    )

    self.assert200(resp)

    exp = dict((cad_map[name], name) for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)

  @ddt.data('System')
  def test_put_not_all_cavs_external(self, obj_type):
    """Test PUT not all cavs for {0!r} are specified for external user"""

    cad_map = self._create_cads(obj_type)
    orig_cavs = dict(
        (name, '{}-orig'.format(name)) for name in cad_map
    )
    obj_id = self._create_model(obj_type, cad_map, orig_cavs)

    self.object_generator.api.login_as_external()

    vals = dict((name, name) for name in cad_map if name != 'ATTR1')
    obj = get_model(obj_type).query.get(obj_id)
    resp, obj = self.object_generator.modify(
        obj,
        obj_type.lower(),
        data={
            'external_custom_attributes': self._get_external_cav_list(vals),
        }
    )

    self.assert200(resp)

    exp = dict((cad_map[name], name if name != 'ATTR1' else orig_cavs['ATTR1'])
               for name in cad_map)
    cav = dict((i.custom_attribute_id, i.attribute_value)
               for i in obj.custom_attribute_values)
    self.assertDictEqual(cav, exp)
Beispiel #9
0
class TestReader(TestCase):
    """ Test reader role """
    def setUp(self):
        super(TestReader, self).setUp()
        self.api = Api()
        self.object_generator = ObjectGenerator()
        self.init_users()

    def init_users(self):
        """ Init users needed by the test cases """
        users = [("reader", "Reader"), ("admin", "Administrator"),
                 ("creator", "Creator")]
        self.users = {}
        for (name, role) in users:
            _, user = self.object_generator.generate_person(
                data={"name": name}, user_role=role)
            self.users[name] = user

    def test_admin_page_access(self):
        """Only admin can use admin requirement"""
        for role, code in (("reader", 403), ("admin", 200)):
            self.api.set_user(self.users[role])
            self.assertEqual(self.api.client.get("/admin").status_code, code)

    def test_reader_can_crud(self):
        """ Test Basic create/read,update/delete operations """
        self.api.set_user(self.users["reader"])
        all_errors = []
        base_models = set([
            "Control",
            "DataAsset",
            "Contract",
            "Policy",
            "Regulation",
            "Standard",
            "Document",
            "Facility",
            "Market",
            "Objective",
            "OrgGroup",
            "Vendor",
            "Product",
            "System",
            "Process",
            "Project",
            "AccessGroup",
            "Metric",
            "TechnologyEnvironment",
            "ProductGroup",
        ])
        for model_singular in base_models:
            try:
                model = get_model(model_singular)
                table_singular = model._inflector.table_singular
                table_plural = model._inflector.table_plural
                # Test POST creation
                response, _ = self.object_generator.generate_object(
                    model,
                    data={
                        table_singular: {
                            "title": model_singular,
                            "context": None,
                            "documents_reference_url": "ref",
                            "link": "https://example.com",  # only for Document
                            "contact": {
                                "type": "Person",
                                "id": self.users["reader"].id,
                            }
                        },
                    })

                if response.status_code != 201:
                    all_errors.append("{} post creation failed {} {}".format(
                        model_singular, response.status, response.data))
                    continue

                obj_id = response.json.get(table_singular).get("id")

                # Test GET when owner
                response = self.api.get(model, obj_id)
                if response.status_code != 200:
                    all_errors.append("{} can't GET object {}".format(
                        model_singular, response.status))
                    continue

                # Test GET collection when owner
                response = self.api.get_collection(model, obj_id)
                collection = response.json.get(
                    "{}_collection".format(table_plural)).get(table_plural)
                if not collection:
                    all_errors.append(
                        "{} cannot retrieve object even if owner (collection)".
                        format(model_singular))
                    continue
            except:
                all_errors.append("{} exception thrown".format(model_singular))
                raise
        self.assertEqual(all_errors, [])

    def test_reader_search(self):
        """ Test if reader can see the correct object while using search api """
        self.api.set_user(self.users['admin'])
        self.api.post(all_models.Regulation, {
            "regulation": {
                "title": "Admin regulation",
                "context": None
            },
        })
        self.api.set_user(self.users['reader'])
        response = self.api.post(all_models.Policy, {
            "policy": {
                "title": "reader Policy",
                "context": None
            },
        })
        response, _ = self.api.search("Regulation,Policy")
        entries = response.json["results"]["entries"]
        self.assertEqual(len(entries), 2)
        response, _ = self.api.search("Regulation,Policy", counts=True)
        self.assertEqual(response.json["results"]["counts"]["Policy"], 1)
        self.assertEqual(response.json["results"]["counts"]["Regulation"], 1)

    def _get_count(self, obj):
        """ Return the number of counts for the given object from search """
        response, _ = self.api.search(obj, counts=True)
        return response.json["results"]["counts"].get(obj)

    def test_reader_should_see_users(self):
        """ Test if creator can see all the users in the system """
        self.api.set_user(self.users['admin'])
        admin_count = self._get_count("Person")
        self.api.set_user(self.users['reader'])
        reader_count = self._get_count("Person")
        self.assertEqual(admin_count, reader_count)

    def test_relationships_access(self):
        """Check if reader can access relationship objects"""
        self.api.set_user(self.users['admin'])
        _, first_regulation = self.object_generator.generate_object(
            all_models.Regulation,
            data={"regulation": {
                "title": "Test regulation",
                "context": None
            }})
        _, second_regulation = self.object_generator.generate_object(
            all_models.Regulation,
            data={
                "regulation": {
                    "title": "Test regulation 2",
                    "context": None
                }
            })
        response, rel = self.object_generator.generate_relationship(
            first_regulation, second_regulation)
        self.assertStatus(response, 201)
        self.api.set_user(self.users['reader'])
        response = self.api.get_collection(all_models.Relationship, rel.id)
        self.assert200(response)
        num = len(response.json["relationships_collection"]["relationships"])
        self.assertEqual(num, 1)

    def test_creation_of_mappings(self):
        """Check if reader can't create mappings"""
        self.object_generator.api.set_user(self.users["admin"])
        _, control = self.object_generator.generate_object(
            all_models.Control,
            data={"control": {
                "title": "Test Control",
                "context": None
            }})

        self.object_generator.api.set_user(self.users['reader'])
        _, program = self.object_generator.generate_object(
            all_models.Program,
            data={"program": {
                "title": "Test Program",
                "context": None
            }})

        response, _ = self.object_generator.generate_relationship(
            control, program, program.context)
        self.assert403(response)

    @ddt.data("creator", "reader")
    def test_unmap_people(self, user_role):
        """Test that global reader/creator can't unmap people from program"""
        user = self.users[user_role]
        with factories.single_commit():
            program = factories.ProgramFactory()
            mapped_person = factories.ObjectPersonFactory(
                personable=program, person=user, context=program.context)
        self.api.set_user(user)
        db.session.add(mapped_person)
        response = self.api.delete(mapped_person)
        self.assert403(response)

    def test_read_evidence_revision(self):
        """Global Read can read Evidence revision content"""
        user = self.users["reader"]
        link = "google.com"
        evidence = factories.EvidenceUrlFactory(link=link)
        evidence_id = evidence.id
        self.api.set_user(user)
        resp = self.api.client.get(
            "/api/revisions?resource_type={}&resource_id={}".format(
                evidence.type, evidence_id))
        rev_content = resp.json["revisions_collection"]["revisions"][0][
            "content"]
        self.assertTrue(rev_content)
        self.assertEquals(link, rev_content["link"])
Beispiel #10
0
class TestPermissionsOnAssessmentTemplate(TestCase):
    """ Test check permissions for ProgramEditor on

  get and post assessment_temaplte action"""
    def setUp(self):
        super(TestPermissionsOnAssessmentTemplate, self).setUp()
        self.api = Api()
        self.generator = ObjectGenerator()
        _, program = self.generator.generate_object(all_models.Program)
        program_id = program.id
        _, self.editor = self.generator.generate_person(user_role="Creator")
        role = perms.all_models.Role.query.filter(
            perms.all_models.Role.name == "ProgramEditor").first()
        self.generator.generate_user_role(
            self.editor, role, all_models.Program.query.get(program_id))
        _, audit = self.generator.generate_object(
            all_models.Audit,
            {
                "title": "Audit",
                "program": {
                    "id": program_id
                },
                "status": "Planned"
            },
        )
        audit_id = audit.id

        generated_at = self.generator.generate_object(
            all_models.AssessmentTemplate, {
                "title": "Template",
                "_NON_RELEVANT_OBJ_TYPES": {},
                "_objectTypes": {},
                "audit": {
                    "id": audit.id
                },
                "audit_title": audit.title,
                "people_value": [],
                "default_people": {
                    "assignees": "Admin",
                    "verifiers": "Admin",
                },
                "context": {
                    "id": audit.context.id
                },
            })
        self.assessment_template_resp, assessment_template = generated_at
        assessment_template_id = assessment_template.id
        self.api.set_user(self.editor)
        self.perms_data = self.api.client.get("/permissions").json
        self.audit = all_models.Audit.query.get(audit_id)
        self.assessment_template = all_models.AssessmentTemplate.query.get(
            assessment_template_id)

    def test_post_action(self):
        """Test create action on AssessmentTemplate created by api"""
        data = [{
            "assessment_template": {
                "_NON_RELEVANT_OBJ_TYPES": {},
                "_objectTypes": {},
                "audit": {
                    "id": self.audit.id
                },
                "audit_title": self.audit.title,
                "people_value": [],
                "default_people": {
                    "assignees": "Admin",
                    "verifiers": "Admin",
                },
                "context": {
                    "id": self.audit.context.id
                },
                "title": "123",
            }
        }]
        self.api.set_user(self.editor)
        resp = self.api.post(all_models.AssessmentTemplate, data)
        self.assert200(resp)

    def test_get_action(self):
        """Test read action on AssessmentTemplate created by api"""
        resp = self.api.get(all_models.AssessmentTemplate,
                            self.assessment_template.id)
        self.assert200(resp)

    def test_put_action(self):
        """Test update action on AssessmentTemplate created by api"""
        to_update = copy.deepcopy(self.assessment_template_resp.json)
        new_title = "new_{}".format(self.assessment_template.title)
        to_update['assessment_template']['title'] = new_title
        resp = self.api.put(self.assessment_template, to_update)
        self.assert200(resp)
        assessment_tmpl = all_models.AssessmentTemplate.query.get(
            self.assessment_template.id)
        self.assertEqual(new_title, assessment_tmpl.title)

    def test_delete_action(self):
        """Test delete action on AssessmentTemplate created by api"""
        resp = self.api.delete(self.assessment_template)
        self.assert200(resp)
        self.assertFalse(
            all_models.AssessmentTemplate.query.filter(
                all_models.AssessmentTemplate ==
                self.assessment_template.id).all())
Beispiel #11
0
class TestResource(TestCase):
    """
  Test /search REST API
  """
    def setUp(self):
        super(TestResource, self).setUp()
        self.api = Api()
        self.object_generator = ObjectGenerator()
        self.create_objects()

    def create_objects(self):
        """Create objects to be searched.

    Creates five controls and makes relationships.
    0   1   2   3   4
    |---|   |---|   |
    |-------|-------|
    """
        self.objects = [
            self.object_generator.generate_object(Control)[1].id
            for _ in xrange(5)
        ]
        self.objects = Control.eager_query().filter(
            Control.id.in_(self.objects)).all()
        for src, dst in [(0, 1), (0, 2), (2, 3), (2, 4)]:
            self.object_generator.generate_relationship(
                self.objects[src], self.objects[dst])

    def search(self, *args, **kwargs):
        res, _ = self.api.search(*args, **kwargs)
        return res.json["results"]["entries"]

    def test_search_all(self):
        """Test search for all objects of a type."""
        res, _ = self.api.search("Control")
        self.assertEqual(len(res.json["results"]["entries"]), 5)

    def test_search_query(self):
        """Test search with query by title."""
        entries = self.search("Control", query=self.objects[0].title)
        self.assertEqual({entry["id"]
                          for entry in entries}, {self.objects[0].id})

    def test_search_relevant(self):
        """Test search with 'relevant to' single object."""
        relevant_objects = "Control:{}".format(self.objects[0].id)
        entries = self.search("Control", relevant_objects=relevant_objects)
        self.assertEqual({entry["id"]
                          for entry in entries},
                         {self.objects[i].id
                          for i in [1, 2]})

    def test_search_relevant_multi(self):
        """Test search with 'relevant to' multiple objects."""
        ids = ",".join("Control:{}".format(self.objects[i].id) for i in (0, 3))
        entries = self.search("Control", relevant_objects=ids)
        self.assertEqual({entry["id"]
                          for entry in entries}, {self.objects[2].id})

    def test_search_fail_with_terms_none(self):
        """Test search to fail with BadRequest (400 Error) when terms are None."""
        query = '/search?types={}&counts_only={}'.format("Control", False)
        response = self.api.client.get(query)
        self.assert400(response)
        self.assertEqual(
            response.json['message'], 'Query parameter "q" '
            'specifying search terms must be provided.')
Beispiel #12
0
class TestResource(TestCase):
  """
  Test /search REST API
  """

  def setUp(self):
    super(TestResource, self).setUp()
    self.api = Api()
    self.object_generator = ObjectGenerator()
    self.create_objects()

  def create_objects(self):
    """Create objects to be searched.

    Creates five controls and makes relationships.
    0   1   2   3   4
    |---|   |---|   |
    |-------|-------|
    """
    self.objects = [
        self.object_generator.generate_object(Control)[1].id
        for _ in xrange(5)
    ]
    self.objects = Control.eager_query().filter(
        Control.id.in_(self.objects)
    ).all()
    for src, dst in [(0, 1), (0, 2), (2, 3), (2, 4)]:
      self.object_generator.generate_relationship(
          self.objects[src], self.objects[dst]
      )

  def search(self, *args, **kwargs):
    res, _ = self.api.search(*args, **kwargs)
    return res.json["results"]["entries"]

  def test_search_all(self):
    """Test search for all objects of a type."""
    res, _ = self.api.search("Control")
    self.assertEqual(len(res.json["results"]["entries"]), 5)

  def test_search_query(self):
    """Test search with query by title."""
    entries = self.search("Control", query=self.objects[0].title)
    self.assertEqual({entry["id"] for entry in entries},
                     {self.objects[0].id})

  def test_search_relevant(self):
    """Test search with 'relevant to' single object."""
    relevant_objects = "Control:{}".format(self.objects[0].id)
    entries = self.search("Control", relevant_objects=relevant_objects)
    self.assertEqual({entry["id"] for entry in entries},
                     {self.objects[i].id for i in [1, 2]})

  def test_search_relevant_multi(self):
    """Test search with 'relevant to' multiple objects."""
    ids = ",".join("Control:{}".format(self.objects[i].id) for i in (0, 3))
    entries = self.search("Control", relevant_objects=ids)
    self.assertEqual({entry["id"] for entry in entries},
                     {self.objects[2].id})

  def test_search_fail_with_terms_none(self):
    """Test search to fail with BadRequest (400 Error) when terms are None."""
    query = '/search?types={}&counts_only={}'.format("Control", False)
    response = self.api.client.get(query)
    self.assert400(response)
    self.assertEqual(response.json['message'], 'Query parameter "q" '
                     'specifying search terms must be provided.')
Beispiel #13
0
class TestPermissionsOnAssessmentTemplate(TestCase):
  """ Test check permissions for ProgramEditor on

  get and post assessment_temaplte action"""

  def setUp(self):
    super(TestPermissionsOnAssessmentTemplate, self).setUp()
    self.api = Api()
    self.generator = ObjectGenerator()
    _, program = self.generator.generate_object(all_models.Program)
    program_id = program.id
    _, self.editor = self.generator.generate_person(
        user_role="Creator"
    )
    role = perms.all_models.Role.query.filter(
        perms.all_models.Role.name == "ProgramEditor"
    ).first()
    self.generator.generate_user_role(
        self.editor,
        role,
        all_models.Program.query.get(program_id)
    )
    _, audit = self.generator.generate_object(
        all_models.Audit,
        {
            "title": "Audit",
            "program": {"id": program_id},
            "status": "Planned"
        },
    )
    audit_id = audit.id

    generated_at = self.generator.generate_object(
        all_models.AssessmentTemplate,
        {
            "title": "Template",
            "_NON_RELEVANT_OBJ_TYPES": {},
            "_objectTypes": {},
            "audit": {"id": audit.id},
            "audit_title": audit.title,
            "people_value": [],
            "default_people": {
                "assessors": "Object Owners",
                "verifiers": "Object Owners",
            },
            "context": {"id": audit.context.id},
        }
    )
    self.assessment_template_resp, assessment_template = generated_at
    assessment_template_id = assessment_template.id
    self.api.set_user(self.editor)
    self.perms_data = self.api.client.get("/permissions").json
    self.audit = all_models.Audit.query.get(audit_id)
    self.assessment_template = all_models.AssessmentTemplate.query.get(
        assessment_template_id)

  def test_post_action(self):
    """Test create action on AssessmentTemplate created by api"""
    data = [{
        "assessment_template": {
            "_NON_RELEVANT_OBJ_TYPES": {},
            "_objectTypes": {},
            "audit": {"id": self.audit.id},
            "audit_title": self.audit.title,
            "people_value": [],
            "default_people": {
                "assessors": "Object Owners",
                "verifiers": "Object Owners",
            },
            "context": {"id": self.audit.context.id},
            "title": "123",
        }
    }]
    self.api.set_user(self.editor)
    resp = self.api.post(all_models.AssessmentTemplate, data)
    self.assert200(resp)

  def test_get_action(self):
    """Test read action on AssessmentTemplate created by api"""
    resp = self.api.get(all_models.AssessmentTemplate,
                        self.assessment_template.id)
    self.assert200(resp)

  def test_put_action(self):
    """Test update action on AssessmentTemplate created by api"""
    to_update = copy.deepcopy(self.assessment_template_resp.json)
    new_title = "new_{}".format(self.assessment_template.title)
    to_update['assessment_template']['title'] = new_title
    resp = self.api.put(self.assessment_template, to_update)
    self.assert200(resp)
    assessment_tmpl = all_models.AssessmentTemplate.query.get(
        self.assessment_template.id
    )
    self.assertEqual(new_title, assessment_tmpl.title)

  def test_delete_action(self):
    """Test delete action on AssessmentTemplate created by api"""
    resp = self.api.delete(self.assessment_template)
    self.assert200(resp)
    self.assertFalse(all_models.AssessmentTemplate.query.filter(
        all_models.AssessmentTemplate == self.assessment_template.id).all())
Beispiel #14
0
class TestReader(TestCase):
  """ Test reader role """

  def setUp(self):
    super(TestReader, self).setUp()
    self.api = Api()
    self.object_generator = ObjectGenerator()
    self.init_users()

  def init_users(self):
    """ Init users needed by the test cases """
    users = [("reader", "Reader"),
             ("admin", "Administrator"),
             ("creator", "Creator")]
    self.users = {}
    for (name, role) in users:
      _, user = self.object_generator.generate_person(
          data={"name": name}, user_role=role)
      self.users[name] = user

    self.users["external"] = self.object_generator.generate_person(
        data={"email": "*****@*****.**"})[1]

  def test_admin_page_access(self):
    """Only admin can use admin requirement"""
    for role, code in (("reader", 403), ("admin", 200)):
      self.api.set_user(self.users[role])
      self.assertEqual(self.api.client.get("/admin").status_code, code)

  def test_reader_can_crud(self):
    """ Test Basic create/read,update/delete operations """
    self.api.set_user(self.users["reader"])
    all_errors = []
    base_models = set([
        "DataAsset", "Contract",
        "Policy", "Regulation", "Standard", "Document", "Facility",
        "Market", "Objective", "OrgGroup", "Vendor", "Product",
        "System", "Process", "Project", "AccessGroup",
        "Metric", "TechnologyEnvironment", "ProductGroup", "KeyReport",
        "AccountBalance",
    ])
    for model_singular in base_models:
      try:
        model = get_model(model_singular)
        table_singular = model._inflector.table_singular
        table_plural = model._inflector.table_plural
        # Test POST creation
        response, _ = self.object_generator.generate_object(
            model,
            data={
                table_singular: {
                    "title": model_singular,
                    "context": None,
                    "documents_reference_url": "ref",
                    "link": "https://example.com",  # only for Document
                    "contact": {
                        "type": "Person",
                        "id": self.users["reader"].id,
                    }
                },
            }
        )

        if response.status_code != 201:
          all_errors.append("{} post creation failed {} {}".format(
              model_singular, response.status, response.data))
          continue

        obj_id = response.json.get(table_singular).get("id")

        # Test GET when owner
        response = self.api.get(model, obj_id)
        if response.status_code != 200:
          all_errors.append("{} can't GET object {}".format(
              model_singular, response.status))
          continue

        # Test GET collection when owner
        response = self.api.get_collection(model, obj_id)
        collection = response.json.get(
            "{}_collection".format(table_plural)).get(table_plural)
        if not collection:
          all_errors.append(
              "{} cannot retrieve object even if owner (collection)".format(
                  model_singular))
          continue
      except:
        all_errors.append("{} exception thrown".format(model_singular))
        raise
    self.assertEqual(all_errors, [])

  def test_reader_search(self):
    """ Test if reader can see the correct object while using search api """
    self.api.set_user(self.users['admin'])
    self.api.post(all_models.Regulation, {
        "regulation": {"title": "Admin regulation", "context": None},
    })
    self.api.set_user(self.users['reader'])
    response = self.api.post(all_models.Policy, {
        "policy": {"title": "reader Policy", "context": None},
    })
    response, _ = self.api.search("Regulation,Policy")
    entries = response.json["results"]["entries"]
    self.assertEqual(len(entries), 2)
    response, _ = self.api.search("Regulation,Policy", counts=True)
    self.assertEqual(response.json["results"]["counts"]["Policy"], 1)
    self.assertEqual(response.json["results"]["counts"]["Regulation"], 1)

  def _get_count(self, obj):
    """ Return the number of counts for the given object from search """
    response, _ = self.api.search(obj, counts=True)
    return response.json["results"]["counts"].get(obj)

  def test_reader_should_see_users(self):
    """ Test if creator can see all the users in the system """
    self.api.set_user(self.users['admin'])
    admin_count = self._get_count("Person")
    self.api.set_user(self.users['reader'])
    reader_count = self._get_count("Person")
    self.assertEqual(admin_count, reader_count)

  def test_relationships_access(self):
    """Check if reader can access relationship objects"""
    self.api.set_user(self.users['admin'])
    _, first_regulation = self.object_generator.generate_object(
        all_models.Regulation,
        data={"regulation": {"title": "Test regulation", "context": None}}
    )
    _, second_regulation = self.object_generator.generate_object(
        all_models.Regulation,
        data={"regulation": {"title": "Test regulation 2", "context": None}}
    )
    response, rel = self.object_generator.generate_relationship(
        first_regulation, second_regulation
    )
    self.assertStatus(response, 201)
    self.api.set_user(self.users['reader'])
    response = self.api.get_collection(all_models.Relationship, rel.id)
    self.assert200(response)
    num = len(response.json["relationships_collection"]["relationships"])
    self.assertEqual(num, 1)

  def test_creation_of_mappings(self):
    """Check if reader can't create mappings"""
    self.object_generator.api.set_user(self.users["external"])
    _, control = self.object_generator.generate_object(
        all_models.Control,
        data={"control": {"title": "Test Control", "context": None}}
    )

    self.object_generator.api.set_user(self.users['reader'])
    _, program = self.object_generator.generate_object(
        all_models.Program,
        data={"program": {"title": "Test Program", "context": None}}
    )

    response, _ = self.object_generator.generate_relationship(
        control, program, program.context
    )
    self.assert403(response)

  @ddt.data("creator", "reader")
  def test_unmap_people(self, user_role):
    """Test that global reader/creator can't unmap people from program"""
    user = self.users[user_role]
    with factories.single_commit():
      program = factories.ProgramFactory()
      mapped_person = factories.ObjectPersonFactory(
          personable=program, person=user, context=program.context
      )
    self.api.set_user(user)
    db.session.add(mapped_person)
    response = self.api.delete(mapped_person)
    self.assert403(response)

  def test_read_evidence_revision(self):
    """Global Read can read Evidence revision content"""
    user = self.users["reader"]
    link = "google.com"
    evidence = factories.EvidenceUrlFactory(link=link)
    evidence_id = evidence.id
    self.api.set_user(user)
    resp = self.api.client.get(
        "/api/revisions?resource_type={}&resource_id={}".format(evidence.type,
                                                                evidence_id))
    rev_content = resp.json["revisions_collection"]["revisions"][0]["content"]
    self.assertTrue(rev_content)
    self.assertEquals(link, rev_content["link"])
Beispiel #15
0
class TestCreator(TestCase):
    """ TestCreator """
    def setUp(self):
        super(TestCreator, self).setUp()
        self.api = Api()
        self.object_generator = ObjectGenerator()
        self.init_users()

    def init_users(self):
        """ Init users needed by the test cases """

        users = [("creator", "Creator"), ("admin", "Administrator")]
        self.users = {}
        for (name, role) in users:
            _, user = self.object_generator.generate_person(
                data={"name": name}, user_role=role)
            self.users[name] = user

    def test_admin_page_access(self):
        """Permissions to admin page."""
        for role, code in (("creator", 403), ("admin", 200)):
            self.api.set_user(self.users[role])
            self.assertEqual(self.api.client.get("/admin").status_code, code)

    def test_creator_can_crud(self):
        """ Test Basic create/read,update/delete operations """
        self.api.set_user(self.users["creator"])
        creator_id = self.users["creator"].id
        audit_id = factories.AuditFactory().id
        all_errors = []
        base_models = {
            "Control",
            "DataAsset",
            "Contract",
            "Requirement",
            "Policy",
            "Regulation",
            "Standard",
            "Document",
            "Facility",
            "Market",
            "Objective",
            "OrgGroup",
            "Vendor",
            "Product",
            "System",
            "Process",
            "Project",
            "AccessGroup",
            "Metric",
            "ProductGroup",
            "TechnologyEnvironment",
        }
        for model_singular in base_models:
            try:
                model = get_model(model_singular)
                table_singular = model._inflector.table_singular
                table_plural = model._inflector.table_plural
                # Test POST creation
                response, _ = self.object_generator.generate_object(
                    model,
                    data={
                        table_singular: {
                            "title": model_singular,
                            "context": None,
                            "documents_reference_url": "ref",
                            # ignored except for Document
                            "link": "https://example.com",
                            "contact": {
                                "type": "Person",
                                "id": creator_id
                            },
                            # this is ignored on everything but Issues
                            "audit": {
                                "id": audit_id,
                                "type": "Audit",
                            }
                        },
                    })

                if response.status_code != 201:
                    all_errors.append("{} post creation failed {} {}".format(
                        model_singular, response.status, response.data))
                    continue

                # Test GET when not owner
                obj_id = response.json.get(table_singular).get("id")
                response = self.api.get(model, obj_id)
                if response.status_code != 403:  # we are not onwers yet
                    all_errors.append(
                        "{} can retrieve object if not owner".format(
                            model_singular))
                    continue
                response = self.api.get_collection(model, obj_id)
                collection = response.json.get(
                    "{}_collection".format(table_plural)).get(table_plural)
                if collection:
                    all_errors.append(
                        "{} can retrieve object if not owner (collection)".
                        format(model_singular))
                    continue

                # Test GET when owner
                acr = all_models.AccessControlRole.query.filter_by(
                    object_type=model_singular, name="Admin").one()
                acl = all_models.AccessControlList.query.filter_by(
                    object_id=obj_id,
                    object_type=model_singular,
                    ac_role=acr,
                ).one()
                factories.AccessControlPersonFactory(
                    ac_list=acl,
                    person_id=creator_id,
                )

                response = self.api.get(model, obj_id)
                if response.status_code != 200:
                    all_errors.append("{} can't GET object {}".format(
                        model_singular, response.status))
                    continue

                # Test GET collection when owner
                response = self.api.get_collection(model, obj_id)
                collection = response.json.get(
                    "{}_collection".format(table_plural)).get(table_plural)
                if not collection:
                    all_errors.append(
                        "{} cannot retrieve object even if owner (collection)".
                        format(model_singular))
                    continue
            except:
                all_errors.append("{} exception thrown".format(model_singular))
                raise
        self.assertEqual(all_errors, [])

    def test_creator_search(self):
        """Test if creator can see the correct object while using the search api"""
        self.api.set_user(self.users['admin'])
        self.api.post(all_models.Regulation, {
            "regulation": {
                "title": "Admin regulation",
                "context": None
            },
        })
        self.api.set_user(self.users['creator'])
        acr_id = all_models.AccessControlRole.query.filter_by(
            object_type="Policy", name="Admin").first().id
        response = self.api.post(
            all_models.Policy, {
                "policy": {
                    "title":
                    "Creator Policy",
                    "context":
                    None,
                    "access_control_list": [
                        acl_helper.get_acl_json(acr_id,
                                                self.users["creator"].id)
                    ],
                },
            })
        response.json.get("policy").get("id")
        response, _ = self.api.search("Regulation,Policy")
        entries = response.json["results"]["entries"]
        self.assertEqual(len(entries), 1)
        self.assertEqual(entries[0]["type"], "Policy")
        response, _ = self.api.search("Regulation,Policy", counts=True)
        self.assertEqual(response.json["results"]["counts"]["Policy"], 1)
        self.assertEqual(response.json["results"]["counts"].get("Regulation"),
                         None)

    def _get_count(self, obj):
        """ Return the number of counts for the given object from search """
        response, _ = self.api.search(obj, counts=True)
        return response.json["results"]["counts"].get(obj)

    def test_creator_should_see_users(self):
        """ Test if creator can see all the users in the system """
        self.api.set_user(self.users['admin'])
        admin_count = self._get_count("Person")
        self.api.set_user(self.users['creator'])
        creator_count = self._get_count("Person")
        self.assertEqual(admin_count, creator_count)

    def test_relationships_access(self):
        """Check if creator cannot access relationship objects"""
        self.api.set_user(self.users['admin'])
        _, first_regulation = self.object_generator.generate_object(
            all_models.Regulation,
            data={"regulation": {
                "title": "Test regulation",
                "context": None
            }})
        _, second_regulation = self.object_generator.generate_object(
            all_models.Regulation,
            data={
                "regulation": {
                    "title": "Test regulation 2",
                    "context": None
                }
            })
        response, rel = self.object_generator.generate_relationship(
            first_regulation, second_regulation)
        relationship_id = rel.id
        self.assertEqual(response.status_code, 201)
        self.api.set_user(self.users['creator'])
        response = self.api.get_collection(all_models.Relationship,
                                           relationship_id)
        self.assertEqual(response.status_code, 200)
        num = len(response.json["relationships_collection"]["relationships"])
        self.assertEqual(num, 0)

    def test_revision_access(self):
        """Check if creator can access the right revision objects."""
        def gen(title, extra_data=None):
            """Generates requirement."""
            requirement_content = {"title": title, "context": None}
            if extra_data:
                requirement_content.update(**extra_data)
            return self.object_generator.generate_object(
                all_models.Requirement,
                data={"requirement": requirement_content})[1]

        def check(obj, expected):
            """Check that how many revisions of an object current user can see."""
            response = self.api.get_query(
                all_models.Revision,
                "resource_type={}&resource_id={}".format(obj.type, obj.id))
            self.assertEqual(response.status_code, 200)
            self.assertEqual(
                len(response.json['revisions_collection']['revisions']),
                expected)

        self.api.set_user(self.users["admin"])
        obj_1 = gen("Test Requirement 1")

        self.api.set_user(self.users["creator"])
        acr_id = all_models.AccessControlRole.query.filter_by(
            object_type="Requirement", name="Admin").first().id
        linked_acl = {
            "access_control_list":
            [acl_helper.get_acl_json(acr_id, self.users["creator"].id)],
        }
        check(obj_1, 0)
        obj_2 = gen("Test Requirement 2", linked_acl)
        obj2_acl = obj_2.access_control_list[0][1]
        check(obj_2, 1)
        check(obj2_acl, 1)

    @ddt.data("creator", "admin")
    def test_count_type_in_accordion(self, glob_role):
        """Return count of Persons in DB for side accordion."""
        self.api.set_user(self.users[glob_role])
        ocordion_api_person_count_link = (
            "/search?"
            "q=&types=Program%2CWorkflow_All%2C"
            "Audit%2CAssessment%2CIssue%2CRegulation%2C"
            "Policy%2CStandard%2CContract%2CRequirement%2CControl%2C"
            "Objective%2CPerson%2COrgGroup%2CVendor%2CAccessGroup%2CSystem%2C"
            "Process%2CDataAsset%2CProduct%2CProject%2CFacility%2C"
            "Market%2CRisk%2CThreat&counts_only=true&"
            "extra_columns=Workflow_All%3DWorkflow%2C"
            "Workflow_Active%3DWorkflow%2CWorkflow_Draft%3D"
            "Workflow%2CWorkflow_Inactive%3DWorkflow&contact_id=1&"
            "extra_params=Workflow%3Astatus%3DActive%3BWorkflow_Active"
            "%3Astatus%3DActive%3BWorkflow_Inactive%3Astatus%3D"
            "Inactive%3BWorkflow_Draft%3Astatus%3DDraft")
        resp = self.api.client.get(ocordion_api_person_count_link)
        self.assertIn("Person", resp.json["results"]["counts"])
        self.assertEqual(all_models.Person.query.count(),
                         resp.json["results"]["counts"]["Person"])

    @ddt.data(
        ("/api/revisions?resource_type={}&resource_id={}", 1),
        ("/api/revisions?source_type={}&source_id={}", 0),
        ("/api/revisions?destination_type={}&destination_id={}", 1),
    )
    @ddt.unpack
    def test_changelog_access(self, link, revision_count):
        """Test accessing changelog under GC user who is assigned to object"""
        with factories.single_commit():
            audit = factories.AuditFactory()
            asmnt = factories.AssessmentFactory(audit=audit)
            asmnt_id = asmnt.id
            factories.RelationshipFactory(source=audit, destination=asmnt)
            factories.AccessControlPersonFactory(
                ac_list=asmnt.acr_name_acl_map["Verifiers"],
                person=self.users["creator"],
            )

        self.api.set_user(self.users["creator"])
        response = self.api.client.get(link.format("Assessment", asmnt_id))
        self.assert200(response)
        self.assertEqual(
            len(
                response.json.get("revisions_collection",
                                  {}).get("revisions")), revision_count)

    @ddt.data(all_models.ControlCategory, all_models.ControlAssertion)
    def test_permissions_for_categories(self, category_model):
        """Test get collection for {0}."""
        self.api.set_user(self.users["creator"])
        resp = self.api.get_collection(category_model, None)
        plural_name = category_model._inflector.table_plural
        key_name = "{}_collection".format(plural_name)
        self.assertIn(key_name, resp.json)
        self.assertIn(plural_name, resp.json[key_name])
        collection = resp.json[key_name][plural_name]
        self.assertTrue(collection, "Collection shouldn't be empty")
class TestWithReadOnlyAccessAPI(TestCase):
  """Test WithReadOnlyAccess mixin"""

  def setUp(self):
    super(TestWithReadOnlyAccessAPI, self).setUp()
    self.object_generator = ObjectGenerator()
    self.object_generator.api.login_as_normal()

  @ddt.data(
      ('System', True),
      ('System', False),
      ('System', None),
      ('System', "qwert"),
  )
  @ddt.unpack
  def test_readonly_ignored_on_post(self, obj_type, readonly):
    """Test flag readonly ignored on object {0} POST for body readonly={1}"""

    dct = dict()
    if readonly is not None:
      dct['readonly'] = readonly
    resp, obj = self.object_generator.generate_object(
        get_model(obj_type),
        {'readonly': readonly},
    )

    self.assertStatus(resp, 201)

    self.assertFalse(obj.readonly)

  @ddt.data(
      ('System', False, False, 200),
      ('System', False, True, 200),
      ('System', False, None, 200),
      ('System', True, False, 405),
      ('System', True, True, 405),
      ('System', True, None, 405),
  )
  @ddt.unpack
  def test_put(self, obj_type, current, new, exp_code):
    """Test {0} PUT readonly={2} for current readonly={1}"""

    factory = factories.get_model_factory(obj_type)
    with factories.single_commit():
      obj = factory(title='a', readonly=current)
      obj_id = obj.id

    data = {'title': 'b'}
    if new is not None:
      data['readonly'] = new

    resp = self.object_generator.api.put(obj, data)

    self.assertStatus(resp, exp_code)
    obj = get_model(obj_type).query.get(obj_id)
    self.assertEqual(obj.readonly, current)

  @ddt.data('System')
  def test_403_if_put_readonly_without_perms(self, obj_type):
    """Test {0} with readonly=True PUT returns 401 instead of 405

    This test ensures that user without permission for the object
    cannot obtain value for flag readonly
    """
    role_obj = all_models.Role.query.filter(
        all_models.Role.name == "Creator").one()

    factory = factories.get_model_factory(obj_type)

    with factories.single_commit():
      # create Global Creator
      person = factories.PersonFactory()
      person_id = person.id
      rbac_factories.UserRoleFactory(role=role_obj, person=person)

      # Create object
      obj = factory(title='a', readonly=True)
      obj_id = obj.id

    self.object_generator.api.set_user(all_models.Person.query.get(person_id))
    obj = get_model(obj_type).query.get(obj_id)
    resp = self.object_generator.api.put(obj, {'title': 'b'})

    self.assert403(resp)

  @ddt.data(
      ('System', False, 200, True),
      ('System', True, 405, False),
  )
  @ddt.unpack
  def test_delete(self, obj_type, readonly, exp_code, exp_deleted):
    """Test {0} DELETE if readonly={1}"""

    factory = factories.get_model_factory(obj_type)
    with factories.single_commit():
      obj = factory(title='a', readonly=readonly)
      obj_id = obj.id

    resp = self.object_generator.api.delete(obj)

    self.assertStatus(resp, exp_code)
    obj = get_model(obj_type).query.get(obj_id)
    if exp_deleted:
      self.assertIsNone(obj)
    else:
      self.assertIsNotNone(obj)

  @ddt.data('System')
  def test_403_if_delete_readonly_without_perms(self, obj_type):
    """Test {0} with readonly=True DELETE returns 401

    This test ensures that user without permission for the object
    cannot obtain value for flag readonly
    """

    role_obj = all_models.Role.query.filter(
        all_models.Role.name == "Creator").one()

    factory = factories.get_model_factory(obj_type)

    with factories.single_commit():
      # create Global Creator
      person = factories.PersonFactory()
      person_id = person.id
      rbac_factories.UserRoleFactory(role=role_obj, person=person)

      # Create object
      obj = factory(title='a', readonly=True)
      obj_id = obj.id

    self.object_generator.api.set_user(all_models.Person.query.get(person_id))
    obj = get_model(obj_type).query.get(obj_id)
    resp = self.object_generator.api.delete(obj)

    self.assert403(resp)
    obj = get_model(obj_type).query.get(obj_id)
    self.assertIsNotNone(obj)

  @ddt.data(
      ('System', False, 'Document', True, 201),
      ('System', False, 'Document', False, 201),
      ('System', True, 'Document', True, 405),
      ('System', True, 'Document', False, 405),
      ('System', False, 'Comment', True, 201),
      ('System', False, 'Comment', False, 201),
      ('System', True, 'Comment', True, 201),
      ('System', True, 'Comment', False, 201),
  )
  @ddt.unpack
  def test_relationship_post(self, obj_type, readonly, rel_obj_type, swap,
                             expected_code):
    """Test PUT relationship {0}.readonly={1}, related object type {2}"""

    factory = factories.get_model_factory(obj_type)
    rel_factory = factories.get_model_factory(rel_obj_type)
    with factories.single_commit():
      obj = factory(title='a', readonly=readonly)
      rel_obj = rel_factory()

    if swap:
      source, destination = rel_obj, obj
    else:
      source, destination = obj, rel_obj

    resp, _ = self.object_generator.generate_relationship(
        source=source, destination=destination
    )

    self.assertStatus(resp, expected_code)

  @ddt.data(
      ('System', False, 'Document', True, 200),
      ('System', False, 'Document', False, 200),
      ('System', True, 'Document', True, 405),
      ('System', True, 'Document', False, 405),
      ('System', False, 'Comment', True, 200),
      ('System', False, 'Comment', False, 200),
      ('System', True, 'Comment', True, 200),
      ('System', True, 'Comment', False, 200),
  )
  @ddt.unpack
  def test_relationship_delete(self, obj_type, readonly, rel_obj_type, swap,
                               expected_code):
    """Test DELETE relationship {0}.readonly={1}, related object type {2}"""

    factory = factories.get_model_factory(obj_type)
    rel_factory = factories.get_model_factory(rel_obj_type)
    with factories.single_commit():
      obj = factory(title='a', readonly=readonly)
      rel_obj = rel_factory()

      if swap:
        source, destination = rel_obj, obj
      else:
        source, destination = obj, rel_obj

      robj = factories.RelationshipFactory(source=source,
                                           destination=destination)

    resp = self.object_generator.api.delete(robj)

    self.assertStatus(resp, expected_code)
Beispiel #17
0
class TestWithReadOnlyAccessAPI(TestCase, query_helper.WithQueryApi):
    """Test WithReadOnlyAccess mixin"""
    def setUp(self):
        super(TestWithReadOnlyAccessAPI, self).setUp()
        self.object_generator = ObjectGenerator()
        self.object_generator.api.login_as_normal()

    @ddt.data(
        ('System', True),
        ('System', False),
        ('System', None),
        ('System', _NOT_SPECIFIED),
        ('System', "qwert"),
    )
    @ddt.unpack
    def test_readonly_ignored_on_post(self, obj_type, readonly):
        """Test flag readonly ignored on object {0} POST for body readonly={1}"""

        dct = dict()
        if readonly is not _NOT_SPECIFIED:
            dct['readonly'] = readonly
        resp, obj = self.object_generator.generate_object(
            get_model(obj_type),
            dct,
        )

        self.assertStatus(resp, 201)
        self.assertFalse(obj.readonly)

    @ddt.data(
        ('System', True, True),
        ('System', False, False),
        ('System', None, False),
        ('System', _NOT_SPECIFIED, False),
    )
    @ddt.unpack
    def test_readonly_set_on_post_as_external(self, obj_type, readonly,
                                              result):
        """Test flag readonly on {0} POST for body readonly={1} as external user"""

        dct = dict()
        if readonly is not _NOT_SPECIFIED:
            dct['readonly'] = readonly

        with self.object_generator.api.as_external():
            resp, obj = self.object_generator.generate_object(
                get_model(obj_type),
                dct,
            )
            obj_id = obj.id

        self.assertStatus(resp, 201)
        obj = get_model(obj_type).query.get(obj_id)
        self.assertEqual(obj.readonly, result)

    @ddt.data(
        ('System', False, False, 200),
        ('System', False, True, 200),
        ('System', False, None, 200),
        ('System', False, _NOT_SPECIFIED, 200),
        ('System', False, "qwerty", 200),
        ('System', True, False, 405),
        ('System', True, True, 405),
        ('System', True, None, 405),
        ('System', True, _NOT_SPECIFIED, 405),
        ('System', True, "qwerty", 405),
    )
    @ddt.unpack
    def test_put(self, obj_type, current, new, exp_code):
        """Test {0} PUT readonly={2} for current readonly={1}"""

        factory = factories.get_model_factory(obj_type)
        with factories.single_commit():
            obj = factory(title='a', readonly=current)
            obj_id = obj.id

        data = {'title': 'b'}
        if new is not _NOT_SPECIFIED:
            data['readonly'] = new

        resp = self.object_generator.api.put(obj, data)

        self.assertStatus(resp, exp_code)
        obj = get_model(obj_type).query.get(obj_id)
        self.assertEqual(obj.readonly, current)

    @ddt.data(
        ('System', False, False, 200, False),
        ('System', False, True, 200, True),
        ('System', False, None, 200, False),
        ('System', False, _NOT_SPECIFIED, 200, False),
        ('System', True, False, 200, False),
        ('System', True, True, 200, True),
        ('System', True, None, 200, True),
        ('System', True, _NOT_SPECIFIED, 200, True),
    )
    @ddt.unpack
    def test_put_as_external(self, obj_type, current, new, exp_code,
                             exp_readonly):
        """Test {0} PUT readonly={2} for current readonly={1} for external user"""

        factory = factories.get_model_factory(obj_type)
        with factories.single_commit():
            obj = factory(title='a', readonly=current)
            obj_id = obj.id

        data = {'title': 'b'}
        if new is not _NOT_SPECIFIED:
            data['readonly'] = new

        with self.object_generator.api.as_external():
            obj = get_model(obj_type).query.get(obj_id)
            resp = self.object_generator.api.put(obj, data)

        self.assertStatus(resp, exp_code)
        obj = get_model(obj_type).query.get(obj_id)
        self.assertEqual(obj.readonly, exp_readonly)

    @ddt.data('System')
    def test_403_if_put_readonly_without_perms(self, obj_type):
        """Test {0} with readonly=True PUT returns 401 instead of 405

    This test ensures that user without permission for the object
    cannot obtain value for flag readonly
    """
        role_obj = all_models.Role.query.filter(
            all_models.Role.name == "Creator").one()

        factory = factories.get_model_factory(obj_type)

        with factories.single_commit():
            # create Global Creator
            person = factories.PersonFactory()
            person_id = person.id
            rbac_factories.UserRoleFactory(role=role_obj, person=person)

            # Create object
            obj = factory(title='a', readonly=True)
            obj_id = obj.id

        self.object_generator.api.set_user(
            all_models.Person.query.get(person_id))
        obj = get_model(obj_type).query.get(obj_id)
        resp = self.object_generator.api.put(obj, {'title': 'b'})

        self.assert403(resp)

    @ddt.data(
        ('System', True, False, 200, True),
        ('System', True, True, 405, False),
        ('System', False, False, 200, True),
        ('System', False, True, 405, False),
    )
    @ddt.unpack
    def test_delete(self, obj_type, is_external, readonly, exp_code,
                    exp_deleted):
        """Test {0} DELETE if readonly={1}"""

        factory = factories.get_model_factory(obj_type)
        with factories.single_commit():
            obj = factory(title='a', readonly=readonly)
            obj_id = obj.id

        if is_external:
            self.object_generator.api.login_as_external()
        else:
            self.object_generator.api.login_as_normal()

        obj = get_model(obj_type).query.get(obj_id)
        resp = self.object_generator.api.delete(obj)

        self.assertStatus(resp, exp_code)
        obj = get_model(obj_type).query.get(obj_id)
        if exp_deleted:
            self.assertIsNone(obj)
        else:
            self.assertIsNotNone(obj)

    @ddt.data('System')
    def test_403_if_delete_readonly_without_perms(self, obj_type):
        """Test {0} with readonly=True DELETE returns 401

    This test ensures that user without permission for the object
    cannot obtain value for flag readonly
    """

        role_obj = all_models.Role.query.filter(
            all_models.Role.name == "Creator").one()

        factory = factories.get_model_factory(obj_type)

        with factories.single_commit():
            # create Global Creator
            person = factories.PersonFactory()
            person_id = person.id
            rbac_factories.UserRoleFactory(role=role_obj, person=person)

            # Create object
            obj = factory(title='a', readonly=True)
            obj_id = obj.id

        self.object_generator.api.set_user(
            all_models.Person.query.get(person_id))
        obj = get_model(obj_type).query.get(obj_id)
        resp = self.object_generator.api.delete(obj)

        self.assert403(resp)
        obj = get_model(obj_type).query.get(obj_id)
        self.assertIsNotNone(obj)

    @ddt.data(
        ('System', False, 'Document', True, 201),
        ('System', False, 'Document', False, 201),
        ('System', True, 'Document', True, 405),
        ('System', True, 'Document', False, 405),
        ('System', False, 'Comment', True, 201),
        ('System', False, 'Comment', False, 201),
        ('System', True, 'Comment', True, 201),
        ('System', True, 'Comment', False, 201),
    )
    @ddt.unpack
    def test_relationship_post(self, obj_type, readonly, rel_obj_type, swap,
                               expected_code):
        """Test PUT relationship {0}.readonly={1}, related object type {2}"""

        factory = factories.get_model_factory(obj_type)
        rel_factory = factories.get_model_factory(rel_obj_type)
        with factories.single_commit():
            obj = factory(title='a', readonly=readonly)
            rel_obj = rel_factory()

        if swap:
            source, destination = rel_obj, obj
        else:
            source, destination = obj, rel_obj

        resp, _ = self.object_generator.generate_relationship(
            source=source, destination=destination)

        self.assertStatus(resp, expected_code)

    @ddt.data(
        ('System', False, 'Document', True, 200),
        ('System', False, 'Document', False, 200),
        ('System', True, 'Document', True, 405),
        ('System', True, 'Document', False, 405),
        ('System', False, 'Comment', True, 200),
        ('System', False, 'Comment', False, 200),
        ('System', True, 'Comment', True, 200),
        ('System', True, 'Comment', False, 200),
    )
    @ddt.unpack
    def test_relationship_delete(self, obj_type, readonly, rel_obj_type, swap,
                                 expected_code):
        """Test DELETE relationship {0}.readonly={1}, related object type {2}"""

        factory = factories.get_model_factory(obj_type)
        rel_factory = factories.get_model_factory(rel_obj_type)
        with factories.single_commit():
            obj = factory(title='a', readonly=readonly)
            rel_obj = rel_factory()

            if swap:
                source, destination = rel_obj, obj
            else:
                source, destination = obj, rel_obj

            robj = factories.RelationshipFactory(source=source,
                                                 destination=destination)

        resp = self.object_generator.api.delete(robj)

        self.assertStatus(resp, expected_code)

    @ddt.data(
        ("yes", "readonly system"),
        ("no", "non readonly system"),
    )
    @ddt.unpack
    def test_readonly_searchable(self, test_value, expected_title):
        """Test filtration by readonly attribute"""
        with factories.single_commit():
            factories.SystemFactory(title="readonly system", readonly=True)
            factories.SystemFactory(title="non readonly system")

        self.client.get("/login")
        actual_systems = self.simple_query(
            "System", expression=["readonly", "=", test_value])
        self.assertEqual([s.get("title") for s in actual_systems],
                         [expected_title])
Beispiel #18
0
class TestCreator(TestCase):
  """ TestCreator """

  def setUp(self):
    super(TestCreator, self).setUp()
    self.api = Api()
    self.object_generator = ObjectGenerator()
    self.init_users()

  def init_users(self):
    """ Init users needed by the test cases """

    users = [("creator", "Creator"), ("admin", "Administrator")]
    self.users = {}
    for (name, role) in users:
      _, user = self.object_generator.generate_person(
          data={"name": name}, user_role=role)
      self.users[name] = user

  def test_admin_page_access(self):
    """Permissions to admin page."""
    for role, code in (("creator", 403), ("admin", 200)):
      self.api.set_user(self.users[role])
      self.assertEqual(self.api.client.get("/admin").status_code, code)

  def test_creator_can_crud(self):
    """ Test Basic create/read,update/delete operations """
    self.api.set_user(self.users["creator"])
    creator_id = self.users["creator"].id
    audit_id = factories.AuditFactory().id
    all_errors = []
    base_models = {
        "DataAsset", "Contract", "Requirement",
        "Policy", "Regulation", "Standard", "Document", "Facility",
        "Market", "Objective", "OrgGroup", "Vendor", "Product",
        "System", "Process", "Project", "AccessGroup",
        "Metric", "ProductGroup", "TechnologyEnvironment",
    }
    for model_singular in base_models:
      try:
        model = get_model(model_singular)
        table_singular = model._inflector.table_singular
        table_plural = model._inflector.table_plural
        # Test POST creation
        response, _ = self.object_generator.generate_object(
            model,
            data={
                table_singular: {
                    "title": model_singular,
                    "context": None,
                    "documents_reference_url": "ref",
                    # ignored except for Document
                    "link": "https://example.com",
                    "contact": {
                        "type": "Person",
                        "id": creator_id
                    },
                    # this is ignored on everything but Issues
                    "audit": {
                        "id": audit_id,
                        "type": "Audit",
                    }
                },
            }
        )

        if response.status_code != 201:
          all_errors.append("{} post creation failed {} {}".format(
              model_singular, response.status, response.data))
          continue

        # Test GET when not owner
        obj_id = response.json.get(table_singular).get("id")
        response = self.api.get(model, obj_id)
        if response.status_code != 403:  # we are not onwers yet
          all_errors.append(
              "{} can retrieve object if not owner".format(model_singular))
          continue
        response = self.api.get_collection(model, obj_id)
        collection = response.json.get(
            "{}_collection".format(table_plural)).get(table_plural)
        if collection:
          all_errors.append(
              "{} can retrieve object if not owner (collection)"
              .format(model_singular))
          continue

        # Test GET when owner
        acr = all_models.AccessControlRole.query.filter_by(
            object_type=model_singular,
            name="Admin"
        ).one()
        acl = all_models.AccessControlList.query.filter_by(
            object_id=obj_id,
            object_type=model_singular,
            ac_role=acr,
        ).one()
        factories.AccessControlPersonFactory(
            ac_list=acl,
            person_id=creator_id,
        )

        response = self.api.get(model, obj_id)
        if response.status_code != 200:
          all_errors.append("{} can't GET object {}".format(
              model_singular, response.status))
          continue

        # Test GET collection when owner
        response = self.api.get_collection(model, obj_id)
        collection = response.json.get(
            "{}_collection".format(table_plural)).get(table_plural)
        if not collection:
          all_errors.append(
              "{} cannot retrieve object even if owner (collection)"
              .format(model_singular))
          continue
      except:
        all_errors.append("{} exception thrown".format(model_singular))
        raise
    self.assertEqual(all_errors, [])

  def test_creator_search(self):
    """Test if creator can see the correct object while using the search api"""
    self.api.set_user(self.users['admin'])
    self.api.post(all_models.Regulation, {
        "regulation": {"title": "Admin regulation", "context": None},
    })
    self.api.set_user(self.users['creator'])
    acr_id = all_models.AccessControlRole.query.filter_by(
        object_type="Policy",
        name="Admin"
    ).first().id
    response = self.api.post(all_models.Policy, {
        "policy": {
            "title": "Creator Policy",
            "context": None,
            "access_control_list": [
                acl_helper.get_acl_json(acr_id, self.users["creator"].id)],
        },
    })
    response.json.get("policy").get("id")
    response, _ = self.api.search("Regulation,Policy")
    entries = response.json["results"]["entries"]
    self.assertEqual(len(entries), 1)
    self.assertEqual(entries[0]["type"], "Policy")
    response, _ = self.api.search("Regulation,Policy", counts=True)
    self.assertEqual(response.json["results"]["counts"]["Policy"], 1)
    self.assertEqual(
        response.json["results"]["counts"].get("Regulation"), None)

  def _get_count(self, obj):
    """ Return the number of counts for the given object from search """
    response, _ = self.api.search(obj, counts=True)
    return response.json["results"]["counts"].get(obj)

  def test_creator_should_see_users(self):
    """ Test if creator can see all the users in the system """
    self.api.set_user(self.users['admin'])
    admin_count = self._get_count("Person")
    self.api.set_user(self.users['creator'])
    creator_count = self._get_count("Person")
    self.assertEqual(admin_count, creator_count)

  def test_relationships_access(self):
    """Check if creator cannot access relationship objects"""
    self.api.set_user(self.users['admin'])
    _, first_regulation = self.object_generator.generate_object(
        all_models.Regulation,
        data={"regulation": {"title": "Test regulation", "context": None}}
    )
    _, second_regulation = self.object_generator.generate_object(
        all_models.Regulation,
        data={"regulation": {"title": "Test regulation 2", "context": None}}
    )
    response, rel = self.object_generator.generate_relationship(
        first_regulation, second_regulation
    )
    relationship_id = rel.id
    self.assertEqual(response.status_code, 201)
    self.api.set_user(self.users['creator'])
    response = self.api.get_collection(all_models.Relationship,
                                       relationship_id)
    self.assertEqual(response.status_code, 200)
    num = len(response.json["relationships_collection"]["relationships"])
    self.assertEqual(num, 0)

  def test_revision_access(self):
    """Check if creator can access the right revision objects."""

    def gen(title, extra_data=None):
      """Generates requirement."""
      requirement_content = {"title": title, "context": None}
      if extra_data:
        requirement_content.update(**extra_data)
      return self.object_generator.generate_object(
          all_models.Requirement,
          data={"requirement": requirement_content}
      )[1]

    def check(obj, expected):
      """Check that how many revisions of an object current user can see."""
      response = self.api.get_query(
          all_models.Revision,
          "resource_type={}&resource_id={}".format(obj.type, obj.id)
      )
      self.assertEqual(response.status_code, 200)
      self.assertEqual(
          len(response.json['revisions_collection']['revisions']),
          expected
      )

    self.api.set_user(self.users["admin"])
    obj_1 = gen("Test Requirement 1")

    self.api.set_user(self.users["creator"])
    acr_id = all_models.AccessControlRole.query.filter_by(
        object_type="Requirement",
        name="Admin"
    ).first().id
    linked_acl = {
        "access_control_list": [
            acl_helper.get_acl_json(acr_id, self.users["creator"].id)],
    }
    check(obj_1, 0)
    obj_2 = gen("Test Requirement 2", linked_acl)
    obj2_acl = obj_2.access_control_list[0][1]
    check(obj_2, 1)
    check(obj2_acl, 1)

  @ddt.data("creator", "admin")
  def test_count_type_in_accordion(self, glob_role):
    """Return count of Persons in DB for side accordion."""
    self.api.set_user(self.users[glob_role])
    ocordion_api_person_count_link = (
        "/search?"
        "q=&types=Program%2CWorkflow_All%2C"
        "Audit%2CAssessment%2CIssue%2CRegulation%2C"
        "Policy%2CStandard%2CContract%2CRequirement%2CControl%2C"
        "Objective%2CPerson%2COrgGroup%2CVendor%2CAccessGroup%2CSystem%2C"
        "Process%2CDataAsset%2CProduct%2CProject%2CFacility%2C"
        "Market%2CRisk%2CThreat&counts_only=true&"
        "extra_columns=Workflow_All%3DWorkflow%2C"
        "Workflow_Active%3DWorkflow%2CWorkflow_Draft%3D"
        "Workflow%2CWorkflow_Inactive%3DWorkflow&contact_id=1&"
        "extra_params=Workflow%3Astatus%3DActive%3BWorkflow_Active"
        "%3Astatus%3DActive%3BWorkflow_Inactive%3Astatus%3D"
        "Inactive%3BWorkflow_Draft%3Astatus%3DDraft"
    )
    resp = self.api.client.get(ocordion_api_person_count_link)
    self.assertIn("Person", resp.json["results"]["counts"])
    self.assertEqual(all_models.Person.query.count(),
                     resp.json["results"]["counts"]["Person"])

  @ddt.data(
      ("/api/revisions?resource_type={}&resource_id={}", 1),
      ("/api/revisions?source_type={}&source_id={}", 0),
      ("/api/revisions?destination_type={}&destination_id={}", 1),
  )
  @ddt.unpack
  def test_changelog_access(self, link, revision_count):
    """Test accessing changelog under GC user who is assigned to object"""
    with factories.single_commit():
      audit = factories.AuditFactory()
      asmnt = factories.AssessmentFactory(audit=audit)
      asmnt_id = asmnt.id
      factories.RelationshipFactory(source=audit, destination=asmnt)
      factories.AccessControlPersonFactory(
          ac_list=asmnt.acr_name_acl_map["Verifiers"],
          person=self.users["creator"],
      )

    self.api.set_user(self.users["creator"])
    response = self.api.client.get(link.format("Assessment", asmnt_id))
    self.assert200(response)
    self.assertEqual(
        len(response.json.get("revisions_collection", {}).get("revisions")),
        revision_count
    )

  @staticmethod
  def _query_revisions(api, resource_type, resource_id):
    """Helper function querying revisions related to particular object."""
    return api.send_request(
        api.client.post,
        api_link="/query",
        data=[{
            "object_name": "Revision",
            "type": "ids",
            "filters": {
                "expression": {
                    "left": {
                        "left": {
                            "left": "resource_type",
                            "op": {"name": "="},
                            "right": resource_type,
                        },
                        "op": {"name": "AND"},
                        "right": {
                            "left": "resource_id",
                            "op": {"name": "="},
                            "right": resource_id,
                        },
                    },
                    "op": {"name": "OR"},
                    "right": {
                        "left": {
                            "left": {
                                "left": "source_type",
                                "op": {"name": "="},
                                "right": resource_type,
                            },
                            "op": {"name": "AND"},
                            "right": {
                                "left": "source_id",
                                "op": {"name": "="},
                                "right": resource_id,
                            }
                        },
                        "op": {"name": "OR"},
                        "right": {
                            "left": {
                                "left": "destination_type",
                                "op": {"name": "="},
                                "right": resource_type,
                            },
                            "op": {"name": "AND"},
                            "right": {
                                "left": "destination_id",
                                "op": {"name": "="},
                                "right": resource_id,
                            }
                        }
                    }
                },
            },
        }],
    )

  def test_revision_access_query(self):
    """Test GC assigned to obj can access revisions through query API."""
    with factories.single_commit():
      program = factories.ProgramFactory()
      audit = factories.AuditFactory()
      factories.RelationshipFactory(
          source=audit,
          destination=program,
      )
      factories.AccessControlPersonFactory(
          ac_list=audit.acr_name_acl_map["Auditors"],
          person=self.users["creator"],
      )

    audit_id = audit.id
    self.api.set_user(self.users["creator"])
    response = self._query_revisions(self.api, audit.type, audit_id)

    self.assert200(response)
    self.assertEqual(response.json[0]["Revision"]["count"], 2)

  def test_rev_access_query_no_right(self):
    """Test GC has no access to revisions of objects it has no right on."""
    with factories.single_commit():
      program = factories.ProgramFactory()
      audit = factories.AuditFactory()
      factories.RelationshipFactory(
          source=audit,
          destination=program,
      )

    audit_id = audit.id
    self.api.set_user(self.users["creator"])
    response = self._query_revisions(self.api, audit.type, audit_id)

    self.assert200(response)
    self.assertEqual(response.json[0]["Revision"]["count"], 0)
Beispiel #19
0
class TestExternalRelationship(TestCase):
    """Integration test suite for External Relationship."""

    # pylint: disable=invalid-name

    def setUp(self):
        """Init API helper"""
        super(TestExternalRelationship, self).setUp()
        self.object_generator = ObjectGenerator()
        self.api = api_helper.Api()
        with factories.single_commit():
            editor_role = all_models.Role.query.filter(
                all_models.Role.name == "Editor").first()
            self.person_ext = factories.PersonFactory(
                email="*****@*****.**")
            self.person_ext_id = self.person_ext.id
            self.person = factories.PersonFactory(
                email="*****@*****.**")
            self.person_id = self.person.id
            rbac_factories.UserRoleFactory(role=editor_role,
                                           person=self.person)

    HEADERS = {
        "Content-Type": "application/json",
        "X-requested-by": "External App",
        "X-ggrc-user": "******"email\": \"[email protected]\"}",
        "X-appengine-inbound-appid": "test_external_app",
    }
    REL_URL = "/api/relationships"

    @staticmethod
    def build_relationship_json(source, destination, is_external=True):
        """Builds relationship create request json."""
        return json.dumps([{
            "relationship": {
                "source": {
                    "id": source.id,
                    "type": source.type
                },
                "destination": {
                    "id": destination.id,
                    "type": destination.type
                },
                "context": {
                    "id": None
                },
                "is_external": is_external
            }
        }])

    @staticmethod
    def create_relationship(source, destination, is_external, user):
        """Creates relationship in database with given params."""
        return factories.RelationshipFactory(
            source=source,
            destination=destination,
            is_external=is_external,
            modified_by_id=user.id,
        )

    def test_create_ext_user_ext_relationship(self):
        """Validation external app user creates external relationship."""
        self.api.set_user(self.person_ext)
        with factories.single_commit():
            product = factories.ProductFactory()
            system = factories.SystemFactory()
        response = self.api.client.post(self.REL_URL,
                                        data=self.build_relationship_json(
                                            product, system, True),
                                        headers=self.HEADERS)
        self.assert200(response)

        relationship = all_models.Relationship.query.get(
            response.json[0][-1]["relationship"]["id"])
        self.assertEqual(relationship.source_type, "Product")
        self.assertEqual(relationship.source_id, product.id)
        self.assertEqual(relationship.destination_type, "System")
        self.assertEqual(relationship.destination_id, system.id)
        self.assertTrue(relationship.is_external)
        self.assertEqual(relationship.modified_by_id, self.person_ext.id)
        self.assertIsNone(relationship.parent_id)
        self.assertIsNone(relationship.automapping_id)
        self.assertIsNone(relationship.context_id)

    def test_create_ext_user_reg_relationship(self):
        """Validation external app user creates regular relationship."""
        self.api.set_user(self.person_ext)
        with factories.single_commit():
            product = factories.ProductFactory()
            system = factories.SystemFactory()
        response = self.api.client.post(self.REL_URL,
                                        data=self.build_relationship_json(
                                            product, system, False),
                                        headers=self.HEADERS)
        self.assert400(response)
        self.assertEqual(response.json[0], [
            400,
            "You do not have the necessary permissions to "
            "create regular relationships.",
        ])

    def test_update_ext_user_ext_relationship(self):
        """Validation external app user updates external relationship."""
        self.api.set_user(self.person_ext)
        with factories.single_commit():
            product = factories.ProductFactory()
            system = factories.SystemFactory()

        self.create_relationship(product, system, True, self.person_ext)
        response = self.api.client.post(self.REL_URL,
                                        data=self.build_relationship_json(
                                            product, system, True),
                                        headers=self.HEADERS)
        self.assert200(response)

        relationship = all_models.Relationship.query.get(
            response.json[0][-1]["relationship"]["id"])
        self.assertEqual(relationship.source_type, "Product")
        self.assertEqual(relationship.source_id, product.id)
        self.assertEqual(relationship.destination_type, "System")
        self.assertEqual(relationship.destination_id, system.id)
        self.assertTrue(relationship.is_external)
        self.assertEqual(relationship.modified_by_id, self.person_ext.id)
        self.assertIsNone(relationship.parent_id)
        self.assertIsNone(relationship.automapping_id)
        self.assertIsNone(relationship.context_id)

    def test_update_ext_user_reg_relationship(self):
        """External app user can update regular relationship."""
        with factories.single_commit():
            product = factories.ProductFactory()
            system = factories.SystemFactory()
            self.create_relationship(product, system, False, self.person)
            product_id = product.id
            system_id = system.id

        self.api.set_user(self.person_ext)
        product = all_models.Product.query.get(product_id)
        system = all_models.System.query.get(system_id)
        response = self.api.client.post(self.REL_URL,
                                        data=self.build_relationship_json(
                                            product, system, True),
                                        headers=self.HEADERS)
        self.assert200(response)
        self.assertEqual(response.json[0][1]["relationship"]["is_external"],
                         True)

    def test_delete_ext_user_ext_relationship(self):
        """Validation external app user deletes external relationship."""
        self.api.set_user(self.person_ext)
        with factories.single_commit():
            product = factories.ProductFactory()
            system = factories.SystemFactory()
            rel = self.create_relationship(product, system, True,
                                           self.person_ext)

        response = self.api.delete(rel)
        self.assert200(response)
        relationship = all_models.Relationship.query.get(rel.id)
        self.assertIsNone(relationship)

    def test_delete_ext_user_reg_relationship(self):
        """External app user can delete regular relationship."""
        self.api.set_user(self.person_ext)
        with factories.single_commit():
            product = factories.ProductFactory()
            system = factories.SystemFactory()

        rel = self.create_relationship(product, system, False, self.person_ext)
        response = self.api.delete(rel)
        self.assert200(response)

    def test_update_reg_user_ext_relationship(self):
        """Validation regular app user updates external relationship."""
        with factories.single_commit():
            product = factories.ProductFactory()
            system = factories.SystemFactory()
            self.create_relationship(product, system, True, self.person_ext)
            product_id = product.id
            system_id = system.id

        self.api.set_user(self.person)
        product = all_models.Product.query.get(product_id)
        system = all_models.System.query.get(system_id)
        response = self.api.client.post(self.REL_URL,
                                        data=self.build_relationship_json(
                                            product, system, False),
                                        headers=self.HEADERS)
        self.assert200(response)

    def test_delete_reg_user_ext_relationship(self):
        """Validation regular user deletes external relationship."""
        with factories.single_commit():
            product = factories.ProductFactory()
            system = factories.SystemFactory()
            self.create_relationship(product, system, True, self.person_ext)

        self.api.set_user(self.person)
        rel = all_models.Relationship.query.first()
        response = self.api.delete(rel)
        self.assert200(response)
        relationship = all_models.Relationship.query.get(rel.id)
        self.assertIsNone(relationship)

    @ddt.data(*READONLY_MAPPING_PAIRS)
    @ddt.unpack
    def test_local_delete_relationship_scoping_directive(self, model1, model2):
        """Test deletion of relationship between {0.__name__} and {1.__name__}"""

        # Set up relationships
        with self.object_generator.api.as_external():
            _, obj1 = self.object_generator.generate_object(model1)
            _, obj2 = self.object_generator.generate_object(model2)

            _, rel = self.object_generator.generate_relationship(
                obj1, obj2, is_external=True)

        # check that relationship cannot be deleted by regular user
        self.api.set_user(all_models.Person.query.get(self.person_id))
        relationship = all_models.Relationship.query.get(rel.id)
        response = self.api.delete(relationship)
        self.assert400(response)

    @ddt.data(*READONLY_MAPPING_PAIRS)
    @ddt.unpack
    def test_local_create_relationship_scoping_directive(self, model1, model2):
        """Test creation of relationship between {0.__name__} and {1.__name__}"""
        # Set up relationships
        with self.object_generator.api.as_external():
            _, obj1 = self.object_generator.generate_object(model1)
            _, obj2 = self.object_generator.generate_object(model2)

        self.object_generator.api.set_user(
            all_models.Person.query.get(self.person_id))

        response, _ = self.object_generator.generate_relationship(
            obj1, obj2, is_external=True)

        self.assert400(response)

    @ddt.data(*READONLY_MAPPING_PAIRS)
    @ddt.unpack
    def test_ext_create_delete_relationship_scoping_directive(
            self, model1, model2):
        """Test ext user and relationship between {0.__name__} and {1.__name__}"""

        # Set up relationships
        with self.object_generator.api.as_external():
            _, obj1 = self.object_generator.generate_object(model1)
            _, obj2 = self.object_generator.generate_object(model2)

            _, rel = self.object_generator.generate_relationship(
                obj1, obj2, is_external=True)

            self.assertIsNotNone(rel)

        # check that external relationship can be deleted by external user
        self.api.set_user(all_models.Person.query.get(self.person_ext_id))
        relationship = all_models.Relationship.query.get(rel.id)
        response = self.api.delete(relationship)
        print response.json
        self.assert200(response)
Beispiel #20
0
class TestWithReadOnlyAccessAPI(TestCase, query_helper.WithQueryApi):
  """Test WithReadOnlyAccess mixin"""

  def setUp(self):
    super(TestWithReadOnlyAccessAPI, self).setUp()
    self.object_generator = ObjectGenerator()
    self.object_generator.api.login_as_normal()

  @ddt.data(
      ('System', True),
      ('System', False),
      ('System', None),
      ('System', _NOT_SPECIFIED),
      ('System', "qwert"),
  )
  @ddt.unpack
  def test_readonly_ignored_on_post(self, obj_type, readonly):
    """Test flag readonly ignored on object {0} POST for body readonly={1}"""

    dct = dict()
    if readonly is not _NOT_SPECIFIED:
      dct['readonly'] = readonly
    resp, obj = self.object_generator.generate_object(
        get_model(obj_type),
        dct,
    )

    self.assertStatus(resp, 201)
    self.assertFalse(obj.readonly)

  @ddt.data(
      ('System', True, True),
      ('System', False, False),
      ('System', None, False),
      ('System', _NOT_SPECIFIED, False),
  )
  @ddt.unpack
  def test_readonly_set_on_post_as_external(self, obj_type, readonly, result):
    """Test flag readonly on {0} POST for body readonly={1} as external user"""

    dct = dict()
    if readonly is not _NOT_SPECIFIED:
      dct['readonly'] = readonly

    with self.object_generator.api.as_external():
      resp, obj = self.object_generator.generate_object(
          get_model(obj_type),
          dct,
      )
      obj_id = obj.id

    self.assertStatus(resp, 201)
    obj = get_model(obj_type).query.get(obj_id)
    self.assertEqual(obj.readonly, result)

  @ddt.data(
      ('System', False, False, 200),
      ('System', False, True, 200),
      ('System', False, None, 200),
      ('System', False, _NOT_SPECIFIED, 200),
      ('System', False, "qwerty", 200),
      ('System', True, False, 405),
      ('System', True, True, 405),
      ('System', True, None, 405),
      ('System', True, _NOT_SPECIFIED, 405),
      ('System', True, "qwerty", 405),
  )
  @ddt.unpack
  def test_put(self, obj_type, current, new, exp_code):
    """Test {0} PUT readonly={2} for current readonly={1}"""

    factory = factories.get_model_factory(obj_type)
    with factories.single_commit():
      obj = factory(title='a', readonly=current)
      obj_id = obj.id

    data = {'title': 'b'}
    if new is not _NOT_SPECIFIED:
      data['readonly'] = new

    resp = self.object_generator.api.put(obj, data)

    self.assertStatus(resp, exp_code)
    obj = get_model(obj_type).query.get(obj_id)
    self.assertEqual(obj.readonly, current)

  @ddt.data(
      ('System', False, False, 200, False),
      ('System', False, True, 200, True),
      ('System', False, None, 200, False),
      ('System', False, _NOT_SPECIFIED, 200, False),
      ('System', True, False, 200, False),
      ('System', True, True, 200, True),
      ('System', True, None, 200, True),
      ('System', True, _NOT_SPECIFIED, 200, True),
  )
  @ddt.unpack
  def test_put_as_external(self, obj_type, current, new, exp_code,
                           exp_readonly):
    """Test {0} PUT readonly={2} for current readonly={1} for external user"""

    factory = factories.get_model_factory(obj_type)
    with factories.single_commit():
      obj = factory(title='a', readonly=current)
      obj_id = obj.id

    data = {'title': 'b'}
    if new is not _NOT_SPECIFIED:
      data['readonly'] = new

    with self.object_generator.api.as_external():
      obj = get_model(obj_type).query.get(obj_id)
      resp = self.object_generator.api.put(obj, data)

    self.assertStatus(resp, exp_code)
    obj = get_model(obj_type).query.get(obj_id)
    self.assertEqual(obj.readonly, exp_readonly)

  @ddt.data('System')
  def test_403_if_put_readonly_without_perms(self, obj_type):
    """Test {0} with readonly=True PUT returns 401 instead of 405

    This test ensures that user without permission for the object
    cannot obtain value for flag readonly
    """
    role_obj = all_models.Role.query.filter(
        all_models.Role.name == "Creator").one()

    factory = factories.get_model_factory(obj_type)

    with factories.single_commit():
      # create Global Creator
      person = factories.PersonFactory()
      person_id = person.id
      rbac_factories.UserRoleFactory(role=role_obj, person=person)

      # Create object
      obj = factory(title='a', readonly=True)
      obj_id = obj.id

    self.object_generator.api.set_user(all_models.Person.query.get(person_id))
    obj = get_model(obj_type).query.get(obj_id)
    resp = self.object_generator.api.put(obj, {'title': 'b'})

    self.assert403(resp)

  @ddt.data(
      ('System', True, False, 200, True),
      ('System', True, True, 405, False),
      ('System', False, False, 200, True),
      ('System', False, True, 405, False),
  )
  @ddt.unpack
  def test_delete(self, obj_type, is_external, readonly, exp_code,
                  exp_deleted):
    """Test {0} DELETE if readonly={1}"""

    factory = factories.get_model_factory(obj_type)
    with factories.single_commit():
      obj = factory(title='a', readonly=readonly)
      obj_id = obj.id

    if is_external:
      self.object_generator.api.login_as_external()
    else:
      self.object_generator.api.login_as_normal()

    obj = get_model(obj_type).query.get(obj_id)
    resp = self.object_generator.api.delete(obj)

    self.assertStatus(resp, exp_code)
    obj = get_model(obj_type).query.get(obj_id)
    if exp_deleted:
      self.assertIsNone(obj)
    else:
      self.assertIsNotNone(obj)

  @ddt.data('System')
  def test_403_if_delete_readonly_without_perms(self, obj_type):
    """Test {0} with readonly=True DELETE returns 401

    This test ensures that user without permission for the object
    cannot obtain value for flag readonly
    """

    role_obj = all_models.Role.query.filter(
        all_models.Role.name == "Creator").one()

    factory = factories.get_model_factory(obj_type)

    with factories.single_commit():
      # create Global Creator
      person = factories.PersonFactory()
      person_id = person.id
      rbac_factories.UserRoleFactory(role=role_obj, person=person)

      # Create object
      obj = factory(title='a', readonly=True)
      obj_id = obj.id

    self.object_generator.api.set_user(all_models.Person.query.get(person_id))
    obj = get_model(obj_type).query.get(obj_id)
    resp = self.object_generator.api.delete(obj)

    self.assert403(resp)
    obj = get_model(obj_type).query.get(obj_id)
    self.assertIsNotNone(obj)

  @ddt.data(
      ('System', False, 'Document', True, 201),
      ('System', False, 'Document', False, 201),
      ('System', True, 'Document', True, 405),
      ('System', True, 'Document', False, 405),
      ('System', False, 'Comment', True, 201),
      ('System', False, 'Comment', False, 201),
      ('System', True, 'Comment', True, 201),
      ('System', True, 'Comment', False, 201),
  )
  @ddt.unpack
  def test_relationship_post(self, obj_type, readonly, rel_obj_type, swap,
                             expected_code):
    """Test PUT relationship {0}.readonly={1}, related object type {2}"""

    factory = factories.get_model_factory(obj_type)
    rel_factory = factories.get_model_factory(rel_obj_type)
    with factories.single_commit():
      obj = factory(title='a', readonly=readonly)
      rel_obj = rel_factory()

    if swap:
      source, destination = rel_obj, obj
    else:
      source, destination = obj, rel_obj

    resp, _ = self.object_generator.generate_relationship(
        source=source, destination=destination
    )

    self.assertStatus(resp, expected_code)

  @ddt.data(
      ('System', False, 'Document', True, 200),
      ('System', False, 'Document', False, 200),
      ('System', True, 'Document', True, 405),
      ('System', True, 'Document', False, 405),
      ('System', False, 'Comment', True, 200),
      ('System', False, 'Comment', False, 200),
      ('System', True, 'Comment', True, 200),
      ('System', True, 'Comment', False, 200),
  )
  @ddt.unpack
  def test_relationship_delete(self, obj_type, readonly, rel_obj_type, swap,
                               expected_code):
    """Test DELETE relationship {0}.readonly={1}, related object type {2}"""

    factory = factories.get_model_factory(obj_type)
    rel_factory = factories.get_model_factory(rel_obj_type)
    with factories.single_commit():
      obj = factory(title='a', readonly=readonly)
      rel_obj = rel_factory()

      if swap:
        source, destination = rel_obj, obj
      else:
        source, destination = obj, rel_obj

      robj = factories.RelationshipFactory(source=source,
                                           destination=destination)

    resp = self.object_generator.api.delete(robj)

    self.assertStatus(resp, expected_code)

  @ddt.data(
      ("yes", "readonly system"),
      ("no", "non readonly system"),
  )
  @ddt.unpack
  def test_readonly_searchable(self, test_value, expected_title):
    """Test filtration by readonly attribute"""
    with factories.single_commit():
      factories.SystemFactory(title="readonly system", readonly=True)
      factories.SystemFactory(title="non readonly system")

    self.client.get("/login")
    actual_systems = self.simple_query(
        "System",
        expression=["readonly", "=", test_value]
    )
    self.assertEqual(
        [s.get("title") for s in actual_systems],
        [expected_title]
    )