def CheckRevealAllToMember(
      self, logged_in_user_id, expected, viewed_user_id=333, group_id=None):
    user_view = framework_views.StuffUserView(
        viewed_user_id, '*****@*****.**', True)

    if group_id:
      pass  # xxx re-implement groups

    users_by_id = {333: user_view}
    self.mr.auth.user_id = logged_in_user_id
    self.mr.auth.effective_ids = {logged_in_user_id}
    # Assert display name is obscured before the reveal.
    self.assertEqual('*****@*****.**', user_view.display_name)
    # Assert profile url contains user ID before the reveal.
    self.assertEqual('/u/%s/' % viewed_user_id, user_view.profile_url)
    framework_views.RevealAllEmailsToMembers(
        self.mr.auth, self.mr.project, users_by_id)
    self.assertEqual(expected, not user_view.obscure_email)
    if expected:
      # Assert display name is now revealed.
      self.assertEqual('*****@*****.**', user_view.display_name)
      # Assert profile url contains the email.
      self.assertEqual('/u/[email protected]/', user_view.profile_url)
    else:
      # Assert display name is still hidden.
      self.assertEqual('*****@*****.**', user_view.display_name)
      # Assert profile url still contains user ID.
      self.assertEqual('/u/%s/' % viewed_user_id, user_view.profile_url)
Ejemplo n.º 2
0
    def ListIssues(self, mc, request):
        """Return the list of issues for projects that satisfy the given query."""
        use_cached_searches = not settings.local_mode
        # TODO(zhangtiff): Rework FrontendSearchPipeline to not depend on url_params
        # for can.
        can = request.canned_query or 1
        with work_env.WorkEnv(mc, self.services) as we:
            start, max_items = converters.IngestPagination(request.pagination)
            pipeline = we.ListIssues(request.query, request.project_names,
                                     mc.auth.user_id, max_items, start,
                                     [('can', can)], can,
                                     request.group_by_spec, request.sort_spec,
                                     use_cached_searches)
        with mc.profiler.Phase('reveal emails to members'):
            projects = self.services.project.GetProjectsByName(
                mc.cnxn, request.project_names)
            for _, p in projects.items():
                framework_views.RevealAllEmailsToMembers(
                    mc.auth, p, pipeline.users_by_id)

        converted_results = []
        with work_env.WorkEnv(mc, self.services) as we:
            for issue in pipeline.visible_results:
                related_refs = we.GetRelatedIssueRefs([issue])
                converted_results.append(
                    converters.ConvertIssue(issue, pipeline.users_by_id,
                                            related_refs,
                                            pipeline.harmonized_config))
        return issues_pb2.ListIssuesResponse(
            issues=converted_results,
            total_results=pipeline.pagination.total_count)
Ejemplo n.º 3
0
def convert_approval_amendments(amendments, mar, services):
    """Convert a list of Monorail Amendment PBs API ApprovalUpdate."""
    amendments_user_ids = tracker_bizobj.UsersInvolvedInAmendments(amendments)
    users_by_id = framework_views.MakeAllUserViews(mar.cnxn, services.user,
                                                   amendments_user_ids)
    framework_views.RevealAllEmailsToMembers(mar.auth, mar.project,
                                             users_by_id)

    result = api_pb2_v1.ApprovalUpdate(kind='monorail#approvalCommentUpdate')
    for amendment in amendments:
        if amendment.field == tracker_pb2.FieldID.CUSTOM:
            if amendment.custom_field_name == 'Status':
                status_number = tracker_pb2.ApprovalStatus(
                    amendment.newvalue.upper()).number
                result.status = api_pb2_v1.ApprovalStatus(status_number).name
            elif amendment.custom_field_name == 'Approvers':
                for user_id in amendment.added_user_ids:
                    user_email = _get_user_email(services.user, mar.cnxn,
                                                 user_id)
                    result.approvers.append(user_email)
                for user_id in amendment.removed_user_ids:
                    user_email = _get_user_email(services.user, mar.cnxn,
                                                 user_id)
                    result.approvers.append('-%s' % user_email)
            else:
                fv = api_pb2_v1.FieldValue()
                fv.fieldName = amendment.custom_field_name
                fv.fieldValue = tracker_bizobj.AmendmentString(
                    amendment, users_by_id)
                # TODO(jojwang): monorail:4229, add approvalName field to FieldValue
                result.fieldValues.append(fv)

    return result
Ejemplo n.º 4
0
    def ListHotlistsByUser(self, mc, request):
        """Return the hotlists for the given user."""
        user_id = converters.IngestUserRef(mc.cnxn, request.user,
                                           self.services.user)

        with work_env.WorkEnv(mc, self.services) as we:
            mc.LookupLoggedInUserPerms(None)
            hotlists = we.ListHotlistsByUser(user_id)

        with mc.profiler.Phase('making user views'):
            users_involved = features_bizobj.UsersOwnersOfHotlists(hotlists)
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, users_involved)
            framework_views.RevealAllEmailsToMembers(mc.auth, None,
                                                     users_by_id)

        converted_hotlists = [
            converters.ConvertHotlist(hotlist, users_by_id)
            for hotlist in hotlists
        ]

        result = features_pb2.ListHotlistsByUserResponse(
            hotlists=converted_hotlists)

        return result
Ejemplo n.º 5
0
    def ListHotlistsByIssue(self, mc, request):
        """Return the hotlists the given issue is part of."""
        issue_id = converters.IngestIssueRefs(mc.cnxn, [request.issue],
                                              self.services)[0]

        with work_env.WorkEnv(mc, self.services) as we:
            project = we.GetProjectByName(request.issue.project_name)
            mc.LookupLoggedInUserPerms(project)
            hotlists = we.ListHotlistsByIssue(issue_id)

        with mc.profiler.Phase('making user views'):
            users_involved = features_bizobj.UsersOwnersOfHotlists(hotlists)
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, users_involved)
            framework_views.RevealAllEmailsToMembers(mc.auth, None,
                                                     users_by_id)

        converted_hotlists = [
            converters.ConvertHotlist(hotlist, users_by_id)
            for hotlist in hotlists
        ]

        result = features_pb2.ListHotlistsByIssueResponse(
            hotlists=converted_hotlists)

        return result
Ejemplo n.º 6
0
    def ListComments(self, mc, request):
        """Return comments on the specified issue in a response proto."""
        project, issue, config = self._GetProjectIssueAndConfig(
            mc, request.issue_ref)
        with work_env.WorkEnv(mc, self.services) as we:
            comments = we.ListIssueComments(issue)
            _, comment_reporters = we.LookupIssueFlaggers(issue)

        with mc.profiler.Phase('making user views'):
            users_involved_in_comments = tracker_bizobj.UsersInvolvedInCommentList(
                comments)
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, users_involved_in_comments)
            framework_views.RevealAllEmailsToMembers(mc.auth, project,
                                                     users_by_id)

        with mc.profiler.Phase('converting to response objects'):
            issue_perms = permissions.UpdateIssuePermissions(
                mc.perms, project, issue, mc.auth.effective_ids, config=config)
            converted_comments = converters.ConvertCommentList(
                issue, comments, config, users_by_id, comment_reporters,
                mc.auth.user_id, issue_perms)
            response = issues_pb2.ListCommentsResponse(
                comments=converted_comments)

        return response
Ejemplo n.º 7
0
    def ConvertIssueApprovalsTemplate(self, mc, request):
        """Update an issue's existing approvals structure to match the one of the
       given template."""

        if not request.issue_ref.local_id or not request.issue_ref.project_name:
            raise exceptions.InputException('Param `issue_ref.local_id` empty')
        if not request.template_name:
            raise exceptions.InputException('Param `template_name` empty')

        project, issue, config = self._GetProjectIssueAndConfig(
            mc, request.issue_ref, use_cache=False)

        with work_env.WorkEnv(mc, self.services) as we:
            we.ConvertIssueApprovalsTemplate(config,
                                             issue,
                                             request.template_name,
                                             request.comment_content,
                                             send_email=request.send_email)
            related_refs = we.GetRelatedIssueRefs([issue])

        with mc.profiler.Phase('making user views'):
            users_involved_in_issue = tracker_bizobj.UsersInvolvedInIssues(
                [issue])
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, users_involved_in_issue)
            framework_views.RevealAllEmailsToMembers(mc.auth, project,
                                                     users_by_id)

        with mc.profiler.Phase('converting to response objects'):
            response = issues_pb2.ConvertIssueApprovalsTemplateResponse()
            response.issue.CopyFrom(
                converters.ConvertIssue(issue, users_by_id, related_refs,
                                        config))
        return response
Ejemplo n.º 8
0
    def PresubmitIssue(self, mc, request):
        """Provide the UI with warnings and suggestions."""
        project, issue, config = self._GetProjectIssueAndConfig(
            mc, request.issue_ref, issue_required=False)

        with mc.profiler.Phase('making user views'):
            try:
                proposed_owner_id = converters.IngestUserRef(
                    mc.cnxn, request.issue_delta.owner_ref, self.services.user)
            except exceptions.NoSuchUserException:
                proposed_owner_id = 0

            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, [proposed_owner_id])
            proposed_owner_view = users_by_id[proposed_owner_id]

        with mc.profiler.Phase('Applying IssueDelta'):
            if issue:
                proposed_issue = copy.deepcopy(issue)
            else:
                proposed_issue = tracker_pb2.Issue(
                    owner_id=framework_constants.NO_USER_SPECIFIED,
                    project_id=config.project_id)
            issue_delta = converters.IngestIssueDelta(
                mc.cnxn,
                self.services,
                request.issue_delta,
                config,
                None,
                ignore_missing_objects=True)
            tracker_bizobj.ApplyIssueDelta(mc.cnxn, self.services.issue,
                                           proposed_issue, issue_delta, config)

        with mc.profiler.Phase('applying rules'):
            _, traces = filterrules_helpers.ApplyFilterRules(
                mc.cnxn, self.services, proposed_issue, config)
            logging.info('proposed_issue is now: %r', proposed_issue)
            logging.info('traces are: %r', traces)

        with mc.profiler.Phase('making derived user views'):
            derived_users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, [proposed_issue.derived_owner_id],
                proposed_issue.derived_cc_ids)
            framework_views.RevealAllEmailsToMembers(mc.auth, project,
                                                     derived_users_by_id)

        with mc.profiler.Phase('pair derived values with rule explanations'):
            (derived_labels, derived_owners, derived_ccs, warnings,
             errors) = (tracker_helpers.PairDerivedValuesWithRuleExplanations(
                 proposed_issue, traces, derived_users_by_id))

        result = issues_pb2.PresubmitIssueResponse(
            owner_availability=proposed_owner_view.avail_message_short,
            owner_availability_state=proposed_owner_view.avail_state,
            derived_labels=converters.ConvertValueAndWhyList(derived_labels),
            derived_owners=converters.ConvertValueAndWhyList(derived_owners),
            derived_ccs=converters.ConvertValueAndWhyList(derived_ccs),
            warnings=converters.ConvertValueAndWhyList(warnings),
            errors=converters.ConvertValueAndWhyList(errors))
        return result
Ejemplo n.º 9
0
    def GatherPageData(self, mr):
        """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """
        page_data = super(AdminRules, self).GatherPageData(mr)
        rules = self.services.features.GetFilterRules(mr.cnxn, mr.project_id)
        users_by_id = framework_views.MakeAllUserViews(
            mr.cnxn, self.services.user,
            [rule.default_owner_id for rule in rules],
            *[rule.add_cc_ids for rule in rules])
        framework_views.RevealAllEmailsToMembers(mr.auth, mr.project,
                                                 users_by_id)
        rule_views = [
            filterrules_views.RuleView(rule, users_by_id) for rule in rules
        ]

        for idx, rule_view in enumerate(rule_views):
            rule_view.idx = idx + 1  # EZT has no loop index, so we set idx.

        page_data.update({
            'rules':
            rule_views,
            'new_rule_indexes':
            (list(range(len(rules) + 1, filterrules_helpers.MAX_RULES + 1))),
            'max_rules':
            filterrules_helpers.MAX_RULES,
        })
        return page_data
Ejemplo n.º 10
0
    def GetConfig(self, mc, request):
        """Return the specified project config."""
        project = self._GetProject(mc, request)

        with work_env.WorkEnv(mc, self.services) as we:
            config = we.GetProjectConfig(project.project_id)

        with mc.profiler.Phase('making user views'):
            users_involved = tracker_bizobj.UsersInvolvedInConfig(config)
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, users_involved)
            framework_views.RevealAllEmailsToMembers(mc.auth, project,
                                                     users_by_id)

            label_ids = tracker_bizobj.LabelIDsInvolvedInConfig(config)
            labels_by_id = {
                label_id:
                self.services.config.LookupLabel(mc.cnxn, config.project_id,
                                                 label_id)
                for label_id in label_ids
            }

        result = converters.ConvertConfig(project, config, users_by_id,
                                          labels_by_id)
        return result
Ejemplo n.º 11
0
  def GatherPageData(self, mr):
    """Build up a dictionary of data values to use when rendering the page."""
    if mr.auth.user_id:
      self.services.user.AddVisitedHotlist(
          mr.cnxn, mr.auth.user_id, mr.hotlist_id)

    all_members = (mr.hotlist.owner_ids +
                   mr.hotlist.editor_ids + mr.hotlist.follower_ids)

    hotlist_url = hotlist_helpers.GetURLOfHotlist(
        mr.cnxn, mr.hotlist, self.services.user)

    with self.profiler.Phase('gathering members on this page'):
      users_by_id = framework_views.MakeAllUserViews(
          mr.cnxn, self.services.user, all_members)
      framework_views.RevealAllEmailsToMembers(mr, users_by_id)

    untrusted_user_group_proxies = []
    # TODO(jojwang): implement FindUntrustedGroups()

    with self.profiler.Phase('making member views'):
      owner_views = self._MakeMemberViews(mr, mr.hotlist.owner_ids, users_by_id)
      editor_views = self._MakeMemberViews(mr, mr.hotlist.editor_ids,
                                           users_by_id)
      follower_views = self._MakeMemberViews(mr, mr.hotlist.follower_ids,
                                             users_by_id)
      all_member_views = owner_views + editor_views + follower_views

    pagination = paginate.ArtifactPagination(
        mr, all_member_views, MEMBERS_PER_PAGE,'%s%s' % (
              hotlist_url, urls.HOTLIST_PEOPLE))

    offer_membership_editing = permissions.CanAdministerHotlist(
        mr.auth.effective_ids, mr.hotlist)

    newly_added_views = [mv for mv in all_member_views
                         if str(mv.user.user_id) in mr.GetParam('new', [])]

    return {
        'is_hotlist': ezt.boolean(True),
        'untrusted_user_groups': untrusted_user_group_proxies,
        'pagination': pagination,
        'initial_add_members': '',
        'subtab_mode': None,
        'initially_expand_form': ezt.boolean(False),
        'newly_added_views': newly_added_views,
        'offer_membership_editing': ezt.boolean(offer_membership_editing),
        'total_num_owners': len(mr.hotlist.owner_ids),
        'check_abandonment': ezt.boolean(True),
        'initial_new_owner_username': '',
        'placeholder': 'new-owner-username',
        'open_dialog': ezt.boolean(False),
        'viewing_user_page': ezt.boolean(True),
        }
Ejemplo n.º 12
0
    def ListHotlistIssues(self, mc, request):
        """Get the issues on the specified hotlist."""
        # TODO(ehmaldonado): This probably doesn't work, since we need to check
        # the permissions for each issue in their own project, and we're not doing
        # that.
        hotlist_id = converters.IngestHotlistRef(mc.cnxn, self.services.user,
                                                 self.services.features,
                                                 request.hotlist_ref)

        with work_env.WorkEnv(mc, self.services) as we:
            hotlist_items = we.GetHotlist(hotlist_id).items
            issue_ids = [item.issue_id for item in hotlist_items]
            issues = we.GetIssuesDict(issue_ids)

            projects = we.GetProjectsByName(
                [issue.project_name for issue in issues.values()])
            configs = we.GetProjectConfigs(
                [project.project_id for project in projects.values()])
            configs = {
                project.project_name: configs[project.project_id]
                for project in projects.values()
            }
            related_refs = we.GetRelatedIssueRefs(iter(issues.values()))

        with mc.profiler.Phase('making user views'):
            users_involved = set(item.adder_id for item in hotlist_items)
            users_involved.update(
                tracker_bizobj.UsersInvolvedInIssues(iter(issues.values())))
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, users_involved)
            framework_views.RevealAllEmailsToMembers(mc.auth, None,
                                                     users_by_id)

        hotlist_items = [
            hotlist_item for hotlist_item in hotlist_items
            if hotlist_item.issue_id in issues
        ]

        start, max_items = converters.IngestPagination(request.pagination)
        pagination = paginate.ArtifactPagination(hotlist_items, max_items,
                                                 start, None, None)

        result = features_pb2.ListHotlistIssuesResponse(items=[
            converters.ConvertHotlistItem(hotlist_item, issues, users_by_id,
                                          related_refs, configs)
            for hotlist_item in pagination.visible_results
        ])
        return result
Ejemplo n.º 13
0
def convert_amendments(issue, amendments, mar, services):
    """Convert a list of Monorail Amendment PBs to API Update."""
    amendments_user_ids = tracker_bizobj.UsersInvolvedInAmendments(amendments)
    users_by_id = framework_views.MakeAllUserViews(mar.cnxn, services.user,
                                                   amendments_user_ids)
    framework_views.RevealAllEmailsToMembers(mar.auth, mar.project,
                                             users_by_id)

    result = api_pb2_v1.Update(kind='monorail#issueCommentUpdate')
    for amendment in amendments:
        if amendment.field == tracker_pb2.FieldID.SUMMARY:
            result.summary = amendment.newvalue
        elif amendment.field == tracker_pb2.FieldID.STATUS:
            result.status = amendment.newvalue
        elif amendment.field == tracker_pb2.FieldID.OWNER:
            if len(amendment.added_user_ids) == 0:
                result.owner = framework_constants.NO_USER_NAME
            else:
                result.owner = _get_user_email(services.user, mar.cnxn,
                                               amendment.added_user_ids[0])
        elif amendment.field == tracker_pb2.FieldID.LABELS:
            result.labels = amendment.newvalue.split()
        elif amendment.field == tracker_pb2.FieldID.CC:
            for user_id in amendment.added_user_ids:
                user_email = _get_user_email(services.user, mar.cnxn, user_id)
                result.cc.append(user_email)
            for user_id in amendment.removed_user_ids:
                user_email = _get_user_email(services.user, mar.cnxn, user_id)
                result.cc.append('-%s' % user_email)
        elif amendment.field == tracker_pb2.FieldID.BLOCKEDON:
            result.blockedOn = _append_project(amendment.newvalue,
                                               issue.project_name)
        elif amendment.field == tracker_pb2.FieldID.BLOCKING:
            result.blocking = _append_project(amendment.newvalue,
                                              issue.project_name)
        elif amendment.field == tracker_pb2.FieldID.MERGEDINTO:
            result.mergedInto = amendment.newvalue
        elif amendment.field == tracker_pb2.FieldID.COMPONENTS:
            result.components = amendment.newvalue.split()
        elif amendment.field == tracker_pb2.FieldID.CUSTOM:
            fv = api_pb2_v1.FieldValue()
            fv.fieldName = amendment.custom_field_name
            fv.fieldValue = tracker_bizobj.AmendmentString(
                amendment, users_by_id)
            result.fieldValues.append(fv)

    return result
Ejemplo n.º 14
0
    def ListReferencedIssues(self, mc, request):
        """Return the specified issues in a response proto."""
        if not request.issue_refs:
            return issues_pb2.ListReferencedIssuesResponse()

        for issue_ref in request.issue_refs:
            if not issue_ref.project_name:
                raise exceptions.InputException(
                    'Param `project_name` required.')
            if not issue_ref.local_id:
                raise exceptions.InputException('Param `local_id` required.')

        default_project_name = request.issue_refs[0].project_name
        ref_tuples = [(ref.project_name, ref.local_id)
                      for ref in request.issue_refs]
        with work_env.WorkEnv(mc, self.services) as we:
            open_issues, closed_issues = we.ListReferencedIssues(
                ref_tuples, default_project_name)
            all_issues = open_issues + closed_issues
            all_project_ids = [issue.project_id for issue in all_issues]
            related_refs = we.GetRelatedIssueRefs(all_issues)
            configs = we.GetProjectConfigs(all_project_ids)

        with mc.profiler.Phase('making user views'):
            users_involved = tracker_bizobj.UsersInvolvedInIssues(all_issues)
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, users_involved)
            framework_views.RevealAllEmailsToMembers(mc.auth, None,
                                                     users_by_id)

        with mc.profiler.Phase('converting to response objects'):
            converted_open_issues = [
                converters.ConvertIssue(issue, users_by_id, related_refs,
                                        configs[issue.project_id])
                for issue in open_issues
            ]
            converted_closed_issues = [
                converters.ConvertIssue(issue, users_by_id, related_refs,
                                        configs[issue.project_id])
                for issue in closed_issues
            ]
            response = issues_pb2.ListReferencedIssuesResponse(
                open_refs=converted_open_issues,
                closed_refs=converted_closed_issues)

        return response
Ejemplo n.º 15
0
    def GetIssue(self, mc, request):
        """Return the specified issue in a response proto."""
        issue_ref = request.issue_ref
        project, issue, config = self._GetProjectIssueAndConfig(
            mc, issue_ref, view_deleted=True, issue_required=False)

        # Code for getting where a moved issue was moved to.
        if issue is None:
            moved_to_ref = self.services.issue.GetCurrentLocationOfMovedIssue(
                mc.cnxn, project.project_id, issue_ref.local_id)
            moved_to_project_id, moved_to_id = moved_to_ref
            moved_to_project_name = None

            if moved_to_project_id is not None:
                with work_env.WorkEnv(mc, self.services) as we:
                    moved_to_project = we.GetProject(moved_to_project_id)
                    moved_to_project_name = moved_to_project.project_name
                return issues_pb2.IssueResponse(
                    moved_to_ref=converters.ConvertIssueRef((
                        moved_to_project_name, moved_to_id)))

            raise exceptions.NoSuchIssueException()

        if issue.deleted:
            return issues_pb2.IssueResponse(issue=issue_objects_pb2.Issue(
                is_deleted=True))

        with work_env.WorkEnv(mc, self.services) as we:
            related_refs = we.GetRelatedIssueRefs([issue])

        with mc.profiler.Phase('making user views'):
            users_involved_in_issue = tracker_bizobj.UsersInvolvedInIssues(
                [issue])
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, users_involved_in_issue)
            framework_views.RevealAllEmailsToMembers(mc.auth, project,
                                                     users_by_id)

        with mc.profiler.Phase('converting to response objects'):
            response = issues_pb2.IssueResponse()
            response.issue.CopyFrom(
                converters.ConvertIssue(issue, users_by_id, related_refs,
                                        config))

        return response
Ejemplo n.º 16
0
    def UpdateApproval(self, mc, request):
        """Update an approval and return the updated approval in a reponse proto."""
        project, issue, config = self._GetProjectIssueAndConfig(
            mc, request.issue_ref, use_cache=False)

        approval_fd = tracker_bizobj.FindFieldDef(request.field_ref.field_name,
                                                  config)
        if not approval_fd:
            raise exceptions.NoSuchFieldDefException()
        if request.HasField('approval_delta'):
            approval_delta = converters.IngestApprovalDelta(
                mc.cnxn, self.services.user, request.approval_delta,
                mc.auth.user_id, config)
        else:
            approval_delta = tracker_pb2.ApprovalDelta()
        attachments = converters.IngestAttachmentUploads(request.uploads)

        with work_env.WorkEnv(mc, self.services) as we:
            av, _comment = we.UpdateIssueApproval(
                issue.issue_id,
                approval_fd.field_id,
                approval_delta,
                request.comment_content,
                request.is_description,
                attachments=attachments,
                send_email=request.send_email,
                kept_attachments=list(request.kept_attachments))

        with mc.profiler.Phase('converting to response objects'):
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, av.approver_ids, [av.setter_id])
            framework_views.RevealAllEmailsToMembers(mc.auth, project,
                                                     users_by_id)
            response = issues_pb2.UpdateApprovalResponse()
            response.approval.CopyFrom(
                converters.ConvertApproval(av, users_by_id, config))

        return response
Ejemplo n.º 17
0
    def ListComponents(self, mc, request):
        """Return all component defs in the specified project."""
        project = self._GetProject(mc, request)

        with work_env.WorkEnv(mc, self.services) as we:
            config = we.GetProjectConfig(project.project_id)

        with mc.profiler.Phase('making user views'):
            users_by_id = {}
            if request.include_admin_info:
                users_involved = tracker_bizobj.UsersInvolvedInConfig(config)
                users_by_id = framework_views.MakeAllUserViews(
                    mc.cnxn, self.services.user, users_involved)
                framework_views.RevealAllEmailsToMembers(
                    mc.auth, project, users_by_id)

        with mc.profiler.Phase('looking up labels'):
            labels_by_id = {}
            if request.include_admin_info:
                label_ids = tracker_bizobj.LabelIDsInvolvedInConfig(config)
                labels_by_id = {
                    label_id:
                    self.services.config.LookupLabel(mc.cnxn,
                                                     config.project_id,
                                                     label_id)
                    for label_id in label_ids
                }

        component_defs = [
            converters.ConvertComponentDef(cd, users_by_id, labels_by_id,
                                           request.include_admin_info)
            for cd in config.component_defs
        ]

        result = projects_pb2.ListComponentsResponse(
            component_defs=component_defs)
        return result
Ejemplo n.º 18
0
    def UpdateIssue(self, mc, request):
        """Apply a delta and comment to the specified issue, then return it."""
        project, issue, config = self._GetProjectIssueAndConfig(
            mc, request.issue_ref, use_cache=False)

        with work_env.WorkEnv(mc, self.services) as we:
            if request.HasField('delta'):
                delta = converters.IngestIssueDelta(mc.cnxn, self.services,
                                                    request.delta, config,
                                                    issue.phases)
            else:
                delta = tracker_pb2.IssueDelta()  # No changes specified.
            attachments = converters.IngestAttachmentUploads(request.uploads)
            we.UpdateIssue(issue,
                           delta,
                           request.comment_content,
                           send_email=request.send_email,
                           attachments=attachments,
                           is_description=request.is_description,
                           kept_attachments=list(request.kept_attachments))
            related_refs = we.GetRelatedIssueRefs([issue])

        with mc.profiler.Phase('making user views'):
            users_involved_in_issue = tracker_bizobj.UsersInvolvedInIssues(
                [issue])
            users_by_id = framework_views.MakeAllUserViews(
                mc.cnxn, self.services.user, users_involved_in_issue)
            framework_views.RevealAllEmailsToMembers(mc.auth, project,
                                                     users_by_id)

        with mc.profiler.Phase('converting to response objects'):
            response = issues_pb2.IssueResponse()
            response.issue.CopyFrom(
                converters.ConvertIssue(issue, users_by_id, related_refs,
                                        config))

        return response
Ejemplo n.º 19
0
    def GatherPageData(self, mr):
        """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """
        page_data = super(AdminComponents, self).GatherPageData(mr)
        config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
        users_by_id = framework_views.MakeAllUserViews(
            mr.cnxn, self.services.user, *[
                list(cd.admin_ids) + list(cd.cc_ids)
                for cd in config.component_defs
            ])
        framework_views.RevealAllEmailsToMembers(mr.auth, mr.project,
                                                 users_by_id)
        component_def_views = [
            tracker_views.ComponentDefView(mr.cnxn, self.services, cd,
                                           users_by_id)
            # TODO(jrobbins): future component-level view restrictions.
            for cd in config.component_defs
        ]
        for cd in component_def_views:
            if mr.auth.email in [user.email for user in cd.admins]:
                cd.classes += 'myadmin '
            if mr.auth.email in [user.email for user in cd.cc]:
                cd.classes += 'mycc '

        page_data.update({
            'component_defs': component_def_views,
            'failed_perm': mr.GetParam('failed_perm'),
            'failed_subcomp': mr.GetParam('failed_subcomp'),
            'failed_templ': mr.GetParam('failed_templ'),
        })
        return page_data
Ejemplo n.º 20
0
  def GatherPageData(self, mr):
    """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """
    search_error_message = ''
    with work_env.WorkEnv(mr, self.services) as we:
      # Check if the user's query is just the ID of an existing issue.
      # TODO(jrobbins): consider implementing this for cross-project search.
      if mr.project and tracker_constants.JUMP_RE.match(mr.query):
        local_id = int(mr.query)
        try:
          we.GetIssueByLocalID(mr.project_id, local_id)  # does it exist?
          url = framework_helpers.FormatAbsoluteURL(
              mr, urls.ISSUE_DETAIL, id=local_id)
          self.redirect(url, abort=True)  # Jump to specified issue.
        except exceptions.NoSuchIssueException:
          pass  # The user is searching for a number that is not an issue ID.
      with mr.profiler.Phase('finishing config work'):
        if mr.project_id:
          config = we.GetProjectConfig(mr.project_id)
        else:
          config = tracker_bizobj.MakeDefaultProjectIssueConfig(None)

      url_params = [(name, mr.GetParam(name)) for name in
                    framework_helpers.RECOGNIZED_PARAMS]
      pipeline = we.ListIssues(
          mr.query, mr.query_project_names, mr.me_user_id, mr.num, mr.start,
          url_params, mr.can, mr.group_by_spec, mr.sort_spec,
          mr.use_cached_searches, display_mode=mr.mode, project=mr.project)
      starred_iid_set = set(we.ListStarredIssueIDs())

    with mr.profiler.Phase('computing col_spec'):
      mr.ComputeColSpec(config)

    with mr.profiler.Phase('publishing emails'):
      framework_views.RevealAllEmailsToMembers(
          mr.auth, mr.project, pipeline.users_by_id)

    with mr.profiler.Phase('getting related issues'):
      related_iids = set()
      if pipeline.grid_mode:
        results_needing_related = pipeline.allowed_results or []
      else:
        results_needing_related = pipeline.visible_results or []
      lower_cols = mr.col_spec.lower().split()
      lower_cols.extend(mr.group_by_spec.lower().split())
      grid_x = (mr.x or config.default_x_attr or '--').lower()
      grid_y = (mr.y or config.default_y_attr or '--').lower()
      lower_cols.append(grid_x)
      lower_cols.append(grid_y)
      for issue in results_needing_related:
        if 'blockedon' in lower_cols:
          related_iids.update(issue.blocked_on_iids)
        if 'blocking' in lower_cols:
          related_iids.update(issue.blocking_iids)
        if 'mergedinto' in lower_cols:
          related_iids.add(issue.merged_into)
      related_issues_list = self.services.issue.GetIssues(
          mr.cnxn, list(related_iids))
      related_issues = {issue.issue_id: issue for issue in related_issues_list}

    with mr.profiler.Phase('filtering unviewable issues'):
      viewable_iids_set = {issue.issue_id
                           for issue in tracker_helpers.GetAllowedIssues(
                               mr, [related_issues.values()], self.services)[0]}

    with mr.profiler.Phase('building table/grid'):
      if pipeline.grid_mode:
        # TODO(eyalsoha): Add viewable_iids_set to the grid so that referenced
        # issues can be links.
        page_data = grid_view_helpers.GetGridViewData(
            mr, pipeline.allowed_results or [], pipeline.harmonized_config,
            pipeline.users_by_id, starred_iid_set, pipeline.grid_limited,
            related_issues)
      else:
        page_data = self.GetTableViewData(
            mr, pipeline.visible_results or [], pipeline.harmonized_config,
            pipeline.users_by_id, starred_iid_set, related_issues,
            viewable_iids_set)

    # We show a special message when no query will every produce any results
    # because the project has no issues in it.
    with mr.profiler.Phase('starting stars promise'):
      if mr.project_id:
        project_has_any_issues = (
            pipeline.allowed_results or
            self.services.issue.GetHighestLocalID(mr.cnxn, mr.project_id) != 0)
      else:
        project_has_any_issues = True  # Message only applies in a project.

    with mr.profiler.Phase('making page perms'):
      page_perms = self.MakePagePerms(
          mr, None,
          permissions.SET_STAR,
          permissions.CREATE_ISSUE,
          permissions.EDIT_ISSUE)

    if pipeline.error_responses:
      search_error_message = (
          '%d search backends did not respond or had errors. '
          'These results are probably incomplete.'
          % len(pipeline.error_responses))

    # Update page data with variables that are shared between list and
    # grid view.
    user_hotlists = self.services.features.GetHotlistsByUserID(
        mr.cnxn, mr.auth.user_id)

    new_ui_url = ''
    if hasattr(self.request, 'url'):
      new_ui_url = self.request.url.replace('issues/list', 'issues/list_new')

    # monorail:6336, needed for <ezt-show-columns-connector>
    phase_names = _GetAllPhaseNames(pipeline.visible_results)

    page_data.update({
        'issue_tab_mode': 'issueList',
        'pagination': pipeline.pagination,
        'is_cross_project': ezt.boolean(len(pipeline.query_project_ids) != 1),
        'project_has_any_issues': ezt.boolean(project_has_any_issues),
        'colspec': mr.col_spec,
        # monorail:6336, used in <ezt-show-columns-connector>
        'phasespec': " ".join(phase_names),
        'page_perms': page_perms,
        'grid_mode': ezt.boolean(pipeline.grid_mode),
        'list_mode': ezt.boolean(pipeline.list_mode),
        'chart_mode': ezt.boolean(pipeline.chart_mode),
        'panel_id': mr.panel_id,
        'search_error_message': search_error_message,
        'is_hotlist': ezt.boolean(False),
        # for update-issues-hotlists-dialog, user_remininag_hotlists
        # are displayed with their checkboxes unchecked.
        'user_remaining_hotlists': user_hotlists,
        'user_issue_hotlists': [], # for update-issues-hotlsits-dialog
        # the following are needed by templates for hotlists
        'owner_permissions': ezt.boolean(False),
        'editor_permissions': ezt.boolean(False),
        'edit_hotlist_token': '',
        'add_local_ids': '',
        'placeholder': '',
        'col_spec': '',
        'new_ui_url': new_ui_url,
    })

    return page_data
Ejemplo n.º 21
0
def GatherUpdatesData(services,
                      mr,
                      project_ids=None,
                      user_ids=None,
                      ending=None,
                      updates_page_url=None,
                      autolink=None,
                      highlight=None):
    """Gathers and returns updates data.

  Args:
    services: Connections to backend services.
    mr: HTTP request info, used by the artifact autolink.
    project_ids: List of project IDs we want updates for.
    user_ids: List of user IDs we want updates for.
    ending: Ending type for activity titles, 'in_project' or 'by_user'.
    updates_page_url: The URL that will be used to create pagination links from.
    autolink: Autolink instance.
    highlight: What to highlight in the middle column on user updates pages
        i.e. 'project', 'user', or None.
  """
    # num should be non-negative number
    num = mr.GetPositiveIntParam('num', UPDATES_PER_PAGE)
    num = min(num, MAX_UPDATES_PER_PAGE)

    updates_data = {
        'no_stars': None,
        'no_activities': None,
        'pagination': None,
        'updates_data': None,
        'ending_type': ending,
    }

    if not user_ids and not project_ids:
        updates_data['no_stars'] = ezt.boolean(True)
        return updates_data

    ascending = bool(mr.after)
    with mr.profiler.Phase('get activities'):
        comments = services.issue.GetIssueActivity(mr.cnxn,
                                                   num=num,
                                                   before=mr.before,
                                                   after=mr.after,
                                                   project_ids=project_ids,
                                                   user_ids=user_ids,
                                                   ascending=ascending)
        # Filter the comments based on permission to view the issue.
        # TODO(jrobbins): push permission checking in the query so that
        # pagination pages never become underfilled, or use backends to shard.
        # TODO(jrobbins): come back to this when I implement private comments.
        # TODO(jrobbins): it would be better if we could just get the dict directly.
        prefetched_issues_list = services.issue.GetIssues(
            mr.cnxn, {c.issue_id
                      for c in comments})
        prefetched_issues = {
            issue.issue_id: issue
            for issue in prefetched_issues_list
        }
        needed_project_ids = {
            issue.project_id
            for issue in prefetched_issues_list
        }
        prefetched_projects = services.project.GetProjects(
            mr.cnxn, needed_project_ids)
        prefetched_configs = services.config.GetProjectConfigs(
            mr.cnxn, needed_project_ids)
        viewable_issues_list = tracker_helpers.FilterOutNonViewableIssues(
            mr.auth.effective_ids, mr.auth.user_pb, prefetched_projects,
            prefetched_configs, prefetched_issues_list)
        viewable_iids = {issue.issue_id for issue in viewable_issues_list}
        comments = [c for c in comments if c.issue_id in viewable_iids]
        if ascending:
            comments.reverse()

    amendment_user_ids = []
    for comment in comments:
        for amendment in comment.amendments:
            amendment_user_ids.extend(amendment.added_user_ids)
            amendment_user_ids.extend(amendment.removed_user_ids)

    users_by_id = framework_views.MakeAllUserViews(
        mr.cnxn, services.user, [c.user_id for c in comments],
        amendment_user_ids)
    framework_views.RevealAllEmailsToMembers(mr.auth, mr.project, users_by_id)

    num_results_returned = len(comments)
    displayed_activities = comments[:UPDATES_PER_PAGE]

    if not num_results_returned:
        updates_data['no_activities'] = ezt.boolean(True)
        return updates_data

    # Get all referenced artifacts first
    all_ref_artifacts = None
    if autolink is not None:
        content_list = []
        for activity in comments:
            content_list.append(activity.content)

        all_ref_artifacts = autolink.GetAllReferencedArtifacts(
            mr, content_list)

    # Now process content and gather activities
    today = []
    yesterday = []
    pastweek = []
    pastmonth = []
    thisyear = []
    older = []

    with mr.profiler.Phase('rendering activities'):
        for activity in displayed_activities:
            entry = ActivityView(activity,
                                 mr,
                                 prefetched_issues,
                                 users_by_id,
                                 prefetched_projects,
                                 prefetched_configs,
                                 autolink=autolink,
                                 all_ref_artifacts=all_ref_artifacts,
                                 ending=ending,
                                 highlight=highlight)

            if entry.date_bucket == 'Today':
                today.append(entry)
            elif entry.date_bucket == 'Yesterday':
                yesterday.append(entry)
            elif entry.date_bucket == 'Last 7 days':
                pastweek.append(entry)
            elif entry.date_bucket == 'Last 30 days':
                pastmonth.append(entry)
            elif entry.date_bucket == 'Earlier this year':
                thisyear.append(entry)
            elif entry.date_bucket == 'Before this year':
                older.append(entry)

    new_after = None
    new_before = None
    if displayed_activities:
        new_after = displayed_activities[0].timestamp
        new_before = displayed_activities[-1].timestamp

    prev_url = None
    next_url = None
    if updates_page_url:
        list_servlet_rel_url = updates_page_url.split('/')[-1]
        recognized_params = [(name, mr.GetParam(name))
                             for name in framework_helpers.RECOGNIZED_PARAMS]
        if displayed_activities and (mr.before or mr.after):
            prev_url = framework_helpers.FormatURL(recognized_params,
                                                   list_servlet_rel_url,
                                                   after=new_after)
        if mr.after or len(comments) > UPDATES_PER_PAGE:
            next_url = framework_helpers.FormatURL(recognized_params,
                                                   list_servlet_rel_url,
                                                   before=new_before)

    if prev_url or next_url:
        pagination = template_helpers.EZTItem(start=None,
                                              last=None,
                                              prev_url=prev_url,
                                              next_url=next_url,
                                              reload_url=None,
                                              visible=ezt.boolean(True),
                                              total_count=None)
    else:
        pagination = None

    updates_data.update({
        'no_activities':
        ezt.boolean(False),
        'pagination':
        pagination,
        'updates_data':
        template_helpers.EZTItem(today=today,
                                 yesterday=yesterday,
                                 pastweek=pastweek,
                                 pastmonth=pastmonth,
                                 thisyear=thisyear,
                                 older=older),
    })

    return updates_data
Ejemplo n.º 22
0
  def GatherPageData(self, mr):
    """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """
    if mr.local_id is None:
      self.abort(404, 'no issue specified')
    with work_env.WorkEnv(mr, self.services) as we:
      # Signed in users could edit the issue, so it must be fresh.
      use_cache = not mr.auth.user_id
      issue = we.GetIssueByLocalID(
          mr.project_id, mr.local_id, use_cache=use_cache)

      # We give no explanation of missing issues on the peek page.
      if issue.deleted:
        self.abort(404, 'issue not found')

      star_cnxn = sql.MonorailConnection()
      star_promise = framework_helpers.Promise(
          we.IsIssueStarred, issue, cnxn=star_cnxn)

      config = we.GetProjectConfig(mr.project_id)
      comments = we.ListIssueComments(issue)

    descriptions, visible_comments, cmnt_pagination = PaginateComments(
        mr, issue, comments, config, self.services)

    with mr.profiler.Phase('making user proxies'):
      involved_user_ids = tracker_bizobj.UsersInvolvedInIssues([issue])
      group_ids = self.services.usergroup.DetermineWhichUserIDsAreGroups(
          mr.cnxn, involved_user_ids)
      comment_user_ids = tracker_bizobj.UsersInvolvedInCommentList(
          descriptions + visible_comments)
      users_by_id = framework_views.MakeAllUserViews(
          mr.cnxn, self.services.user, involved_user_ids,
          comment_user_ids, group_ids=group_ids)
      framework_views.RevealAllEmailsToMembers(mr.auth, mr.project, users_by_id)

    (issue_view, description_views,
     comment_views) = self._MakeIssueAndCommentViews(
         mr, issue, users_by_id, descriptions, visible_comments, config,
         issue_reporters=[], comment_reporters=[])

    with mr.profiler.Phase('getting starring info'):
      starred = star_promise.WaitAndGetValue()
      star_cnxn.Close()
      permit_edit = permissions.CanEditIssue(
          mr.auth.effective_ids, mr.perms, mr.project, issue)

    mr.ComputeColSpec(config)
    restrict_to_known = config.restrict_to_known

    page_perms = self.MakePagePerms(
        mr, issue,
        permissions.CREATE_ISSUE,
        permissions.SET_STAR,
        permissions.EDIT_ISSUE,
        permissions.EDIT_ISSUE_SUMMARY,
        permissions.EDIT_ISSUE_STATUS,
        permissions.EDIT_ISSUE_OWNER,
        permissions.EDIT_ISSUE_CC,
        permissions.DELETE_ISSUE,
        permissions.ADD_ISSUE_COMMENT,
        permissions.DELETE_OWN,
        permissions.DELETE_ANY,
        permissions.VIEW_INBOUND_MESSAGES)
    page_perms.EditIssue = ezt.boolean(permit_edit)

    prevent_restriction_removal = (
        mr.project.only_owners_remove_restrictions and
        not framework_bizobj.UserOwnsProject(
            mr.project, mr.auth.effective_ids))

    cmd_slots, default_slot_num = self.services.features.GetRecentCommands(
        mr.cnxn, mr.auth.user_id, mr.project_id)
    cmd_slot_views = [
        template_helpers.EZTItem(
            slot_num=slot_num, command=command, comment=comment)
        for slot_num, command, comment in cmd_slots]

    previous_locations = self.GetPreviousLocations(mr, issue)

    return {
        'issue_tab_mode': 'issueDetail',
        'issue': issue_view,
        'description': description_views,
        'comments': comment_views,
        'labels': issue.labels,
        'num_detail_rows': len(comment_views) + 4,
        'noisy': ezt.boolean(tracker_helpers.IsNoisy(
            len(comment_views), issue.star_count)),

        'cmnt_pagination': cmnt_pagination,
        'colspec': mr.col_spec,
        'searchtip': 'You can jump to any issue by number',
        'starred': ezt.boolean(starred),

        'pagegen': str(int(time.time() * 1000000)),

        'restrict_to_known': ezt.boolean(restrict_to_known),
        'prevent_restriction_removal': ezt.boolean(
            prevent_restriction_removal),

        'statuses_offer_merge': config.statuses_offer_merge,
        'page_perms': page_perms,
        'cmd_slots': cmd_slot_views,
        'default_slot_num': default_slot_num,
        'quick_edit_submit_url': tracker_helpers.FormatRelativeIssueURL(
            issue.project_name, urls.ISSUE_PEEK + '.do', id=issue.local_id),
        'previous_locations': previous_locations,
        # for template issue-meta-part shared by issuedetail servlet
        'user_remaining_hotlists': [],
        'user_issue_hotlists': [],
        'involved_users_issue_hotlists': [],
        'remaining_issue_hotlists': [],
        }
Ejemplo n.º 23
0
  def CheckRevealAllToMember(
      self, logged_in_user_id, expected, viewed_user_id=333L, group_id=None):
    user_view = framework_views.StuffUserView(
        viewed_user_id, '*****@*****.**', True)

    if group_id:
      pass  # xxx re-implement groups

    users_by_id = {333L: user_view}
    self.mr.auth.user_id = logged_in_user_id
    self.mr.auth.effective_ids = {logged_in_user_id}
    # Assert display name is obscured before the reveal.
    self.assertEqual('*****@*****.**', user_view.display_name)
    # Assert profile url contains user ID before the reveal.
    self.assertEqual('/u/%s/' % viewed_user_id, user_view.profile_url)
    framework_views.RevealAllEmailsToMembers(self.mr, users_by_id)
    self.assertEqual(expected, not user_view.obscure_email)
    if expected:
      # Assert display name is now revealed.
      self.assertEqual('*****@*****.**', user_view.display_name)
      # Assert profile url contains the email.
      self.assertEqual('/u/[email protected]/', user_view.profile_url)
    else:
      # Assert display name is still hidden.
      self.assertEqual('*****@*****.**', user_view.display_name)
      # Assert profile url still contains user ID.
      self.assertEqual('/u/%s/' % viewed_user_id, user_view.profile_url)

  def testRevealEmailsToPriviledgedDomain(self):
    for priviledged_user_domain in settings.priviledged_user_domains:
      self.mr.auth.user_pb.email = 'test@' + priviledged_user_domain
Ejemplo n.º 24
0
    def GatherPageData(self, mr):
        """Build up a dictionary of data values to use when rendering the page."""
        all_members = (mr.project.owner_ids + mr.project.committer_ids +
                       mr.project.contributor_ids)

        with self.profiler.Phase('gathering members on this page'):
            users_by_id = framework_views.MakeAllUserViews(
                mr.cnxn, self.services.user, all_members)
            framework_views.RevealAllEmailsToMembers(mr, users_by_id)

        # TODO(jrobbins): re-implement FindUntrustedGroups()
        untrusted_user_group_proxies = []

        with self.profiler.Phase('gathering commitments (notes)'):
            project_commitments = self.services.project.GetProjectCommitments(
                mr.cnxn, mr.project_id)

        with self.profiler.Phase('gathering autocomple exclusion ids'):
            acexclusion_ids = self.services.project.GetProjectAutocompleteExclusion(
                mr.cnxn, mr.project_id)

        with self.profiler.Phase('making member views'):
            owner_views = self._MakeMemberViews(mr.auth.user_id, users_by_id,
                                                mr.project.owner_ids,
                                                mr.project,
                                                project_commitments,
                                                acexclusion_ids)
            committer_views = self._MakeMemberViews(
                mr.auth.user_id, users_by_id, mr.project.committer_ids,
                mr.project, project_commitments, acexclusion_ids)
            contributor_views = self._MakeMemberViews(
                mr.auth.user_id, users_by_id, mr.project.contributor_ids,
                mr.project, project_commitments, acexclusion_ids)
            all_member_views = owner_views + committer_views + contributor_views

        pagination = paginate.ArtifactPagination(mr, all_member_views,
                                                 MEMBERS_PER_PAGE,
                                                 urls.PEOPLE_LIST)

        offer_membership_editing = mr.perms.HasPerm(permissions.EDIT_PROJECT,
                                                    mr.auth.user_id,
                                                    mr.project)

        check_abandonment = permissions.ShouldCheckForAbandonment(mr)

        newly_added_views = [
            mv for mv in all_member_views
            if str(mv.user.user_id) in mr.GetParam('new', [])
        ]

        return {
            'pagination': pagination,
            'subtab_mode': None,
            'offer_membership_editing': ezt.boolean(offer_membership_editing),
            'initial_add_members': '',
            'initially_expand_form': ezt.boolean(False),
            'untrusted_user_groups': untrusted_user_group_proxies,
            'check_abandonment': ezt.boolean(check_abandonment),
            'total_num_owners': len(mr.project.owner_ids),
            'newly_added_views': newly_added_views,
            'is_hotlist': ezt.boolean(False),
        }
Ejemplo n.º 25
0
    def ListActivities(self, mc, request):
        """Return issue activities by a specified user in a response proto."""
        converted_user = converters.IngestUserRef(mc.cnxn, request.user_ref,
                                                  self.services.user)
        user = self.services.user.GetUser(mc.cnxn, converted_user)
        comments = self.services.issue.GetIssueActivity(
            mc.cnxn, user_ids={request.user_ref.user_id})
        issues = self.services.issue.GetIssues(mc.cnxn,
                                               {c.issue_id
                                                for c in comments})
        project_dict = tracker_helpers.GetAllIssueProjects(
            mc.cnxn, issues, self.services.project)
        config_dict = self.services.config.GetProjectConfigs(
            mc.cnxn, list(project_dict.keys()))
        allowed_issues = tracker_helpers.FilterOutNonViewableIssues(
            mc.auth.effective_ids, user, project_dict, config_dict, issues)
        issue_dict = {issue.issue_id: issue for issue in allowed_issues}
        comments = [c for c in comments if c.issue_id in issue_dict]

        users_by_id = framework_views.MakeAllUserViews(
            mc.cnxn, self.services.user, [request.user_ref.user_id],
            tracker_bizobj.UsersInvolvedInCommentList(comments))
        for project in project_dict.values():
            framework_views.RevealAllEmailsToMembers(mc.auth, project,
                                                     users_by_id)

        issues_by_project = {}
        for issue in allowed_issues:
            issues_by_project.setdefault(issue.project_id, []).append(issue)

        # A dictionary {issue_id: perms} of the PermissionSet for the current user
        # on each of the issues.
        issue_perms_dict = {}
        # A dictionary {comment_id: [reporter_id]} of users who have reported the
        # comment as spam.
        comment_reporters = {}
        for project_id, project_issues in issues_by_project.items():
            mc.LookupLoggedInUserPerms(project_dict[project_id])
            issue_perms_dict.update({
                issue.issue_id: permissions.UpdateIssuePermissions(
                    mc.perms,
                    project_dict[issue.project_id],
                    issue,
                    mc.auth.effective_ids,
                    config=config_dict[issue.project_id])
                for issue in project_issues
            })

            with work_env.WorkEnv(mc, self.services) as we:
                project_issue_reporters = we.LookupIssuesFlaggers(
                    project_issues)
                for _, issue_comment_reporters in project_issue_reporters.values(
                ):
                    comment_reporters.update(issue_comment_reporters)

        with mc.profiler.Phase('converting to response objects'):
            converted_comments = []
            for c in comments:
                issue = issue_dict.get(c.issue_id)
                issue_perms = issue_perms_dict.get(c.issue_id)
                result = converters.ConvertComment(
                    issue, c, config_dict.get(issue.project_id), users_by_id,
                    comment_reporters.get(c.id, []),
                    {c.id: 1} if c.is_description else {}, mc.auth.user_id,
                    issue_perms)
                converted_comments.append(result)
            converted_issues = [
                issue_objects_pb2.IssueSummary(project_name=issue.project_name,
                                               local_id=issue.local_id,
                                               summary=issue.summary)
                for issue in allowed_issues
            ]
            response = issues_pb2.ListActivitiesResponse(
                comments=converted_comments, issue_summaries=converted_issues)

        return response
Ejemplo n.º 26
0
    def GatherPageData(self, mr):
        """Build up a dictionary of data values to use when rendering the page."""

        member_id = self.ValidateMemberID(mr.cnxn, mr.specified_user_id,
                                          mr.project)
        group_ids = self.services.usergroup.DetermineWhichUserIDsAreGroups(
            mr.cnxn, [member_id])
        users_by_id = framework_views.MakeAllUserViews(mr.cnxn,
                                                       self.services.user,
                                                       [member_id])
        framework_views.RevealAllEmailsToMembers(mr.auth, mr.project,
                                                 users_by_id)

        project_commitments = self.services.project.GetProjectCommitments(
            mr.cnxn, mr.project_id)
        (ac_exclusion_ids, no_expand_ids
         ) = self.services.project.GetProjectAutocompleteExclusion(
             mr.cnxn, mr.project_id)
        member_view = project_views.MemberView(
            mr.auth.user_id,
            member_id,
            users_by_id[member_id],
            mr.project,
            project_commitments,
            ac_exclusion=(member_id in ac_exclusion_ids),
            no_expand=(member_id in no_expand_ids),
            is_group=(member_id in group_ids))

        member_user = self.services.user.GetUser(mr.cnxn, member_id)
        # This ignores indirect memberships, which is ok because we are viewing
        # the page for a member directly involved in the project
        role_perms = permissions.GetPermissions(member_user, {member_id},
                                                mr.project)

        # TODO(jrobbins): clarify in the UI which permissions are built-in to
        # the user's direct role, vs. which are granted via a group membership,
        # vs. which ones are extra_perms that have been added specifically for
        # this user.
        member_perms = template_helpers.EZTItem()
        for perm in CHECKBOX_PERMS:
            setattr(
                member_perms, perm,
                ezt.boolean(role_perms.HasPerm(perm, member_id, mr.project)))

        displayed_extra_perms = [
            perm for perm in member_view.extra_perms
            if perm not in CHECKBOX_PERMS
        ]

        viewing_self = mr.auth.user_id == member_id
        warn_abandonment = (viewing_self
                            and permissions.ShouldCheckForAbandonment(mr))

        return {
            'subtab_mode':
            None,
            'member':
            member_view,
            'role_perms':
            role_perms,
            'member_perms':
            member_perms,
            'displayed_extra_perms':
            displayed_extra_perms,
            'offer_edit_perms':
            ezt.boolean(self.CanEditPerms(mr)),
            'offer_edit_member_notes':
            ezt.boolean(self.CanEditMemberNotes(mr, member_id)),
            'offer_remove_role':
            ezt.boolean(self.CanRemoveRole(mr, member_id)),
            'expand_perms':
            ezt.boolean(mr.auth.user_pb.keep_people_perms_open),
            'warn_abandonment':
            ezt.boolean(warn_abandonment),
            'total_num_owners':
            len(mr.project.owner_ids),
        }
Ejemplo n.º 27
0
    def GatherPageData(self, mr):
        """Build up a dictionary of data values to use when rendering the page.

    Args:
      mr: commonly used info parsed from the request.

    Returns:
      Dict of values used by EZT for rendering the page.
    """

        config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
        template = self.services.template.GetTemplateByName(
            mr.cnxn, mr.template_name, mr.project_id)
        template_view = tracker_views.IssueTemplateView(
            mr, template, self.services.user, config)
        with mr.profiler.Phase('making user views'):
            users_involved = tracker_bizobj.UsersInvolvedInTemplate(template)
            users_by_id = framework_views.MakeAllUserViews(
                mr.cnxn, self.services.user, users_involved)
            framework_views.RevealAllEmailsToMembers(mr.auth, mr.project,
                                                     users_by_id)
        field_name_set = {
            fd.field_name.lower()
            for fd in config.field_defs
            if fd.field_type is tracker_pb2.FieldTypes.ENUM_TYPE
            and not fd.is_deleted
        }
        non_masked_labels = tracker_bizobj.NonMaskedLabels(
            template.labels, field_name_set)

        field_views = tracker_views.MakeAllFieldValueViews(
            config,
            template.labels, [],
            template.field_values,
            users_by_id,
            phases=template.phases)

        (prechecked_approvals, required_approval_ids,
         initial_phases) = template_helpers.GatherApprovalsPageData(
             template.approval_values, template.phases, config)

        allow_edit = permissions.CanEditTemplate(mr.auth.effective_ids,
                                                 mr.perms, mr.project,
                                                 template)

        return {
            'admin_tab_mode':
            self._PROCESS_SUBTAB,
            'allow_edit':
            ezt.boolean(allow_edit),
            'new_template_form':
            ezt.boolean(False),
            'initial_members_only':
            template_view.members_only,
            'template_name':
            template_view.name,
            'initial_summary':
            template_view.summary,
            'initial_must_edit_summary':
            template_view.summary_must_be_edited,
            'initial_content':
            template_view.content,
            'initial_status':
            template_view.status,
            'initial_owner':
            template_view.ownername,
            'initial_owner_defaults_to_member':
            template_view.owner_defaults_to_member,
            'initial_components':
            template_view.components,
            'initial_component_required':
            template_view.component_required,
            'fields': [
                view for view in field_views
                if view.field_def.type_name is not 'APPROVAL_TYPE'
            ],
            'initial_add_approvals':
            ezt.boolean(prechecked_approvals),
            'initial_phases':
            initial_phases,
            'approvals': [
                view for view in field_views
                if view.field_def.type_name is 'APPROVAL_TYPE'
            ],
            'prechecked_approvals':
            prechecked_approvals,
            'required_approval_ids':
            required_approval_ids,
            'labels':
            non_masked_labels,
            'initial_admins':
            template_view.admin_names,
        }