Example #1
0
 def copy(self, _other=None, **kwargs):
     """Create a partial copy of the current workflow.
 """
     columns = [
         'title', 'description', 'notify_on_change',
         'notify_custom_message', 'end_date', 'start_date', 'repeat_every',
         'unit', 'is_verification_needed'
     ]
     if kwargs.get('clone_people', False):
         access_control_list = [{
             "ac_role_id": acl.ac_role.id,
             "person": {
                 "id": person.id
             }
         } for person, acl in self.access_control_list]
     else:
         role_id = {
             name: ind
             for (ind,
                  name) in role.get_custom_roles_for(self.type).iteritems()
         }['Admin']
         access_control_list = [{
             "ac_role_id": role_id,
             "person": {
                 "id": get_current_user().id
             }
         }]
     target = self.copy_into(_other,
                             columns,
                             access_control_list=access_control_list,
                             **kwargs)
     return target
 def test_old_comments(self):
     """Test if notifications will be sent for mix of old and new comments"""
     cur_user = all_models.Person.query.filter_by(
         email="*****@*****.**").first()
     assigee_role_id = {
         v: k
         for k, v in get_custom_roles_for("Assessment").items()
     }["Assignees"]
     with factories.single_commit():
         assessment = factories.AssessmentFactory()
         factories.AccessControlListFactory(ac_role_id=assigee_role_id,
                                            person=cur_user,
                                            object=assessment)
     with freeze_time("2015-04-01 17:13:10"):
         self.generator.generate_comment(assessment,
                                         "",
                                         "some comment1",
                                         send_notification="true")
     self.generator.generate_comment(assessment,
                                     "",
                                     "some comment2",
                                     send_notification="true")
     response = self.client.get("/_notifications/show_pending")
     for comment in ["some comment1", "some comment2"]:
         self.assertIn(
             comment, response.data,
             "Information about comment '{}' absent in report".format(
                 comment))
Example #3
0
    def generate_task_group_task(self, task_group=None, data=None):
        """Generate task group task over api."""
        if data is None:
            data = {}
        if not task_group:
            _, task_group = self.generate_task_group()
        task_group = self._session_add(task_group)

        default_start = self.random_date()
        default_end = self.random_date(default_start, date.today())
        obj_name = "task_group_task"
        cycle_task_role_id = {
            v: k
            for (k,
                 v) in role.get_custom_roles_for("TaskGroupTask").iteritems()
        }['Task Assignees']
        tgt = TaskGroupTask(
            task_group_id=task_group.id,
            context_id=task_group.context.id,
            title="tgt " + factories.random_str(),
            start_date=default_start,
            end_date=default_end,
        )
        obj_dict = self.obj_to_dict(tgt, obj_name)
        if "access_control_list" not in data:
            wf_admin_id = Person.query.first().id
            data["access_control_list"] = [
                acl_helper.get_acl_json(cycle_task_role_id, wf_admin_id)
            ]
        obj_dict[obj_name].update(data)
        return self.generate(TaskGroupTask, obj_name, obj_dict)
Example #4
0
def handle_relationship_creation(session, flush_context):
    """Create relations for mapped objects."""
    # pylint: disable=unused-argument
    base_objects = defaultdict(set)
    related_objects = defaultdict(set)
    snapshot_ids = {}
    for obj in session.new:
        if isinstance(obj, all_models.Relationship) and (
                issubclass(type(obj.source), Assignable)
                or issubclass(type(obj.destination), Assignable)):
            assign_obj, other = obj.source, obj.destination
            if not issubclass(type(obj.source), Assignable):
                assign_obj, other = other, assign_obj
            for acl in assign_obj.access_control_list:
                acr_id = acl.ac_role.id if acl.ac_role else acl.ac_role_id
                ac_role = get_custom_roles_for(acl.object_type).get(
                    acr_id, None)
                if ac_role in assign_obj.ASSIGNEE_TYPES:
                    assign_stub = Stub(assign_obj.type, assign_obj.id)
                    other_stub = Stub(other.type, other.id)
                    base_objects[assign_stub].add(acl)
                    related_objects[assign_stub].add(other_stub)

                    if other.type == "Snapshot":
                        snapshot_ids[other.id] = assign_stub

    if base_objects:
        if snapshot_ids:
            add_related_snapshots(snapshot_ids, related_objects)
        create_related_roles(base_objects, related_objects)
Example #5
0
  def test_assigned_task_delete(self, user_role, ac_role, can_delete):
    """ Test possibility to delete of assigned cycle task"""
    user = self.users[user_role]

    workflow_obj = self.activate_workflow_with_cycle(self.workflow_obj)[1]
    cycle_task = workflow_obj.cycles[0].cycle_task_group_object_tasks[0]

    role_map = {
        name: ind
        for (ind, name) in
        role.get_custom_roles_for(all_models.Workflow.__name__).iteritems()
    }
    put_params = {'access_control_list': [
        acl_helper.get_acl_json(role_map[ac_role], user.id),
        acl_helper.get_acl_json(role_map["Admin"], self.users["admin"].id),
    ]}
    response = self.api.put(workflow_obj, put_params)
    self.assert200(response)

    self.api.set_user(user)
    res = self.api.delete(cycle_task)

    if can_delete:
      self.assert200(res)
    else:
      self.assert403(res)
Example #6
0
    def test_assigned_task_delete(self, user_role, ac_role, can_delete):
        """ Test possibility to delete of assigned cycle task"""
        user = self.users[user_role]

        workflow_obj = self.activate_workflow_with_cycle(self.workflow_obj)[1]
        cycle_task = workflow_obj.cycles[0].cycle_task_group_object_tasks[0]

        role_map = {
            name: ind
            for (ind, name) in role.get_custom_roles_for(
                all_models.Workflow.__name__).iteritems()
        }
        put_params = {
            'access_control_list': [
                acl_helper.get_acl_json(role_map[ac_role], user.id),
                acl_helper.get_acl_json(role_map["Admin"],
                                        self.users["admin"].id),
            ]
        }
        response = self.api.put(workflow_obj, put_params)
        self.assert200(response)

        self.api.set_user(user)
        res = self.api.delete(cycle_task)

        if can_delete:
            self.assert200(res)
        else:
            self.assert403(res)
Example #7
0
  def copy(self, _other=None, **kwargs):
    columns = ['title',
               'description',
               'task_group',
               'start_date',
               'end_date',
               'access_control_list',
               'modified_by',
               'task_type',
               'response_options']

    if kwargs.get('clone_people', False):
      access_control_list = [
          {"ac_role_id": acl.ac_role_id, "person": {"id": person.id}}
          for person, acl in self.access_control_list
      ]
    else:
      role_id = {
          v: k for (k, v) in
          role.get_custom_roles_for(self.type).iteritems()
      }['Task Assignees']
      access_control_list = [
          {"ac_role_id": role_id, "person": {"id": get_current_user().id}}
      ]
    kwargs['modified_by'] = get_current_user()
    return self.copy_into(_other,
                          columns,
                          access_control_list=access_control_list,
                          **kwargs)
Example #8
0
  def create_assignees(cls, obj, persons):
    """Create assignees for object.

    This is used only during object creation because we cannot create
    assignees at that point yet.

    Args:
      obj: Assignable object.
      persons: [("(string) email", "Assignee roles"), ...] A list of people
        and their roles
    Returns:
      [(person, acr_role), ...] A list of persons with their roles.
    """
    from ggrc.access_control.role import get_custom_roles_for
    ac_roles = {
        acr_name: acr_id
        for acr_id, acr_name in get_custom_roles_for(obj.type).items()
    }
    assignees = []
    with factories.single_commit():
      for person, roles in persons:
        person = factories.PersonFactory(email=person)

        for role in roles.split(","):
          factories.AccessControlListFactory(
              person=person,
              ac_role_id=ac_roles[role],
              object=obj
          )
          assignees.append((person, role))
    return assignees
Example #9
0
  def generate_workflow(self, data=None):
    """ create a workflow with dict data
    return: wf if it was created, or response otherwise
    """
    if data is None:
      data = {}
    obj_name = "workflow"
    data = copy.deepcopy(data)

    tgs = data.pop("task_groups", [])

    wf_instance = Workflow(title="wf " + factories.random_str())
    obj_dict = self.obj_to_dict(wf_instance, obj_name)
    wf_admin_role_id = {
        n: i
        for (i, n) in role.get_custom_roles_for(Workflow.__name__).iteritems()
    }['Admin']
    if "access_control_list" not in data:
      wf_admin_id = Person.query.first().id
      data["access_control_list"] = [
          acl_helper.get_acl_json(wf_admin_role_id, wf_admin_id)]
    obj_dict[obj_name].update(data)

    response, workflow = self.generate(Workflow, obj_name, obj_dict)

    for task_group in tgs:
      self.generate_task_group(workflow, task_group)

    return response, workflow
Example #10
0
  def generate_task_group_task(self, task_group=None, data=None):
    """Generate task group task over api."""
    if data is None:
      data = {}
    if not task_group:
      _, task_group = self.generate_task_group()
    task_group = self._session_add(task_group)

    default_start = self.random_date()
    default_end = self.random_date(default_start, date.today())
    obj_name = "task_group_task"
    cycle_task_role_id = {
        v: k for (k, v) in
        role.get_custom_roles_for("TaskGroupTask").iteritems()
    }['Task Assignees']
    tgt = TaskGroupTask(
        task_group_id=task_group.id,
        context_id=task_group.context.id,
        title="tgt " + factories.random_str(),
        start_date=default_start,
        end_date=default_end,
    )
    obj_dict = self.obj_to_dict(tgt, obj_name)
    if "access_control_list" not in data:
      wf_admin_id = Person.query.first().id
      data["access_control_list"] = [
          acl_helper.get_acl_json(cycle_task_role_id, wf_admin_id)]
    obj_dict[obj_name].update(data)
    return self.generate(TaskGroupTask, obj_name, obj_dict)
Example #11
0
def get_wf_propagated_role_ids():
  """Getting propagated role ids."""
  wf_roles = role.get_custom_roles_for(all_models.Workflow.__name__)
  return {
      id_ for id_, name in wf_roles.items()
      if name in WF_PROPAGATED_ROLES
  }
    def _test_assessment_users(self, asmt, users):
        """ Test that all users have correct roles on specified Assessment"""
        verification_errors = ""
        ac_roles = {
            acr_name: acr_id
            for acr_id, acr_name in get_custom_roles_for(asmt.type).items()
        }
        for user_name, expected_types in users.items():
            for role in expected_types:
                try:
                    user = all_models.Person.query.filter_by(
                        name=user_name).first()
                    acl_len = all_models.AccessControlPerson.query.join(
                        all_models.AccessControlList
                    ).filter(
                        all_models.AccessControlList.ac_role_id ==
                        ac_roles[role],
                        all_models.AccessControlPerson.person_id == user.id,
                        all_models.AccessControlList.object_id == asmt.id,
                        all_models.AccessControlList.object_type == asmt.type,
                    ).count()
                    self.assertEqual(
                        acl_len, 1, "User {} is not mapped to {}".format(
                            user.email, asmt.slug))
                except AssertionError as error:
                    verification_errors += "\n\nChecks for Users-Assessment mapping "\
                        "failed for user '{}' with:\n{}".format(user_name, str(error))

        self.assertEqual(verification_errors, "", verification_errors)
Example #13
0
def _create_cycle_task(task_group_task, cycle, cycle_task_group, current_user):
  """Create a cycle task along with relations to other objects"""
  description = models.CycleTaskGroupObjectTask.default_description if \
      task_group_task.object_approval else task_group_task.description

  workflow = cycle.workflow
  start_date = workflow.calc_next_adjusted_date(task_group_task.start_date)
  end_date = workflow.calc_next_adjusted_date(task_group_task.end_date)
  access_control_list = []
  for role_id, role_name in role.get_custom_roles_for(
          models.CycleTaskGroupObjectTask.__name__).iteritems():
    for person_id in task_group_task.get_person_ids_for_rolename(role_name):
      access_control_list.append(
          {"ac_role_id": role_id, "person": {"id": person_id}}
      )
  cycle_task_group_object_task = models.CycleTaskGroupObjectTask(
      context=cycle.context,
      cycle=cycle,
      cycle_task_group=cycle_task_group,
      task_group_task=task_group_task,
      title=task_group_task.title,
      description=description,
      sort_index=task_group_task.sort_index,
      start_date=start_date,
      end_date=end_date,
      access_control_list=access_control_list,
      status=models.CycleTaskGroupObjectTask.ASSIGNED,
      modified_by=current_user,
      task_type=task_group_task.task_type,
      response_options=task_group_task.response_options,
  )
  return cycle_task_group_object_task
Example #14
0
 def get_role_id_for_obj(obj, role_name):
   """Return role id for ent instance and role_name."""
   from ggrc.access_control import role as ac_role
   for role_id, name in ac_role.get_custom_roles_for(obj.type).iteritems():
     if name == role_name:
       return role_id
   return None
Example #15
0
  def init_workflow(self):
    """Creates a workflow which is owned by an user with Admin role"""

    admin_role_id = {
        n: i
        for (i, n) in role.get_custom_roles_for(Workflow.__name__).iteritems()
    }['Admin']

    initial_workflow_data = {
        "title": "test workflow",
        "description": "test workflow",
        "access_control_list": [
            acl_helper.get_acl_json(admin_role_id, self.users['admin'].id)],
        "status": "Draft",
        "task_groups": [{
            "title": "task group 1",
            "contact": self.person_dict(self.users['admin'].id),
            "task_group_tasks": [{
                "title": "task 1",
                "description": "some task",
                "contact": self.person_dict(self.users['admin'].id),
                "start_date": date(2016, 5, 26),
                "end_date": date(2016, 5, 28),
            }],
            "task_group_objects": self.random_objects[:2]
        }]
    }

    self.workflow_res, self.workflow_obj =\
        self.generator.generate_workflow(initial_workflow_data)
Example #16
0
 def copy(self, _other=None, **kwargs):
   """Create a partial copy of the current workflow.
   """
   columns = ['title',
              'description',
              'notify_on_change',
              'notify_custom_message',
              'end_date',
              'start_date',
              'repeat_every',
              'unit',
              'is_verification_needed']
   if kwargs.get('clone_people', False):
     access_control_list = [{"ac_role": acl.ac_role, "person": acl.person}
                            for acl in self.access_control_list]
   else:
     role_id = {
         name: ind
         for (ind, name) in role.get_custom_roles_for(self.type).iteritems()
     }['Admin']
     access_control_list = [{"ac_role_id": role_id,
                             "person": {"id": get_current_user().id}}]
   target = self.copy_into(_other, columns,
                           access_control_list=access_control_list, **kwargs)
   return target
Example #17
0
 def test_old_comments(self):
   """Test if notifications will be sent for mix of old and new comments"""
   cur_user = all_models.Person.query.filter_by(
       email="*****@*****.**"
   ).first()
   assigee_role_id = {
       v: k for k, v in get_custom_roles_for("Assessment").items()
   }["Assignees"]
   with factories.single_commit():
     assessment = factories.AssessmentFactory()
     factories.AccessControlListFactory(
         ac_role_id=assigee_role_id, person=cur_user, object=assessment
     )
   with freeze_time("2015-04-01 17:13:10"):
     self.generator.generate_comment(
         assessment, "", "some comment1", send_notification="true"
     )
   self.generator.generate_comment(
       assessment, "", "some comment2", send_notification="true"
   )
   response = self.client.get("/_notifications/show_pending")
   for comment in ["some comment1", "some comment2"]:
     self.assertIn(
         comment, response.data,
         "Information about comment '{}' absent in report".format(comment)
     )
Example #18
0
def _create_cycle_task(task_group_task, cycle, cycle_task_group, current_user):
  """Create a cycle task along with relations to other objects"""
  description = models.CycleTaskGroupObjectTask.default_description if \
      task_group_task.object_approval else task_group_task.description

  workflow = cycle.workflow
  start_date = workflow.calc_next_adjusted_date(task_group_task.start_date)
  end_date = workflow.calc_next_adjusted_date(task_group_task.end_date)
  access_control_list = []
  for role_id, role_name in role.get_custom_roles_for(
          models.CycleTaskGroupObjectTask.__name__).iteritems():
    for person_id in task_group_task.get_person_ids_for_rolename(role_name):
      access_control_list.append(
          {"ac_role_id": role_id, "person": {"id": person_id}}
      )
  cycle_task_group_object_task = models.CycleTaskGroupObjectTask(
      context=cycle.context,
      cycle=cycle,
      cycle_task_group=cycle_task_group,
      task_group_task=task_group_task,
      title=task_group_task.title,
      description=description,
      sort_index=task_group_task.sort_index,
      start_date=start_date,
      end_date=end_date,
      access_control_list=access_control_list,
      status=models.CycleTaskGroupObjectTask.ASSIGNED,
      modified_by=current_user,
      task_type=task_group_task.task_type,
      response_options=task_group_task.response_options,
  )
  return cycle_task_group_object_task
Example #19
0
 def get_role_id_for_obj(obj, role_name):
   """Return role id for ent instance and role_name."""
   from ggrc.access_control import role as ac_role
   for role_id, name in ac_role.get_custom_roles_for(obj.type).iteritems():
     if name == role_name:
       return role_id
   return None
  def _test_assessment_users(self, asmt, users):
    """ Test that all users have correct roles on specified Assessment"""
    verification_errors = ""
    ac_roles = {
        acr_name: acr_id
        for acr_id, acr_name in get_custom_roles_for(asmt.type).items()
    }
    for user_name, expected_types in users.items():
      for role in expected_types:
        try:
          user = all_models.Person.query.filter_by(name=user_name).first()
          acl_len = all_models.AccessControlList.query.filter_by(
              ac_role_id=ac_roles[role],
              person_id=user.id,
              object_id=asmt.id,
              object_type=asmt.type,
          ).count()
          self.assertEqual(
              acl_len, 1,
              "User {} is not mapped to {}".format(user.email, asmt.slug)
          )
        except AssertionError as error:
          verification_errors += "\n\nChecks for Users-Assessment mapping "\
              "failed for user '{}' with:\n{}".format(user_name, str(error))

    self.assertEqual(verification_errors, "", verification_errors)
Example #21
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(),
                        ))
Example #22
0
    def generate_workflow(self, data=None):
        """ create a workflow with dict data
    return: wf if it was created, or response otherwise
    """
        if data is None:
            data = {}
        obj_name = "workflow"
        data = copy.deepcopy(data)

        tgs = data.pop("task_groups", [])

        wf_instance = Workflow(title="wf " + factories.random_str())
        obj_dict = self.obj_to_dict(wf_instance, obj_name)
        wf_admin_role_id = {
            n: i
            for (
                i,
                n) in role.get_custom_roles_for(Workflow.__name__).iteritems()
        }['Admin']
        if "access_control_list" not in data:
            wf_admin_id = Person.query.first().id
            data["access_control_list"] = [
                acl_helper.get_acl_json(wf_admin_role_id, wf_admin_id)
            ]
        obj_dict[obj_name].update(data)

        response, workflow = self.generate(Workflow, obj_name, obj_dict)

        for task_group in tgs:
            self.generate_task_group(workflow, task_group)

        return response, workflow
Example #23
0
 def assert_acr_exist(name, definition_type):
   """Validate that there is no ACR with provided name."""
   model_name = get_inflector_model_name_dict()[definition_type]
   acrs = {i.lower() for i in acr.get_custom_roles_for(model_name).values()}
   if name.lower() in acrs:
     raise ValueError(
         errors.DUPLICATE_CUSTOM_ROLE.format(role_name=name)
     )
Example #24
0
 def get_persons_for_rolename(self, role_name):
   """Return list of persons that are valid for send role_name."""
   for role_id, name in role.get_custom_roles_for(self.type).iteritems():
     if name != role_name:
       continue
     return [i.person for i in self.access_control_list
             if i.ac_role_id == role_id]
   return []
Example #25
0
 def setUp(self):
   super(TestAssessmentBase, self).setUp()
   self.api = ggrc.api_helper.Api()
   self.assignee_roles = {
       role_name: role_id
       for role_id, role_name in get_custom_roles_for("Assessment").items()
       if role_name in ["Assignees", "Creators", "Verifiers"]
   }
Example #26
0
 def get_persons_for_rolename(self, role_name):
   """Return list of persons that are valid for send role_name."""
   for role_id, name in role.get_custom_roles_for(self.type).iteritems():
     if name != role_name:
       continue
     return [i.person for i in self.access_control_list
             if i.ac_role_id == role_id]
   return []
 def setUp(self):
   super(TestAssessmentBase, self).setUp()
   self.api = ggrc.api_helper.Api()
   self.assignee_roles = {
       role_name: role_id
       for role_id, role_name in get_custom_roles_for("Assessment").items()
       if role_name in ["Assignees", "Creators", "Verifiers"]
   }
Example #28
0
  def validate_title(self, key, value):
    """Validate CAD title/name uniqueness.

    Note: title field is used for storing CAD names.
    CAD names need to follow 4 uniqueness rules:
      1) Names must not match any attribute name on any existing object.
      2) Object level CAD names must not match any global CAD name.
      3) Object level CAD names can clash, but not for the same Object
         instance. This means we can have two CAD with a name "my cad", with
         different attributable_id fields.
      4) Names must not match any existing custom attribute role name

    Third rule is handled by the database with unique key uq_custom_attribute
    (`definition_type`,`definition_id`,`title`).

    This validator should check for name collisions for 1st and 2nd rule.

    This validator works, because definition_type is never changed. It only
    gets set when the cad is created and after that only title filed can
    change. This makes validation using both fields possible.

    Args:
      value: custom attribute definition name

    Returns:
      value if the name passes all uniqueness checks.
    """

    if key == "title" and self.definition_type:
      name = value.lower()
      definition_type = self.definition_type
    elif key == "definition_type" and self.title:
      name = self.title.lower()
      definition_type = value.lower()
    else:
      return value

    if name in self._get_reserved_names(definition_type):
      raise ValueError(u"Attribute '{}' is reserved for this object type."
                       .format(name))

    if (self._get_global_cad_names(definition_type).get(name) is not None and
            self._get_global_cad_names(definition_type).get(name) != self.id):
      raise ValueError(u"Global custom attribute '{}' "
                       u"already exists for this object type"
                       .format(name))
    model_name = self.inflector_model_name_dict[definition_type]
    acrs = {i.lower() for i in acr.get_custom_roles_for(model_name).values()}
    if name in acrs:
      raise ValueError(u"Custom Role with a name of '{}' "

                       u"already existsfor this object type".format(name))

    if definition_type == "assessment":
      self.validate_assessment_title(name)

    return value
Example #29
0
 def setUp(self):
   super(TestAssigneeRBAC, self).setUp()
   self.api = Api()
   self.set_up_people()
   self.assignee_roles = {
       role_name: role_id
       for role_id, role_name in get_custom_roles_for("Assessment").items()
       if role_name in ["Assignees", "Creators", "Verifiers"]
   }
  def validate_title(self, key, value):
    """Validate CAD title/name uniqueness.

    Note: title field is used for storing CAD names.
    CAD names need to follow 4 uniqueness rules:
      1) Names must not match any attribute name on any existing object.
      2) Object level CAD names must not match any global CAD name.
      3) Object level CAD names can clash, but not for the same Object
         instance. This means we can have two CAD with a name "my cad", with
         different attributable_id fields.
      4) Names must not match any existing custom attribute role name

    Third rule is handled by the database with unique key uq_custom_attribute
    (`definition_type`,`definition_id`,`title`).

    This validator should check for name collisions for 1st and 2nd rule.

    This validator works, because definition_type is never changed. It only
    gets set when the cad is created and after that only title filed can
    change. This makes validation using both fields possible.

    Args:
      value: custom attribute definition name

    Returns:
      value if the name passes all uniqueness checks.
    """

    if key == "title" and self.definition_type:
      name = value.lower()
      definition_type = self.definition_type
    elif key == "definition_type" and self.title:
      name = self.title.lower()
      definition_type = value.lower()
    else:
      return value

    if name in self._get_reserved_names(definition_type):
      raise ValueError(u"Attribute '{}' is reserved for this object type."
                       .format(name))

    if (self._get_global_cad_names(definition_type).get(name) is not None and
            self._get_global_cad_names(definition_type).get(name) != self.id):
      raise ValueError(u"Global custom attribute '{}' "
                       u"already exists for this object type"
                       .format(name))
    model_name = self.inflector_model_name_dict[definition_type]
    acrs = {i.lower() for i in acr.get_custom_roles_for(model_name).values()}
    if name in acrs:
      raise ValueError(u"Custom Role with a name of '{}' "

                       u"already existsfor this object type".format(name))

    if definition_type == "assessment":
      self.validate_assessment_title(name)

    return value
Example #31
0
    def populate_acl(self):
        """Add access_control_list info for older revisions."""
        roles_dict = role.get_custom_roles_for(self.resource_type)
        reverted_roles_dict = {n: i for i, n in roles_dict.iteritems()}
        access_control_list = self._content.get("access_control_list") or []
        map_field_to_role = {
            "principal_assessor":
            reverted_roles_dict.get("Principal Assignees"),
            "secondary_assessor":
            reverted_roles_dict.get("Secondary Assignees"),
            "contact": reverted_roles_dict.get("Primary Contacts"),
            "secondary_contact": reverted_roles_dict.get("Secondary Contacts"),
            "owners": reverted_roles_dict.get("Admin"),
        }
        exists_roles = {i["ac_role_id"] for i in access_control_list}

        for field, role_id in map_field_to_role.items():
            if role_id in exists_roles or role_id is None:
                continue
            if field not in self._content:
                continue
            field_content = self._content.get(field) or {}
            if not field_content:
                continue
            if not isinstance(field_content, list):
                field_content = [field_content]
            person_ids = {fc.get("id") for fc in field_content if fc.get("id")}
            for person_id in person_ids:
                access_control_list.append({
                    "display_name": roles_dict[role_id],
                    "ac_role_id": role_id,
                    "context_id": None,
                    "created_at": None,
                    "object_type": self.resource_type,
                    "updated_at": None,
                    "object_id": self.resource_id,
                    "modified_by_id": None,
                    "person_id": person_id,
                    # Frontend require data in such format
                    "person": {
                        "id": person_id,
                        "type": "Person",
                        "href": "/api/people/{}".format(person_id)
                    },
                    "modified_by": None,
                    "id": None,
                })

        acl_with_people = self._populate_acl_with_people(access_control_list)
        filtered_acl = self._filter_internal_acls(acl_with_people)
        result_acl = [
            acl for acl in filtered_acl if acl["ac_role_id"] in roles_dict
        ]
        return {
            "access_control_list": result_acl,
        }
    def test_models_comments(self, obj_factory, _):
        """Test setting notification entries for model comments.

    Check if the correct notification entries are created when a comment gets
    posted.
    """
        if obj_factory in self.SCOPING_OBJECT_FACTORIES:
            recipient_types = [
                "Admin", "Primary Contacts", "Secondary Contacts", "Assignee",
                "Compliance Contacts", "Verifier", "Product Managers",
                "Technical / Program Managers", "Technical Leads",
                "System Owners", "Legal Counsels"
            ]
        else:
            recipient_types = [
                "Admin", "Primary Contacts", "Secondary Contacts"
            ]
        person = all_models.Person.query.first()
        person_email = person.email

        with factories.single_commit():
            obj = obj_factory(
                recipients=",".join(recipient_types),
                send_by_default=False,
            )
            ac_roles = get_custom_roles_for(obj.type)
            for acr_id, acr_name in ac_roles.items():
                if acr_name in recipient_types:
                    factories.AccessControlListFactory(ac_role_id=acr_id,
                                                       object=obj,
                                                       person=person)

        self.generator.generate_comment(obj,
                                        "",
                                        "some comment",
                                        send_notification="true")

        notifications, notif_data = common.get_daily_notifications()
        self.assertEqual(len(notifications), 1,
                         "Missing comment notification entry.")

        recip_notifs = notif_data.get(person_email, {})
        comment_notifs = recip_notifs.get("comment_created", {})
        self.assertEqual(len(comment_notifs), 1)

        # Check if correct revisions count is created
        revisions = Revision.query.filter(
            Revision.resource_type == 'Notification',
            Revision.resource_id.in_([n.id for n in notifications]))
        self.assertEqual(revisions.count(), 1)

        self.client.get("/_notifications/send_daily_digest")
        notifications = self._get_notifications(
            notif_type="comment_created").all()
        self.assertEqual(len(notifications), 0,
                         "Found a comment notification that was not sent.")
Example #33
0
 def get_person_ids_for_rolename(self, role_name):
   """Return list of persons that are valid for send role_name."""
   for role_id, name in role.get_custom_roles_for(self.type).iteritems():
     if name != role_name:
       continue
     # TODO: use ac_role_id as temporary solution until GGRC-3784 implemented
     return [i.person.id for i in self.access_control_list
             if (i.ac_role and i.ac_role.id == role_id) or
             (i.ac_role_id and i.ac_role_id == role_id)]
   return []
Example #34
0
 def setUp(self):
     super(TestAssigneeRBAC, self).setUp()
     self.api = Api()
     self.set_up_people()
     self.assignee_roles = {
         role_name: role_id
         for role_id, role_name in get_custom_roles_for(
             "Assessment").items()
         if role_name in ["Assignees", "Creators", "Verifiers"]
     }
Example #35
0
 def get_person_ids_for_rolename(self, role_name):
   """Return list of persons that are valid for send role_name."""
   for role_id, name in role.get_custom_roles_for(self.type).iteritems():
     if name != role_name:
       continue
     # TODO: use ac_role_id as temporary solution until GGRC-3784 implemented
     return [i.person.id for i in self.access_control_list
             if (i.ac_role and i.ac_role.id == role_id) or
             (i.ac_role_id and i.ac_role_id == role_id)]
   return []
Example #36
0
 def assert_assignees(self, role, response, *users):
     """Check if Assignee people in response are same with passed users"""
     acls = response.json["assessment"]["access_control_list"]
     asmnt_roles = get_custom_roles_for("Assessment")
     acl_people = all_models.Person.query.filter(
         all_models.Person.id.in_([
             acl.get("person", {}).get("id") for acl in acls
             if asmnt_roles.get(acl.get("ac_role_id")) == role
         ]))
     self.assertEqual(list(users), [p.email for p in acl_people])
Example #37
0
  def populate_acl(self):
    """Add access_control_list info for older revisions."""
    roles_dict = role.get_custom_roles_for(self.resource_type)
    reverted_roles_dict = {n: i for i, n in roles_dict.iteritems()}
    access_control_list = self._content.get("access_control_list") or []
    map_field_to_role = {
        "principal_assessor": reverted_roles_dict.get("Principal Assignees"),
        "secondary_assessor": reverted_roles_dict.get("Secondary Assignees"),
        "contact": reverted_roles_dict.get("Primary Contacts"),
        "secondary_contact": reverted_roles_dict.get("Secondary Contacts"),
        "owners": reverted_roles_dict.get("Admin"),
    }
    exists_roles = {i["ac_role_id"] for i in access_control_list}

    for field, role_id in map_field_to_role.items():
      if role_id in exists_roles or role_id is None:
        continue
      if field not in self._content:
        continue
      field_content = self._content.get(field) or {}
      if not field_content:
        continue
      if not isinstance(field_content, list):
        field_content = [field_content]
      person_ids = {fc.get("id") for fc in field_content if fc.get("id")}
      for person_id in person_ids:
        access_control_list.append({
            "display_name": roles_dict[role_id],
            "ac_role_id": role_id,
            "context_id": None,
            "created_at": None,
            "object_type": self.resource_type,
            "updated_at": None,
            "object_id": self.resource_id,
            "modified_by_id": None,
            "person_id": person_id,
            # Frontend require data in such format
            "person": {
                "id": person_id,
                "type": "Person",
                "href": "/api/people/{}".format(person_id)
            },
            "modified_by": None,
            "id": None,
        })

    acl_with_people = self._populate_acl_with_people(access_control_list)
    filtered_acl = self._filter_internal_acls(acl_with_people)
    result_acl = [
        acl for acl in filtered_acl if acl["ac_role_id"] in roles_dict
    ]
    return {
        "access_control_list": result_acl,
    }
Example #38
0
    def assignee_roles(self):
        """Returns assignee roles.

    Returns:
      A dictionary with assignee role name and id.
    """
        return {
            role_name: role_id
            for role_id, role_name in get_custom_roles_for(
                self.type).iteritems() if role_name in self.ASSIGNEE_TYPES
        }
 def assert_assignees(self, role, response, *users):
   """Check if Assignee people in response are same with passed users"""
   acls = response.json["assessment"]["access_control_list"]
   asmnt_roles = get_custom_roles_for("Assessment")
   acl_people = all_models.Person.query.filter(
       all_models.Person.id.in_([
           a.get("person", {}).get("id")
           for a in acls if asmnt_roles.get(a.get("ac_role_id")) == role
       ])
   )
   self.assertEqual(list(users), [p.email for p in acl_people])
Example #40
0
 def handle_comment_post(mapper, connection, target):
   """Save information on which user created the Comment object."""
   # pylint: disable=unused-argument
   for role_id, role_name in role.get_custom_roles_for(target.type).items():
     user = get_current_user()
     if role_name == "Admin" and not user.is_anonymous():
       AccessControlList(
           ac_role_id=role_id,
           person=user,
           object=target,
       )
       return
Example #41
0
 def handle_comment_post(mapper, connection, target):
     """Save information on which user created the Comment object."""
     # pylint: disable=unused-argument
     for role_id, role_name in role.get_custom_roles_for(
             target.type).items():
         user = get_current_user()
         if role_name == "Admin" and not user.is_anonymous():
             AccessControlList(
                 ac_role_id=role_id,
                 person=user,
                 object=target,
             )
             return
  def test_models_comments(self, obj_factory, _):
    """Test setting notification entries for model comments.

    Check if the correct notification entries are created when a comment gets
    posted.
    """
    if obj_factory in self.SCOPING_OBJECT_FACTORIES:
      recipient_types = ["Admin", "Primary Contacts", "Secondary Contacts",
                         "Product Managers", "Technical / Program Managers",
                         "Technical Leads", "System Owners", "Legal Counsels"]
    else:
      recipient_types = ["Admin", "Primary Contacts", "Secondary Contacts"]
    person = all_models.Person.query.first()
    person_email = person.email

    with factories.single_commit():
      obj = obj_factory(
          recipients=",".join(recipient_types),
          send_by_default=False,
      )
      ac_roles = get_custom_roles_for(obj.type)
      for acr_id, acr_name in ac_roles.items():
        if acr_name in recipient_types:
          factories.AccessControlListFactory(
              ac_role_id=acr_id, object=obj, person=person
          )

    self.generator.generate_comment(
        obj, "", "some comment", send_notification="true")

    notifications, notif_data = common.get_daily_notifications()
    self.assertEqual(len(notifications), 1,
                     "Missing comment notification entry.")

    recip_notifs = notif_data.get(person_email, {})
    comment_notifs = recip_notifs.get("comment_created", {})
    self.assertEqual(len(comment_notifs), 1)

    # Check if correct revisions count is created
    revisions = Revision.query.filter(
        Revision.resource_type == 'Notification',
        Revision.resource_id.in_([n.id for n in notifications])
    )
    self.assertEqual(revisions.count(), 1)

    self.client.get("/_notifications/send_daily_digest")
    notifications = self._get_notifications(notif_type="comment_created").all()
    self.assertEqual(len(notifications), 0,
                     "Found a comment notification that was not sent.")
def handle_acl_creation(session):
    """Create relations for mapped objects."""
    base_objects = defaultdict(set)
    for obj in session.new:
        if isinstance(obj, all_models.AccessControlList):
            acr_id = obj.ac_role.id if obj.ac_role else obj.ac_role_id
            acr_name = get_custom_roles_for(obj.object_type).get(acr_id)
            if acr_name in Assignable.ASSIGNEE_TYPES:
                base_objects[Stub(obj.object_type, obj.object_id)].add(obj)
    if base_objects:
        related_objects = related(base_objects.keys(), RelationshipsCache())
        snapshot_ids = collect_snapshot_ids(related_objects)
        if snapshot_ids:
            add_related_snapshots(snapshot_ids, related_objects)
        create_related_roles(base_objects, related_objects)
Example #44
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(),
   )
Example #45
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(),
   )
Example #46
0
def generate_role_object_dict(snapshot, audit):
  """Generate roles dict for sent snapshot and audit.

  returns dict of roles with key as role name and list of people ids as values.
  """

  acr_dict = role.get_custom_roles_for(snapshot.child_type)
  acl_dict = defaultdict(list)
  # populated content should have access_control_list
  for acl in snapshot.revision.content["access_control_list"]:
    acl_dict[acr_dict[acl["ac_role_id"]]].append(acl["person_id"])
  # populate Access Control List by generated role from the related Audit
  acl_dict["Audit Lead"].append(audit.contact_id)
  acl_dict["Auditors"].extend([user_role.person_id
                               for user_role in audit.context.user_roles
                               if user_role.role.name == u"Auditor"])
  return acl_dict
Example #47
0
def init_globals(models):
  """Load all ACRs and CADs into memory from db"""
  with app.app_context():
    with factories.single_commit():
      for model in models:
        AC_ROLES[model] = {
            name: id for id, name in
            get_custom_roles_for(model).items()
        }

        CADS[model] = {
            CAD_PERSON_TYPE: factories.CustomAttributeDefinitionFactory(
                title=CAD_PERSON_TITLE,
                definition_type=utils.underscore_from_camelcase(model),
                attribute_type=CAD_PERSON_TYPE,
            ).id
        }
Example #48
0
def init_globals(models):
  """Load all ACRs and CADs into memory from db"""
  with app.app_context():
    with factories.single_commit():
      for model in models:
        AC_ROLES[model] = {
            name: id for id, name in
            get_custom_roles_for(model).items()
        }

        CADS[model] = {
            CAD_PERSON_TYPE: factories.CustomAttributeDefinitionFactory(
                title=CAD_PERSON_TITLE,
                definition_type=utils.underscore_from_camelcase(model),
                attribute_type=CAD_PERSON_TYPE,
            ).id
        }
Example #49
0
def get_mapped_role(object_type, acr_name, mapped_obj_type):
    """Get AC role that is mapped to provided one.

  Args:
    object_type(str): Type of object
    acr_name(str): Name of AC role
    mapped_obj_type(str): Type of mapped object

  Returns:
    Id of AC role with name '<Assignee type> Mapped' or
    '<Assignee type> Document Mapped' will be returned
  """
    obj_roles = {
        role_name: role_id
        for role_id, role_name in get_custom_roles_for(object_type).items()
    }
    doc_part = " Document" if mapped_obj_type == "Document" else ""
    return obj_roles.get("{}{} Mapped".format(acr_name, doc_part))
Example #50
0
def generate_role_object_dict(snapshot, audit):
    """Generate roles dict for sent snapshot and audit.

  returns dict of roles with key as role name and list of people ids as values.
  """

    acr_dict = role.get_custom_roles_for(snapshot.child_type)
    acl_dict = defaultdict(list)
    # populated content should have access_control_list
    for acl in snapshot.revision.content["access_control_list"]:
        acl_dict[acr_dict[acl["ac_role_id"]]].append(acl["person_id"])
    # populate Access Control List by generated role from the related Audit
    acl_dict["Audit Lead"].append(audit.contact_id)
    acl_dict["Auditors"].extend([
        user_role.person_id for user_role in audit.context.user_roles
        if user_role.role.name == u"Auditor"
    ])
    return acl_dict
  def modify_assignee(self, obj, email, new_roles):
    """Modfiy assignee type.

    Args:
      obj: Object
      email: Person's email
      new_role: New roles for AssigneeType
    """
    person = models.Person.query.filter_by(email=email).first()
    ac_roles = {
        acr_name: acr_id
        for acr_id, acr_name in get_custom_roles_for(obj.type).items()
    }
    self.api.modify_object(obj, {
        "access_control_list": [
            acl_helper.get_acl_json(ac_roles[role], person.id)
            for role in new_roles
        ]
    })
Example #52
0
  def populated_content(self):
    """Property. Contains the revision content dict.

    Updated by required values, generated from saved content dict."""
    roles_dict = role.get_custom_roles_for(self.resource_type)
    reverted_roles_dict = {n: i for i, n in roles_dict.iteritems()}
    access_control_list = self.content.get("access_control_list") or []
    map_field_to_role = {
        "principal_assessor": reverted_roles_dict.get("Principal Assignees"),
        "secondary_assessor": reverted_roles_dict.get("Secondary Assignees"),
        "contact": reverted_roles_dict.get("Primary Contacts"),
        "secondary_contact": reverted_roles_dict.get("Secondary Contacts"),
    }
    exists_roles = {i["ac_role_id"] for i in access_control_list}
    for field, role_id in map_field_to_role.items():
      if field not in self.content:
        continue
      if role_id in exists_roles or role_id is None:
        continue
      person_id = (self.content.get(field) or {}).get("id")
      if not person_id:
        continue
      access_control_list.append({
          "display_name": roles_dict[role_id],
          "ac_role_id": role_id,
          "context_id": None,
          "created_at": None,
          "object_type": self.resource_type,
          "updated_at": None,
          "object_id": self.resource_id,
          "modified_by_id": None,
          "person_id": person_id,
          "modified_by": None,
          "id": None,
      })
    content = self.content.copy()
    content["access_control_list"] = access_control_list
    return content
Example #53
0
  def _create_test_cases_data(self):
    """Create test cases data: for object generation,
    expected data for checks"""
    def person_dict(person_id):
      """Return person data"""
      return {
          "href": "/api/people/%d" % person_id,
          "id": person_id,
          "type": "Person"
      }

    wf_admin_role_id = {
        n: i
        for (i, n) in role.get_custom_roles_for(Workflow.__name__).iteritems()
    }['Admin']

    self.workflow_active = {
        "title": "workflow active title",
        "description": "workflow active description",
        "access_control_list": [
            acl_helper.get_acl_json(wf_admin_role_id, self.person_1.id)],
        "notify_on_change": False,
    }

    self.task_group_active = {
        "title": "task group active title",
        "contact": person_dict(self.person_1.id),
    }

    self.task_group_tasks_active = [{
        "title": "task active title 1",
        "description": "task active description 1",
        "contact": person_dict(self.person_1.id),
        "start_date": "07/01/2016",
        "end_date": "07/06/2016",
    }, {
        "title": "task active title 2",
        "description": "task active description 2",
        "contact": person_dict(self.person_1.id),
        "start_date": "07/07/2016",
        "end_date": "07/12/2016",
    }, {
        "title": "task active title 3",
        "description": "task active description 3",
        "contact": person_dict(self.person_1.id),
        "start_date": "07/13/2016",
        "end_date": "07/18/2016",
    }, {
        "title": "task active title 4",
        "description": "task active description 4",
        "contact": person_dict(self.person_1.id),
        "start_date": "07/19/2016",
        "end_date": "07/24/2016",
    }, {
        "title": "task active title 5",
        "description": "task active description 5",
        "contact": person_dict(self.person_1.id),
        "start_date": "07/25/2016",
        "end_date": "07/30/2016",
    }]

    # Active cycle tasks which should be generated from previous structure
    # at the beginning of each test
    self.generated_cycle_tasks_active = {
        "CYCLETASK-1": {
            "title": self.task_group_tasks_active[0]["title"],
            "description": self.task_group_tasks_active[0]["description"],
            "start_date": "2016-07-01",
            "end_date": "2016-07-06",
            "finished_date": "None",
            "verified_date": "None",
            "status": "Assigned"
        },
        "CYCLETASK-2": {
            "title": self.task_group_tasks_active[1]["title"],
            "description": self.task_group_tasks_active[1]["description"],
            "start_date": "2016-07-07",
            "end_date": "2016-07-12",
            "finished_date": "None",
            "verified_date": "None",
            "status": "Declined"
        },
        "CYCLETASK-3": {
            "title": self.task_group_tasks_active[2]["title"],
            "description": self.task_group_tasks_active[2]["description"],
            "start_date": "2016-07-13",
            "end_date": "2016-07-18",
            "finished_date": "None",
            "verified_date": "None",
            "status": "In Progress"
        },
        "CYCLETASK-4": {
            "title": self.task_group_tasks_active[3]["title"],
            "description": self.task_group_tasks_active[3]["description"],
            "start_date": "2016-07-19",
            "end_date": "2016-07-22",
            "finished_date": "2016-07-01",
            "verified_date": "None",
            "status": "Finished"
        },
        "CYCLETASK-5": {
            "title": self.task_group_tasks_active[4]["title"],
            "description": self.task_group_tasks_active[4]["description"],
            "start_date": "2016-07-25",
            "end_date": "2016-07-29",
            "finished_date": "2016-07-01",
            "verified_date": "2016-07-01",
            "status": "Verified"
        }
    }

    self.workflow_historical = {
        "title": "workflow historical title",
        "description": "workflow historical description",
        "access_control_list": [
            acl_helper.get_acl_json(wf_admin_role_id, self.person_1.id)],
        "notify_on_change": False,
    }

    self.task_group_historical = {
        "title": "task group historical title",
        "contact": person_dict(self.person_1.id),
    }

    self.task_group_tasks_historical = [{
        "title": "task historical title 1",
        "description": "task historical description 1",
        "contact": person_dict(self.person_1.id),
        "start_date": "05/01/2014",
        "end_date": "05/06/2014",
    }, {
        "title": "task historical title 2",
        "description": "task historical description 2",
        "contact": person_dict(self.person_1.id),
        "start_date": "05/07/2014",
        "end_date": "05/12/2014",
    }, {
        "title": "task historical title 3",
        "description": "task historical description 3",
        "contact": person_dict(self.person_1.id),
        "start_date": "05/13/2014",
        "end_date": "05/18/2014",
    }, {
        "title": "task historical title 4",
        "description": "task historical description 4",
        "contact": person_dict(self.person_1.id),
        "start_date": "05/19/2014",
        "end_date": "05/24/2014",
    }, {
        "title": "task historical title 5",
        "description": "task historical description 5",
        "contact": person_dict(self.person_1.id),
        "start_date": "05/25/2014",
        "end_date": "05/30/2014",
    },
    ]

    # Historical cycle tasks which should be generated from previous structure
    # at the beginning of each test.
    self.generated_cycle_tasks_historical = {
        "CYCLETASK-6": {
            "title": self.task_group_tasks_historical[0]["title"],
            "description": self.task_group_tasks_historical[0]["description"],
            "start_date": "2014-05-01",
            "end_date": "2014-05-06",
            "finished_date": "None",
            "verified_date": "None",
            "status": "Assigned"
        },
        "CYCLETASK-7": {
            "title": self.task_group_tasks_historical[1]["title"],
            "description": self.task_group_tasks_historical[1]["description"],
            "start_date": "2014-05-07",
            "end_date": "2014-05-12",
            "finished_date": "None",
            "verified_date": "None",
            "status": "Declined"
        },
        "CYCLETASK-8": {
            "title": self.task_group_tasks_historical[2]["title"],
            "description": self.task_group_tasks_historical[2]["description"],
            "start_date": "2014-05-13",
            "end_date": "2014-05-16",
            "finished_date": "None",
            "verified_date": "None",
            "status": "In Progress"
        },
        "CYCLETASK-9": {
            "title": self.task_group_tasks_historical[3]["title"],
            "description": self.task_group_tasks_historical[3]["description"],
            "start_date": "2014-05-19",
            "end_date": "2014-05-23",
            "finished_date": "2014-05-01",
            "verified_date": "None",
            "status": "Finished"
        },
        "CYCLETASK-10": {
            "title": self.task_group_tasks_historical[4]["title"],
            "description": self.task_group_tasks_historical[4]["description"],
            "start_date": "2014-05-23",
            "end_date": "2014-05-30",
            "finished_date": "2014-05-01",
            "verified_date": "2014-05-01",
            "status": "Verified"
        }
    }

    # Expected cycle tasks which should be created in correct cycle task update
    # case. It is needed for most tests.
    self.expected_cycle_task_correct = {
        "CYCLETASK-1": {
            "title": self.task_group_tasks_active[0]["title"] + " one",
            "description":
                self.task_group_tasks_active[0]["description"] + " one",
            "start_date": "2016-06-01",
            "end_date": "2016-06-06",
            "finished_date": "None",
            "verified_date": "None",
            "status": "Assigned"
        },
        "CYCLETASK-2": {
            "title": self.task_group_tasks_active[1]["title"] + " two",
            "description":
                self.task_group_tasks_active[1]["description"] + " two",
            "start_date": "2016-06-07",
            "end_date": "2016-06-12",
            "finished_date": "None",
            "verified_date": "None",
            "status": "Declined"
        },
        "CYCLETASK-3": {
            "title": self.task_group_tasks_active[2]["title"] + " three",
            "description":
                self.task_group_tasks_active[2]["description"] + " three",
            "start_date": "2016-06-13",
            "end_date": "2016-06-18",
            "finished_date": "None",
            "verified_date": "None",
            "status": "In Progress"
        },
        "CYCLETASK-4": {
            "title": self.task_group_tasks_active[3]["title"] + " four",
            "description":
                self.task_group_tasks_active[3]["description"] + " four",
            "start_date": "2016-06-19",
            "end_date": "2016-06-24",
            "finished_date": "2016-07-19",
            "verified_date": "None",
            "status": "Finished"
        },
        "CYCLETASK-5": {
            "title": self.task_group_tasks_active[4]["title"] + " five",
            "description":
                self.task_group_tasks_active[4]["description"] + " five",
            "start_date": "2016-06-25",
            "end_date": "2016-06-30",
            "finished_date": "2016-07-25",
            "verified_date": "2016-08-30",
            "status": "Verified"
        },
        "CYCLETASK-6": {
            "title": self.task_group_tasks_historical[0]["title"] + " one",
            "description":
                self.task_group_tasks_historical[0]["description"] + " one",
            "start_date": "2014-04-01",
            "end_date": "2014-04-06",
            "finished_date": "None",
            "verified_date": "None",
            "status": "Assigned"
        },
        "CYCLETASK-7": {
            "title": self.task_group_tasks_historical[1]["title"] + " two",
            "description":
                self.task_group_tasks_historical[1]["description"] + " two",
            "start_date": "2014-04-07",
            "end_date": "2014-04-12",
            "finished_date": "None",
            "verified_date": "None",
            "status": "Declined"
        },
        "CYCLETASK-8": {
            "title": self.task_group_tasks_historical[2]["title"] + " three",
            "description":
                self.task_group_tasks_historical[2]["description"] + " three",
            "start_date": "2014-04-13",
            "end_date": "2014-04-18",
            "finished_date": "None",
            "verified_date": "None",
            "status": "In Progress"
        },
        "CYCLETASK-9": {
            "title": self.task_group_tasks_historical[3]["title"] + " four",
            "description":
                self.task_group_tasks_historical[3]["description"] + " four",
            "start_date": "2014-04-19",
            "end_date": "2014-04-24",
            "finished_date": "2014-05-19",
            "verified_date": "None",
            "status": "Finished"
        },
        "CYCLETASK-10": {
            "title": self.task_group_tasks_historical[4]["title"] + " five",
            "description":
                self.task_group_tasks_historical[4]["description"] + " five",
            "start_date": "2014-04-25",
            "end_date": "2014-04-30",
            "finished_date": "2014-05-25",
            "verified_date": "2014-06-30",
            "status": "Verified"
        }
    }

    # This is an error message which should be shown during
    # test_cycle_task_create_error test
    self.expected_create_error = {
        'Cycle Task': {
            'row_errors': {errors.CREATE_INSTANCE_ERROR.format(line=13)}
        }
    }

    # Below is expected date errors for test_cycle_task_date_error. They should
    # be shown during date validator's tests.
    self.expected_date_error = {
        'Cycle Task': {
            'row_errors': {
                errors.INVALID_START_END_DATES.format(
                    line=3,
                    start_date="Start Date",
                    end_date="End Date",
                ),
                errors.INVALID_STATUS_DATE_CORRELATION.format(
                    line=4,
                    date="Actual Finish Date",
                    deny_states=DENY_FINISHED_DATES_STATUSES_STR,
                ),
                errors.INVALID_STATUS_DATE_CORRELATION.format(
                    line=6,
                    date="Actual Verified Date",
                    deny_states=DENY_VERIFIED_DATES_STATUSES_STR,
                ),
                errors.INVALID_START_END_DATES.format(
                    line=7,
                    start_date="Actual Finish Date",
                    end_date="Actual Verified Date",
                ),
                errors.INVALID_START_END_DATES.format(
                    line=8,
                    start_date="Start Date",
                    end_date="End Date",
                ),
            },
        }
    }
    # Below is expected cycle-tasks data which should appear in test DB after
    # test_cycle_task_date_error run
    self.expected_cycle_task_date_error = dict()
    self.expected_cycle_task_date_error.update(
        self.generated_cycle_tasks_active)
    self.expected_cycle_task_date_error.update(
        self.generated_cycle_tasks_historical)
    self.expected_cycle_task_date_error["CYCLETASK-9"] = (
        self.expected_cycle_task_correct["CYCLETASK-9"])
    self.expected_cycle_task_date_error["CYCLETASK-10"] = (
        self.expected_cycle_task_correct["CYCLETASK-10"])

    # Expected error message which should be shown after
    # test_cycle_task_permission_error run
    self.expected_permission_error = {
        'Cycle Task': {
            'block_errors': {errors.PERMISSION_ERROR.format(line=2)}
        }
    }
Example #54
0
  def content(self):
    """Property. Contains the revision content dict.

    Updated by required values, generated from saved content dict."""
    # pylint: disable=too-many-locals
    roles_dict = role.get_custom_roles_for(self.resource_type)
    reverted_roles_dict = {n: i for i, n in roles_dict.iteritems()}
    access_control_list = self._content.get("access_control_list") or []
    map_field_to_role = {
        "principal_assessor": reverted_roles_dict.get("Principal Assignees"),
        "secondary_assessor": reverted_roles_dict.get("Secondary Assignees"),
        "contact": reverted_roles_dict.get("Primary Contacts"),
        "secondary_contact": reverted_roles_dict.get("Secondary Contacts"),
        "owners": reverted_roles_dict.get("Admin"),
    }
    exists_roles = {i["ac_role_id"] for i in access_control_list}
    for field, role_id in map_field_to_role.items():
      if field not in self._content:
        continue
      if role_id in exists_roles or role_id is None:
        continue
      field_content = self._content.get(field) or {}
      if not field_content:
        continue
      if not isinstance(field_content, list):
        field_content = [field_content]
      person_ids = {fc.get("id") for fc in field_content if fc.get("id")}
      for person_id in person_ids:
        access_control_list.append({
            "display_name": roles_dict[role_id],
            "ac_role_id": role_id,
            "context_id": None,
            "created_at": None,
            "object_type": self.resource_type,
            "updated_at": None,
            "object_id": self.resource_id,
            "modified_by_id": None,
            "person_id": person_id,
            # Frontend require data in such format
            "person": {
                "id": person_id,
                "type": "Person",
                "href": "/api/people/{}".format(person_id)
            },
            "modified_by": None,
            "id": None,
        })
    populated_content = self._content.copy()

    # Add person with id and type for old snapshots compatibility
    for acl in access_control_list:
      if "person" not in acl:
        acl["person"] = {"id": acl.get("person_id"), "type": "Person"}
    populated_content["access_control_list"] = access_control_list

    if 'url' in self._content:
      reference_url_list = []
      for key in ('url', 'reference_url'):
        link = self._content[key]
        # link might exist, but can be an empty string - we treat those values
        # as non-existing (empty) reference URLs
        if not link:
          continue

        # if creation/modification date is not available, we estimate it by
        # using the corresponding information from the Revision itself
        created_at = (self._content.get("created_at") or
                      self.created_at.isoformat())
        updated_at = (self._content.get("updated_at") or
                      self.updated_at.isoformat())

        reference_url_list.append({
            "display_name": link,
            "document_type": "REFERENCE_URL",
            "link": link,
            "title": link,
            "id": None,
            "created_at": created_at,
            "updated_at": updated_at,
        })
      populated_content['reference_url'] = reference_url_list

    return populated_content