def __init__(self, *args, **kwargs): for ac_role in role.get_ac_roles_for(self.type).values(): AccessControlList( object=self, ac_role=ac_role, ) super(Roleable, self).__init__(*args, **kwargs)
def apply_acl(instance, content): """Apply ACLs.""" any_acl_applied = False if not isinstance(instance, roleable.Roleable): return any_acl_applied instance_acl_dict = {(l.ac_role_id, p.id): l for p, l in instance.access_control_list} person_ids = set() for role_id, data in content.get("access_control_list", {}).iteritems(): person_ids |= {i["id"] for i in data["added"] + data["deleted"]} person_dict = { p.id: p for p in all_models.Person.query.filter( all_models.Person.id.in_(person_ids)) } acr_dict = {r.id: r for r in ACR.get_ac_roles_for(instance.type).values()} for role_id, data in content.get("access_control_list", {}).iteritems(): role_id = int(role_id) if role_id not in acr_dict: continue for add in data["added"]: if (role_id, add["id"]) not in instance_acl_dict: instance.add_person_with_role_id(person_dict[add["id"]], role_id) any_acl_applied = True for delete in data["deleted"]: if (role_id, delete["id"]) in instance_acl_dict: instance.acr_id_acl_map[role_id].remove_person( person_dict[delete["id"]]) any_acl_applied = True return any_acl_applied
def apply_acl(instance, content): """Apply ACLs.""" any_acl_applied = False if not isinstance(instance, roleable.Roleable): return any_acl_applied instance_acl_dict = {(l.ac_role_id, l.person_id): l for l in instance.access_control_list} person_ids = set() for role_id, data in content.get("access_control_list", {}).iteritems(): person_ids |= {i["id"] for i in data["added"] + data["deleted"]} person_dict = { p.id: p for p in all_models.Person.query.filter( all_models.Person.id.in_(person_ids)) } acr_dict = {r.id: r for r in ACR.get_ac_roles_for(instance.type).values()} for role_id, data in content.get("access_control_list", {}).iteritems(): role_id = int(role_id) if role_id not in acr_dict: continue for add in data["added"]: if (role_id, add["id"]) not in instance_acl_dict: # add ACL if it hasn't added yet all_models.AccessControlList( person=person_dict[add["id"]], ac_role=acr_dict[int(role_id)], object=instance, ) any_acl_applied = True for delete in data["deleted"]: if (role_id, delete["id"]) in instance_acl_dict: acl = instance_acl_dict[(role_id, delete["id"])] instance.access_control_list.remove(acl) any_acl_applied = True return any_acl_applied
def test_permission_check(self): """Test generation if user has rights on part of objects.""" _, assessment_ids = self.setup_assessments(3) with_rights_ids = assessment_ids[:2] without_rights_ids = assessment_ids[2:] _, assignee_user = self.gen.generate_person(user_role="Creator") with factories.single_commit(): for id_ in with_rights_ids: factories.AccessControlListFactory( object_id=id_, object_type="Assessment", ac_role_id=role.get_ac_roles_for("Assessment") ["Creators"].id, person_id=assignee_user.id, ) self.api.set_user(assignee_user) asmnt_issuetracker_info = [("Assessment", id_, "123", "321") for id_ in assessment_ids] response = self.generate_issues_for(asmnt_issuetracker_info) self.assert200(response) forbidden_err = "403 Forbidden: You don't have the permission to access " \ "the requested resource. It is either read-protected or " \ "not readable by the server." expected_errors = [["Assessment", id_, forbidden_err] for id_ in without_rights_ids] self.assertEqual(response.json.get("errors"), expected_errors) with_rights_info = [("Assessment", id_, "123", "321") for id_ in with_rights_ids] self.assert_obj_issues(with_rights_info, "*****@*****.**") self.assert_not_updated("Assessment", without_rights_ids)
def __init__(self, *args, **kwargs): for ac_role in role.get_ac_roles_for(self.type).values(): AccessControlList( object=self, ac_role=ac_role, ) super(Roleable, self).__init__(*args, **kwargs)
def test_partially_rights(self): """Test generation if user has rights on part of Assessments.""" audit_id, assessment_ids = self.setup_assessments(3) changed_asmnt_id = assessment_ids[0] norights_asmnt_ids = assessment_ids[1:] _, assignee_user = self.gen.generate_person(user_role="Creator") with factories.single_commit(): factories.AccessControlListFactory( object_id=changed_asmnt_id, object_type="Assessment", ac_role_id=role.get_ac_roles_for("Assessment")["Creators"].id, person_id=assignee_user.id, ) audit_role = factories.AccessControlRoleFactory( name="Edit Role", object_type="Audit", update=True) factories.AccessControlListFactory( object_id=audit_id, object_type="Audit", ac_role_id=audit_role.id, person_id=assignee_user.id, ) self.api.set_user(assignee_user) response = self.generate_children_issues_for("Audit", audit_id, "Assessment") self.assert200(response) self.assert_children_asmnt_issues([changed_asmnt_id]) self.assert_not_updated("Assessment", norights_asmnt_ids)
def apply_acl(instance, content): """Apply ACLs.""" any_acl_applied = False if not isinstance(instance, roleable.Roleable): return any_acl_applied instance_acl_dict = {(l.ac_role_id, p.id): l for p, l in instance.access_control_list} person_ids = set() for role_id, data in content.get("access_control_list", {}).iteritems(): person_ids |= {i["id"] for i in data["added"] + data["deleted"]} person_dict = {p.id: p for p in all_models.Person.query.filter( all_models.Person.id.in_(person_ids)) } acr_dict = {r.id: r for r in ACR.get_ac_roles_for(instance.type).values()} for role_id, data in content.get("access_control_list", {}).iteritems(): role_id = int(role_id) if role_id not in acr_dict: continue for add in data["added"]: if (role_id, add["id"]) not in instance_acl_dict: instance.add_person_with_role_id(person_dict[add["id"]], role_id) any_acl_applied = True for delete in data["deleted"]: if (role_id, delete["id"]) in instance_acl_dict: instance.acr_id_acl_map[role_id].remove_person( person_dict[delete["id"]] ) any_acl_applied = True return any_acl_applied
def setup_assessments(self, asmnt_count, issue_id=None, enabled=True): """Create Audit with couple of Assessments and linked IssueTrackerIssues. Args: asmnt_count: Count of Assessments in Audit. Returns: Tuple with Audit id and list of Assessment ids. """ with factories.single_commit(): audit = factories.AuditFactory() factories.AccessControlListFactory( object=audit, ac_role=role.get_ac_roles_for(audit.type)["Audit Captains"], person=self.role_people["Audit Captains"], ) factories.IssueTrackerIssueFactory( enabled=enabled, issue_tracked_obj=audit, issue_id=issue_id, issue_type="BUG", component_id=12345, hotlist_id=12345, issue_priority="P2", issue_severity="S2", ) assessment_ids = [] for _ in range(asmnt_count): asmnt = factories.AssessmentFactory(audit=audit) factories.RelationshipFactory(source=audit, destination=asmnt) for role_name in ["Creators", "Assignees", "Verifiers"]: factories.AccessControlListFactory( object=asmnt, ac_role=role.get_ac_roles_for(asmnt.type)[role_name], person=self.role_people[role_name], ) factories.IssueTrackerIssueFactory( enabled=enabled, issue_tracked_obj=asmnt, issue_id=issue_id, title=None, ) assessment_ids.append(asmnt.id) return audit.id, assessment_ids
def _setup_wf_person(self, g_rname, wf_rname, workflow): """Generate Person with Global + Workflow Scope role. Args: g_rname: Global Role name. wf_rname: Workflow Access Control Role name. workflow: Workflow instance, in which scope person should have role. """ wf_person = self.setup_person(g_rname, wf_rname) wf_acr = role.get_ac_roles_for(all_models.Workflow.__name__)[wf_rname] factories.AccessControlListFactory(ac_role=wf_acr, object=workflow, person=wf_person)
def test_issue_bulk_generate(self): """Test bulk update of issues for Issues.""" issue_ids = [] with factories.single_commit(): for _ in range(3): issue = factories.IssueFactory() factories.IssueTrackerIssueFactory( enabled=True, issue_tracked_obj=issue, issue_id=self.issue_id, component_id=12345, hotlist_id=54321, issue_priority="P2", issue_severity="S2", ) issue_ids.append(issue.id) with factories.single_commit(): person = factories.PersonFactory() person_email = person.email for issue in all_models.Issue.query.all(): issue.modified_by = person for role_name in ["Admin", "Primary Contacts"]: factories.AccessControlListFactory( object=issue, ac_role=role.get_ac_roles_for(issue.type)[role_name], person=person, ) # Verify that IssueTracker issues hasn't updated data issues = all_models.IssuetrackerIssue.query.filter( all_models.IssuetrackerIssue.object_type == "Issue", all_models.IssuetrackerIssue.object_id.in_(issue_ids)).all() for issue in issues: parent_obj = issue.Issue_issue_tracked self.assertNotEqual(issue.title, parent_obj.title) self.assertEqual(issue.assignee, None) issue_issuetracker_info = [("Issue", id_, None, None) for id_ in issue_ids] response = self.update_issues_for(issue_issuetracker_info) self.assert200(response) self.assertEqual(response.json.get("errors"), []) # IssueTracker issues should be updated with proper values issues = all_models.IssuetrackerIssue.query.filter( all_models.IssuetrackerIssue.object_type == "Issue", all_models.IssuetrackerIssue.object_id.in_(issue_ids)).all() for issue in issues: parent_obj = issue.Issue_issue_tracked self.assertEqual(issue.title, parent_obj.title) self.assertEqual(issue.assignee, person_email) self.assertEqual(issue.cc_list, "")
def _get_acl_subdict(acr_name, person, model): """Generate ACL sub-dict representation for using inside JSON. Args: acr_name: Access Control Role name. person: Person instance, who should get `acr_name` in scope of `model`. model: Model, in which scope ACR should be assigned to `person`. Returns: ACL entry sub-dict representation. It is used for inserting into object JSON representation under 'access_control_list' key. """ acr = role.get_ac_roles_for(model.__name__)[acr_name] return {"ac_role_id": acr.id, "person": _get_object_subdict(person)}
def _setup_wf_person(self, g_rname, wf_rname, workflow): """Generate Person with Global + Workflow Scope role. Args: g_rname: Global Role name. wf_rname: Workflow Access Control Role name. workflow: Workflow instance, in which scope person should have role. """ wf_person = self.setup_person(g_rname, wf_rname) wf_acr = role.get_ac_roles_for(all_models.Workflow.__name__)[wf_rname] factories.AccessControlListFactory(ac_role=wf_acr, object=workflow, person=wf_person)
def _add_task_acl(task): """Add ACL entry for the current users background task.""" roles = role.get_ac_roles_for(task.type) admin_role = roles.get("Admin", None) if admin_role: acl.AccessControlList( person=get_current_user(), ac_role=admin_role, object=task, ) db.session.add(task) db.session.commit() if admin_role: from ggrc.cache.utils import clear_users_permission_cache clear_users_permission_cache([get_current_user().id])
def _add_task_acl(task): """Add ACL entry for the current users background task.""" roles = role.get_ac_roles_for(task.type) admin_role = roles.get("Admin", None) if admin_role: acl.AccessControlList( person=get_current_user(), ac_role=admin_role, object=task, ) db.session.add(task) db.session.commit() if admin_role: from ggrc.cache.utils import clear_users_permission_cache clear_users_permission_cache([get_current_user().id])
def test_issue_bulk_generate(self): """Test bulk generation of issuetracker issues for Issue.""" issue_ids = [] with factories.single_commit(): person = factories.PersonFactory() person_email = person.email for _ in range(3): issue = factories.IssueFactory(modified_by=person) for role_name in ["Admin", "Primary Contacts"]: factories.AccessControlListFactory( object=issue, ac_role=role.get_ac_roles_for(issue.type)[role_name], person=person, ) factories.IssueTrackerIssueFactory( enabled=True, issue_tracked_obj=issue, issue_id=None, component_id=12345, hotlist_id=54321, issue_priority="P2", issue_severity="S2", ) issue_ids.append(issue.id) issue_issuetracker_info = [("Issue", id_, None, None) for id_ in issue_ids] response = self.generate_issues_for(issue_issuetracker_info) self.assert200(response) self.assertEqual(response.json.get("errors"), []) issues = all_models.IssuetrackerIssue.query.filter( all_models.IssuetrackerIssue.object_type == "Issue", all_models.IssuetrackerIssue.object_id.in_(issue_ids)).all() for issue in issues: parent_obj = issue.Issue_issue_tracked self.assertEqual(issue.enabled, 1) self.assertEqual(issue.title, parent_obj.title) self.assertEqual(issue.component_id, "12345") self.assertEqual(issue.hotlist_id, "54321") self.assertEqual(issue.issue_priority, "P2") self.assertEqual(issue.issue_severity, "S2") self.assertEqual(issue.assignee, person_email) self.assertEqual(issue.cc_list, "") self.assertEqual(issue.issue_id, self.issue_id) self.assertEqual(issue.issue_url, "http://issue/{}".format(self.issue_id))
def _get_acl_subdict(acr_name, person, model): """Generate ACL sub-dict representation for using inside JSON. Args: acr_name: Access Control Role name. person: Person instance, who should get `acr_name` in scope of `model`. model: Model, in which scope ACR should be assigned to `person`. Returns: ACL entry sub-dict representation. It is used for inserting into object JSON representation under 'access_control_list' key. """ acr = role.get_ac_roles_for(model.__name__)[acr_name] return { "ac_role_id": acr.id, "person": utils.create_stub(person) }
def handle_comment_post(mapper, objects, **kwargs): """Save information on which user created the Comment object. Comments have their users set in a hook, because we must ensure that it is always set to the current user, and that is why the info is not sent from the front-end through access_control_list property. """ # pylint: disable=unused-argument comment_roles = role.get_ac_roles_for(all_models.Comment.__name__) comment_admin = comment_roles["Admin"] user = login.get_current_user() for comment in objects: all_models.AccessControlList( ac_role=comment_admin, person=user, object=comment, )
def handle_comment_post(mapper, objects, **kwargs): """Save information on which user created the Comment object. Comments have their users set in a hook, because we must ensure that it is always set to the current user, and that is why the info is not sent from the front-end through access_control_list property. """ # pylint: disable=unused-argument comment_roles = role.get_ac_roles_for(all_models.Comment.__name__) comment_admin = comment_roles["Admin"] user = login.get_current_user() for comment in objects: all_models.AccessControlList( ac_role=comment_admin, person=user, object=comment, )
def acrs(self): """Return ACRs for sent instance.""" if not isinstance(self.instance, roleable.Roleable): return set() return set(ACR.get_ac_roles_for(self.instance.type).values())
def acrs(self): """Return ACRs for sent instance.""" if not isinstance(self.instance, roleable.Roleable): return set() return set(ACR.get_ac_roles_for(self.instance.type).values())
def test_async_request_state_transitions(self): """Test asynchronous transitions""" # Due to complexity of the test and the actual need for all variables # pylint: disable=too-many-locals tgt_roles = role.get_ac_roles_for("TaskGroupTask") queue = Queue.Queue() wf = self.generator.generate_workflow(self.weekly_wf)[1] context_id = wf.context.id tg_id = all_models.TaskGroup.query.first().id obj_count = 10 # actual thread count is 20, 10 tgt + 10 tgo with factories.single_commit(): person_id = factories.PersonFactory().id controls = [ factories.ControlFactory().id for _ in range(obj_count) ] def create_tgo(context_id, tg_id, control_id): queue.put( self.api.post(all_models.TaskGroupObject, [{ "task_group_object": { "context": { "id": context_id, "type": "Context" }, "task_group": { "id": tg_id, "type": "TaskGroup" }, "object": { "id": control_id, "type": "Control" }, }, }])) def create_tgt(context_id, tg_id, tgt_roles, person_id): queue.put( self.api.post(all_models.TaskGroupTask, [{ "task_group_task": { "response_options": [], "start_date": "2018-03-29", "end_date": "2018-04-05T00:23:41.000Z", "minStartDate": "2018-03-29T00:23:41.576Z", "access_control_list": [{ "ac_role_id": tgt_roles["Task Assignees"].id, "person": { "id": person_id, "type": "Person" } }], "contact": { "id": person_id, "type": "Person" }, "task_group": { "id": tg_id, "type": "TaskGroup" }, "context": { "id": context_id, "type": "Context" }, "sort_index": "1", "modal_title": "Create New Task", "title": "Dummy task title", "task_type": "text", "description": "", "slug": "", } }])) # Move all tasks to In Progress threads = [] for control_id in controls: threads.append( Thread(target=create_tgo, args=(context_id, tg_id, control_id))) threads.append( Thread(target=create_tgt, args=(context_id, tg_id, tgt_roles, person_id))) for t in threads: t.start() for t in threads: t.join() while not queue.empty(): response = queue.get() self.assert200(response, response.data) internal_acl_count = all_models.AccessControlList.query.filter( all_models.AccessControlList.parent_id.isnot(None)).count() self.assertEqual( internal_acl_count, (1 + 2 * obj_count) * 2, # wf role on 1 task group + number of tgo and tgt # times 2 is for all relationships that belong to each object )