def test_create_from_ggrcq(self, definition_type, title): """Test create definition only for GGRCQ.""" api = Api() payload = [ { "custom_attribute_definition": { "attribute_type": "Text", "context": {"id": None}, "definition_type": definition_type, "helptext": "", "mandatory": False, "modal_title": "Title", "placeholder": "", "title": title } } ] with api.as_external(): response = api.post(all_models.CustomAttributeDefinition, payload) self.assertEqual(response.status_code, 200)
def test_create_from_ggrcq(self, definition_type, title): """Test create definition only for GGRCQ.""" api = Api() payload = [{ "custom_attribute_definition": { "attribute_type": "Text", "context": { "id": None }, "definition_type": definition_type, "helptext": "", "mandatory": False, "modal_title": "Title", "placeholder": "", "title": title } }] with api.as_external(): response = api.post(all_models.CustomAttributeDefinition, payload) self.assertEqual(response.status_code, 200)
class TestAccessControlRole(TestCase): """TestAccessControlRole""" def setUp(self): self.clear_data() super(TestAccessControlRole, self).setUp() self.api = Api() self.object_generator = ObjectGenerator() self.people = {} for name in ["Creator", "Reader", "Editor"]: _, user = self.object_generator.generate_person( data={"name": name}, user_role=name) self.people[name] = user def _post_role(self, name=None, object_type="Control"): """Helper function for POSTing roles""" if name is None: name = random_str(prefix="Access Control Role - ") return self.api.post( AccessControlRole, { "access_control_role": { "name": name, "object_type": object_type, "context": None, "read": True }, }) def test_create_after_objects(self): """Test eager creation of ACLs on existing objects with new ACR.""" program_id = factories.ProgramFactory().id role_name = "New Custom Role" self._post_role(name=role_name, object_type="Program") program = all_models.Program.query.get(program_id) self.assertIn(role_name, program.acr_name_acl_map.keys()) self.assertIsNotNone(program.acr_name_acl_map[role_name]) def test_create(self): """Test Access Control Role creation""" response = self._post_role(object_type="Program") assert response.status_code == 201, \ "Failed to create a new access control role, response was {}".format( response.status) id_ = response.json['access_control_role']['id'] role = AccessControlRole.query.filter( AccessControlRole.id == id_).first() assert role.read == 1, \ "Read permission not correctly saved {}".format(role.read) assert role.update == 1, \ "Update permission not correctly saved {}".format(role.update) assert role.delete == 1, \ "Update permission not correctly saved {}".format(role.delete) @ddt.data( { "mandatory": True, "exp_response": MANDATORY_ROLE_RESPONSE }, { "mandatory": False, "exp_response": NON_MANDATORY_ROLE_RESPONSE }, ) @ddt.unpack def test_mandatory_delete(self, mandatory, exp_response): """Test set empty field via import if acr mandatory is {mandatory}""" role = factories.AccessControlRoleFactory( name=ROLE_NAME, object_type="Program", mandatory=mandatory, ) with factories.single_commit(): user = factories.PersonFactory() program = factories.ProgramFactory() role_id = role.id factories.AccessControlPersonFactory( ac_list=program.acr_name_acl_map[ROLE_NAME], person=user, ) response = self.import_data( OrderedDict([ ("object_type", "Program"), ("Code*", program.slug), (ROLE_NAME, "--"), ])) self._check_csv_response(response, exp_response) db_data = defaultdict(set) program = all_models.Program.query.get(program.id) for person, acl in program.access_control_list: db_data[acl.ac_role_id].add(person.id) if mandatory: cur_user = all_models.Person.query.filter_by( email="*****@*****.**").first() self.assertEqual(set([cur_user.id]), db_data[role_id]) else: self.assertFalse(db_data[role_id]) def test_only_admin_can_post(self): """Only admin users should be able to POST access control roles""" for name in ("Creator", "Reader", "Editor"): person = self.people.get(name) self.api.set_user(person) response = self._post_role() assert response.status_code == 403, \ "Non admins should get forbidden error when POSTing role. {}".format( response.status) @ddt.data( ("name", "New ACR"), ("read", False), ("mandatory", False), ("non_editable", False), ) @ddt.unpack def test_modify_non_editable_role(self, field_name, field_value): """Test if user can modify non-editable role""" # Primary Contacts role of Control is non-editable ac_role = AccessControlRole.query.filter_by( object_type="Control", name="Control Operators", ).first() response = self.api.put(ac_role, {field_name: field_value}) assert response.status_code == 403, \ "Forbidden error should be thrown when non-editable " \ "role {} updated.".format(ac_role.name) def test_delete_non_editable_role(self): """Test if user can delete non-editable role""" # Primary Contacts role of Control is non-editable ac_role = AccessControlRole.query.filter_by( object_type="Control", name="Control Operators", ).first() response = self.api.delete(ac_role) assert response.status_code == 403, \ "Forbidden error should be thrown when non-editable " \ "role {} deleted.".format(ac_role.name) @ddt.data("Control") def test_create_from_ggrcq(self, object_type): """Test that create action only for GGRCQ.""" with self.api.as_external(): response = self._post_role(object_type=object_type) self.assertEqual(response.status_code, 201) @ddt.data("Control") def test_create_from_ggrc(self, object_type): """Test create action not allowed for GGRC.""" response = self._post_role(object_type=object_type) self.assertEqual(response.status_code, 405) @ddt.data("Control") def test_modify_from_ggrcq(self, object_type): """Test that modify action only for GGRCQ.""" with factories.single_commit(): acr_id = factories.AccessControlRoleFactory( object_type=object_type).id with self.api.as_external(): acr = all_models.AccessControlRole.query.get(acr_id) response = self.api.put(acr, {"name": "new acr"}) self.assertEqual(response.status_code, 200) @ddt.data("Control") def test_modify_from_ggrc(self, object_type): """Test modify action not allowed for GGRC.""" with factories.single_commit(): acr = factories.AccessControlRoleFactory(object_type=object_type) response = self.api.put(acr, {"name": "new acr"}) self.assertEqual(response.status_code, 405) @ddt.data("Control") def test_delete_from_ggrcq(self, object_type): """Test that modify action only for GGRCQ.""" with factories.single_commit(): acr_id = factories.AccessControlRoleFactory( object_type=object_type).id with self.api.as_external(): acr = all_models.AccessControlRole.query.get(acr_id) response = self.api.delete(acr) self.assertEqual(response.status_code, 200) @ddt.data("Control") def test_delete_from_ggrc(self, object_type): """Test modify action not allowed for GGRC.""" with factories.single_commit(): acr = factories.AccessControlRoleFactory(object_type=object_type) response = self.api.delete(acr) self.assertEqual(response.status_code, 405) @ddt.data( { "name": "Test 1", "update": False, "read": False, "delete": True }, { "name": "Test 2", "update": True, "read": False, "delete": False }, { "name": "Test 3", "update": True, "read": False, "delete": True }, ) @ddt.unpack def test_create_with_wrong_options(self, name, update, read, delete): """ Test if user create ACR with wrong options.""" options = [{ 'access_control_role': { 'modal_title': 'Add Custom Role to type Regulation', 'object_type': 'Regulation', 'parent_type': 'Regulation', 'context': { 'id': None }, 'delete': delete, 'update': update, 'read': read, 'name': name } }] response = self.api.post(AccessControlRole, options) self.assert400(response)
class TestAccessControlRole(TestCase): """TestAccessControlRole""" def setUp(self): self.clear_data() super(TestAccessControlRole, self).setUp() self.api = Api() self.object_generator = ObjectGenerator() self.people = {} for name in ["Creator", "Reader", "Editor"]: _, user = self.object_generator.generate_person( data={"name": name}, user_role=name) self.people[name] = user def _post_role(self, name=None, object_type="Control"): """Helper function for POSTing roles""" if name is None: name = random_str(prefix="Access Control Role - ") return self.api.post(AccessControlRole, { "access_control_role": { "name": name, "object_type": object_type, "context": None, "read": True }, }) def test_create_after_objects(self): """Test eager creation of ACLs on existing objects with new ACR.""" risk_id = factories.RiskFactory().id role_name = "New Custom Role" self._post_role(name=role_name, object_type="Risk") risk = all_models.Risk.query.get(risk_id) self.assertIn(role_name, risk.acr_name_acl_map.keys()) self.assertIsNotNone(risk.acr_name_acl_map[role_name]) def test_create(self): """Test Access Control Role creation""" response = self._post_role(object_type="Risk") assert response.status_code == 201, \ "Failed to create a new access control role, response was {}".format( response.status) id_ = response.json['access_control_role']['id'] role = AccessControlRole.query.filter(AccessControlRole.id == id_).first() assert role.read == 1, \ "Read permission not correctly saved {}".format(role.read) assert role.update == 1, \ "Update permission not correctly saved {}".format(role.update) assert role.delete == 1, \ "Update permission not correctly saved {}".format(role.delete) @ddt.data( {"mandatory": True, "exp_response": MANDATORY_ROLE_RESPONSE}, {"mandatory": False, "exp_response": NON_MANDATORY_ROLE_RESPONSE}, ) @ddt.unpack def test_mandatory_delete(self, mandatory, exp_response): """Test set empty field via import if acr mandatory is {mandatory}""" role = factories.AccessControlRoleFactory( name=ROLE_NAME, object_type="Risk", mandatory=mandatory, ) with factories.single_commit(): user = factories.PersonFactory() risk = factories.RiskFactory() role_id = role.id factories.AccessControlPersonFactory( ac_list=risk.acr_name_acl_map[ROLE_NAME], person=user, ) response = self.import_data(OrderedDict([ ("object_type", "Risk"), ("Code*", risk.slug), (ROLE_NAME, "--"), ])) self._check_csv_response(response, exp_response) db_data = defaultdict(set) risk = all_models.Risk.query.get(risk.id) for person, acl in risk.access_control_list: db_data[acl.ac_role_id].add(person.id) if mandatory: cur_user = all_models.Person.query.filter_by( email="*****@*****.**").first() self.assertEqual(set([cur_user.id]), db_data[role_id]) else: self.assertFalse(db_data[role_id]) def test_only_admin_can_post(self): """Only admin users should be able to POST access control roles""" for name in ("Creator", "Reader", "Editor"): person = self.people.get(name) self.api.set_user(person) response = self._post_role() assert response.status_code == 403, \ "Non admins should get forbidden error when POSTing role. {}".format( response.status) @ddt.data( ("name", "New ACR"), ("read", False), ("mandatory", False), ("non_editable", False), ) @ddt.unpack def test_modify_non_editable_role(self, field_name, field_value): """Test if user can modify non-editable role""" # Primary Contacts role of Control is non-editable ac_role = AccessControlRole.query.filter_by( object_type="Control", name="Control Operators", ).first() response = self.api.put(ac_role, {field_name: field_value}) assert response.status_code == 403, \ "Forbidden error should be thrown when non-editable " \ "role {} updated.".format(ac_role.name) def test_delete_non_editable_role(self): """Test if user can delete non-editable role""" # Primary Contacts role of Control is non-editable ac_role = AccessControlRole.query.filter_by( object_type="Control", name="Control Operators", ).first() response = self.api.delete(ac_role) assert response.status_code == 403, \ "Forbidden error should be thrown when non-editable " \ "role {} deleted.".format(ac_role.name) @ddt.data("Control") def test_create_from_ggrcq(self, object_type): """Test that create action only for GGRCQ.""" with self.api.as_external(): response = self._post_role(object_type=object_type) self.assertEqual(response.status_code, 201) @ddt.data("Control") def test_create_from_ggrc(self, object_type): """Test create action not allowed for GGRC.""" response = self._post_role(object_type=object_type) self.assertEqual(response.status_code, 405) @ddt.data("Control") def test_modify_from_ggrcq(self, object_type): """Test that modify action only for GGRCQ.""" with factories.single_commit(): acr_id = factories.AccessControlRoleFactory(object_type=object_type).id with self.api.as_external(): acr = all_models.AccessControlRole.query.get(acr_id) response = self.api.put(acr, {"name": "new acr"}) self.assertEqual(response.status_code, 200) @ddt.data("Control") def test_modify_from_ggrc(self, object_type): """Test modify action not allowed for GGRC.""" with factories.single_commit(): acr = factories.AccessControlRoleFactory(object_type=object_type) response = self.api.put(acr, {"name": "new acr"}) self.assertEqual(response.status_code, 405) @ddt.data("Control") def test_delete_from_ggrcq(self, object_type): """Test that modify action only for GGRCQ.""" with factories.single_commit(): acr_id = factories.AccessControlRoleFactory(object_type=object_type).id with self.api.as_external(): acr = all_models.AccessControlRole.query.get(acr_id) response = self.api.delete(acr) self.assertEqual(response.status_code, 200) @ddt.data("Control") def test_delete_from_ggrc(self, object_type): """Test modify action not allowed for GGRC.""" with factories.single_commit(): acr = factories.AccessControlRoleFactory(object_type=object_type) response = self.api.delete(acr) self.assertEqual(response.status_code, 405)
class TestAccessControlList(TestCase): """TestAccessControlList""" @classmethod def setUpClass(cls): """Sets objects common for all tests in TestCase.""" super(TestAccessControlList, cls).setUpClass() cls.api = Api() def setUp(self): super(TestAccessControlList, self).setUp() self.api = Api() self.person = factories.PersonFactory(name="My Person") self.acr = factories.AccessControlRoleFactory(object_type="Control", read=True) self.second_acr = factories.AccessControlRoleFactory( object_type="Control", read=True) self.control = factories.ControlFactory() factories.AccessControlPersonFactory( ac_list=self.control.acr_acl_map[self.acr], person=self.person, ) def _acl_asserts(self, acl, acr_id, person_id): """Run asserts on a given acl list""" self.assertEqual( len(acl), 1, "Access control list did not get saved {}".format(acl)) self.assertTrue(acl[0]["id"] > 0, "Acces control list did not set an id") self.assertEqual( acl[0]["ac_role_id"], acr_id, "Access control list does not include the saved role id") self.assertEqual( acl[0]["person_id"], person_id, "Access control list does not include person id {}".format(acl[0])) def _post_control(self, acr_id, person_id, assertion, collection=False): """Helper function for posting a control""" title = factories.random_str(prefix="Control - ") control = { "control": { "title": title, "type": "Control", "context": None, "access_control_list": [acl_helper.get_acl_json(acr_id, person_id)], "assertions": '["{}"]'.format(assertion), "external_id": factories.SynchronizableExternalId.next(), "external_slug": factories.random_str(), "review_status": all_models.Review.STATES.UNREVIEWED, "review_status_display_name": "some status", }, } with self.api.as_external(): response = self.api.post(all_models.Control, [control] if collection else control) self.assertTrue( response.status_code == 200 or response.status_code == 201, "Control not created successfully {}".format(response.status)) if collection: return response.json[0][1] return response.json def test_object_roles(self): """Test if roles are fetched with the object""" acr_id, person_id = self.acr.id, self.person.id response = self.api.get(all_models.Control, self.control.id) self.assert200( response, "Failed to fetch created control {}".format(response.status)) self.assertIn( "access_control_list", response.json["control"], "Access Control List not present in {}".format( response.json["control"].keys())) acl = response.json["control"]["access_control_list"] self._acl_asserts(acl, acr_id, person_id) def test_post_object_roles(self): """Test if roles are stored correctly when POSTed with the object""" acr_id, person_id = self.acr.id, self.person.id response = self._post_control(acr_id, person_id, "test assertion") acl = response["control"]["access_control_list"] self._acl_asserts(acl, acr_id, person_id) def test_acl_revision_content(self): """Test if the access control list is added to revisions""" acr_id, person_id = self.acr.id, self.person.id response = self._post_control(acr_id, person_id, "test assertion") control_id = response["control"]["id"] rev = all_models.Revision.query.filter( all_models.Revision.resource_id == control_id, all_models.Revision.resource_type == "Control").first() acl = rev.content["access_control_list"] self._acl_asserts(acl, acr_id, person_id) def test_put_object_roles(self): """Test if PUTing object roles saves them correctly""" second_acr_id, person_id = self.second_acr.id, self.person.id response = self.api.get(all_models.Control, self.control.id) self.assert200( response, "Failed to fetch created control {}".format(response.status)) control = response.json['control'] control['access_control_list'].append( acl_helper.get_acl_json(second_acr_id, person_id)) with self.api.as_external(): response = self.api.put(self.control, {"control": control}) self.assert200(response, "PUTing control failed {}".format(response.status)) acl = response.json['control']['access_control_list'] self.assertEqual(len(acl), 2, "Access control list not updated {}".format(acl)) def test_put_removing_roles(self): """Test if PUTing an empty list removes object roles correct""" response = self.api.get(all_models.Control, self.control.id) self.assert200( response, "Failed to fetch created control {}".format(response.status)) control = response.json['control'] control['access_control_list'] = [] with self.api.as_external(): response = self.api.put(self.control, {"control": control}) self.assert200(response, "PUTing control failed {}".format(response.status)) acl = response.json['control']['access_control_list'] self.assertEqual(len(acl), 0, "Access control list not empty {}".format(acl)) def test_acl_indexing_on_post(self): """Test if roles are stored correctly when POSTed with the object""" acr_id, person_id = self.acr.id, self.person.id response = self._post_control(acr_id, person_id, "test assertion") control = response["control"] res = mysql.MysqlRecordProperty.query.filter( mysql.MysqlRecordProperty.type == "Control", mysql.MysqlRecordProperty.key == control["id"], mysql.MysqlRecordProperty.property == self.acr.name).all() self.assertTrue( len(res) > 0, "Full text record index not created for {}".format(self.acr.name)) # email is presented in __sort__ subproperty as well self.assertEqual( len([r for r in res if r.content == self.person.email]), 2, "Person email not indexed {}".format(self.person.email)) self.assertEqual( len([r for r in res if r.content == self.person.name]), 1, "Person name not indexed {}".format(self.person.name)) def test_acl_revision_count(self): """Test if acl revision is created when object POSTed and PUTed""" acr_id, person_id = self.acr.id, self.person.id response = self._post_control(acr_id, person_id, "test assertion") # One ACL and Control created in setUp and on by POST self.assertEqual( all_models.Revision.query.filter_by( resource_type="AccessControlPerson").count(), 3) self.assertEqual( all_models.Revision.query.filter_by( resource_type="Control").count(), 2) # If content of "access_control_list" is changed, # new revision should be created for ACL control = response["control"] control["access_control_list"] = [] with self.api.as_external(): self.api.put(all_models.Control.query.get(control["id"]), {"control": control}) self.assertEqual( all_models.Revision.query.filter_by( resource_type="AccessControlPerson").count(), 4) self.assertEqual( all_models.Revision.query.filter_by( resource_type="Control").count(), 3)