Merge branch 'main' into avm99963-monorail

Merged commit 34d8229ae2b51fb1a15bd208e6fe6185c94f6266

GitOrigin-RevId: 7ee0917f93a577e475f8e09526dd144d245593f4
diff --git a/tracker/issueadmin.py b/tracker/issueadmin.py
index 10fbdc8..849e59f 100644
--- a/tracker/issueadmin.py
+++ b/tracker/issueadmin.py
@@ -1,7 +1,6 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file or at
-# https://developers.google.com/open-source/licenses/bsd
+# Copyright 2016 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
 
 """Servlets for issue tracker configuration.
 
@@ -14,18 +13,12 @@
 from __future__ import absolute_import
 
 import collections
-import itertools
 import logging
 import time
 
-import ezt
-
 from features import filterrules_helpers
 from features import filterrules_views
 from features import savedqueries_helpers
-from framework import authdata
-from framework import flaskservlet
-from framework import framework_bizobj
 from framework import framework_constants
 from framework import framework_helpers
 from framework import framework_views
@@ -33,8 +26,7 @@
 from framework import permissions
 from framework import servlet
 from framework import urls
-from proto import tracker_pb2
-from tracker import field_helpers
+from mrproto import tracker_pb2
 from tracker import tracker_bizobj
 from tracker import tracker_constants
 from tracker import tracker_helpers
@@ -44,7 +36,7 @@
 class IssueAdminBase(servlet.Servlet):
   """Base class for servlets allowing project owners to configure tracker."""
 
-  _MAIN_TAB_MODE = flaskservlet.FlaskServlet.MAIN_TAB_PROCESS
+  _MAIN_TAB_MODE = servlet.Servlet.MAIN_TAB_PROCESS
   _PROCESS_SUBTAB = None  # specified in subclasses
 
   def GatherPageData(self, mr):
@@ -63,12 +55,19 @@
     labels_text = tracker_views.LabelDefsAsText(config)
 
     return {
-        'admin_tab_mode': self._PROCESS_SUBTAB,
-        'config': config_view,
-        'open_text': open_text,
-        'closed_text': closed_text,
-        'labels_text': labels_text,
-        }
+        'admin_tab_mode':
+            self._PROCESS_SUBTAB,
+        'config':
+            config_view,
+        'open_text':
+            open_text,
+        'closed_text':
+            closed_text,
+        'labels_text':
+            labels_text,
+        'can_edit_project':
+            permissions.CanEditProjectConfig(mr, self.services) or None,
+    }
 
   def ProcessFormData(self, mr, post_data):
     """Validate and store the contents of the issues tracker admin page.
@@ -91,7 +90,7 @@
   """Servlet allowing project owners to configure well-known statuses."""
 
   _PAGE_TEMPLATE = 'tracker/admin-statuses-page.ezt'
-  _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_STATUSES
+  _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_STATUSES
 
   def ProcessSubtabForm(self, post_data, mr):
     """Process the status definition section of the admin page.
@@ -103,7 +102,7 @@
     Returns:
       The URL of the page to show after processing.
     """
-    if not self.CheckPerm(mr, permissions.EDIT_PROJECT):
+    if not permissions.CanEditProjectConfig(mr, self.services):
       raise permissions.PermissionException(
           'Only project owners may edit the status definitions')
 
@@ -142,18 +141,18 @@
 
     return urls.ADMIN_STATUSES
 
-  # def GetAdminStatusesPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def GetAdminStatusesPage(self, **kwargs):
+    return self.handler(**kwargs)
 
-  # def PostAdminStatusesPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def PostAdminStatusesPage(self, **kwargs):
+    return self.handler(**kwargs)
 
 
 class AdminLabels(IssueAdminBase):
   """Servlet allowing project owners to labels and fields."""
 
   _PAGE_TEMPLATE = 'tracker/admin-labels-page.ezt'
-  _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_LABELS
+  _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_LABELS
 
   def GatherPageData(self, mr):
     """Build up a dictionary of data values to use when rendering the page.
@@ -186,7 +185,7 @@
     Returns:
       The URL of the page to show after processing.
     """
-    if not self.CheckPerm(mr, permissions.EDIT_PROJECT):
+    if not permissions.CanEditProjectConfig(mr, self.services):
       raise permissions.PermissionException(
           'Only project owners may edit the label definitions')
 
@@ -231,18 +230,18 @@
 
     return urls.ADMIN_LABELS
 
-  # def GetAdminLabelsPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def GetAdminLabelsPage(self, **kwargs):
+    return self.handler(**kwargs)
 
-  # def PostAdminLabelsPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def PostAdminLabelsPage(self, **kwargs):
+    return self.handler(**kwargs)
 
 
 class AdminTemplates(IssueAdminBase):
   """Servlet allowing project owners to configure templates."""
 
   _PAGE_TEMPLATE = 'tracker/admin-templates-page.ezt'
-  _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_TEMPLATES
+  _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_TEMPLATES
 
   def GatherPageData(self, mr):
     """Build up a dictionary of data values to use when rendering the page.
@@ -265,7 +264,7 @@
     Returns:
       The URL of the page to show after processing.
     """
-    if not self.CheckPerm(mr, permissions.EDIT_PROJECT):
+    if not permissions.CanEditProjectConfig(mr, self.services):
       raise permissions.PermissionException(
           'Only project owners may edit the default templates')
 
@@ -301,18 +300,18 @@
     return (GetSelectedTemplateID('default_template_for_developers'),
             GetSelectedTemplateID('default_template_for_users'))
 
-  # def GetAdminTemplatesPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def GetAdminTemplatesPage(self, **kwargs):
+    return self.handler(**kwargs)
 
-  # def PostAdminTemplatesPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def PostAdminTemplatesPage(self, **kwargs):
+    return self.handler(**kwargs)
 
 
 class AdminComponents(IssueAdminBase):
   """Servlet allowing project owners to view the list of components."""
 
   _PAGE_TEMPLATE = 'tracker/admin-components-page.ezt'
-  _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_COMPONENTS
+  _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_COMPONENTS
 
   def GatherPageData(self, mr):
     """Build up a dictionary of data values to use when rendering the page.
@@ -389,7 +388,7 @@
 
     for component_def in component_defs:
       allow_edit = permissions.CanEditComponentDef(
-          mr.auth.effective_ids, mr.perms, mr.project, component_def, config)
+          mr, self.services, component_def, config)
       if not allow_edit:
         perm_errors.append(component_def.path)
 
@@ -417,18 +416,18 @@
         failed_templ=','.join(templates_errors),
         deleted=','.join(deleted_components))
 
-  # def GetAdminComponentsPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def GetAdminComponentsPage(self, **kwargs):
+    return self.handler(**kwargs)
 
-  # def PostAdminComponentsPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def PostAdminComponentsPage(self, **kwargs):
+    return self.handler(**kwargs)
 
 
 class AdminViews(IssueAdminBase):
   """Servlet for project owners to set default columns, axes, and sorting."""
 
   _PAGE_TEMPLATE = 'tracker/admin-views-page.ezt'
-  _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_VIEWS
+  _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_VIEWS
 
   def GatherPageData(self, mr):
     """Build up a dictionary of data values to use when rendering the page.
@@ -466,7 +465,7 @@
     Returns:
       The URL of the page to show after processing.
     """
-    if not self.CheckPerm(mr, permissions.EDIT_PROJECT):
+    if not permissions.CanEditProjectConfig(mr, self.services):
       raise permissions.PermissionException(
           'Only project owners may edit the default views')
     existing_queries = savedqueries_helpers.ParseSavedQueries(
@@ -488,11 +487,11 @@
 
     return urls.ADMIN_VIEWS
 
-  # def GetAdminViewsPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def GetAdminViewsPage(self, **kwargs):
+    return self.handler(**kwargs)
 
-  # def PostAdminViewsPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def PostAdminViewsPage(self, **kwargs):
+    return self.handler(**kwargs)
 
 
 def _ParseListPreferences(post_data):
@@ -540,7 +539,7 @@
   """Servlet allowing project owners to configure filter rules."""
 
   _PAGE_TEMPLATE = 'tracker/admin-rules-page.ezt'
-  _PROCESS_SUBTAB = flaskservlet.FlaskServlet.PROCESS_TAB_RULES
+  _PROCESS_SUBTAB = servlet.Servlet.PROCESS_TAB_RULES
 
   def AssertBasePermission(self, mr):
     """Check whether the user has any permission to visit this page.
@@ -549,7 +548,7 @@
       mr: commonly used info parsed from the request.
     """
     super(AdminRules, self).AssertBasePermission(mr)
-    if not self.CheckPerm(mr, permissions.EDIT_PROJECT):
+    if not permissions.CanEditProjectConfig(mr, self.services):
       raise permissions.PermissionException(
           'User is not allowed to administer this project')
 
@@ -617,8 +616,8 @@
 
     return urls.ADMIN_RULES
 
-  # def GetAdminRulesPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def GetAdminRulesPage(self, **kwargs):
+    return self.handler(**kwargs)
 
-  # def PostAdminRulesPage(self, **kwargs):
-  #   return self.handler(**kwargs)
+  def PostAdminRulesPage(self, **kwargs):
+    return self.handler(**kwargs)