Esempio n. 1
0
    def testGetURLOfHotlist(self):
        cnxn = 'fake cnxn'
        user = self.services.user.TestAddUser('*****@*****.**', 432)
        user.obscure_email = False
        hotlist1 = self.services.features.TestAddHotlist('hotlist1',
                                                         hotlist_id=123,
                                                         owner_ids=[432])
        url = hotlist_helpers.GetURLOfHotlist(cnxn, hotlist1,
                                              self.services.user)
        self.assertEqual('/u/[email protected]/hotlists/hotlist1', url)

        url = hotlist_helpers.GetURLOfHotlist(cnxn,
                                              hotlist1,
                                              self.services.user,
                                              url_for_token=True)
        self.assertEqual('/u/432/hotlists/hotlist1', url)

        user.obscure_email = True
        url = hotlist_helpers.GetURLOfHotlist(cnxn, hotlist1,
                                              self.services.user)
        self.assertEqual('/u/432/hotlists/hotlist1', url)

        # Test that a Hotlist without an owner has an empty URL.
        hotlist_unowned = self.services.features.TestAddHotlist('hotlist2',
                                                                hotlist_id=234,
                                                                owner_ids=[])
        url = hotlist_helpers.GetURLOfHotlist(cnxn, hotlist_unowned,
                                              self.services.user)
        self.assertFalse(url)
Esempio n. 2
0
  def ProcessChangeOwnership(self, mr, post_data):
    new_owner_id_set = project_helpers.ParseUsernames(
        mr.cnxn, self.services.user, post_data.get('changeowners'))
    remain_as_editor = post_data.get('becomeeditor') == 'on'
    if len(new_owner_id_set) != 1:
      mr.errors.transfer_ownership = (
          'Please add one valid user email.')
    else:
      new_owner_id = new_owner_id_set.pop()
      if self.services.features.LookupHotlistIDs(
          mr.cnxn, [mr.hotlist.name], [new_owner_id]):
        mr.errors.transfer_ownership = (
            'This user already owns a hotlist with the same name')

    if mr.errors.AnyErrors():
      self.PleaseCorrect(
          mr, initial_new_owner_username=post_data.get('changeowners'),
          open_dialog=ezt.boolean(True))
    else:
      old_and_new_owner_ids = [new_owner_id] + mr.hotlist.owner_ids
      (_, editor_ids, follower_ids) = hotlist_helpers.MembersWithoutGivenIDs(
          mr.hotlist, old_and_new_owner_ids)
      if remain_as_editor and mr.hotlist.owner_ids:
        editor_ids.append(mr.hotlist.owner_ids[0])

      self.services.features.UpdateHotlistRoles(
          mr.cnxn, mr.hotlist_id, [new_owner_id], editor_ids, follower_ids)

      hotlist = self.services.features.GetHotlist(mr.cnxn, mr.hotlist_id)
      hotlist_url = hotlist_helpers.GetURLOfHotlist(
        mr.cnxn, hotlist, self.services.user)
      return framework_helpers.FormatAbsoluteURL(
          mr,'%s%s' % (hotlist_url, urls.HOTLIST_PEOPLE),
          saved=1, ts=int(time.time()),
          include_project=False)
Esempio n. 3
0
def _ComputeBackToListURL(mr, issue, config, hotlist, services):
    """Construct a URL to return the user to the place that they came from."""
    if hotlist:
        back_to_list_url = hotlist_helpers.GetURLOfHotlist(
            mr.cnxn, hotlist, services.user)
    else:
        back_to_list_url = tracker_helpers.FormatIssueListURL(
            mr, config, cursor='%s:%d' % (issue.project_name, issue.local_id))

    return back_to_list_url
    def _GatherHotlists(self, mr):
        """Return a dict of hotlist names the current user is involved in."""
        with self.profiler.Phase('GetUserHotlists'):
            user_hotlists = self.services.features.GetHotlistsByUserID(
                mr.cnxn, mr.auth.user_id)

            user_starred_hids = self.services.hotlist_star.LookupStarredItemIDs(
                mr.cnxn, mr.auth.user_id)
            user_starred_hotlists, _ = self.services.features.GetHotlistsByID(
                mr.cnxn, user_starred_hids)

            recently_visited_hids = self.services.user.GetRecentlyVisitedHotlists(
                mr.cnxn, mr.auth.user_id)
            recently_visited_hotlists, _ = self.services.features.GetHotlistsByID(
                mr.cnxn, [hid for hid in recently_visited_hids])

        hotlists_dict = {
            'ownerof':
            [(h.name,
              hotlist_helpers.GetURLOfHotlist(mr.cnxn, h, self.services.user))
             for h in user_hotlists if mr.auth.user_id in h.owner_ids],
            'editorof':
            [(h.name,
              hotlist_helpers.GetURLOfHotlist(mr.cnxn, h, self.services.user))
             for h in user_hotlists if mr.auth.user_id in h.editor_ids],
            'starred_hotlists':
            [(h.name,
              hotlist_helpers.GetURLOfHotlist(mr.cnxn, h, self.services.user))
             for h in user_starred_hotlists.values()
             if permissions.CanViewHotlist(mr.auth.effective_ids, h)
             and h not in user_hotlists],
            'visited_hotlists':
            [(recently_visited_hotlists[hid].name,
              hotlist_helpers.GetURLOfHotlist(mr.cnxn,
                                              recently_visited_hotlists[hid],
                                              self.services.user))
             for hid in recently_visited_hids
             if recently_visited_hotlists[hid] not in user_hotlists
             and hid not in user_starred_hids],
            'user':
            mr.auth.email
        }
        return hotlists_dict
Esempio n. 5
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),
        }
Esempio n. 6
0
    def GetTableViewData(self, mr):
        """EZT template values to render a Table View of issues.

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

    Returns:
      Dictionary of page data for rendering of the Table View.
    """
        table_data, table_related_dict = hotlist_helpers.CreateHotlistTableData(
            mr, mr.hotlist.items, self.services)
        columns = mr.col_spec.split()
        ordered_columns = [
            template_helpers.EZTItem(col_index=i, name=col)
            for i, col in enumerate(columns)
        ]
        table_view_data = {
            'table_data':
            table_data,
            'panels':
            [template_helpers.EZTItem(ordered_columns=ordered_columns)],
            'cursor':
            mr.cursor or mr.preview,
            'preview':
            mr.preview,
            'default_colspec':
            features_constants.DEFAULT_COL_SPEC,
            'default_results_per_page':
            10,
            'preview_on_hover': (settings.enable_quick_edit
                                 and mr.auth.user_pb.preview_on_hover),
            # token must be generated using url with userid to accommodate
            # multiple urls for one hotlist
            'edit_hotlist_token':
            xsrf.GenerateToken(
                mr.auth.user_id,
                hotlist_helpers.GetURLOfHotlist(mr.cnxn,
                                                mr.hotlist,
                                                self.services.user,
                                                url_for_token=True) + '.do'),
            'add_local_ids':
            '',
            'placeholder':
            _INITIAL_ADD_ISSUES_MESSAGE,
            'add_issues_selected':
            ezt.boolean(False),
            'col_spec':
            ''
        }
        table_view_data.update(table_related_dict)

        return table_view_data
Esempio n. 7
0
 def ProcessFormData(self, mr, post_data):
   """Process the posted form."""
   permit_edit = permissions.CanAdministerHotlist(
       mr.auth.effective_ids, mr.hotlist)
   if not permit_edit:
     raise permissions.PermissionException(
         'User is not permitted to edit hotlist membership')
   hotlist_url = hotlist_helpers.GetURLOfHotlist(
       mr.cnxn, mr.hotlist, self.services.user)
   if 'addbtn' in post_data:
     return self.ProcessAddMembers(mr, post_data, hotlist_url)
   elif 'removebtn' in post_data:
     return self.ProcessRemoveMembers(mr, post_data, hotlist_url)
   elif 'changeowners' in post_data:
     return self.ProcessChangeOwnership(mr, post_data)
Esempio n. 8
0
    def ProcessFormData(self, mr, post_data):
        if post_data.get('deletestate') == 'true':
            hotlist_helpers.RemoveHotlist(mr.cnxn, mr.hotlist_id,
                                          self.services)
            return framework_helpers.FormatAbsoluteURL(mr,
                                                       '/u/%s/hotlists' %
                                                       mr.auth.email,
                                                       saved=1,
                                                       ts=int(time.time()),
                                                       include_project=False)

        hotlist_view_url = hotlist_helpers.GetURLOfHotlist(
            mr.cnxn, mr.hotlist, self.services.user)
        current_col_spec = post_data.get('current_col_spec')
        default_url = framework_helpers.FormatAbsoluteURL(
            mr,
            hotlist_view_url,
            include_project=False,
            colspec=current_col_spec)
        sorting.InvalidateArtValuesKeys(
            mr.cnxn,
            [hotlist_item.issue_id for hotlist_item in mr.hotlist.items])

        if post_data.get('remove') == 'true':
            project_and_local_ids = post_data.get('remove_local_ids')
        else:
            project_and_local_ids = post_data.get('add_local_ids')
            if not project_and_local_ids:
                return default_url

        selected_iids = []
        if project_and_local_ids:
            pattern = re.compile(features_constants.ISSUE_INPUT_REGEX)
            if pattern.match(project_and_local_ids):
                issue_refs_tuples = [
                    (pair.split(':')[0].strip(),
                     int(pair.split(':')[1].strip()))
                    for pair in project_and_local_ids.split(',')
                    if pair.strip()
                ]
                project_names = {
                    project_name
                    for (project_name, _) in issue_refs_tuples
                }
                projects_dict = self.services.project.GetProjectsByName(
                    mr.cnxn, project_names)
                selected_iids, _misses = self.services.issue.ResolveIssueRefs(
                    mr.cnxn, projects_dict, mr.project_name, issue_refs_tuples)
                if (not selected_iids
                    ) or len(issue_refs_tuples) > len(selected_iids):
                    mr.errors.issues = _MSG_ISSUES_NOT_FOUND
                    # TODO(jojwang): give issues that were not found.
            else:
                mr.errors.issues = _MSG_INVALID_ISSUES_INPUT

        try:
            with work_env.WorkEnv(mr, self.services) as we:
                selected_issues = we.GetIssuesDict(selected_iids)
        except exceptions.NoSuchIssueException:
            mr.errors.issues = _MSG_ISSUES_NOT_FOUND
        if len(selected_issues) < len(selected_iids):
            mr.errors.issues = _MSG_ISSUES_NOT_VIEWABLE

        # TODO(jojwang): fix: when there are errors, hidden column come back on
        # the .do page but go away once the errors are fixed and the form
        # is submitted again
        if mr.errors.AnyErrors():
            self.PleaseCorrect(mr,
                               add_local_ids=project_and_local_ids,
                               add_issues_selected=ezt.boolean(True),
                               col_spec=current_col_spec)

        else:
            with work_env.WorkEnv(mr, self.services) as we:
                if post_data.get('remove') == 'true':
                    we.RemoveIssuesFromHotlists([mr.hotlist_id], selected_iids)
                else:
                    we.AddIssuesToHotlists([mr.hotlist_id], selected_iids, '')
            return framework_helpers.FormatAbsoluteURL(
                mr,
                hotlist_view_url,
                saved=1,
                ts=int(time.time()),
                include_project=False,
                colspec=current_col_spec)
Esempio n. 9
0
    def ProcessFormData(self, mr, post_data):
        """Process the hotlist create form.

    Args:
      mr: commonly used info parsed from the request.
      post_data: The post_data dict for the current request.

    Returns:
      String URL to redirect the user to after processing.
    """
        hotlist_name = post_data.get('hotlistname')
        if not hotlist_name:
            mr.errors.hotlistname = _MSG_MISSING_HOTLIST_NAME
        elif not framework_bizobj.IsValidHotlistName(hotlist_name):
            mr.errors.hotlistname = _MSG_INVALID_HOTLIST_NAME

        summary = post_data.get('summary')
        if not summary:
            mr.errors.summary = _MSG_MISSING_HOTLIST_SUMMARY

        description = post_data.get('description', '')

        editors = post_data.get('editors', '')
        editor_ids = []
        if editors:
            editor_emails = [email.strip() for email in editors.split(',')]
            try:
                editor_dict = self.services.user.LookupUserIDs(
                    mr.cnxn, editor_emails)
                editor_ids = editor_dict.values()
            except user_svc.NoSuchUserException:
                mr.errors.editors = _MSG_INVALID_MEMBERS_INPUT
            # In case the logged-in user specifies themselves as an editor, ignore it.
            editor_ids = [eid for eid in editor_ids if eid != mr.auth.user_id]

        is_private = post_data.get('is_private')

        if not mr.errors.AnyErrors():
            try:
                hotlist = self.services.features.CreateHotlist(
                    mr.cnxn,
                    hotlist_name,
                    summary,
                    description,
                    owner_ids=[mr.auth.user_id],
                    editor_ids=editor_ids,
                    is_private=(is_private == 'yes'),
                    ts=int(time.time()))
            except features_svc.HotlistAlreadyExists:
                mr.errors.hotlistname = _MSG_HOTLIST_NAME_NOT_AVAIL

        if mr.errors.AnyErrors():
            self.PleaseCorrect(mr,
                               initial_name=hotlist_name,
                               initial_summary=summary,
                               initial_description=description,
                               initial_editors=editors,
                               initial_privacy=is_private)
        else:
            return framework_helpers.FormatAbsoluteURL(
                mr,
                hotlist_helpers.GetURLOfHotlist(mr.cnxn, hotlist,
                                                self.services.user),
                include_project=False)
Esempio n. 10
0
    def HandleRequest(self, mr):
        project_names = []
        refs = []
        for issue_ref in mr.issue_refs:
            issue_split = issue_ref.split(':')
            project_names.append(issue_split[0])
            refs.append((issue_split[0], int(issue_split[1])))
        ref_projects = self.services.project.GetProjectsByName(
            mr.cnxn, project_names)
        # TODO(jojwang): a default_project_name can be passed in for adding an issue
        # via the issuedetail page
        default_project_name = ''
        selected_iids, misses = self.services.issue.ResolveIssueRefs(
            mr.cnxn, ref_projects, default_project_name, refs)
        added_tuples = [(issue_id, mr.auth.user_id, int(time.time()), '')
                        for issue_id in selected_iids]
        if not mr.hotlist_ids:
            hotlist_name = 'Hotlist-1'
            count = 1
            taken_names = [
                h.name for h in self.services.features.GetHotlistsByUserID(
                    mr.cnxn, mr.auth.user_id)
            ]
            while hotlist_name in taken_names:
                count += 1
                hotlist_name = 'Hotlist-%d' % count
            hotlist = self.services.features.CreateHotlist(
                mr.cnxn,
                hotlist_name,
                'Hotlist of bulk added issues',
                '', [mr.auth.user_id], [],
                issue_ids=selected_iids)
            hotlist_ids = [hotlist.hotlist_id]
        else:
            hotlist_ids = mr.hotlist_ids
            self.services.features.AddIssuesToHotlists(mr.cnxn, hotlist_ids,
                                                       added_tuples)

        missed = []
        for miss in misses:
            project_name = self.services.project.GetProject(
                mr.cnxn, miss[0]).project_name
            missed.append(('%s:%d' % (project_name, miss[1])))

        added_hotlist_pbs = [
            self.services.features.GetHotlist(mr.cnxn, hotlist_id)
            for hotlist_id in hotlist_ids
        ]

        user_issue_hotlists = list(
            set(
                self.services.features.GetHotlistsByUserID(
                    mr.cnxn, mr.auth.user_id)) & set(
                        self.services.features.GetHotlistsByIssueID(
                            mr.cnxn, selected_iids[0])))
        all_hotlist_urls = [
            hotlist_helpers.GetURLOfHotlist(mr.cnxn, hotlist,
                                            self.services.user)
            for hotlist in user_issue_hotlists
        ]
        all_hotlist_names = [hotlist.name for hotlist in user_issue_hotlists]
        return {
            'addedHotlistIDs': hotlist_ids,
            # hotlist_ids issues were added to or new hotlist's id
            'missed': missed,  # missed issues
            'addedHotlistNames': [h.name for h in added_hotlist_pbs],
            # hotlist names issues were added to or new hotlist's name
            'allHotlistNames': all_hotlist_names,  # user's hotlists' names
            'allHotlistUrls': all_hotlist_urls
        }  # user's hotlists' urls