Пример #1
0
 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)
Пример #2
0
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
Пример #3
0
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
Пример #4
0
    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)
Пример #5
0
 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)
Пример #6
0
    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)
Пример #7
0
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
Пример #8
0
    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
Пример #9
0
  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)
Пример #10
0
    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, "")
Пример #11
0
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)}
Пример #12
0
    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)
Пример #13
0
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])
Пример #14
0
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])
Пример #15
0
    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))
Пример #16
0
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)
  }
Пример #17
0
  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,
      )
Пример #18
0
    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,
            )
Пример #19
0
 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())
Пример #20
0
 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())
Пример #21
0
    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
        )