コード例 #1
0
def create_related_roles(context):
    """Create related roles for Workflow related objects.

  Args:
      context: dictionary with information for ACL propagation.
  """
    if not context:
        return

    for related in context.values():
        for rel_model, rel_acl_map in related.iteritems():
            for rel_id, acl_set in rel_acl_map.iteritems():
                for p_acl in acl_set:
                    rel_person_id = p_acl.person.id if p_acl.person else p_acl.person_id
                    custom_roles = get_custom_roles_for(p_acl.object_type)
                    parent_acr_id = (p_acl.ac_role.id
                                     if p_acl.ac_role else p_acl.ac_role_id)
                    parent_acr_name = custom_roles[parent_acr_id]
                    rel_acr_name = "{} Mapped".format(parent_acr_name)
                    rel_acr_id = next(ind for ind in custom_roles
                                      if custom_roles[ind] == rel_acr_name)
                    db.session.add(
                        all_models.AccessControlList(
                            person_id=rel_person_id,
                            ac_role_id=rel_acr_id,
                            object_type=rel_model.__name__,
                            object_id=rel_id,
                            parent=p_acl,
                            modified_by_id=login.get_current_user_id(),
                        ))
コード例 #2
0
def generate_assignee_relations(assessment, assignee_ids, verifier_ids,
                                creator_ids):
    """Generates db relations to assessment for sent role ids.

    Args:
        assessment (model instance): Assessment model
        assignee_ids (list): list of person ids
        verifier_ids (list): list of person ids
        creator_ids (list): list of person ids
  """
    people = set(assignee_ids + verifier_ids + creator_ids)
    person_dict = {
        i.id: i
        for i in all_models.Person.query.filter(
            all_models.Person.id.in_(people))
    }

    person_roles = []
    for person_id in people:
        person = person_dict.get(person_id)
        if person is None:
            continue
        if person_id in assignee_ids:
            person_roles.append((person, "Assignees"))
        if person_id in verifier_ids:
            person_roles.append((person, "Verifiers"))
        if person_id in creator_ids:
            person_roles.append((person, "Creators"))

    ac_roles = access_control.role.get_ac_roles_for(assessment.type)

    db.session.add_all(
        all_models.AccessControlList(
            ac_role=ac_roles[role], person=person, object=assessment)
        for person, role in person_roles)
コード例 #3
0
ファイル: applier.py プロジェクト: sepatus88/ggrc-core
def apply_acl_proposal(instance, content):
    if not isinstance(instance, roleable.Roleable):
        return
    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 = {
        i.id: i
        for i in all_models.AccessControlRole.query.filter(
            all_models.AccessControlRole.object_type == instance.type)
    }
    for role_id, data in content.get("access_control_list", {}).iteritems():
        role_id = int(role_id)
        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,
                )
        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)
コード例 #4
0
ファイル: applier.py プロジェクト: zhaoshiling1017/ggrc-core
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
コード例 #5
0
def create_missed_issue_acl(email, role_name, obj):
    """Create missed acl for emails from IssueTracker"""
    person = all_models.Person.query.filter_by(email=email).first()
    acr = all_models.AccessControlRole.query.filter_by(
        name=role_name,
        object_type=all_models.Issue.__name__,
    ).first()
    all_models.AccessControlList(
        person_id=person.id,
        ac_role_id=acr.id,
        object=obj,
    )
コード例 #6
0
ファイル: audit_roles.py プロジェクト: vincent9407/ggrc-core
 def add(self, obj, parent, person, role_id):
     """Add new item if it wasn't already added"""
     key = (obj.id, obj.type, person.id, role_id, parent.id)
     if key in self.cache:
         return
     self.cache.add(key)
     acl = all_models.AccessControlList(object_id=obj.id,
                                        object_type=obj.type,
                                        parent=parent,
                                        person=person,
                                        ac_role_id=role_id)
     if hasattr(obj, "access_control_list"):
         obj.access_control_list.append(acl)
コード例 #7
0
 def get_or_create(self, obj, parent, person, role_id):
     """Add new item if it wasn't already added"""
     key = (obj.id, obj.type, person.id, role_id, parent.id)
     if key in self.object_queue:
         return self.object_queue[key]
     acl = all_models.AccessControlList(object_id=obj.id,
                                        object_type=obj.type,
                                        parent=parent,
                                        person=person,
                                        ac_role_id=role_id)
     self.object_queue[key] = acl
     if hasattr(obj, "access_control_list"):
         obj.access_control_list.append(acl)
     return acl
コード例 #8
0
 def ensure_assignee_is_workflow_member(self):  # pylint: disable=invalid-name
   """Add Workflow Member role to user without role in scope of Workflow."""
   people_with_role_ids = (
       self.workflow.get_person_ids_for_rolename("Admin") +
       self.workflow.get_person_ids_for_rolename("Workflow Member"))
   if self.contact.id in people_with_role_ids:
     return
   wf_member_role_id = next(
       ind for ind, name in role.get_custom_roles_for("Workflow").iteritems()
       if name == "Workflow Member")
   all_models.AccessControlList(
       person=self.contact,
       ac_role_id=wf_member_role_id,
       object=self.workflow,
       modified_by=get_current_user(),
   )
コード例 #9
0
ファイル: comment.py プロジェクト: zhaoshiling1017/ggrc-core
    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,
            )
コード例 #10
0
ファイル: factories.py プロジェクト: pavelglebov/ggrc-core
    def _create(cls, target_class, *args, **kwargs):
        """Create instance of model"""
        acls = kwargs.pop("access_control_list_", [])
        cavs = kwargs.pop("custom_attribute_values_", [])

        instance = target_class(**kwargs)
        db.session.add(instance)
        db.session.flush()

        if acls and isinstance(instance, roleable.Roleable):
            for acl in acls:
                db.session.add(
                    all_models.AccessControlList(
                        object=instance,
                        ac_role_id=acl.get("ac_role_id"),
                        person_id=acl.get("person_id"),
                    ))
        for cav in cavs:
            if isinstance(instance, all_models.mixins.CustomAttributable):
                db.session.add(
                    all_models.CustomAttributeValue(
                        attributable=instance,
                        attribute_value=cav.get("attribute_value"),
                        attribute_object_id=cav.get("attribute_object_id"),
                        custom_attribute_id=cav.get("custom_attribute_id"),
                    ))
            elif isinstance(instance,
                            all_models.mixins.ExternalCustomAttributable):
                db.session.add(
                    all_models.ExternalCustomAttributeValue(
                        attributable=instance,
                        attribute_value=cav.get("attribute_value"),
                        custom_attribute_id=cav.get("custom_attribute_id"),
                    ))

        if isinstance(instance, (all_models.CustomAttributeValue,
                                 all_models.ExternalCustomAttributeValue)):
            cls._log_event(instance.attributable)
        if hasattr(instance, "log_json"):
            cls._log_event(instance)
        if getattr(db.session, "single_commit", True):
            db.session.commit()
        return instance
コード例 #11
0
def handle_role_acls(role):
  """Handle creation of ACL entries for the given role.

  This function takes care of eager acl creation when a new role is created.
  Because this is called after the commit on the role, we can not have new
  role creation and people assignment to that role in the same request.
  """
  with utils.benchmark(u"Generating ACL entries on {} for role {}".format(
          role.object_type, role.name)):
    query = _get_missing_models_query(role)
    if not query:
      return

    while query.count():
      for roleable_obj in query.limit(1000):
        db.session.add(all_models.AccessControlList(
            ac_role=role,
            object=roleable_obj,
        ))
      db.session.commit()
コード例 #12
0
ファイル: relationship.py プロジェクト: jkowalskic/ggrc-core
def create_related_roles(base_objects, related_objects):
    """Create mapped roles for related objects

  Args:
    base_objects(defaultdict(dict)): Objects which have Assignee role
    related_objects(defaultdict(set)): Objects related to assigned
  """
    if not base_objects or not related_objects:
        return

    acl_row = namedtuple(
        "acl_row", "person_id object_id object_type ac_role_id parent_id")
    acl_parent = namedtuple("acl_parent", "context parent")
    acl_data = {}
    for base_stub, related_stubs in related_objects.items():
        for related_stub in related_stubs:
            for acl in base_objects[base_stub]:
                acr_id = acl.ac_role.id if acl.ac_role else acl.ac_role_id
                mapped_acr_id = get_mapped_role(
                    base_stub.type,
                    get_custom_roles_for(base_stub.type)[acr_id],
                    related_stub.type)
                if not mapped_acr_id:
                    raise Exception("Mapped role wasn't found for role with "
                                    "id: {}".format(acl.ac_role_id))
                acl_data[acl_row(
                    acl.person_id or acl.person.id,
                    related_stub.id,
                    related_stub.type,
                    mapped_acr_id,
                    acl.id,
                )] = acl_parent(acl.context, acl)

    # Find existing acl instances in db
    existing_acls = set(
        db.session.query(
            all_models.AccessControlList.person_id,
            all_models.AccessControlList.object_id,
            all_models.AccessControlList.object_type,
            all_models.AccessControlList.ac_role_id,
            all_models.AccessControlList.parent_id,
        ).filter(
            sa.tuple_(
                all_models.AccessControlList.person_id,
                all_models.AccessControlList.object_id,
                all_models.AccessControlList.object_type,
                all_models.AccessControlList.ac_role_id,
                all_models.AccessControlList.parent_id,
            ).in_(acl_data.keys())).all())
    # Find existing acl instances in session
    session_acls = {(
        a.person_id,
        a.object_id,
        a.object_type,
        a.ac_role_id,
        a.parent.id if a.parent else a.parent_id,
    ): (a.person_id, a.object_id, a.object_type, a.ac_role_id, a.parent)
                    for a in db.session.new
                    if isinstance(a, all_models.AccessControlList)}
    existing_acls.update(session_acls.keys())

    current_user_id = login.get_current_user_id()
    # Create new acl instance only if it absent in db and session
    for acl in set(acl_data.keys()) - existing_acls:
        # In some cases parent_id will be None, but parent object is not empty.
        # that's why we should additionally compare parent objects
        if (acl.person_id, acl.object_id, acl.object_type, acl.ac_role_id,
                acl_data[acl].parent) not in session_acls.values():
            db.session.add(
                all_models.AccessControlList(
                    person_id=acl.person_id,
                    ac_role_id=acl.ac_role_id,
                    object_id=acl.object_id,
                    object_type=acl.object_type,
                    context=acl_data[acl].context,
                    modified_by_id=current_user_id,
                    parent=acl_data[acl].parent,
                ))