Exemplo n.º 1
0
  def ProcessFormData(self, mr, post_data):
    """Validate and store the contents of the issues tracker admin page.

    Args:
      mr: commonly used info parsed from the request.
      post_data: HTML form data from the request.

    Returns:
      String URL to redirect the user to, or None if response was already sent.
    """
    config, field_def = self._GetFieldDef(mr)
    allow_edit = permissions.CanEditFieldDef(
        mr.auth.effective_ids, mr.perms, mr.project, field_def)
    if not allow_edit:
      raise permissions.PermissionException(
          'User is not allowed to delete this field')

    if 'deletefield' in post_data:
      self._ProcessDeleteField(mr, field_def)
      return framework_helpers.FormatAbsoluteURL(
          mr, urls.ADMIN_LABELS, deleted=1, ts=int(time.time()))

    else:
      self._ProcessEditField(mr, post_data, config, field_def)
      return framework_helpers.FormatAbsoluteURL(
          mr, urls.FIELD_DETAIL, field=field_def.field_name,
          saved=1, ts=int(time.time()))
Exemplo n.º 2
0
    def ProcessFormData(self, mr, post_data):
        """Process the posted form."""
        # 1. Parse and validate user input.
        user_id, role, extra_perms, notes, ac_exclusion, no_expand = (
            self.ParsePersonData(mr, post_data))
        member_id = self.ValidateMemberID(mr.cnxn, user_id, mr.project)

        # 2. Call services layer to save changes.
        if 'remove' in post_data:
            self.ProcessRemove(mr, member_id)
        else:
            self.ProcessSave(mr, role, extra_perms, notes, member_id,
                             ac_exclusion, no_expand)

        # 3. Determine the next page in the UI flow.
        if 'remove' in post_data:
            return framework_helpers.FormatAbsoluteURL(mr,
                                                       urls.PEOPLE_LIST,
                                                       saved=1,
                                                       ts=int(time.time()))
        else:
            return framework_helpers.FormatAbsoluteURL(mr,
                                                       urls.PEOPLE_DETAIL,
                                                       u=user_id,
                                                       saved=1,
                                                       ts=int(time.time()))
    def ProcessFormData(self, mr, post_data):
        """Process the posted form.

    Args:
      mr: commonly used info parsed from the request.
      post_data: dictionary of HTML form data.

    Returns:
      String URL to redirect to after processing is completed.
    """
        if 'savechanges' in post_data:
            self._ProcessQuota(mr, post_data)
        else:
            self._ProcessPublishingOptions(mr, post_data)

        if 'deletebtn' in post_data:
            url = framework_helpers.FormatAbsoluteURL(mr,
                                                      urls.HOSTING_HOME,
                                                      include_project=False)
        else:
            url = framework_helpers.FormatAbsoluteURL(mr,
                                                      urls.ADMIN_ADVANCED,
                                                      saved=1,
                                                      ts=int(time.time()))

        return url
 def testFormatAbsoluteURL_CommonRequestParams(self):
   _request, mr = testing_helpers.GetRequestObjects(
       path='/p/proj/some-path?foo=bar&can=1',
       headers={'Host': 'www.test.com'})
   self.assertEqual(
       'http://www.test.com/p/proj/some/path?can=1',
       framework_helpers.FormatAbsoluteURL(mr, '/some/path'))
   self.assertEqual(
       'http://www.test.com/p/proj/some/path',
       framework_helpers.FormatAbsoluteURL(
           mr, '/some/path', copy_params=False))
Exemplo n.º 5
0
  def ProcessRemoveMembers(self, mr, post_data):
    """Process the user's request to remove members.

    Args:
      mr: common information parsed from the HTTP request.
      post_data: dictionary of form data.

    Returns:
      String URL to redirect the user to after processing.
    """
    # 1. Gather data from the request.
    remove_strs = post_data.getall('remove')
    logging.info('remove_strs = %r', remove_strs)

    if not remove_strs:
      mr.errors.remove = 'No users specified'

    # 2. Call services layer to save changes.
    if not mr.errors.AnyErrors():
      remove_ids = set(
          self.services.user.LookupUserIDs(mr.cnxn, remove_strs).values())
      self.services.usergroup.RemoveMembers(
          mr.cnxn, mr.viewed_user_auth.user_id, remove_ids)

    # 3. Determine the next page in the UI flow.
    if mr.errors.AnyErrors():
      self.PleaseCorrect(mr)
    else:
      return framework_helpers.FormatAbsoluteURL(
          mr, '/g/%s/' % mr.viewed_username, include_project=False,
          saved=1, ts=int(time.time()))
Exemplo n.º 6
0
  def ProcessAddMembers(self, mr, post_data):
    """Process the user's request to add members.

    Args:
      mr: common information parsed from the HTTP request.
      post_data: dictionary of form data.

    Returns:
      String URL to redirect the user to after processing.
    """
    # 1. Gather data from the request.
    group_id = mr.viewed_user_auth.user_id
    add_members_str = post_data.get('addmembers')
    new_member_ids = project_helpers.ParseUsernames(
        mr.cnxn, self.services.user, add_members_str)
    role = post_data['role']

    # 2. Call services layer to save changes.
    if not mr.errors.AnyErrors():
      try:
        self.services.usergroup.UpdateMembers(
            mr.cnxn, group_id, new_member_ids, role)
      except usergroup_svc.CircularGroupException:
        mr.errors.addmembers = (
            'The members are already ancestors of current group.')

    # 3. Determine the next page in the UI flow.
    if mr.errors.AnyErrors():
      self.PleaseCorrect(
          mr, initial_add_members=add_members_str,
          initially_expand_form=ezt.boolean(True))
    else:
      return framework_helpers.FormatAbsoluteURL(
          mr, '/g/%s/' % mr.viewed_username, include_project=False,
          saved=1, ts=int(time.time()))
Exemplo n.º 7
0
    def ProcessFormData(self, mr, post_data):
        """Process a posted advanced query form.

    Args:
      mr: commonly used info parsed from the request.
      post_data: HTML form data from the request.

    Returns:
      String URL to redirect the user to after processing.
    """
        # Default to searching open issues in this project.
        can = post_data.get('can', 2)

        terms = []
        self._AccumulateANDTerm('', 'words', post_data, terms)
        self._AccumulateANDTerm('-', 'without', post_data, terms)
        self._AccumulateANDTerm('label:', 'labels', post_data, terms)
        self._AccumulateORTerm('component:', 'components', post_data, terms)
        self._AccumulateORTerm('status:', 'statuses', post_data, terms)
        self._AccumulateORTerm('reporter:', 'reporters', post_data, terms)
        self._AccumulateORTerm('owner:', 'owners', post_data, terms)
        self._AccumulateORTerm('cc:', 'cc', post_data, terms)
        self._AccumulateORTerm('commentby:', 'commentby', post_data, terms)

        if 'starcount' in post_data:
            starcount = int(post_data['starcount'])
            if starcount >= 0:
                terms.append('starcount:%s' % starcount)

        return framework_helpers.FormatAbsoluteURL(mr,
                                                   urls.ISSUE_LIST,
                                                   q=' '.join(terms),
                                                   can=can)
 def testFormatAbsoluteURL(self):
   _request, mr = testing_helpers.GetRequestObjects(
       path='/p/proj/some-path',
       headers={'Host': 'www.test.com'})
   self.assertEqual(
       'http://www.test.com/p/proj/some/path',
       framework_helpers.FormatAbsoluteURL(mr, '/some/path'))
Exemplo n.º 9
0
    def ProcessFormData(self, mr, post_data):
        """Validate and store the contents of the issues tracker admin page.

    Args:
      mr: commonly used info parsed from the request.
      post_data: HTML form data from the request.

    Returns:
      String URL to redirect the user to, or None if response was already sent.
    """
        existing_queries = savedqueries_helpers.ParseSavedQueries(
            mr.cnxn, post_data, self.services.project)
        added_queries = savedqueries_helpers.ParseSavedQueries(
            mr.cnxn, post_data, self.services.project, prefix='new_')
        saved_queries = existing_queries + added_queries

        self.services.features.UpdateUserSavedQueries(
            mr.cnxn, mr.viewed_user_auth.user_id, saved_queries)

        return framework_helpers.FormatAbsoluteURL(
            mr,
            '/u/%s%s' % (mr.viewed_username, urls.SAVED_QUERIES),
            include_project=False,
            saved=1,
            ts=int(time.time()))
Exemplo n.º 10
0
def ComputeIssueEntryURL(mr, config):
  """Compute the URL to use for the "New issue" subtab.

  Args:
    mr: commonly used info parsed from the request.
    config: ProjectIssueConfig for the current project.

  Returns:
    A URL string to use.  It will be simply "entry" in the non-customized
    case. Otherewise it will be a fully qualified URL that includes some
    query string parameters.
  """
  if not config.custom_issue_entry_url:
    return '/p/%s/issues/entry' % (mr.project_name)

  base_url = config.custom_issue_entry_url
  sep = '&' if '?' in base_url else '?'
  token = xsrf.GenerateToken(
    mr.auth.user_id, '/p/%s%s%s' % (mr.project_name, urls.ISSUE_ENTRY, '.do'))
  role_name = framework_helpers.GetRoleName(mr.auth.effective_ids, mr.project)

  continue_url = urllib.quote(framework_helpers.FormatAbsoluteURL(
      mr, urls.ISSUE_ENTRY + '.do'))

  return '%s%stoken=%s&role=%s&continue=%s' % (
      base_url, sep, urllib.quote(token),
      urllib.quote(role_name or ''), continue_url)
Exemplo n.º 11
0
    def _CheckForMovedProject(self, mr, request):
        """If the project moved, redirect there or to an informational page."""
        if not mr.project:
            return  # We are on a site-wide or user page.
        if not mr.project.moved_to:
            return  # This project has not moved.
        admin_url = '/p/%s%s' % (mr.project_name, urls.ADMIN_META)
        if request.path.startswith(admin_url):
            return  # It moved, but we are near the page that can un-move it.

        logging.info('project %s has moved: %s', mr.project.project_name,
                     mr.project.moved_to)

        moved_to = mr.project.moved_to
        if framework_bizobj.RE_PROJECT_NAME.match(moved_to):
            # Use the redir query parameter to avoid redirect loops.
            if mr.redir is None:
                url = framework_helpers.FormatMovedProjectURL(mr, moved_to)
                if '?' in url:
                    url += '&redir=1'
                else:
                    url += '?redir=1'
                logging.info('trusted move to a new project on our site')
                self.redirect(url, abort=True)

        logging.info('not a trusted move, will display link to user to click')
        # Attach the project name as a url param instead of generating a /p/
        # link to the destination project.
        url = framework_helpers.FormatAbsoluteURL(mr,
                                                  urls.PROJECT_MOVED,
                                                  include_project=False,
                                                  copy_params=False,
                                                  project=mr.project_name)
        self.redirect(url, abort=True)
Exemplo n.º 12
0
  def GatherPageData(self, mr):
    """Build up a dictionary of data values to use when rendering the page."""

    # We are not actually in /p/PROJECTNAME, so mr.project_name is None.
    # Putting the ProjectMoved page inside a moved project would make
    # the redirect logic much more complicated.
    if not mr.specified_project:
      raise monorailrequest.InputException('No project specified')

    project = self.services.project.GetProjectByName(
        mr.cnxn, mr.specified_project)
    if not project:
      self.abort(404, 'project not found')

    if not project.moved_to:
      # Only show this page for projects that are actually moved.
      # Don't allow hackers to construct misleading links to this servlet.
      logging.info('attempt to view ProjectMoved for non-moved project: %s',
                   mr.specified_project)
      self.abort(400, 'This project has not been moved')

    if framework_bizobj.RE_PROJECT_NAME.match(project.moved_to):
      moved_to_url = framework_helpers.FormatAbsoluteURL(
          mr, urls.SUMMARY, include_project=True, project_name=project.moved_to)
    elif (project.moved_to.startswith('https://') or
          project.moved_to.startswith('http://')):
      moved_to_url = project.moved_to
    else:
      # Prevent users from using javascript: or any other tricky URL scheme.
      moved_to_url = '#invalid-destination-url'

    return {
        'project_name': mr.specified_project,
        'moved_to_url': moved_to_url,
        }
Exemplo n.º 13
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)
Exemplo n.º 14
0
    def ProcessRemoveMembers(self, mr, post_data):
        """Process the user's request to remove members.

    Args:
      mr: common information parsed from the HTTP request.
      post_data: dictionary of form data.

    Returns:
      String URL to redirect the user to after processing.
    """
        # 1. Parse and validate user input.
        remove_strs = post_data.getall('remove')
        logging.info('remove_strs = %r', remove_strs)
        remove_ids = set(
            self.services.user.LookupUserIDs(mr.cnxn, remove_strs).values())
        (owner_ids, committer_ids,
         contributor_ids) = project_helpers.MembersWithoutGivenIDs(
             mr.project, remove_ids)

        # 2. Call services layer to save changes.
        self.services.project.UpdateProjectRoles(mr.cnxn,
                                                 mr.project.project_id,
                                                 owner_ids, committer_ids,
                                                 contributor_ids)

        # 3. Determine the next page in the UI flow.
        return framework_helpers.FormatAbsoluteURL(mr,
                                                   urls.PEOPLE_LIST,
                                                   saved=1,
                                                   ts=int(time.time()))
Exemplo n.º 15
0
 def GatherPageData(self, mr):
     logging.info(
         'Redirecting from approval page to the new issue detail page.')
     url = framework_helpers.FormatAbsoluteURL(mr,
                                               urls.ISSUE_DETAIL,
                                               id=mr.local_id)
     return self.redirect(url, abort=True)
Exemplo n.º 16
0
 def _ProcessDeleteComponent(self, mr, component_def):
   """The user wants to delete the specified custom field definition."""
   self.services.issue.DeleteComponentReferences(
       mr.cnxn, component_def.component_id)
   self.services.config.DeleteComponentDef(
       mr.cnxn, mr.project_id, component_def.component_id)
   return framework_helpers.FormatAbsoluteURL(
       mr, urls.ADMIN_COMPONENTS, deleted=1, ts=int(time.time()))
 def testFormatAbsoluteURL_NoProject(self):
     path = '/some/path'
     _request, mr = testing_helpers.GetRequestObjects(
         headers={'Host': 'www.test.com'}, path=path)
     url = framework_helpers.FormatAbsoluteURL(mr,
                                               path,
                                               include_project=False)
     self.assertEqual(url, 'http://www.test.com/some/path')
Exemplo n.º 18
0
def _LoginOrIssueEntryURL(mr, config):
    """Make a URL to sign in, if needed, on the way to entering an issue."""
    issue_entry_url = servlet_helpers.ComputeIssueEntryURL(mr, config)
    if mr.auth.user_id:
        return issue_entry_url
    else:
        after_login_url = framework_helpers.FormatAbsoluteURL(
            mr, urls.ISSUE_ENTRY_AFTER_LOGIN)
        return _SafeCreateLoginURL(mr, after_login_url)
Exemplo n.º 19
0
    def ProcessFormData(self, mr, post_data):
        """Processes a POST command to delete components.

    Args:
      mr: commonly used info parsed from the request.
      post_data: HTML form data from the request.

    Returns:
      String URL to redirect the user to, or None if response was already sent.
    """
        config = self.services.config.GetProjectConfig(mr.cnxn, mr.project_id)
        component_defs = self._GetComponentDefs(mr, post_data, config)
        # Reverse the component_defs so that we start deleting from subcomponents.
        component_defs.reverse()

        # Collect errors.
        perm_errors = []
        subcomponents_errors = []
        templates_errors = []
        # Collect successes.
        deleted_components = []

        for component_def in component_defs:
            allow_edit = permissions.CanEditComponentDef(
                mr.auth.effective_ids, mr.perms, mr.project, component_def,
                config)
            if not allow_edit:
                perm_errors.append(component_def.path)

            subcomponents = tracker_bizobj.FindDescendantComponents(
                config, component_def)
            if subcomponents:
                subcomponents_errors.append(component_def.path)

            templates = self.services.template.TemplatesWithComponent(
                mr.cnxn, component_def.component_id)
            if templates:
                templates_errors.append(component_def.path)

            allow_delete = allow_edit and not subcomponents and not templates
            if allow_delete:
                self._ProcessDeleteComponent(mr, component_def)
                deleted_components.append(component_def.path)
                # Refresh project config after the component deletion.
                config = self.services.config.GetProjectConfig(
                    mr.cnxn, mr.project_id)

        return framework_helpers.FormatAbsoluteURL(
            mr,
            urls.ADMIN_COMPONENTS,
            ts=int(time.time()),
            failed_perm=','.join(perm_errors),
            failed_subcomp=','.join(subcomponents_errors),
            failed_templ=','.join(templates_errors),
            deleted=','.join(deleted_components))
Exemplo n.º 20
0
 def get(self, **kwargs):
     """Construct a 302 pointing at project.source_url, or at adminIntro."""
     if not self.mr.project:
         self.response.status = httplib.NOT_FOUND
         return
     source_url = self.mr.project.source_url
     if not source_url:
         source_url = framework_helpers.FormatAbsoluteURL(
             self.mr, urls.ADMIN_INTRO, include_project=True)
     self.response.location = source_url
     self.response.status = httplib.MOVED_PERMANENTLY
Exemplo n.º 21
0
    def ProcessFormData(self, mr, post_data):
        """Process the posted form."""

        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)

        (summary, description, name,
         default_col_spec) = self._ParseMetaData(post_data, mr)
        is_private = post_data.get('is_private') != 'no'

        if not mr.errors.AnyErrors():
            self.services.features.UpdateHotlist(
                mr.cnxn,
                mr.hotlist.hotlist_id,
                name=name,
                summary=summary,
                description=description,
                is_private=is_private,
                default_col_spec=default_col_spec)

        if mr.errors.AnyErrors():
            self.PleaseCorrect(mr,
                               initial_summary=summary,
                               initial_description=description,
                               initial_name=name,
                               initial_default_col_spec=default_col_spec)
        else:
            return framework_helpers.FormatAbsoluteURL(
                mr,
                '/u/%s/hotlists/%s%s' %
                (mr.auth.user_id, mr.hotlist_id, urls.HOTLIST_DETAIL),
                saved=1,
                ts=int(time.time()),
                include_project=False)
Exemplo n.º 22
0
 def ProcessFormData(self, mr, post_data):
     """Process the posted form."""
     viewed_user = mr.viewed_user_auth.user_pb
     viewed_user.email_bounce_timestamp = None
     self.services.user.UpdateUser(mr.cnxn, viewed_user.user_id,
                                   viewed_user)
     return framework_helpers.FormatAbsoluteURL(
         mr,
         mr.viewed_user_auth.user_view.profile_url,
         include_project=False,
         saved=1,
         ts=int(time.time()))
Exemplo n.º 23
0
  def ProcessFormData(self, mr, post_data):
    """Process the posted form."""
    # 1. Gather data from the request.
    group_name = post_data.get('groupname')
    try:
      existing_group_id = self.services.user.LookupUserID(mr.cnxn, group_name)
      existing_settings = self.services.usergroup.GetGroupSettings(
          mr.cnxn, existing_group_id)
      if existing_settings:
        mr.errors.groupname = 'That user group already exists'
    except exceptions.NoSuchUserException:
      pass

    if post_data.get('import_group'):
      vis = usergroup_pb2.MemberVisibility.OWNERS
      ext_group_type = post_data.get('group_type')
      friend_projects = ''
      if not ext_group_type:
        mr.errors.groupimport = 'Please provide external group type'
      else:
        ext_group_type = str(
            usergroup_pb2.GroupType(int(ext_group_type))).lower()

      if (ext_group_type == 'computed' and
          not group_name.startswith('everyone@')):
        mr.errors.groupimport = 'Computed groups must be named everyone@'

    else:
      vis = usergroup_pb2.MemberVisibility(int(post_data['visibility']))
      ext_group_type = None
      friend_projects = post_data.get('friendprojects', '')
    who_can_view_members = str(vis).lower()

    if not mr.errors.AnyErrors():
      project_ids, error = self.services.usergroup.ValidateFriendProjects(
          mr.cnxn, self.services, friend_projects)
      if error:
        mr.errors.friendprojects = error

    # 2. Call services layer to save changes.
    if not mr.errors.AnyErrors():
      group_id = self.services.usergroup.CreateGroup(
          mr.cnxn, self.services, group_name, who_can_view_members,
          ext_group_type, project_ids)

    # 3. Determine the next page in the UI flow.
    if mr.errors.AnyErrors():
      self.PleaseCorrect(mr, initial_name=group_name)
    else:
      # Go to the new user group's detail page.
      return framework_helpers.FormatAbsoluteURL(
          mr, '/g/%s/' % group_id, include_project=False)
Exemplo n.º 24
0
    def ProcessFormData(self, mr, post_data):
        """Process the posted form."""
        with work_env.WorkEnv(mr, self.services) as we:
            framework_helpers.UserSettings.ProcessSettingsForm(
                we, post_data, mr.auth.user_pb)

        url = framework_helpers.FormatAbsoluteURL(mr,
                                                  urls.USER_SETTINGS,
                                                  include_project=False,
                                                  saved=1,
                                                  ts=int(time.time()))

        return url
Exemplo n.º 25
0
    def _ProcessDeleteField(self, mr, config, field_def):
        """The user wants to delete the specified custom field definition."""
        field_ids = [field_def.field_id]
        if field_def.field_type is tracker_pb2.FieldTypes.APPROVAL_TYPE:
            for fd in config.field_defs:
                if fd.approval_id == field_def.field_id:
                    field_ids.append(fd.field_id)
        self.services.config.SoftDeleteFieldDefs(mr.cnxn, mr.project_id,
                                                 field_ids)

        return framework_helpers.FormatAbsoluteURL(mr,
                                                   urls.ADMIN_LABELS,
                                                   deleted=1,
                                                   ts=int(time.time()))
Exemplo n.º 26
0
    def ProcessFormData(self, mr, post_data):
        """Process the posted form."""
        if not permissions.CanBan(mr, self.services):
            raise permissions.PermissionException(
                "You do not have permission to ban users.")

        framework_helpers.UserSettings.ProcessBanForm(
            mr.cnxn, self.services.user, post_data,
            mr.viewed_user_auth.user_id, mr.viewed_user_auth.user_pb)

        # TODO(jrobbins): Check all calls to FormatAbsoluteURL for include_project.
        return framework_helpers.FormatAbsoluteURL(
            mr,
            mr.viewed_user_auth.user_view.profile_url,
            include_project=False,
            saved=1,
            ts=int(time.time()))
Exemplo n.º 27
0
  def ProcessRemoveMembers(self, mr, post_data, hotlist_url):
    """Process the user's request to remove members."""
    remove_strs = post_data.getall('remove')
    logging.info('remove_strs = %r', remove_strs)
    remove_ids = set(
        self.services.user.LookupUserIDs(mr.cnxn, remove_strs).values())
    (owner_ids, editor_ids,
     follower_ids) = hotlist_helpers.MembersWithoutGivenIDs(
         mr.hotlist, remove_ids)

    self.services.features.UpdateHotlistRoles(
        mr.cnxn, mr.hotlist_id, owner_ids, editor_ids, follower_ids)

    return framework_helpers.FormatAbsoluteURL(
        mr, '%s%s' % (
              hotlist_url, urls.HOTLIST_PEOPLE),
          saved=1, ts=int(time.time()), include_project=False)
Exemplo n.º 28
0
    def ProcessAddMembers(self, mr, post_data):
        """Process the user's request to add members.

    Args:
      mr: common information parsed from the HTTP request.
      post_data: dictionary of form data.

    Returns:
      String URL to redirect the user to after processing.
    """
        # 1. Parse and validate user input.
        new_member_ids = project_helpers.ParseUsernames(
            mr.cnxn, self.services.user, post_data.get('addmembers'))
        role = post_data['role']

        (owner_ids, committer_ids,
         contributor_ids) = project_helpers.MembersWithGivenIDs(
             mr.project, new_member_ids, role)

        total_people = len(owner_ids) + len(committer_ids) + len(
            contributor_ids)
        if total_people > framework_constants.MAX_PROJECT_PEOPLE:
            mr.errors.addmembers = (
                'Too many project members.  The combined limit is %d.' %
                framework_constants.MAX_PROJECT_PEOPLE)

        # 2. Call services layer to save changes.
        if not mr.errors.AnyErrors():
            self.services.project.UpdateProjectRoles(mr.cnxn,
                                                     mr.project.project_id,
                                                     owner_ids, committer_ids,
                                                     contributor_ids)

        # 3. Determine the next page in the UI flow.
        if mr.errors.AnyErrors():
            add_members_str = post_data.get('addmembers', '')
            self.PleaseCorrect(mr,
                               initial_add_members=add_members_str,
                               initially_expand_form=True)
        else:
            return framework_helpers.FormatAbsoluteURL(
                mr,
                urls.PEOPLE_LIST,
                saved=1,
                ts=int(time.time()),
                new=','.join([str(u) for u in new_member_ids]))
Exemplo n.º 29
0
    def ProcessFormData(self, mr, post_data):
        """Validate and store the contents of the issues tracker admin page.

    Args:
      mr: commonly used info parsed from the request.
      post_data: HTML form data from the request.

    Returns:
      String URL to redirect the user to, or None if response was already sent.
    """
        page_url = self.ProcessSubtabForm(post_data, mr)

        if page_url:
            return framework_helpers.FormatAbsoluteURL(mr,
                                                       page_url,
                                                       saved=1,
                                                       ts=int(time.time()))
Exemplo n.º 30
0
  def ProcessFormData(self, mr, post_data):
    """Process the posted form."""
    # 1. Gather data from the request.
    group_name = mr.viewed_username
    group_id = mr.viewed_user_auth.user_id

    if post_data.get('import_group'):
      vis_level = usergroup_pb2.MemberVisibility.OWNERS
      ext_group_type = post_data.get('group_type')
      friend_projects = ''
      if not ext_group_type:
        mr.errors.groupimport = 'Please provide external group type'
      else:
        ext_group_type = usergroup_pb2.GroupType(int(ext_group_type))
    else:
      vis_level = post_data.get('visibility')
      ext_group_type = None
      friend_projects = post_data.get('friendprojects', '')
      if vis_level:
        vis_level = usergroup_pb2.MemberVisibility(int(vis_level))
      else:
        mr.errors.groupimport = 'Cannot update settings for imported group'

    if not mr.errors.AnyErrors():
      project_ids, error = self.services.usergroup.ValidateFriendProjects(
          mr.cnxn, self.services, friend_projects)
      if error:
        mr.errors.friendprojects = error

    # 2. Call services layer to save changes.
    if not mr.errors.AnyErrors():
      group_settings = usergroup_pb2.UserGroupSettings(
        who_can_view_members=vis_level,
        ext_group_type=ext_group_type,
        friend_projects=project_ids)
      self.services.usergroup.UpdateSettings(
          mr.cnxn, group_id, group_settings)

    # 3. Determine the next page in the UI flow.
    if mr.errors.AnyErrors():
      self.PleaseCorrect(mr, initial_name=group_name)
    else:
      return framework_helpers.FormatAbsoluteURL(
          mr, '/g/%s%s' % (group_name, urls.GROUP_ADMIN),
          include_project=False, saved=1, ts=int(time.time()))