示例#1
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})
示例#2
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})
示例#3
0
class TestWorkflowTypesBase(TestCase):
  """
  Base class for /search REST API test
  """

  def setUp(self):
    """Create API instance
    """

    super(TestWorkflowTypesBase, self).setUp()

    self.api = Api()

  def _get_search_ids(self, types, query):
    """Make request and return entries in format dict(type->list_of_ids)"""
    response, _ = self.api.search(types=types, query=query, counts=False)

    entries = response.json['results']['entries']

    ret = defaultdict(set)
    for entry in entries:
      ret[entry['type']].add(entry['id'])

    return dict(ret)

  def _get_count_ids(self, types, query):
    """Make request and return entries in format dict(type->number_of_ids)"""
    response, _ = self.api.search(types=types, query=query, counts=True)

    return response.json['results']['counts']

  def _convert_expected_to_dict(self, type_, expected):
    """Convert list of (type, title) to dict (type -> list_of_ids)"""

    ret = defaultdict(set)
    for _, key in expected:
      ret[type_].add(self.objects[key])

    return dict(ret)

  @staticmethod
  # pylint: disable=invalid-name
  def _convert_expected_dict_to_counts(expected):
    """Convert dict(type->list_of_ids) to dict(type->count_of_ids)"""

    return dict((k, len(v)) for k, v in expected.iteritems())
示例#4
0
class TestWorkflowTypesBase(TestCase):
    """
  Base class for /search REST API test
  """
    def setUp(self):
        """Create API instance
    """

        super(TestWorkflowTypesBase, self).setUp()

        self.api = Api()

    def _get_search_ids(self, types, query):
        """Make request and return entries in format dict(type->list_of_ids)"""
        response, _ = self.api.search(types=types, query=query, counts=False)

        entries = response.json['results']['entries']

        ret = defaultdict(set)
        for entry in entries:
            ret[entry['type']].add(entry['id'])

        return dict(ret)

    def _get_count_ids(self, types, query):
        """Make request and return entries in format dict(type->number_of_ids)"""
        response, _ = self.api.search(types=types, query=query, counts=True)

        return response.json['results']['counts']

    def _convert_expected_to_dict(self, type_, expected):
        """Convert list of (type, title) to dict (type -> list_of_ids)"""

        ret = defaultdict(set)
        for _, key in expected:
            ret[type_].add(self.objects[key])

        return dict(ret)

    @staticmethod
    # pylint: disable=invalid-name
    def _convert_expected_dict_to_counts(expected):
        """Convert dict(type->list_of_ids) to dict(type->count_of_ids)"""

        return dict((k, len(v)) for k, v in expected.iteritems())
示例#5
0
class TestStatus(TestCase):
  """
  Test /search REST API status code
  """

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

  def test_search_existing_type(self):
    """Test search for existing type"""
    res, _ = self.api.search(types="Requirement")
    self.assert200(res)

  def test_search_non_existing_type(self):
    """Test search for non existing type"""
    res, _ = self.api.search(types="Requirementsss")
    self.assert200(res)

  def test_search_multiple_types(self):
    """Test search for multiple types"""
    res, _ = self.api.search(types="Requirement,Requirement")
    self.assert200(res)

  def test_counts_existing_type(self):
    """Test counts for existing type"""
    res, _ = self.api.search(types="Requirement", counts=True)
    self.assert200(res)

  def test_counts_non_existing_type(self):
    """Test counts for non existing type"""
    res, _ = self.api.search(types="Requirementsss", counts=True)
    self.assert200(res)

  def test_counts_multiple_types(self):
    """Test counts for multiple types"""
    res, _ = self.api.search(types="Requirement,Requirement", counts=True)
    self.assert200(res)

  # pylint: disable=invalid-name
  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("Requirement", False)
    response = self.api.client.get(query)
    self.assert400(response)
    self.assertEqual(response.json['message'], 'Query parameter "q" '
                     'specifying search terms must be provided.')
示例#6
0
class TestStatus(TestCase):
    """
  Test /search REST API status code
  """
    def setUp(self):
        super(TestStatus, self).setUp()
        self.api = Api()

    def test_search_existing_type(self):
        """Test search for existing type"""
        res, _ = self.api.search(types="Requirement")
        self.assert200(res)

    def test_search_non_existing_type(self):
        """Test search for non existing type"""
        res, _ = self.api.search(types="Requirementsss")
        self.assert200(res)

    def test_search_multiple_types(self):
        """Test search for multiple types"""
        res, _ = self.api.search(types="Requirement,Requirement")
        self.assert200(res)

    def test_counts_existing_type(self):
        """Test counts for existing type"""
        res, _ = self.api.search(types="Requirement", counts=True)
        self.assert200(res)

    def test_counts_non_existing_type(self):
        """Test counts for non existing type"""
        res, _ = self.api.search(types="Requirementsss", counts=True)
        self.assert200(res)

    def test_counts_multiple_types(self):
        """Test counts for multiple types"""
        res, _ = self.api.search(types="Requirement,Requirement", counts=True)
        self.assert200(res)

    # pylint: disable=invalid-name
    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("Requirement", False)
        response = self.api.client.get(query)
        self.assert400(response)
        self.assertEqual(
            response.json['message'], 'Query parameter "q" '
            'specifying search terms must be provided.')
示例#7
0
class TestCreator(TestCase):
    """ TestCreator """
    def setUp(self):
        super(TestCreator, self).setUp()
        self.generator = Generator()
        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", "Policy", "Regulation",
            "Standard", "Document", "Facility", "Market", "Objective",
            "OrgGroup", "Vendor", "Product", "Clause", "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.api.post(model, {
                    table_singular: {
                        "title": model_singular,
                        "context": None,
                        "documents_reference_url": "ref",
                        "link": "https://example.com",  # ignored except for Document
                        "contact": {
                            "type": "Person",
                            "id": creator_id,
                        },
                        "audit": {  # this is ignored on everything but Issues
                            "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").first()
                factories.AccessControlListFactory(object_id=obj_id,
                                                   object_type=model_singular,
                                                   ac_role=acr,
                                                   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'])
        _, obj_0 = self.generator.generate(all_models.Regulation, "regulation",
                                           {
                                               "regulation": {
                                                   "title": "Test regulation",
                                                   "context": None
                                               },
                                           })
        _, obj_1 = self.generator.generate(
            all_models.Regulation, "regulation", {
                "regulation": {
                    "title": "Test regulation 2",
                    "context": None
                },
            })
        response, rel = self.generator.generate(
            all_models.Relationship, "relationship", {
                "relationship": {
                    "source": {
                        "id": obj_0.id,
                        "type": "Regulation"
                    },
                    "destination": {
                        "id": obj_1.id,
                        "type": "Regulation"
                    },
                    "context": None
                },
            })
        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.generator.generate(
                all_models.Requirement, "requirement",
                {"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]
        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%2CClause%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)
            verifier_role = all_models.AccessControlRole.query.filter_by(
                object_type="Assessment",
                name="Verifiers",
            ).first()
            factories.AccessControlListFactory(
                person=self.users["creator"],
                ac_role=verifier_role,
                object=asmnt,
            )

        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")
示例#8
0
class TestCreator(TestCase):
  """ TestCreator """

  def setUp(self):
    super(TestCreator, self).setUp()
    self.generator = Generator()
    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 = set([
        "Control", "DataAsset", "Contract",
        "Policy", "Regulation", "Standard", "Document", "Facility",
        "Market", "Objective", "OrgGroup", "Vendor", "Product",
        "Clause", "System", "Process", "Project", "AccessGroup",
        "Metric"
    ])
    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.api.post(model, {
            table_singular: {
                "title": model_singular,
                "context": None,
                "documents_reference_url": "ref",
                "link": "https://example.com",  # ignored except for Document
                "contact": {
                    "type": "Person",
                    "id": creator_id,
                },
                "audit": {  # this is ignored on everything but Issues
                    "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"
        ).first()
        factories.AccessControlListFactory(
            object_id=obj_id,
            object_type=model_singular,
            ac_role=acr,
            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'])
    _, obj_0 = self.generator.generate(all_models.Regulation, "regulation", {
        "regulation": {"title": "Test regulation", "context": None},
    })
    _, obj_1 = self.generator.generate(all_models.Regulation, "regulation", {
        "regulation": {"title": "Test regulation 2", "context": None},
    })
    response, rel = self.generator.generate(
        all_models.Relationship, "relationship", {
            "relationship": {"source": {
                "id": obj_0.id,
                "type": "Regulation"
            }, "destination": {
                "id": obj_1.id,
                "type": "Regulation"
            }, "context": None},
        }
    )
    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 section."""
      section_content = {"title": title, "context": None}
      if extra_data:
        section_content.update(**extra_data)
      return self.generator.generate(all_models.Section, "section", {
          "section": section_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 Section 1")

    self.api.set_user(self.users["creator"])
    acr_id = all_models.AccessControlRole.query.filter_by(
        object_type="Section",
        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 Section 2", linked_acl)
    obj2_acl = obj_2.access_control_list[0]
    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%2CClause%2CSection%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)
      verifier_role = all_models.AccessControlRole.query.filter_by(
          object_type="Assessment",
          name="Verifiers",
      ).first()
      factories.AccessControlListFactory(
          person=self.users["creator"],
          ac_role=verifier_role,
          object=asmnt,
      )

    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")
示例#9
0
class TestReader(TestCase):
    """ Test reader role """
    def setUp(self):
        super(TestReader, self).setUp()
        self.generator = Generator()
        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 section"""
        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", "Clause", "System", "Process",
            "Project", "AccessGroup", "Metric"
        ])
        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.api.post(
                    model,
                    {
                        table_singular: {
                            "title": model_singular,
                            "context": None,
                            "documents_reference_url": "ref",
                            "link":
                            "https://example.com",  # ignored except 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'])
        _, obj_0 = self.generator.generate(all_models.Regulation, "regulation",
                                           {
                                               "regulation": {
                                                   "title": "Test regulation",
                                                   "context": None
                                               },
                                           })
        _, obj_1 = self.generator.generate(
            all_models.Regulation, "regulation", {
                "regulation": {
                    "title": "Test regulation 2",
                    "context": None
                },
            })
        response, rel = self.generator.generate(
            all_models.Relationship, "relationship", {
                "relationship": {
                    "source": {
                        "id": obj_0.id,
                        "type": "Regulation"
                    },
                    "destination": {
                        "id": obj_1.id,
                        "type": "Regulation"
                    },
                    "context": None
                },
            })
        relationship_id = rel.id
        self.assertEqual(response.status_code, 201)
        self.api.set_user(self.users['reader'])
        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, 1)

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

        response, _ = self.generator.generate(
            all_models.Relationship, "relationship", {
                "relationship": {
                    "destination": {
                        "id": program.id,
                        "type": "Program"
                    },
                    "source": {
                        "id": control.id,
                        "type": "Control"
                    },
                    "context": {
                        "id": program.context.id,
                        "type": "context"
                    }
                },
            })
        self.assertEqual(response.status_code, 403)

    @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.assertEqual(response.status_code, 403)

    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"])
示例#10
0
class TestReader(TestCase):
    """ Test reader role """
    def setUp(self):
        super(TestReader, self).setUp()
        self.generator = Generator()
        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")]
        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):
        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",
            "Clause",
            "System",
            "Process",
            "Project",
            "AccessGroup",
        ])
        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.api.post(
                    model, {
                        table_singular: {
                            "title": model_singular,
                            "context": None,
                            "reference_url": "ref",
                            "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 len(collection) == 0:
                    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'])
        _, obj_0 = self.generator.generate(all_models.Regulation, "regulation",
                                           {
                                               "regulation": {
                                                   "title": "Test regulation",
                                                   "context": None
                                               },
                                           })
        _, obj_1 = self.generator.generate(
            all_models.Regulation, "regulation", {
                "regulation": {
                    "title": "Test regulation 2",
                    "context": None
                },
            })
        response, rel = self.generator.generate(
            all_models.Relationship, "relationship", {
                "relationship": {
                    "source": {
                        "id": obj_0.id,
                        "type": "Regulation"
                    },
                    "destination": {
                        "id": obj_1.id,
                        "type": "Regulation"
                    },
                    "context": None
                },
            })
        relationship_id = rel.id
        self.assertEqual(response.status_code, 201)
        self.api.set_user(self.users['reader'])
        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, 1)

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

        response, _ = self.generator.generate(
            all_models.Relationship, "relationship", {
                "relationship": {
                    "destination": {
                        "id": program.id,
                        "type": "Program"
                    },
                    "source": {
                        "id": control.id,
                        "type": "Control"
                    },
                    "context": {
                        "id": program.context.id,
                        "type": "context"
                    }
                },
            })
        self.assertEqual(response.status_code, 403)
示例#11
0
class TestCreator(TestCase):
  """ TestCreator """

  def setUp(self):
    super(TestCreator, self).setUp()
    self.generator = Generator()
    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):
    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"])
    audit_id = factories.AuditFactory().id
    all_errors = []
    base_models = set([
        "Control", "DataAsset", "Contract",
        "Policy", "Regulation", "Standard", "Document", "Facility",
        "Market", "Objective", "OrgGroup", "Vendor", "Product",
        "Clause", "System", "Process", "Project", "AccessGroup"
    ])
    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.api.post(model, {
            table_singular: {
                "title": model_singular,
                "context": None,
                "reference_url": "ref",
                "contact": {
                    "type": "Person",
                    "id": self.users["creator"].id,
                },
                "audit": {  # this is ignored on everything but Issues
                    "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 len(collection) != 0:
          all_errors.append(
              "{} can retrieve object if not owner (collection)"
              .format(model_singular))
          continue
        # Become an owner
        response = self.api.post(all_models.ObjectOwner, {"object_owner": {
            "person": {
                "id": self.users['creator'].id,
                "type": "Person",
            }, "ownable": {
                "type": model_singular,
                "id": obj_id
            }, "context": None}})
        if response.status_code != 201:
          all_errors.append("{} can't create owner {}.".format(
              model_singular, response.status))
          continue

        # 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 len(collection) == 0:
          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'])
    response = self.api.post(all_models.Policy, {
        "policy": {"title": "Creator Policy", "context": None},
    })
    obj_id = response.json.get("policy").get("id")
    self.api.post(all_models.ObjectOwner, {"object_owner": {
        "person": {
            "id": self.users['creator'].id,
            "type": "Person",
        }, "ownable": {
            "type": "Policy",
            "id": obj_id,
        }, "context": None}})
    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_creator_cannot_be_owner(self):
    """Test if creator cannot become owner of the object he has not created"""
    self.api.set_user(self.users['admin'])
    _, obj = self.generator.generate(all_models.Regulation, "regulation", {
        "regulation": {"title": "Test regulation", "context": None},
    })
    self.api.set_user(self.users['creator'])
    response = self.api.post(all_models.ObjectOwner, {"object_owner": {
        "person": {
            "id": self.users['creator'].id,
            "type": "Person",
        }, "ownable": {
            "type": "Regulation",
            "id": obj.id,
        }, "context": None}})
    self.assertEqual(response.status_code, 403)

  def test_relationships_access(self):
    """Check if creator cannot access relationship objects"""
    self.api.set_user(self.users['admin'])
    _, obj_0 = self.generator.generate(all_models.Regulation, "regulation", {
        "regulation": {"title": "Test regulation", "context": None},
    })
    _, obj_1 = self.generator.generate(all_models.Regulation, "regulation", {
        "regulation": {"title": "Test regulation 2", "context": None},
    })
    response, rel = self.generator.generate(
        all_models.Relationship, "relationship", {
            "relationship": {"source": {
                "id": obj_0.id,
                "type": "Regulation"
            }, "destination": {
                "id": obj_1.id,
                "type": "Regulation"
            }, "context": None},
        }
    )
    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):
      return self.generator.generate(all_models.Section, "section", {
          "section": {"title": title, "context": None},
      })[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 Section 1")
    obj_2 = gen("Test Section 2")

    self.api.post(all_models.ObjectOwner, {"object_owner": {
        "person": {
            "id": self.users['creator'].id,
            "type": "Person",
        }, "ownable": {
            "type": "Section",
            "id": obj_2.id,
        }, "context": None}})

    self.api.set_user(self.users["creator"])
    check(obj_1, 0)
    check(obj_2, 2)
示例#12
0
class TestMultipleTypes(TestCase):
  """
  Test /search REST API
  """

  def setUp(self):
    """Create indexable objects which provide required set of fulltext attrs

    Fulltext attributes are: title, name, email, notes, description, slug
    """

    super(TestMultipleTypes, self).setUp()

    self.api = Api()

    self.objects = dict()

    with factories.single_commit():
      # Create Requirements
      requirements = [factories.RequirementFactory(title=title,
                                                   description=desc,
                                                   notes=notes)
                      for title, desc, notes in (('t01', 'd01', 'n01'),
                                                 ('t02', 'd02', 'n02'),
                                                 ('t11', 'd11', 'n11'),
                                                 )]
      self.objects['Requirement'] = dict((i.title, i.id) for i in requirements)

      # Create people
      people = [factories.PersonFactory(name=name, email=email)
                for name, email in (('n01', '*****@*****.**'),
                                    ('n02', '*****@*****.**'),
                                    ('n11', '*****@*****.**'),
                                    )]
      self.objects['Person'] = dict((i.name, i.id) for i in people)

      # Create regulations (regulations represented as directives)
      regulations = [factories.RegulationFactory(title=title, notes=notes,
                                                 description=desc)
                     for title, notes, desc in (('t01r', 'n01', 'd01'),
                                                ('t02r', 'n02-qq1', 'd02'),
                                                ('t11r', 'n11', 'd11'),
                                                )]
      self.objects['Regulation'] = dict((i.title, i.id) for i in regulations)

      # Create standards (standards represented as directives)
      standards = [factories.StandardFactory(title=title, notes=notes,
                                             description=desc)
                   for title, notes, desc in (('t01s', 'n01-qq1', 'd01'),
                                              ('t02s', 'n02', 'd02'),
                                              ('t11s', 'n11', 'd11'),
                                              ('t21s', 'n21', 'd11'),
                                              )]
      self.objects['Standard'] = dict((i.title, i.id) for i in standards)

  def _get_search_ids(self, types, query, extra_params):
    """Make request and return entries in format dict(type->list_of_ids)"""

    response, _ = self.api.search(types=types, query=query, counts=False,
                                  extra_params=extra_params)

    entries = response.json['results']['entries']

    ret = defaultdict(set)
    for entry in entries:
      ret[entry['type']].add(entry['id'])

    return dict(ret)

  def _get_count_ids(self, types, query, extra_params, extra_columns=None):
    """Make request and return entries in format dict(type->number_of_ids)"""
    response, _ = self.api.search(types=types, query=query, counts=True,
                                  extra_params=extra_params,
                                  extra_columns=extra_columns)

    return response.json['results']['counts']

  def _convert_expected_to_dict(self, expected):
    """Convert list of (type, title) to dict (type -> list_of_ids)"""

    ret = defaultdict(set)
    for type_, key in expected:
      ret[type_].add(self.objects[type_][key])

    return dict(ret)

  @staticmethod
  # pylint: disable=invalid-name
  def _convert_expected_dict_to_counts(expected):
    """Convert dict(type->list_of_ids) to dict(type->count_of_ids)"""

    return dict((k, len(v)) for k, v in expected.iteritems())

  @ddt.data(
      # search for Requirements by title
      ("Requirement", "t0", None, (('Requirement', 't01'),
                                   ('Requirement', 't02'),
                                   )),
      # search for Requirements by description
      ("Requirement", "d1", None, (('Requirement', 't11'),
                                   )),
      # search for Requirements by slug
      ("Requirement", "REQUIREMENT", None, (('Requirement', 't01'),
                                            ('Requirement', 't02'),
                                            ('Requirement', 't11'),
                                            )),
      # search for people by name
      ("Person", "n0", None, (('Person', 'n01'),
                              ('Person', 'n02'),
                              )),
      # search for people by email
      ("Person", "e1", None, (('Person', 'n11'),
                              )),
      # search for regulations by notes
      ("Regulation", "n0", None, (('Regulation', 't01r'),
                                  ('Regulation', 't02r'),
                                  )),
      # search for regulations by title
      ("Regulation", "t1", None, (('Regulation', 't11r'),
                                  )),
      # search for Requirements and Reguklations by title
      ("Requirement,Regulation", "t0", None, (('Requirement', 't01'),
                                              ('Requirement', 't02'),
                                              ('Regulation', 't01r'),
                                              ('Regulation', 't02r'),
                                              )),
      # search for subtypes of the same base type
      # Regulation and Standard are both represented as Directive model
      ("Regulation,Standard", "-qq1", None, (('Regulation', 't02r'),
                                             ('Standard', 't01s'),
                                             )),
      # search with empty types
      ("", "", None, ()),
      # search with non-existing type
      ("qwe", "", None, ()),
      # search for 2 types, one does not exist
      ("Requirement,qwe", "t0", None, (('Requirement', 't01'),
                                       ('Requirement', 't02'),
                                       )),
      # search for empty text
      ("Requirement", "", None, (('Requirement', 't01'),
                                 ('Requirement', 't02'),
                                 ('Requirement', 't11'),
                                 )),
      # search for added empty extra_params
      ("Requirement", "", "", (('Requirement', 't01'),
                               ('Requirement', 't02'),
                               ('Requirement', 't11'),
                               )),
      # search by title using extra_params
      ("Requirement", "", "Requirement:title=t01", (('Requirement', 't01'),
                                                    )),
      # search by title using extra_params where model name is lowercase
      ("Requirement", "", "requirement:title=t01", (('Requirement', 't01'),
                                                    )),
      # search by title using extra_params where model name is lowercase
      ("Regulation", "", "Requirement:title=t01", (('Regulation', 't01r'),
                                                   ('Regulation', 't02r'),
                                                   ('Regulation', 't11r'),
                                                   )),
      # search nonexisting type by title using extra_params
      ("Requirement", "", "qwe:title=t01", (('Requirement', 't01'),
                                            ('Requirement', 't02'),
                                            ('Requirement', 't11'),
                                            )),
      # search in multiple models, one by title using extra_params
      # filter uses AND operation to search indexed fields and extra_params
      # for single model.
      # There is no such Requirement where indexed fields contain "d0" and
      # title is "t01", so only regulations will be returned where indexed
      # fields contain "n0"
      ("Requirement,Regulation", "d0", "Requirement:title=t11",
          (('Regulation', 't01r'),
           ('Regulation', 't02r'),
           )),
      # search for subtypes of the same base type based on extra_params
      # Regulation and Standard are both represented as Directive model
      # ensure that extra_params for Regulation will not return Standard
      # with the same notes
      ("Regulation,Standard", "-qq1", "Regulation:description=d02",
          (('Regulation', 't02r'),  # contains "-qq1" and description = "d02"
           ('Standard', 't01s'),  # contains "-qq1"
           )),
  )
  @ddt.unpack
  def test_search(self, types, query, extra_params, expected):
    """Test search of objects for types={0}, q={1}, extra_params={2}"""

    exp_search = self._convert_expected_to_dict(expected)
    response_search = self._get_search_ids(types, query, extra_params)
    self.assertEqual(response_search, exp_search)

    exp_count = self._convert_expected_dict_to_counts(exp_search)
    response_count = self._get_count_ids(types, query, extra_params)
    self.assertEqual(response_count, exp_count)

  @ddt.data(
      ("Standard", "", "Standard:title=t01s;SS:description=d11",
       "SS=Standard",
       {
           "Standard": 1,
           "SS": 2
       }),
      # Add "Standard_ALL" column for which extra_params is not defined
      ("Standard", "", "SS:description=d11",
       "SS=Standard,Standard_All=Standard",
       {
           "SS": 2,
           "Standard_All": 4
       }),
      # types can contain column name from extra_columns
      # ensure that it is also handled correctly
      ("Standard_All", "", "SS:description=d11",
       "SS=Standard,Standard_All=Standard",
       {
           "Standard_All": 4,
           "SS": 2
       }),
  )
  @ddt.unpack
  # pylint: disable=too-many-arguments
  def test_count_with_extra_coloumns(self, types, query, extra_params,
                                     extra_columns, expected):
    """Test extra_columns types={0}, q={1}, extra_params={2}, extra_columns={3}
    """

    response_count = self._get_count_ids(types, query, extra_params,
                                         extra_columns)
    self.assertEqual(response_count, expected)
示例#13
0
class TestReader(TestCase):
  """ Test reader role """

  def setUp(self):
    super(TestReader, self).setUp()
    self.generator = Generator()
    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")]
    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):
    return
    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):
    return
    """ Test Basic create/read,update/delete operations """
    self.api.set_user(self.users["reader"])
    all_errors = []
    base_models = set([
        "Control", "Assessment", "DataAsset", "Contract",
        "Policy", "Regulation", "Standard", "Document", "Facility",
        "Market", "Objective", "OrgGroup", "Vendor", "Product",
        "Clause", "System", "Process", "Issue", "Project", "AccessGroup",
    ])
    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.api.post(model, {
            table_singular: {
                "title": model_singular,
                "context": None,
                "reference_url": "ref",
                "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 len(collection) == 0:
          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):
    return
    """ 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},
    })
    obj_id = response.json.get("policy").get("id")
    self.api.post(all_models.ObjectOwner, {"object_owner": {
        "person": {
            "id": self.users['reader'].id,
            "type": "Person",
        }, "ownable": {
            "type": "Policy",
            "id": obj_id,
        }, "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'])
    _, obj_0 = self.generator.generate(all_models.Regulation, "regulation", {
        "regulation": {"title": "Test regulation", "context": None},
    })
    _, obj_1 = self.generator.generate(all_models.Regulation, "regulation", {
        "regulation": {"title": "Test regulation 2", "context": None},
    })
    response, rel = self.generator.generate(
        all_models.Relationship, "relationship", {
            "relationship": {"source": {
                "id": obj_0.id,
                "type": "Regulation"
            }, "destination": {
                "id": obj_1.id,
                "type": "Regulation"
            }, "context": None},
        }
    )
    relationship_id = rel.id
    self.assertEqual(response.status_code, 201)
    self.api.set_user(self.users['reader'])
    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, 1)

  def test_creation_of_mappings(self):
    self.generator.api.set_user(self.users["admin"])
    _, control = self.generator.generate(all_models.Control, "control", {
        "control": {"title": "Test Control", "context": None},
    })
    self.generator.api.set_user(self.users['reader'])
    _, program = self.generator.generate(all_models.Program, "program", {
        "program": {"title": "Test Program", "context": None},
    })

    response, _ = self.generator.generate(
        all_models.Relationship, "relationship", {
            "relationship": {"destination": {
                "id": program.id,
                "type": "Program"
            }, "source": {
                "id": control.id,
                "type": "Control"
            }, "context": {
                "id": program.context.id,
                "type": "context"
            }},
        })
    self.assertEqual(response.status_code, 403)
示例#14
0
class TestMultipleTypes(TestCase):
    """
  Test /search REST API
  """
    def setUp(self):
        """Create indexable objects which provide required set of fulltext attrs

    Fulltext attributes are: title, name, email, notes, description, slug
    """

        super(TestMultipleTypes, self).setUp()

        self.api = Api()

        self.objects = dict()

        with factories.single_commit():
            # Create Requirements
            requirements = [
                factories.RequirementFactory(title=title,
                                             description=desc,
                                             notes=notes)
                for title, desc, notes in (
                    ('t01', 'd01', 'n01'),
                    ('t02', 'd02', 'n02'),
                    ('t11', 'd11', 'n11'),
                )
            ]
            self.objects['Requirement'] = dict(
                (i.title, i.id) for i in requirements)

            # Create people
            people = [
                factories.PersonFactory(name=name, email=email)
                for name, email in (
                    ('n01', '*****@*****.**'),
                    ('n02', '*****@*****.**'),
                    ('n11', '*****@*****.**'),
                )
            ]
            self.objects['Person'] = dict((i.name, i.id) for i in people)

            # Create regulations (regulations represented as directives)
            regulations = [
                factories.RegulationFactory(title=title,
                                            notes=notes,
                                            description=desc)
                for title, notes, desc in (
                    ('t01r', 'n01', 'd01'),
                    ('t02r', 'n02-qq1', 'd02'),
                    ('t11r', 'n11', 'd11'),
                )
            ]
            self.objects['Regulation'] = dict(
                (i.title, i.id) for i in regulations)

            # Create standards (standards represented as directives)
            standards = [
                factories.StandardFactory(title=title,
                                          notes=notes,
                                          description=desc)
                for title, notes, desc in (
                    ('t01s', 'n01-qq1', 'd01'),
                    ('t02s', 'n02', 'd02'),
                    ('t11s', 'n11', 'd11'),
                    ('t21s', 'n21', 'd11'),
                )
            ]
            self.objects['Standard'] = dict((i.title, i.id) for i in standards)

    def _get_search_ids(self, types, query, extra_params):
        """Make request and return entries in format dict(type->list_of_ids)"""

        response, _ = self.api.search(types=types,
                                      query=query,
                                      counts=False,
                                      extra_params=extra_params)

        entries = response.json['results']['entries']

        ret = defaultdict(set)
        for entry in entries:
            ret[entry['type']].add(entry['id'])

        return dict(ret)

    def _get_count_ids(self, types, query, extra_params, extra_columns=None):
        """Make request and return entries in format dict(type->number_of_ids)"""
        response, _ = self.api.search(types=types,
                                      query=query,
                                      counts=True,
                                      extra_params=extra_params,
                                      extra_columns=extra_columns)

        return response.json['results']['counts']

    def _convert_expected_to_dict(self, expected):
        """Convert list of (type, title) to dict (type -> list_of_ids)"""

        ret = defaultdict(set)
        for type_, key in expected:
            ret[type_].add(self.objects[type_][key])

        return dict(ret)

    @staticmethod
    # pylint: disable=invalid-name
    def _convert_expected_dict_to_counts(expected):
        """Convert dict(type->list_of_ids) to dict(type->count_of_ids)"""

        return dict((k, len(v)) for k, v in expected.iteritems())

    @ddt.data(
        # search for Requirements by title
        ("Requirement", "t0", None, (
            ('Requirement', 't01'),
            ('Requirement', 't02'),
        )),
        # search for Requirements by description
        ("Requirement", "d1", None, (('Requirement', 't11'), )),
        # search for Requirements by slug
        ("Requirement", "REQUIREMENT", None, (
            ('Requirement', 't01'),
            ('Requirement', 't02'),
            ('Requirement', 't11'),
        )),
        # search for people by name
        ("Person", "n0", None, (
            ('Person', 'n01'),
            ('Person', 'n02'),
        )),
        # search for people by email
        ("Person", "e1", None, (('Person', 'n11'), )),
        # search for regulations by notes
        ("Regulation", "n0", None, (
            ('Regulation', 't01r'),
            ('Regulation', 't02r'),
        )),
        # search for regulations by title
        ("Regulation", "t1", None, (('Regulation', 't11r'), )),
        # search for Requirements and Reguklations by title
        ("Requirement,Regulation", "t0", None, (
            ('Requirement', 't01'),
            ('Requirement', 't02'),
            ('Regulation', 't01r'),
            ('Regulation', 't02r'),
        )),
        # search for subtypes of the same base type
        # Regulation and Standard are both represented as Directive model
        ("Regulation,Standard", "-qq1", None, (
            ('Regulation', 't02r'),
            ('Standard', 't01s'),
        )),
        # search with empty types
        ("", "", None, ()),
        # search with non-existing type
        ("qwe", "", None, ()),
        # search for 2 types, one does not exist
        ("Requirement,qwe", "t0", None, (
            ('Requirement', 't01'),
            ('Requirement', 't02'),
        )),
        # search for empty text
        ("Requirement", "", None, (
            ('Requirement', 't01'),
            ('Requirement', 't02'),
            ('Requirement', 't11'),
        )),
        # search for added empty extra_params
        ("Requirement", "", "", (
            ('Requirement', 't01'),
            ('Requirement', 't02'),
            ('Requirement', 't11'),
        )),
        # search by title using extra_params
        ("Requirement", "", "Requirement:title=t01",
         (('Requirement', 't01'), )),
        # search by title using extra_params where model name is lowercase
        ("Requirement", "", "requirement:title=t01",
         (('Requirement', 't01'), )),
        # search by title using extra_params where model name is lowercase
        ("Regulation", "", "Requirement:title=t01", (
            ('Regulation', 't01r'),
            ('Regulation', 't02r'),
            ('Regulation', 't11r'),
        )),
        # search nonexisting type by title using extra_params
        ("Requirement", "", "qwe:title=t01", (
            ('Requirement', 't01'),
            ('Requirement', 't02'),
            ('Requirement', 't11'),
        )),
        # search in multiple models, one by title using extra_params
        # filter uses AND operation to search indexed fields and extra_params
        # for single model.
        # There is no such Requirement where indexed fields contain "d0" and
        # title is "t01", so only regulations will be returned where indexed
        # fields contain "n0"
        ("Requirement,Regulation", "d0", "Requirement:title=t11", (
            ('Regulation', 't01r'),
            ('Regulation', 't02r'),
        )),
        # search for subtypes of the same base type based on extra_params
        # Regulation and Standard are both represented as Directive model
        # ensure that extra_params for Regulation will not return Standard
        # with the same notes
        (
            "Regulation,Standard",
            "-qq1",
            "Regulation:description=d02",
            (
                ('Regulation',
                 't02r'),  # contains "-qq1" and description = "d02"
                ('Standard', 't01s'),  # contains "-qq1"
            )),
    )
    @ddt.unpack
    def test_search(self, types, query, extra_params, expected):
        """Test search of objects for types={0}, q={1}, extra_params={2}"""

        exp_search = self._convert_expected_to_dict(expected)
        response_search = self._get_search_ids(types, query, extra_params)
        self.assertEqual(response_search, exp_search)

        exp_count = self._convert_expected_dict_to_counts(exp_search)
        response_count = self._get_count_ids(types, query, extra_params)
        self.assertEqual(response_count, exp_count)

    @ddt.data(
        ("Standard", "", "Standard:title=t01s;SS:description=d11",
         "SS=Standard", {
             "Standard": 1,
             "SS": 2
         }),
        # Add "Standard_ALL" column for which extra_params is not defined
        ("Standard", "", "SS:description=d11",
         "SS=Standard,Standard_All=Standard", {
             "SS": 2,
             "Standard_All": 4
         }),
        # types can contain column name from extra_columns
        # ensure that it is also handled correctly
        ("Standard_All", "", "SS:description=d11",
         "SS=Standard,Standard_All=Standard", {
             "Standard_All": 4,
             "SS": 2
         }),
    )
    @ddt.unpack
    # pylint: disable=too-many-arguments
    def test_count_with_extra_coloumns(self, types, query, extra_params,
                                       extra_columns, expected):
        """Test extra_columns types={0}, q={1}, extra_params={2}, extra_columns={3}
    """

        response_count = self._get_count_ids(types, query, extra_params,
                                             extra_columns)
        self.assertEqual(response_count, expected)
示例#15
0
class TestCreator(TestCase):
    """ TestCreator """
    def setUp(self):
        super(TestCreator, self).setUp()
        self.generator = Generator()
        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):
        for role, code in (("creator", 403), ("admin", 200)):
            self.api.set_user(self.users[role])
            self.assertEqual(self.api.tc.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"])
        all_errors = []
        base_models = set([
            "Control", "DataAsset", "Contract", "Policy", "Regulation",
            "Standard", "Document", "Facility", "Market", "Objective",
            "OrgGroup", "Vendor", "Product", "Clause", "System", "Process",
            "Issue", "Project", "AccessGroup"
        ])
        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.api.post(
                    model, {
                        table_singular: {
                            "title": model_singular,
                            "context": None,
                            "reference_url": "ref",
                            "contact": {
                                "type": "Person",
                                "id": self.users["creator"].id,
                            },
                        },
                    })
                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 len(collection) != 0:
                    all_errors.append(
                        "{} can retrieve object if not owner (collection)".
                        format(model_singular))
                    continue
                # Become an owner
                response = self.api.post(
                    all_models.ObjectOwner, {
                        "object_owner": {
                            "person": {
                                "id": self.users['creator'].id,
                                "type": "Person",
                            },
                            "ownable": {
                                "type": model_singular,
                                "id": obj_id
                            },
                            "context": None
                        }
                    })
                if response.status_code != 201:
                    all_errors.append("{} can't create owner {}.".format(
                        model_singular, response.status))
                    continue

                # 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 len(collection) == 0:
                    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'])
        response = self.api.post(all_models.Policy, {
            "policy": {
                "title": "Creator Policy",
                "context": None
            },
        })
        obj_id = response.json.get("policy").get("id")
        self.api.post(
            all_models.ObjectOwner, {
                "object_owner": {
                    "person": {
                        "id": self.users['creator'].id,
                        "type": "Person",
                    },
                    "ownable": {
                        "type": "Policy",
                        "id": obj_id,
                    },
                    "context": None
                }
            })
        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_creator_cannot_be_owner(self):
        """Test if creator cannot become owner of the object he has not created"""
        self.api.set_user(self.users['admin'])
        _, obj = self.generator.generate(all_models.Regulation, "regulation", {
            "regulation": {
                "title": "Test regulation",
                "context": None
            },
        })
        self.api.set_user(self.users['creator'])
        response = self.api.post(
            all_models.ObjectOwner, {
                "object_owner": {
                    "person": {
                        "id": self.users['creator'].id,
                        "type": "Person",
                    },
                    "ownable": {
                        "type": "Regulation",
                        "id": obj.id,
                    },
                    "context": None
                }
            })
        self.assertEqual(response.status_code, 403)

    def test_relationships_access(self):
        """Check if creator cannot access relationship objects"""
        self.api.set_user(self.users['admin'])
        _, obj_0 = self.generator.generate(all_models.Regulation, "regulation",
                                           {
                                               "regulation": {
                                                   "title": "Test regulation",
                                                   "context": None
                                               },
                                           })
        _, obj_1 = self.generator.generate(
            all_models.Regulation, "regulation", {
                "regulation": {
                    "title": "Test regulation 2",
                    "context": None
                },
            })
        response, rel = self.generator.generate(
            all_models.Relationship, "relationship", {
                "relationship": {
                    "source": {
                        "id": obj_0.id,
                        "type": "Regulation"
                    },
                    "destination": {
                        "id": obj_1.id,
                        "type": "Regulation"
                    },
                    "context": None
                },
            })
        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):
            return self.generator.generate(all_models.Section, "section", {
                "section": {
                    "title": title,
                    "context": None
                },
            })[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 Section 1")
        obj_2 = gen("Test Section 2")

        self.api.post(
            all_models.ObjectOwner, {
                "object_owner": {
                    "person": {
                        "id": self.users['creator'].id,
                        "type": "Person",
                    },
                    "ownable": {
                        "type": "Section",
                        "id": obj_2.id,
                    },
                    "context": None
                }
            })

        self.api.set_user(self.users["creator"])
        check(obj_1, 0)
        check(obj_2, 2)
示例#16
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.')
示例#17
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"])
示例#18
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.')