Ejemplo n.º 1
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)
Ejemplo n.º 2
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"])
Ejemplo n.º 3
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")
Ejemplo n.º 4
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")
Ejemplo n.º 5
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)
Ejemplo n.º 6
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"])
Ejemplo n.º 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):
    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)
Ejemplo n.º 8
0
class TestReviewApi(TestCase):
    """Base TestCase class proposal api tests."""
    def setUp(self):
        super(TestReviewApi, self).setUp()
        self.api = Api()
        self.api.client.get("/login")
        self.generator = generator.ObjectGenerator()

    def test_simple_get(self):
        """Test simple get"""
        with factories.single_commit():
            control = factories.ControlFactory()
            review = factories.ReviewFactory(
                email_message="test email message",
                notification_type="email",
                reviewable=control,
                status=all_models.Review.STATES.UNREVIEWED,
            )
        resp = self.api.get(all_models.Review, review.id)
        self.assert200(resp)
        self.assertIn("review", resp.json)
        resp_review = resp.json["review"]
        self.assertEqual(all_models.Review.STATES.UNREVIEWED,
                         resp_review["status"])
        self.assertEqual(all_models.Review.NotificationTypes.EMAIL_TYPE,
                         resp_review["notification_type"])
        self.assertEqual("test email message", resp_review["email_message"])

    def test_collection_get(self):
        """Test simple collection get"""
        with factories.single_commit():
            review1 = factories.ReviewFactory(
                status=all_models.Review.STATES.UNREVIEWED)
            review2 = factories.ReviewFactory(
                status=all_models.Review.STATES.REVIEWED)

        resp = self.api.get_collection(all_models.Review,
                                       [review1.id, review2.id])
        self.assert200(resp)
        self.assertIn("reviews_collection", resp.json)
        self.assertIn("reviews", resp.json["reviews_collection"])
        self.assertEquals(2, len(resp.json["reviews_collection"]["reviews"]))

    def test_create_review(self):
        """Create review via API, check that single relationship is created"""
        control = factories.ControlFactory()
        control_id = control.id
        resp = self.api.post(
            all_models.Review,
            {
                "review": {
                    "reviewable": {
                        "type": control.type,
                        "id": control.id,
                    },
                    "context": None,
                    "notification_type": "email",
                    "status": all_models.Review.STATES.UNREVIEWED,
                    "access_control_list": build_reviewer_acl()
                },
            },
        )
        self.assertEqual(201, resp.status_code)
        review_id = resp.json["review"]["id"]
        review = all_models.Review.query.get(review_id)
        self.assertEqual(all_models.Review.STATES.UNREVIEWED, review.status)
        self.assertEqual(control.type, review.reviewable_type)
        self.assertEqual(control_id, review.reviewable_id)

        control_review_rel_count = all_models.Relationship.query.filter(
            all_models.Relationship.source_id == review.id,
            all_models.Relationship.source_type == review.type,
            all_models.Relationship.destination_id == control_id,
            all_models.Relationship.destination_type == control.type,
        ).union(
            all_models.Relationship.query.filter(
                all_models.Relationship.destination_id == review.id,
                all_models.Relationship.destination_type == review.type,
                all_models.Relationship.source_id == control_id,
                all_models.Relationship.source_type == control.type,
            )).count()
        self.assertEqual(1, control_review_rel_count)

    def test_delete_review(self):
        """Test delete review via API"""
        with factories.single_commit():
            control = factories.ControlFactory()
            control_id = control.id
            review = factories.ReviewFactory(reviewable=control)
            review_id = review.id
        resp = self.api.delete(review)
        self.assert200(resp)
        review = all_models.Review.query.get(review_id)
        control = all_models.Control.query.get(control_id)

        self.assertIsNone(review)
        self.assertEquals(0, len(control.related_objects(_types=["Review"])))

    def test_last_reviewed(self):
        """last_reviewed_by, last_reviewed_by should be set if reviewed"""
        control = factories.ControlFactory()
        resp, review = self.generator.generate_object(
            all_models.Review,
            {
                "reviewable": {
                    "type": control.type,
                    "id": control.id,
                },
                "context": None,
                "status": all_models.Review.STATES.UNREVIEWED,
                "access_control_list": build_reviewer_acl(),
                "notification_type":
                all_models.Review.NotificationTypes.EMAIL_TYPE
            },
        )
        review_id = review.id
        resp = self.api.put(
            review,
            {
                "status": all_models.Review.STATES.REVIEWED,
            },
        )
        self.assert200(resp)
        self.assertIsNotNone(resp.json["review"]["last_reviewed_by"])
        self.assertIsNotNone(resp.json["review"]["last_reviewed_at"])

        review = all_models.Review.query.get(review_id)
        self.assertIsNotNone(review.last_reviewed_by)
        self.assertIsNotNone(review.last_reviewed_at)

    def test_reviewable_revisions(self):
        """Check that proper revisions are created"""
        control = factories.ControlFactory()
        resp, review = self.generator.generate_object(
            all_models.Review,
            {
                "reviewable": {
                    "type": control.type,
                    "id": control.id,
                },
                "context": None,
                "status": all_models.Review.STATES.UNREVIEWED,
                "access_control_list": build_reviewer_acl(),
                "notification_type":
                all_models.Review.NotificationTypes.EMAIL_TYPE
            },
        )
        control_id = control.id
        reviewable = review.reviewable

        control_revisions = all_models.Revision.query.filter_by(
            resource_id=control_id, resource_type=control.type).order_by(
                all_models.Revision.created_at, ).all()
        self.assertEquals(2, len(control_revisions))
        self.assertEquals(all_models.Review.STATES.UNREVIEWED,
                          control_revisions[0].content["review_status"])
        self.assertEquals(all_models.Review.STATES.UNREVIEWED,
                          control_revisions[1].content["review_status"])
        resp = self.api.put(
            review,
            {
                "status": all_models.Review.STATES.REVIEWED,
            },
        )
        self.assert200(resp)

        control_revisions = all_models.Revision.query.filter_by(
            resource_id=control_id, resource_type=control.type).order_by(
                all_models.Revision.created_at, ).all()
        self.assertEquals(3, len(control_revisions))
        self.assertEquals(all_models.Review.STATES.REVIEWED,
                          control_revisions[2].content["review_status"])

        resp = self.api.put(reviewable,
                            {"description": "some new description"})
        self.assert200(resp)

        control_revisions = all_models.Revision.query.filter_by(
            resource_id=control_id, resource_type=control.type).order_by(
                all_models.Revision.created_at, ).all()
        self.assertEquals(4, len(control_revisions))
        self.assertEquals(all_models.Review.STATES.UNREVIEWED,
                          control_revisions[3].content["review_status"])
Ejemplo n.º 9
0
class TestReviewApi(TestCase):
  """Base TestCase class proposal api tests."""

  def setUp(self):
    super(TestReviewApi, self).setUp()
    self.api = Api()
    self.api.client.get("/login")
    self.generator = generator.ObjectGenerator()

  def test_simple_get(self):
    """Test simple get"""
    with factories.single_commit():
      risk = factories.RiskFactory()
      review = factories.ReviewFactory(
          email_message="test email message",
          notification_type="email",
          reviewable=risk,
          status=all_models.Review.STATES.UNREVIEWED,
      )
    resp = self.api.get(all_models.Review, review.id)
    self.assert200(resp)
    self.assertIn("review", resp.json)
    resp_review = resp.json["review"]
    self.assertEqual(all_models.Review.STATES.UNREVIEWED,
                     resp_review["status"])
    self.assertEqual(all_models.Review.NotificationTypes.EMAIL_TYPE,
                     resp_review["notification_type"])
    self.assertEqual("test email message",
                     resp_review["email_message"])

  def test_collection_get(self):
    """Test simple collection get"""
    with factories.single_commit():
      review1 = factories.ReviewFactory(
          status=all_models.Review.STATES.UNREVIEWED
      )
      review2 = factories.ReviewFactory(
          status=all_models.Review.STATES.REVIEWED
      )

    resp = self.api.get_collection(all_models.Review,
                                   [review1.id, review2.id])
    self.assert200(resp)
    self.assertIn("reviews_collection", resp.json)
    self.assertIn("reviews", resp.json["reviews_collection"])
    self.assertEquals(2, len(resp.json["reviews_collection"]["reviews"]))

  def test_create_review(self):
    """Create review via API, check that single relationship is created"""
    program = factories.ProgramFactory()
    program_id = program.id
    resp = self.api.post(
        all_models.Review,
        {
            "review": {
                "reviewable": {
                    "type": program.type,
                    "id": program.id,
                },
                "context": None,
                "notification_type": "email",
                "status": all_models.Review.STATES.UNREVIEWED,
                "access_control_list": build_reviewer_acl()
            },
        },
    )
    self.assertEqual(201, resp.status_code)
    review_id = resp.json["review"]["id"]
    review = all_models.Review.query.get(review_id)
    self.assertEqual(all_models.Review.STATES.UNREVIEWED, review.status)
    self.assertEqual(program.type, review.reviewable_type)
    self.assertEqual(program_id, review.reviewable_id)

    control_review_rel_count = all_models.Relationship.query.filter(
        all_models.Relationship.source_id == review.id,
        all_models.Relationship.source_type == review.type,
        all_models.Relationship.destination_id == program_id,
        all_models.Relationship.destination_type == program.type,
    ).union(
        all_models.Relationship.query.filter(
            all_models.Relationship.destination_id == review.id,
            all_models.Relationship.destination_type == review.type,
            all_models.Relationship.source_id == program_id,
            all_models.Relationship.source_type == program.type,
        )
    ).count()
    self.assertEqual(1, control_review_rel_count)

  def test_delete_review(self):
    """Test delete review via API"""
    with factories.single_commit():
      risk = factories.RiskFactory()
      risk_id = risk.id
      review = factories.ReviewFactory(reviewable=risk)
      review_id = review.id
    resp = self.api.delete(review)
    self.assert200(resp)
    review = all_models.Review.query.get(review_id)
    risk = all_models.Risk.query.get(risk_id)

    self.assertIsNone(review)
    self.assertEquals(0, len(risk.related_objects(_types=["Review"])))

  def test_last_reviewed(self):
    """last_reviewed_by, last_reviewed_by should be set if reviewed"""
    risk = factories.RiskFactory()
    resp, review = self.generator.generate_object(
        all_models.Review,
        {
            "reviewable": {
                "type": risk.type,
                "id": risk.id,
            },
            "context": None,
            "status": all_models.Review.STATES.UNREVIEWED,
            "access_control_list": build_reviewer_acl(),
            "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE
        },
    )
    review_id = review.id
    resp = self.api.put(
        review,
        {
            "status": all_models.Review.STATES.REVIEWED,
        },
    )
    self.assert200(resp)
    self.assertIsNotNone(resp.json["review"]["last_reviewed_by"])
    self.assertIsNotNone(resp.json["review"]["last_reviewed_at"])

    review = all_models.Review.query.get(review_id)
    self.assertIsNotNone(review.last_reviewed_by)
    self.assertIsNotNone(review.last_reviewed_at)

  def test_reviewable_revisions(self):
    """Check that proper revisions are created"""
    program = factories.ProgramFactory()
    resp, review = self.generator.generate_object(
        all_models.Review,
        {
            "reviewable": {
                "type": program.type,
                "id": program.id,
            },
            "context": None,
            "status": all_models.Review.STATES.UNREVIEWED,
            "access_control_list": build_reviewer_acl(),
            "notification_type": all_models.Review.NotificationTypes.EMAIL_TYPE
        },
    )
    program_id = program.id
    reviewable = review.reviewable

    program_revisions = all_models.Revision.query.filter_by(
        resource_id=program_id,
        resource_type=program.type
    ).order_by(
        all_models.Revision.id,
    ).all()
    self.assertEquals(2, len(program_revisions))
    self.assertEquals(all_models.Review.STATES.UNREVIEWED,
                      program_revisions[0].content["review_status"])
    self.assertEquals(all_models.Review.STATES.UNREVIEWED,
                      program_revisions[1].content["review_status"])
    resp = self.api.put(
        review,
        {
            "status": all_models.Review.STATES.REVIEWED,
        },
    )
    self.assert200(resp)

    program_revisions = all_models.Revision.query.filter_by(
        resource_id=program_id,
        resource_type=program.type
    ).order_by(
        all_models.Revision.id,
    ).all()
    self.assertEquals(3, len(program_revisions))
    self.assertEquals(all_models.Review.STATES.REVIEWED,
                      program_revisions[2].content["review_status"])

    resp = self.api.put(
        reviewable,
        {
            "description": "some new description"
        }
    )
    self.assert200(resp)

    program_revisions = all_models.Revision.query.filter_by(
        resource_id=program_id,
        resource_type=program.type
    ).order_by(
        all_models.Revision.id,
    ).all()
    self.assertEquals(4, len(program_revisions))
    self.assertEquals(all_models.Review.STATES.UNREVIEWED,
                      program_revisions[3].content["review_status"])
Ejemplo n.º 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):
    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)
Ejemplo n.º 11
0
class TestCreatorProgram(TestCase):
    """Set up necessary objects and test Creator role with Program roles"""
    def setUp(self):
        TestCase.setUp(self)
        self.generator = Generator()
        self.api = Api()
        self.object_generator = ObjectGenerator()
        self.init_users()
        self.init_roles()
        self.init_test_cases()
        self.objects = {}

    def init_test_cases(self):
        """ Create a dict of all possible test cases """
        self.test_cases = {
            "notmapped": {
                "objects": {
                    "program": {
                        "get": 403,
                        "put": 403,
                        "delete": 403
                    },
                    "mapped_object": {
                        "get": 403,
                        "put": 403,
                        "delete": 403
                    },
                    "unrelated": {
                        "get": 403,
                        "put": 403,
                        "delete": 403,
                        "map": 403,
                    }
                },
            },
            "mapped": {
                "objects": {
                    "program": {
                        "get": 403,
                        "put": 403,
                        "delete": 403
                    },
                    "mapped_object": {
                        "get": 403,
                        "put": 403,
                        "delete": 403
                    },
                    "unrelated": {
                        "get": 403,
                        "put": 403,
                        "delete": 403,
                        "map": 403,
                    }
                }
            },
            "ProgramReader": {
                "program_role": "ProgramReader",
                "objects": {
                    "program": {
                        "get": 200,
                        "put": 403,
                        "delete": 403
                    },
                    "mapped_object": {
                        "get": 200,
                        "put": 403,
                        "delete": 403
                    },
                    "unrelated": {
                        "get": 403,
                        "put": 403,
                        "delete": 403,
                        "map": 403,
                    }
                }
            },
            "ProgramOwner": {
                "program_role": "ProgramOwner",
                "objects": {
                    "program": {
                        "get": 200,
                        "put": 200,
                        "delete": 200
                    },
                    "mapped_object": {
                        "get": 200,
                        "put": 200,
                        "delete": 200,
                    },
                    "unrelated": {
                        "get": 403,
                        "put": 403,
                        "delete": 403,
                        "map": 403,
                    }
                }
            },
            "ProgramEditor": {
                "program_role": "ProgramEditor",
                "objects": {
                    "program": {
                        "get": 200,
                        "put": 200,
                        "delete": 200
                    },
                    "mapped_object": {
                        "get": 200,
                        "put": 200,
                        "delete": 200
                    },
                    "unrelated": {
                        "get": 403,
                        "put": 403,
                        "delete": 403,
                        "map": 403,
                    }
                }
            },
        }

    def init_roles(self):
        """ Create a delete request for the given object """
        response = self.api.get_query(all_models.Role, "")
        self.roles = {}
        for role in response.json.get("roles_collection").get("roles"):
            self.roles[role.get("name")] = role

    def init_users(self):
        """ Create users used by test cases """
        users = [("creator", "Creator"), ("notmapped", "Creator"),
                 ("mapped", "Creator"), ("ProgramReader", "Creator"),
                 ("ProgramEditor", "Creator"), ("ProgramOwner", "Creator")]
        self.people = {}
        for (name, role) in users:
            _, user = self.object_generator.generate_person(
                data={"name": name}, user_role=role)
            self.people[name] = user

    def delete(self, obj):
        """ Create a delete request for the given object """
        return self.api.delete(obj).status_code

    def get(self, obj):
        """ Create a get request for the given object """
        return self.api.get(obj.__class__, obj.id).status_code

    def put(self, obj):
        """ Create a put request for the given object """
        response = self.api.get(obj.__class__, obj.id)
        if response.status_code == 200:
            return self.api.put(obj, response.json).status_code
        else:
            return response.status_code

    def map(self, dest):
        """ Map src to dest """
        response = self.api.post(
            all_models.Relationship, {
                "relationship": {
                    "source": {
                        "id": self.objects["program"].id,
                        "type": self.objects["program"].type,
                    },
                    "destination": {
                        "id": dest.id,
                        "type": dest.type
                    },
                    "context": None
                },
            })
        return response.status_code

    def init_objects(self, test_case_name):
        """ Create a Program and a Mapped object for a given test case """
        # Create a program
        test_case = self.test_cases[test_case_name]
        creator = self.people.get('creator')
        self.api.set_user(creator)
        random_title = factories.random_str()
        response = self.api.post(all_models.Program, {
            "program": {
                "title": random_title,
                "context": None
            },
        })
        self.assertEqual(response.status_code, 201)
        context_id = response.json.get("program").get("context").get("id")
        program_id = response.json.get("program").get("id")
        self.objects["program"] = all_models.Program.query.get(program_id)
        # Create an object:
        for obj in ("mapped_object", "unrelated"):
            random_title = factories.random_str()
            response = self.api.post(all_models.System, {
                "system": {
                    "title": random_title,
                    "context": None
                },
            })
            self.assertEqual(response.status_code, 201)
            system_id = response.json.get("system").get("id")
            self.objects[obj] = all_models.System.query.get(system_id)
            # Become the owner
            response = self.api.post(
                all_models.ObjectOwner, {
                    "object_owner": {
                        "person": {
                            "id": creator.id,
                            "type": "Person",
                        },
                        "ownable": {
                            "id": system_id,
                            "type": "System"
                        },
                        "context": None
                    }
                })
        # Map Object to Program
        response = self.api.post(
            all_models.Relationship, {
                "relationship": {
                    "source": {
                        "id": program_id,
                        "type": "Program"
                    },
                    "destination": {
                        "id": self.objects["mapped_object"].id,
                        "type": "System"
                    },
                    "context": None
                },
            })
        self.assertEqual(response.status_code, 201)

        # Map people to Program:
        if test_case_name != "notmapped":
            person = self.people.get(test_case_name)
            response = self.api.post(
                all_models.ObjectPerson, {
                    "object_person": {
                        "person": {
                            "id": person.id,
                            "type": "Person",
                            "href": "/api/people/{}".format(person.id),
                        },
                        "personable": {
                            "type": "Program",
                            "href": "/api/programs/{}".format(program_id),
                            "id": program_id,
                        },
                        "context": {
                            "type": "Context",
                            "id": context_id,
                            "href": "/api/contexts/{}".format(context_id)
                        }
                    }
                })

        # Add roles to mapped users:
        if "program_role" in test_case:
            person = self.people.get(test_case_name)
            role = self.roles[test_case["program_role"]]
            response = self.api.post(
                all_models.UserRole, {
                    "user_role": {
                        "person": {
                            "id": person.id,
                            "type": "Person",
                            "href": "/api/people/{}".format(person.id),
                        },
                        "role": {
                            "type": "Role",
                            "href": "/api/roles/{}".format(role["id"]),
                            "id": role["id"],
                        },
                        "context": {
                            "type": "Context",
                            "id": context_id,
                            "href": "/api/contexts/{}".format(context_id)
                        }
                    }
                })
            self.assertEqual(response.status_code, 201)

    def test_creator_program_roles(self):
        """ Test creator role with all program scoped roles """
        # Check permissions based on test_cases:
        errors = []
        for test_case in self.test_cases:
            self.init_objects(test_case)
            person = self.people.get(test_case)
            objects = self.test_cases.get(test_case).get('objects')
            self.api.set_user(person)
            for obj in ("unrelated", "mapped_object", "program"):
                actions = objects[obj]
                for action in ("map", "get", "put", "delete"):
                    # reset sesion:
                    db.session.commit()
                    if action not in actions:
                        continue
                    func = getattr(self, action)
                    res = func(self.objects[obj])
                    if res != actions[action]:
                        errors.append(
                            "{}: Tried {} on {}, but received {} instead of {}"
                            .format(test_case, action, obj, res,
                                    actions[action]))
            # Try mapping
        self.assertEqual(errors, [])

    def test_creator_audit_request_creation(self):
        self.init_objects("ProgramOwner")
        program = self.objects.get("program")
        creator = self.people.get("creator")
        # Create an audit
        response = self.api.post(
            all_models.Audit, {
                "audit": {
                    "title": "Audit for program",
                    "status": "Planned",
                    "context": {
                        "id": program.context_id,
                        "type": "Context"
                    },
                    "program": {
                        "context_id": program.context_id,
                        "id": program.id,
                        "type": "Program",
                    },
                    "contact": {
                        "id": creator.id,
                        "type": "Person"
                    }
                },
            })
        self.assertEqual(response.status_code, 201)
        audit_id = response.json.get("audit").get("id")
        audit_context_id = response.json.get("audit").get("context").get("id")
        # Create a request
        response = self.api.post(
            all_models.Request, {
                "request": {
                    "title": "Request for audit",
                    "status": "In Progress",
                    "context": {
                        "id": audit_context_id,
                        "type": "Context"
                    },
                    "audit": {
                        "id": audit_id,
                        "type": "Audit",
                    },
                    "end_date": "2015-12-08",
                    "start_date": "2015-12-01",
                    "request_type": "documentation"
                },
            })
        self.assertEqual(response.status_code, 201)
        request_id = response.json.get("request").get("id")

        # Create assignee/requester relationships
        assignee = self.people.get("notmapped")
        response = self.api.post(
            all_models.Relationship, {
                "relationship": {
                    "attrs": {
                        "AssigneeType": "Assignee"
                    },
                    "context": {
                        "id": audit_context_id,
                        "type": "Context",
                    },
                    "destination": {
                        "id": request_id,
                        "type": "Request",
                    },
                    "source": {
                        "id": assignee.id,
                        "type": "Person"
                    }
                },
            })
        self.assertEqual(response.status_code, 201)
        relationship_id = response.json.get("relationship").get("id")
        response = self.api.get_collection(all_models.Relationship,
                                           relationship_id)
        num = len(response.json["relationships_collection"]["relationships"])
        self.assertEqual(num, 2)