diff --git a/framework/permissions.py b/framework/permissions.py
new file mode 100644
index 0000000..eb40dc7
--- /dev/null
+++ b/framework/permissions.py
@@ -0,0 +1,1242 @@
+# 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
+
+"""Classes and functions to implement permission checking.
+
+The main data structure is a simple map from (user role, project status,
+project_access_level) to specific perms.
+
+A perm is simply a string that indicates that the user has a given
+permission.  The servlets and templates can test whether the current
+user has permission to see a UI element or perform an action by
+testing for the presence of the corresponding perm in the user's
+permission set.
+
+The user role is one of admin, owner, member, outsider user, or anon.
+The project status is one of the project states defined in project_pb2,
+or a special constant defined below.  Likewise for access level.
+"""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import bisect
+import collections
+import logging
+import time
+
+import ezt
+
+import settings
+from framework import framework_bizobj
+from framework import framework_constants
+from proto import project_pb2
+from proto import site_pb2
+from proto import tracker_pb2
+from proto import usergroup_pb2
+from tracker import tracker_bizobj
+
+# Constants that define permissions.
+# Note that perms with a leading "_" can never be granted
+# to users who are not site admins.
+VIEW = 'View'
+EDIT_PROJECT = 'EditProject'
+CREATE_PROJECT = 'CreateProject'
+PUBLISH_PROJECT = '_PublishProject'  # for making "doomed" projects LIVE
+VIEW_DEBUG = '_ViewDebug'  # on-page debugging info
+EDIT_OTHER_USERS = '_EditOtherUsers'  # can edit other user's prefs, ban, etc.
+CUSTOMIZE_PROCESS = 'CustomizeProcess'  # can use some enterprise features
+VIEW_EXPIRED_PROJECT = '_ViewExpiredProject'  # view long-deleted projects
+# View the list of contributors even in hub-and-spoke projects.
+VIEW_CONTRIBUTOR_LIST = 'ViewContributorList'
+
+# Quota
+VIEW_QUOTA = 'ViewQuota'
+EDIT_QUOTA = 'EditQuota'
+
+# Permissions for editing user groups
+CREATE_GROUP = 'CreateGroup'
+EDIT_GROUP = 'EditGroup'
+DELETE_GROUP = 'DeleteGroup'
+VIEW_GROUP = 'ViewGroup'
+
+# Perms for Source tools
+# TODO(jrobbins): Monorail is just issue tracking with no version control, so
+# phase out use of the term "Commit", sometime after Monorail's initial launch.
+COMMIT = 'Commit'
+
+# Perms for issue tracking
+CREATE_ISSUE = 'CreateIssue'
+EDIT_ISSUE = 'EditIssue'
+EDIT_ISSUE_OWNER = 'EditIssueOwner'
+EDIT_ISSUE_SUMMARY = 'EditIssueSummary'
+EDIT_ISSUE_STATUS = 'EditIssueStatus'
+EDIT_ISSUE_CC = 'EditIssueCc'
+EDIT_ISSUE_APPROVAL = 'EditIssueApproval'
+DELETE_ISSUE = 'DeleteIssue'
+# This allows certain API clients to attribute comments to other users.
+# The permission is not offered in the UI, but it can be typed in as
+# a custom permission name.  The ID of the API client is also recorded.
+IMPORT_COMMENT = 'ImportComment'
+ADD_ISSUE_COMMENT = 'AddIssueComment'
+VIEW_INBOUND_MESSAGES = 'ViewInboundMessages'
+CREATE_HOTLIST = 'CreateHotlist'
+# Note, there is no separate DELETE_ATTACHMENT perm.  We
+# allow a user to delete an attachment iff they could soft-delete
+# the comment that holds the attachment.
+
+# Note: the "_" in the perm name makes it impossible for a
+# project owner to grant it to anyone as an extra perm.
+ADMINISTER_SITE = '_AdministerSite'
+
+# Permissions to soft-delete artifact comment
+DELETE_ANY = 'DeleteAny'
+DELETE_OWN = 'DeleteOwn'
+
+# Granting this allows owners to delegate some team management work.
+EDIT_ANY_MEMBER_NOTES = 'EditAnyMemberNotes'
+
+# Permission to star/unstar any artifact.
+SET_STAR = 'SetStar'
+
+# Permission to flag any artifact as spam.
+FLAG_SPAM = 'FlagSpam'
+VERDICT_SPAM = 'VerdictSpam'
+MODERATE_SPAM = 'ModerateSpam'
+
+# Permissions for custom fields.
+EDIT_FIELD_DEF = 'EditFieldDef'
+EDIT_FIELD_DEF_VALUE = 'EditFieldDefValue'
+
+# Permissions for user hotlists.
+ADMINISTER_HOTLIST = 'AdministerHotlist'
+EDIT_HOTLIST = 'EditHotlist'
+VIEW_HOTLIST = 'ViewHotlist'
+HOTLIST_OWNER_PERMISSIONS = [ADMINISTER_HOTLIST, EDIT_HOTLIST]
+HOTLIST_EDITOR_PERMISSIONS = [EDIT_HOTLIST]
+
+RESTRICTED_APPROVAL_STATUSES = [
+    tracker_pb2.ApprovalStatus.NA,
+    tracker_pb2.ApprovalStatus.APPROVED,
+    tracker_pb2.ApprovalStatus.NOT_APPROVED]
+
+STANDARD_ADMIN_PERMISSIONS = [
+    EDIT_PROJECT, CREATE_PROJECT, PUBLISH_PROJECT, VIEW_DEBUG,
+    EDIT_OTHER_USERS, CUSTOMIZE_PROCESS,
+    VIEW_QUOTA, EDIT_QUOTA, ADMINISTER_SITE,
+    EDIT_ANY_MEMBER_NOTES, VERDICT_SPAM, MODERATE_SPAM]
+
+STANDARD_ISSUE_PERMISSIONS = [
+    VIEW, EDIT_ISSUE, ADD_ISSUE_COMMENT, DELETE_ISSUE, FLAG_SPAM]
+
+# Monorail has no source control, but keep COMMIT for backward compatability.
+STANDARD_SOURCE_PERMISSIONS = [COMMIT]
+
+STANDARD_COMMENT_PERMISSIONS = [DELETE_OWN, DELETE_ANY]
+
+STANDARD_OTHER_PERMISSIONS = [CREATE_ISSUE, FLAG_SPAM, SET_STAR]
+
+STANDARD_PERMISSIONS = (STANDARD_ADMIN_PERMISSIONS +
+                        STANDARD_ISSUE_PERMISSIONS +
+                        STANDARD_SOURCE_PERMISSIONS +
+                        STANDARD_COMMENT_PERMISSIONS +
+                        STANDARD_OTHER_PERMISSIONS)
+
+# roles
+SITE_ADMIN_ROLE = 'admin'
+OWNER_ROLE = 'owner'
+COMMITTER_ROLE = 'committer'
+CONTRIBUTOR_ROLE = 'contributor'
+USER_ROLE = 'user'
+ANON_ROLE = 'anon'
+
+# Project state out-of-band values for keys
+UNDEFINED_STATUS = 'undefined_status'
+UNDEFINED_ACCESS = 'undefined_access'
+WILDCARD_ACCESS = 'wildcard_access'
+
+
+class PermissionSet(object):
+  """Class to represent the set of permissions available to the user."""
+
+  def __init__(self, perm_names, consider_restrictions=True):
+    """Create a PermissionSet with the given permissions.
+
+    Args:
+      perm_names: a list of permission name strings.
+      consider_restrictions: if true, the user's permissions can be blocked
+          by restriction labels on an artifact.  Project owners and site
+          admins do not consider restrictions so that they cannot
+          "lock themselves out" of editing an issue.
+    """
+    self.perm_names = frozenset(p.lower() for p in perm_names)
+    self.consider_restrictions = consider_restrictions
+
+  def __getattr__(self, perm_name):
+    """Easy permission testing in EZT.  E.g., [if-any perms.format_drive]."""
+    return ezt.boolean(self.HasPerm(perm_name, None, None))
+
+  def CanUsePerm(
+      self, perm_name, effective_ids, project, restriction_labels,
+      granted_perms=None):
+    """Return True if the user can use the given permission.
+
+    Args:
+      perm_name: string name of permission, e.g., 'EditIssue'.
+      effective_ids: set of int user IDs for the user (including any groups),
+          or an empty set if user is not signed in.
+      project: Project PB for the project being accessed, or None if not
+          in a project.
+      restriction_labels: list of strings that restrict permission usage.
+      granted_perms: optional list of lowercase strings of permissions that the
+          user is granted only within the scope of one issue, e.g., by being
+          named in a user-type custom field that grants permissions.
+
+    Restriction labels have 3 parts, e.g.:
+    'Restrict-EditIssue-InnerCircle' blocks the use of just the
+    EditIssue permission, unless the user also has the InnerCircle
+    permission.  This allows fine-grained restrictions on specific
+    actions, such as editing, commenting, or deleting.
+
+    Restriction labels and permissions are case-insensitive.
+
+    Returns:
+      True if the user can use the given permission, or False
+      if they cannot (either because they don't have that permission
+      or because it is blocked by a relevant restriction label).
+    """
+    # TODO(jrobbins): room for performance improvement: avoid set creation and
+    # repeated string operations.
+    granted_perms = granted_perms or set()
+    perm_lower = perm_name.lower()
+    if perm_lower in granted_perms:
+      return True
+
+    needed_perms = {perm_lower}
+    if self.consider_restrictions:
+      for label in restriction_labels:
+        label = label.lower()
+        # format: Restrict-Action-ToThisPerm
+        _kw, requested_perm, needed_perm = label.split('-', 2)
+        if requested_perm == perm_lower and needed_perm not in granted_perms:
+          needed_perms.add(needed_perm)
+
+    if not effective_ids:
+      effective_ids = {framework_constants.NO_USER_SPECIFIED}
+
+    # Get all extra perms for all effective ids.
+    # Id X might have perm A and Y might have B, if both A and B are needed
+    # True should be returned.
+    extra_perms = set()
+    for user_id in effective_ids:
+      extra_perms.update(p.lower() for p in GetExtraPerms(project, user_id))
+    return all(self.HasPerm(perm, None, None, extra_perms)
+               for perm in needed_perms)
+
+  def HasPerm(self, perm_name, user_id, project, extra_perms=None):
+    """Return True if the user has the given permission (ignoring user groups).
+
+    Args:
+      perm_name: string name of permission, e.g., 'EditIssue'.
+      user_id: int user id of the user, or None if user is not signed in.
+      project: Project PB for the project being accessed, or None if not
+          in a project.
+      extra_perms: list of extra perms. If not given, GetExtraPerms will be
+          called to get them.
+
+    Returns:
+      True if the user has the given perm.
+    """
+    perm_name = perm_name.lower()
+
+    # Return early if possible.
+    if perm_name in self.perm_names:
+      return True
+
+    if extra_perms is None:
+      # TODO(jrobbins): room for performance improvement: pre-compute
+      # extra perms (maybe merge them into the perms object), avoid
+      # redundant call to lower().
+      return any(
+          p.lower() == perm_name
+          for p in GetExtraPerms(project, user_id))
+
+    return perm_name in extra_perms
+
+  def DebugString(self):
+    """Return a useful string to show when debugging."""
+    return 'PermissionSet(%s)' % ', '.join(sorted(self.perm_names))
+
+  def __repr__(self):
+    return '%s(%r)' % (self.__class__.__name__, self.perm_names)
+
+
+EMPTY_PERMISSIONSET = PermissionSet([])
+
+READ_ONLY_PERMISSIONSET = PermissionSet([VIEW])
+
+USER_PERMISSIONSET = PermissionSet([
+    VIEW, FLAG_SPAM, SET_STAR,
+    CREATE_ISSUE, ADD_ISSUE_COMMENT,
+    DELETE_OWN])
+
+CONTRIBUTOR_ACTIVE_PERMISSIONSET = PermissionSet(
+    [VIEW,
+     FLAG_SPAM, VERDICT_SPAM, SET_STAR,
+     CREATE_ISSUE, ADD_ISSUE_COMMENT,
+     DELETE_OWN])
+
+CONTRIBUTOR_INACTIVE_PERMISSIONSET = PermissionSet(
+    [VIEW])
+
+COMMITTER_ACTIVE_PERMISSIONSET = PermissionSet(
+    [VIEW, COMMIT, VIEW_CONTRIBUTOR_LIST,
+     FLAG_SPAM, VERDICT_SPAM, SET_STAR, VIEW_QUOTA,
+     CREATE_ISSUE, ADD_ISSUE_COMMENT, EDIT_ISSUE, VIEW_INBOUND_MESSAGES,
+     DELETE_OWN])
+
+COMMITTER_INACTIVE_PERMISSIONSET = PermissionSet(
+    [VIEW, VIEW_CONTRIBUTOR_LIST,
+     VIEW_INBOUND_MESSAGES, VIEW_QUOTA])
+
+OWNER_ACTIVE_PERMISSIONSET = PermissionSet(
+    [VIEW, VIEW_CONTRIBUTOR_LIST, EDIT_PROJECT, COMMIT,
+     FLAG_SPAM, VERDICT_SPAM, SET_STAR, VIEW_QUOTA,
+     CREATE_ISSUE, ADD_ISSUE_COMMENT, EDIT_ISSUE, DELETE_ISSUE,
+     VIEW_INBOUND_MESSAGES,
+     DELETE_ANY, EDIT_ANY_MEMBER_NOTES],
+    consider_restrictions=False)
+
+OWNER_INACTIVE_PERMISSIONSET = PermissionSet(
+    [VIEW, VIEW_CONTRIBUTOR_LIST, EDIT_PROJECT,
+     VIEW_INBOUND_MESSAGES, VIEW_QUOTA],
+    consider_restrictions=False)
+
+ADMIN_PERMISSIONSET = PermissionSet(
+    [VIEW, VIEW_CONTRIBUTOR_LIST,
+     CREATE_PROJECT, EDIT_PROJECT, PUBLISH_PROJECT, VIEW_DEBUG,
+     COMMIT, CUSTOMIZE_PROCESS, FLAG_SPAM, VERDICT_SPAM, SET_STAR,
+     ADMINISTER_SITE, VIEW_EXPIRED_PROJECT, EDIT_OTHER_USERS,
+     VIEW_QUOTA, EDIT_QUOTA,
+     CREATE_ISSUE, ADD_ISSUE_COMMENT, EDIT_ISSUE, DELETE_ISSUE,
+     EDIT_ISSUE_APPROVAL,
+     VIEW_INBOUND_MESSAGES,
+     DELETE_ANY, EDIT_ANY_MEMBER_NOTES,
+     CREATE_GROUP, EDIT_GROUP, DELETE_GROUP, VIEW_GROUP,
+     MODERATE_SPAM, CREATE_HOTLIST],
+     consider_restrictions=False)
+
+GROUP_IMPORT_BORG_PERMISSIONSET = PermissionSet(
+    [CREATE_GROUP, VIEW_GROUP, EDIT_GROUP])
+
+# Permissions for project pages, e.g., the project summary page
+_PERMISSIONS_TABLE = {
+
+    # Project owners can view and edit artifacts in a LIVE project.
+    (OWNER_ROLE, project_pb2.ProjectState.LIVE, WILDCARD_ACCESS):
+      OWNER_ACTIVE_PERMISSIONSET,
+
+    # Project owners can view, but not edit artifacts in ARCHIVED.
+    # Note: EDIT_PROJECT is not enough permission to change an ARCHIVED project
+    # back to LIVE if a delete_time was set.
+    (OWNER_ROLE, project_pb2.ProjectState.ARCHIVED, WILDCARD_ACCESS):
+      OWNER_INACTIVE_PERMISSIONSET,
+
+    # Project members can view their own project, regardless of state.
+    (COMMITTER_ROLE, project_pb2.ProjectState.LIVE, WILDCARD_ACCESS):
+      COMMITTER_ACTIVE_PERMISSIONSET,
+    (COMMITTER_ROLE, project_pb2.ProjectState.ARCHIVED, WILDCARD_ACCESS):
+      COMMITTER_INACTIVE_PERMISSIONSET,
+
+    # Project contributors can view their own project, regardless of state.
+    (CONTRIBUTOR_ROLE, project_pb2.ProjectState.LIVE, WILDCARD_ACCESS):
+      CONTRIBUTOR_ACTIVE_PERMISSIONSET,
+    (CONTRIBUTOR_ROLE, project_pb2.ProjectState.ARCHIVED, WILDCARD_ACCESS):
+      CONTRIBUTOR_INACTIVE_PERMISSIONSET,
+
+    # Non-members users can read and comment in projects with access == ANYONE
+    (USER_ROLE, project_pb2.ProjectState.LIVE,
+     project_pb2.ProjectAccess.ANYONE):
+      USER_PERMISSIONSET,
+
+    # Anonymous users can only read projects with access == ANYONE.
+    (ANON_ROLE, project_pb2.ProjectState.LIVE,
+     project_pb2.ProjectAccess.ANYONE):
+      READ_ONLY_PERMISSIONSET,
+
+    # Permissions for site pages, e.g., creating a new project
+    (USER_ROLE, UNDEFINED_STATUS, UNDEFINED_ACCESS):
+      PermissionSet([CREATE_PROJECT, CREATE_GROUP, CREATE_HOTLIST]),
+    }
+
+def GetPermissions(user, effective_ids, project):
+  """Return a permission set appropriate for the user and project.
+
+  Args:
+    user: The User PB for the signed-in user, or None for anon users.
+    effective_ids: set of int user IDs for the current user and all user
+        groups that they are a member of.  This will be an empty set for
+        anonymous users.
+    project: either a Project protobuf, or None for a page whose scope is
+        wider than a single project.
+
+  Returns:
+    a PermissionSet object for the current user and project (or for
+    site-wide operations if project is None).
+
+  If an exact match for the user's role and project status is found, that is
+  returned. Otherwise, we look for permissions for the user's role that is
+  not specific to any project status, or not specific to any project access
+  level.  If neither of those are defined, we give the user an empty
+  permission set.
+  """
+  # Site admins get ADMIN_PERMISSIONSET regardless of groups or projects.
+  if user and user.is_site_admin:
+    return ADMIN_PERMISSIONSET
+
+  # Grant the borg job permission to view/edit groups
+  if user and user.email == settings.borg_service_account:
+    return GROUP_IMPORT_BORG_PERMISSIONSET
+
+  # Anon users don't need to accumulate anything.
+  if not effective_ids:
+    role, status, access = _GetPermissionKey(None, project)
+    return _LookupPermset(role, status, access)
+
+  effective_perms = set()
+  consider_restrictions = True
+
+  # Check for signed-in user with no roles in the current project.
+  if not project or not framework_bizobj.UserIsInProject(
+      project, effective_ids):
+    role, status, access = _GetPermissionKey(None, project)
+    return _LookupPermset(USER_ROLE, status, access)
+
+  # Signed-in user gets the union of all their PermissionSets from the table.
+  for user_id in effective_ids:
+    role, status, access = _GetPermissionKey(user_id, project)
+    role_perms = _LookupPermset(role, status, access)
+    # Accumulate a union of all the user's permissions.
+    effective_perms.update(role_perms.perm_names)
+    # If any role allows the user to ignore restriction labels, then
+    # ignore them overall.
+    if not role_perms.consider_restrictions:
+      consider_restrictions = False
+
+  return PermissionSet(
+      effective_perms, consider_restrictions=consider_restrictions)
+
+
+def UpdateIssuePermissions(
+    perms, project, issue, effective_ids, granted_perms=None, config=None):
+  """Update the PermissionSet for an specific issue.
+
+  Take into account granted permissions and label restrictions to filter the
+  permissions, and updates the VIEW and EDIT_ISSUE permissions depending on the
+  role of the user in the issue (i.e. owner, reporter, cc or approver).
+
+  Args:
+    perms: The PermissionSet to update.
+    project: The Project PB for the issue project.
+    issue: The Issue PB.
+    effective_ids: Set of int user IDs for the current user and all user
+        groups that they are a member of.  This will be an empty set for
+        anonymous users.
+    granted_perms: optional list of strings of permissions that the user is
+        granted only within the scope of one issue, e.g., by being named in
+        a user-type custom field that grants permissions.
+    config: optional ProjectIssueConfig PB where granted perms should be
+        extracted from, if granted_perms is not given.
+  """
+  if config:
+    granted_perms = tracker_bizobj.GetGrantedPerms(
+        issue, effective_ids, config)
+  elif granted_perms is None:
+    granted_perms = []
+
+  # If the user has no permission to view the project, it has no permissions on
+  # this issue.
+  if not perms.HasPerm(VIEW, None, None):
+    return EMPTY_PERMISSIONSET
+
+  # Compute the restrictions for the given issue and store them in a dictionary
+  # of {perm: set(needed_perms)}.
+  restrictions = collections.defaultdict(set)
+  if perms.consider_restrictions:
+    for label in GetRestrictions(issue):
+      label = label.lower()
+      # format: Restrict-Action-ToThisPerm
+      _, requested_perm, needed_perm = label.split('-', 2)
+      restrictions[requested_perm.lower()].add(needed_perm.lower())
+
+  # Store the user permissions, and the extra permissions of all effective IDs
+  # in the given project.
+  all_perms = set(perms.perm_names)
+  for effective_id in effective_ids:
+    all_perms.update(p.lower() for p in GetExtraPerms(project, effective_id))
+
+  # And filter them applying the restriction labels.
+  filtered_perms = set()
+  for perm_name in all_perms:
+    perm_name = perm_name.lower()
+    restricted = any(
+        restriction not in all_perms and restriction not in granted_perms
+        for restriction in restrictions.get(perm_name, []))
+    if not restricted:
+      filtered_perms.add(perm_name)
+
+  # Add any granted permissions.
+  filtered_perms.update(granted_perms)
+
+  # The VIEW perm might have been removed due to restrictions, but the issue
+  # owner, reporter, cc and approvers can always be an issue.
+  allowed_ids = set(
+      tracker_bizobj.GetCcIds(issue)
+      + tracker_bizobj.GetApproverIds(issue)
+      + [issue.reporter_id, tracker_bizobj.GetOwnerId(issue)])
+  if effective_ids and not allowed_ids.isdisjoint(effective_ids):
+    filtered_perms.add(VIEW.lower())
+
+  # If the issue is deleted, only the VIEW and DELETE_ISSUE permissions are
+  # relevant.
+  if issue.deleted:
+    if VIEW.lower() not in filtered_perms:
+      return EMPTY_PERMISSIONSET
+    if DELETE_ISSUE.lower() in filtered_perms:
+      return PermissionSet([VIEW, DELETE_ISSUE], perms.consider_restrictions)
+    return PermissionSet([VIEW], perms.consider_restrictions)
+
+  # The EDIT_ISSUE permission might have been removed due to restrictions, but
+  # the owner always has permission to edit it.
+  if effective_ids and tracker_bizobj.GetOwnerId(issue) in effective_ids:
+    filtered_perms.add(EDIT_ISSUE.lower())
+
+  return PermissionSet(filtered_perms, perms.consider_restrictions)
+
+
+def _LookupPermset(role, status, access):
+  """Lookup the appropriate PermissionSet in _PERMISSIONS_TABLE.
+
+  Args:
+    role: a string indicating the user's role in the project.
+    status: a Project PB status value, or UNDEFINED_STATUS.
+    access: a Project PB access value, or UNDEFINED_ACCESS.
+
+  Returns:
+    A PermissionSet that is appropriate for that kind of user in that
+    project context.
+  """
+  if (role, status, access) in _PERMISSIONS_TABLE:
+    return _PERMISSIONS_TABLE[(role, status, access)]
+  elif (role, status, WILDCARD_ACCESS) in _PERMISSIONS_TABLE:
+    return _PERMISSIONS_TABLE[(role, status, WILDCARD_ACCESS)]
+  else:
+    return EMPTY_PERMISSIONSET
+
+
+def _GetPermissionKey(user_id, project, expired_before=None):
+  """Return a permission lookup key appropriate for the user and project."""
+  if user_id is None:
+    role = ANON_ROLE
+  elif project and IsExpired(project, expired_before=expired_before):
+    role = USER_ROLE  # Do not honor roles in expired projects.
+  elif project and user_id in project.owner_ids:
+    role = OWNER_ROLE
+  elif project and user_id in project.committer_ids:
+    role = COMMITTER_ROLE
+  elif project and user_id in project.contributor_ids:
+    role = CONTRIBUTOR_ROLE
+  else:
+    role = USER_ROLE
+
+  if project is None:
+    status = UNDEFINED_STATUS
+  else:
+    status = project.state
+
+  if project is None:
+    access = UNDEFINED_ACCESS
+  else:
+    access = project.access
+
+  return role, status, access
+
+
+def GetExtraPerms(project, member_id):
+  """Return a list of extra perms for the user in the project.
+
+  Args:
+    project: Project PB for the current project.
+    member_id: user id of a project owner, member, or contributor.
+
+  Returns:
+    A list of strings for the extra perms granted to the
+    specified user in this project.  The list will often be empty.
+  """
+
+  _, extra_perms = FindExtraPerms(project, member_id)
+
+  if extra_perms:
+    return list(extra_perms.perms)
+  else:
+    return []
+
+
+def FindExtraPerms(project, member_id):
+  """Return a ExtraPerms PB for the given user in the project.
+
+  Args:
+    project: Project PB for the current project, or None if the user is
+      not currently in a project.
+    member_id: user ID of a project owner, member, or contributor.
+
+  Returns:
+    A pair (idx, extra_perms).
+    * If project is None or member_id is not part of the project, both are None.
+    * If member_id has no extra_perms, extra_perms is None, and idx points to
+      the position where it should go to keep the ExtraPerms sorted in project.
+    * Otherwise, idx is the position of member_id in the project's extra_perms,
+      and extra_perms is an ExtraPerms PB.
+  """
+  class ExtraPermsView(object):
+    def __len__(self):
+      return len(project.extra_perms)
+    def __getitem__(self, idx):
+      return project.extra_perms[idx].member_id
+
+  if not project:
+    # TODO(jrobbins): maybe define extra perms for site-wide operations.
+    return None, None
+
+  # Users who have no current role cannot have any extra perms.  Don't
+  # consider effective_ids (which includes user groups) for this check.
+  if not framework_bizobj.UserIsInProject(project, {member_id}):
+    return None, None
+
+  extra_perms_view = ExtraPermsView()
+  # Find the index of the first extra_perms.member_id greater than or equal to
+  # member_id.
+  idx = bisect.bisect_left(extra_perms_view, member_id)
+  if idx >= len(project.extra_perms) or extra_perms_view[idx] > member_id:
+    return idx, None
+  return idx, project.extra_perms[idx]
+
+
+def GetCustomPermissions(project):
+  """Return a sorted iterable of custom perms granted in a project."""
+  custom_permissions = set()
+  for extra_perms in project.extra_perms:
+    for perm in extra_perms.perms:
+      if perm not in STANDARD_PERMISSIONS:
+        custom_permissions.add(perm)
+
+  return sorted(custom_permissions)
+
+
+def UserCanViewProject(user, effective_ids, project, expired_before=None):
+  """Return True if the user can view the given project.
+
+  Args:
+    user: User protobuf for the user trying to view the project.
+    effective_ids: set of int user IDs of the user trying to view the project
+        (including any groups), or an empty set for anonymous users.
+    project: the Project protobuf to check.
+    expired_before: option time value for testing.
+
+  Returns:
+    True if the user should be allowed to view the project.
+  """
+  perms = GetPermissions(user, effective_ids, project)
+
+  if IsExpired(project, expired_before=expired_before):
+    needed_perm = VIEW_EXPIRED_PROJECT
+  else:
+    needed_perm = VIEW
+
+  return perms.CanUsePerm(needed_perm, effective_ids, project, [])
+
+
+def IsExpired(project, expired_before=None):
+  """Return True if a project deletion has been pending long enough already.
+
+  Args:
+    project: The project being viewed.
+    expired_before: If supplied, this method will return True only if the
+      project expired before the given time.
+
+  Returns:
+    True if the project is eligible for reaping.
+  """
+  if project.state != project_pb2.ProjectState.ARCHIVED:
+    return False
+
+  if expired_before is None:
+    expired_before = int(time.time())
+
+  return project.delete_time and project.delete_time < expired_before
+
+
+def CanDeleteComment(comment, commenter, user_id, perms):
+  """Returns true if the user can (un)delete the given comment.
+
+  UpdateIssuePermissions must have been called first.
+
+  Args:
+    comment: An IssueComment PB object.
+    commenter: An User PB object with the user who created the comment.
+    user_id: The ID of the user whose permission we want to check.
+    perms: The PermissionSet with the issue permissions.
+
+  Returns:
+    True if the user can (un)delete the comment.
+  """
+  # User is not logged in or has no permissions.
+  if not user_id or not perms:
+    return False
+
+  # Nobody can (un)delete comments by banned users or spam comments, which
+  # should be un-flagged instead.
+  if commenter.banned or comment.is_spam:
+    return False
+
+  # Site admin or project owners can delete any comment.
+  permit_delete_any = perms.HasPerm(DELETE_ANY, None, None, [])
+  if permit_delete_any:
+    return True
+
+  # Users cannot undelete unless they deleted.
+  if comment.deleted_by and comment.deleted_by != user_id:
+    return False
+
+  # Users can delete their own items.
+  permit_delete_own = perms.HasPerm(DELETE_OWN, None, None, [])
+  if permit_delete_own and comment.user_id == user_id:
+    return True
+
+  return False
+
+
+def CanFlagComment(comment, commenter, comment_reporters, user_id, perms):
+  """Returns true if the user can flag the given comment.
+
+  UpdateIssuePermissions must have been called first.
+  Assumes that the user has permission to view the issue.
+
+  Args:
+    comment: An IssueComment PB object.
+    commenter: An User PB object with the user who created the comment.
+    comment_reporters: A collection of user IDs who flagged the comment as spam.
+    user_id: The ID of the user for whom we're checking permissions.
+    perms: The PermissionSet with the issue permissions.
+
+  Returns:
+    A tuple (can_flag, is_flagged).
+    can_flag is True if the user can flag the comment. and is_flagged is True
+    if the user sees the comment marked as spam.
+  """
+  # Nobody can flag comments by banned users.
+  if commenter.banned:
+    return False, comment.is_spam
+
+  # If a comment was deleted for a reason other than being spam, nobody can
+  # flag or un-flag it.
+  if comment.deleted_by and not comment.is_spam:
+    return False, comment.is_spam
+
+  # A user with the VerdictSpam permission sees whether the comment is flagged
+  # as spam or not, and can mark it as flagged or un-flagged.
+  # If the comment is flagged as spam, all users see it as flagged, but only
+  # those with the VerdictSpam can un-flag it.
+  permit_verdict_spam = perms.HasPerm(VERDICT_SPAM, None, None, [])
+  if permit_verdict_spam or comment.is_spam:
+    return permit_verdict_spam, comment.is_spam
+
+  # Otherwise, the comment is not marked as flagged and the user doesn't have
+  # the VerdictSpam permission.
+  # They are able to report a comment as spam if they have the FlagSpam
+  # permission, and they see the comment as flagged if the have previously
+  # reported it as spam.
+  permit_flag_spam = perms.HasPerm(FLAG_SPAM, None, None, [])
+  return permit_flag_spam, user_id in comment_reporters
+
+
+def CanViewComment(comment, commenter, user_id, perms):
+  """Returns true if the user can view the given comment.
+
+  UpdateIssuePermissions must have been called first.
+  Assumes that the user has permission to view the issue.
+
+  Args:
+    comment: An IssueComment PB object.
+    commenter: An User PB object with the user who created the comment.
+    user_id: The ID of the user whose permission we want to check.
+    perms: The PermissionSet with the issue permissions.
+
+  Returns:
+    True if the user can view the comment.
+  """
+  # Nobody can view comments by banned users.
+  if commenter.banned:
+    return False
+
+  # Only users with the permission to un-flag comments can view flagged
+  # comments.
+  if comment.is_spam:
+    # If the comment is marked as spam, whether the user can un-flag the comment
+    # or not doesn't depend on who reported it as spam.
+    can_flag, _ = CanFlagComment(comment, commenter, [], user_id, perms)
+    return can_flag
+
+  # Only users with the permission to un-delete comments can view deleted
+  # comments.
+  if comment.deleted_by:
+    return CanDeleteComment(comment, commenter, user_id, perms)
+
+  return True
+
+
+def CanViewInboundMessage(comment, user_id, perms):
+  """Returns true if the user can view the given comment's inbound message.
+
+  UpdateIssuePermissions must have been called first.
+  Assumes that the user has permission to view the comment.
+
+  Args:
+    comment: An IssueComment PB object.
+    commenter: An User PB object with the user who created the comment.
+    user_id: The ID of the user whose permission we want to check.
+    perms: The PermissionSet with the issue permissions.
+
+  Returns:
+    True if the user can view the comment's inbound message.
+  """
+  return (perms.HasPerm(VIEW_INBOUND_MESSAGES, None, None, [])
+          or comment.user_id == user_id)
+
+
+def CanView(effective_ids, perms, project, restrictions, granted_perms=None):
+  """Checks if user has permission to view an issue."""
+  return perms.CanUsePerm(
+      VIEW, effective_ids, project, restrictions, granted_perms=granted_perms)
+
+
+def CanCreateProject(perms):
+  """Return True if the given user may create a project.
+
+  Args:
+    perms: Permissionset for the current user.
+
+  Returns:
+    True if the user should be allowed to create a project.
+  """
+  # "ANYONE" means anyone who has the needed perm.
+  if (settings.project_creation_restriction ==
+      site_pb2.UserTypeRestriction.ANYONE):
+    return perms.HasPerm(CREATE_PROJECT, None, None)
+
+  if (settings.project_creation_restriction ==
+      site_pb2.UserTypeRestriction.ADMIN_ONLY):
+    return perms.HasPerm(ADMINISTER_SITE, None, None)
+
+  return False
+
+
+def CanCreateGroup(perms):
+  """Return True if the given user may create a user group.
+
+  Args:
+    perms: Permissionset for the current user.
+
+  Returns:
+    True if the user should be allowed to create a group.
+  """
+  # "ANYONE" means anyone who has the needed perm.
+  if (settings.group_creation_restriction ==
+      site_pb2.UserTypeRestriction.ANYONE):
+    return perms.HasPerm(CREATE_GROUP, None, None)
+
+  if (settings.group_creation_restriction ==
+      site_pb2.UserTypeRestriction.ADMIN_ONLY):
+    return perms.HasPerm(ADMINISTER_SITE, None, None)
+
+  return False
+
+
+def CanEditGroup(perms, effective_ids, group_owner_ids):
+  """Return True if the given user may edit a user group.
+
+  Args:
+    perms: Permissionset for the current user.
+    effective_ids: set of user IDs for the logged in user.
+    group_owner_ids: set of user IDs of the user group owners.
+
+  Returns:
+    True if the user should be allowed to edit the group.
+  """
+  return (perms.HasPerm(EDIT_GROUP, None, None) or
+          not effective_ids.isdisjoint(group_owner_ids))
+
+
+def CanViewGroupMembers(perms, effective_ids, group_settings, member_ids,
+                        owner_ids, user_project_ids):
+  """Return True if the given user may view a user group's members.
+
+  Args:
+    perms: Permissionset for the current user.
+    effective_ids: set of user IDs for the logged in user.
+    group_settings: PB of UserGroupSettings.
+    member_ids: A list of member ids of this user group.
+    owner_ids: A list of owner ids of this user group.
+    user_project_ids: A list of project ids which the user has a role.
+
+  Returns:
+    True if the user should be allowed to view the group's members.
+  """
+  if perms.HasPerm(VIEW_GROUP, None, None):
+    return True
+  # The user could view this group with membership of some projects which are
+  # friends of the group.
+  if (group_settings.friend_projects and user_project_ids
+      and (set(group_settings.friend_projects) & set(user_project_ids))):
+    return True
+  visibility = group_settings.who_can_view_members
+  if visibility == usergroup_pb2.MemberVisibility.OWNERS:
+    return not effective_ids.isdisjoint(owner_ids)
+  elif visibility == usergroup_pb2.MemberVisibility.MEMBERS:
+    return (not effective_ids.isdisjoint(member_ids) or
+            not effective_ids.isdisjoint(owner_ids))
+  else:
+    return True
+
+
+def IsBanned(user, user_view):
+  """Return True if this user is banned from using our site."""
+  if user is None:
+    return False  # Anyone is welcome to browse
+
+  if user.banned:
+    return True  # We checked the "Banned" checkbox for this user.
+
+  if user_view:
+    if user_view.domain in settings.banned_user_domains:
+      return True  # Some spammers create many accounts with the same domain.
+
+  if '+' in (user.email or ''):
+    # Spammers can make plus-addr Google accounts in unexpected domains.
+    return True
+
+  return False
+
+
+def CanBan(mr, services):
+  """Return True if the user is allowed to ban other users, site-wide."""
+  if mr.perms.HasPerm(ADMINISTER_SITE, None, None):
+    return True
+
+  owned, _, _ = services.project.GetUserRolesInAllProjects(mr.cnxn,
+      mr.auth.effective_ids)
+  return len(owned) > 0
+
+
+def CanExpungeUsers(mr):
+  """Return True is the user is allowed to delete user accounts."""
+  return mr.perms.HasPerm(ADMINISTER_SITE, None, None)
+
+
+def CanViewContributorList(mr, project):
+  """Return True if we should display the list project contributors.
+
+  This is used on the project summary page, when deciding to offer the
+  project People page link, and when generating autocomplete options
+  that include project members.
+
+  Args:
+    mr: commonly used info parsed from the request.
+    project: the Project we're interested in.
+
+  Returns:
+    True if we should display the project contributor list.
+  """
+  if not project:
+    return False  # We are not even in a project context.
+
+  if not project.only_owners_see_contributors:
+    return True  # Contributor list is not resticted.
+
+  # If it is hub-and-spoke, check for the perm that allows the user to
+  # view it anyway.
+  return mr.perms.HasPerm(
+      VIEW_CONTRIBUTOR_LIST, mr.auth.user_id, project)
+
+
+def ShouldCheckForAbandonment(mr):
+  """Return True if user should be warned before changing/deleting their role.
+
+  Args:
+    mr: common info parsed from the user's request.
+
+  Returns:
+    True if user should be warned before changing/deleting their role.
+  """
+  # Note: No need to warn admins because they won't lose access anyway.
+  if mr.perms.CanUsePerm(
+      ADMINISTER_SITE, mr.auth.effective_ids, mr.project, []):
+    return False
+
+  return mr.perms.CanUsePerm(
+      EDIT_PROJECT, mr.auth.effective_ids, mr.project, [])
+
+
+# For speed, we remember labels that we have already classified as being
+# restriction labels or not being restriction labels.  These sets are for
+# restrictions in general, not for any particular perm.
+_KNOWN_RESTRICTION_LABELS = set()
+_KNOWN_NON_RESTRICTION_LABELS = set()
+
+
+def IsRestrictLabel(label, perm=''):
+  """Returns True if a given label is a restriction label.
+
+  Args:
+    label: string for the label to examine.
+    perm: a permission that can be restricted (e.g. 'View' or 'Edit').
+        Defaults to '' to mean 'any'.
+
+  Returns:
+    True if a given label is a restriction label (of the specified perm)
+  """
+  if label in _KNOWN_NON_RESTRICTION_LABELS:
+    return False
+  if not perm and label in _KNOWN_RESTRICTION_LABELS:
+    return True
+
+  prefix = ('restrict-%s-' % perm.lower()) if perm else 'restrict-'
+  is_restrict = label.lower().startswith(prefix) and label.count('-') >= 2
+
+  if is_restrict:
+    _KNOWN_RESTRICTION_LABELS.add(label)
+  elif not perm:
+    _KNOWN_NON_RESTRICTION_LABELS.add(label)
+
+  return is_restrict
+
+
+def HasRestrictions(issue, perm=''):
+  """Return True if the issue has any restrictions (on the specified perm)."""
+  return (
+      any(IsRestrictLabel(lab, perm=perm) for lab in issue.labels) or
+      any(IsRestrictLabel(lab, perm=perm) for lab in issue.derived_labels))
+
+
+def GetRestrictions(issue, perm=''):
+  """Return a list of restriction labels on the given issue."""
+  if not issue:
+    return []
+
+  return [lab.lower() for lab in tracker_bizobj.GetLabels(issue)
+          if IsRestrictLabel(lab, perm=perm)]
+
+
+def CanViewIssue(
+    effective_ids, perms, project, issue, allow_viewing_deleted=False,
+    granted_perms=None):
+  """Checks if user has permission to view an artifact.
+
+  Args:
+    effective_ids: set of user IDs for the logged in user and any user
+        group memberships.  Should be an empty set for anon users.
+    perms: PermissionSet for the user.
+    project: Project PB for the project that contains this issue.
+    issue: Issue PB for the issue being viewed.
+    allow_viewing_deleted: True if the user should be allowed to view
+        deleted artifacts.
+    granted_perms: optional list of strings of permissions that the user is
+        granted only within the scope of one issue, e.g., by being named in
+        a user-type custom field that grants permissions.
+
+  Returns:
+    True iff the user can view the specified issue.
+  """
+  if issue.deleted and not allow_viewing_deleted:
+    return False
+
+  perms = UpdateIssuePermissions(
+      perms, project, issue, effective_ids, granted_perms=granted_perms)
+  return perms.HasPerm(VIEW, None, None)
+
+
+def CanEditIssue(effective_ids, perms, project, issue, granted_perms=None):
+  """Return True if a user can edit an issue.
+
+  Args:
+    effective_ids: set of user IDs for the logged in user and any user
+        group memberships.  Should be an empty set for anon users.
+    perms: PermissionSet for the user.
+    project: Project PB for the project that contains this issue.
+    issue: Issue PB for the issue being viewed.
+    granted_perms: optional list of strings of permissions that the user is
+        granted only within the scope of one issue, e.g., by being named in
+        a user-type custom field that grants permissions.
+
+  Returns:
+    True iff the user can edit the specified issue.
+  """
+  perms = UpdateIssuePermissions(
+      perms, project, issue, effective_ids, granted_perms=granted_perms)
+  return perms.HasPerm(EDIT_ISSUE, None, None)
+
+
+def CanCommentIssue(effective_ids, perms, project, issue, granted_perms=None):
+  """Return True if a user can comment on an issue."""
+
+  return perms.CanUsePerm(
+      ADD_ISSUE_COMMENT, effective_ids, project,
+      GetRestrictions(issue), granted_perms=granted_perms)
+
+
+def CanUpdateApprovalStatus(
+    effective_ids, perms, project, approver_ids, new_status):
+  """Return True if a user can change the approval status to the new status."""
+  if not effective_ids.isdisjoint(approver_ids):
+    return True # Approval approvers can always change the approval status
+
+  if new_status not in RESTRICTED_APPROVAL_STATUSES:
+    return True
+
+  return perms.CanUsePerm(EDIT_ISSUE_APPROVAL, effective_ids, project, [])
+
+
+def CanUpdateApprovers(effective_ids, perms, project, current_approver_ids):
+  """Return True if a user can edit the list of approvers for an approval."""
+  if not effective_ids.isdisjoint(current_approver_ids):
+    return True
+
+  return perms.CanUsePerm(EDIT_ISSUE_APPROVAL, effective_ids, project, [])
+
+
+def CanViewComponentDef(effective_ids, perms, project, component_def):
+  """Return True if a user can view the given component definition."""
+  if not effective_ids.isdisjoint(component_def.admin_ids):
+    return True  # Component admins can view that component.
+
+  # TODO(jrobbins): check restrictions on the component definition.
+  return perms.CanUsePerm(VIEW, effective_ids, project, [])
+
+
+def CanEditComponentDef(effective_ids, perms, project, component_def, config):
+  """Return True if a user can edit the given component definition."""
+  if not effective_ids.isdisjoint(component_def.admin_ids):
+    return True  # Component admins can edit that component.
+
+  # Check to see if user is admin of any parent component.
+  parent_components = tracker_bizobj.FindAncestorComponents(
+      config, component_def)
+  for parent in parent_components:
+    if not effective_ids.isdisjoint(parent.admin_ids):
+      return True
+
+  return perms.CanUsePerm(EDIT_PROJECT, effective_ids, project, [])
+
+
+def CanViewFieldDef(effective_ids, perms, project, field_def):
+  """Return True if a user can view the given field definition."""
+  if not effective_ids.isdisjoint(field_def.admin_ids):
+    return True  # Field admins can view that field.
+
+  # TODO(jrobbins): check restrictions on the field definition.
+  return perms.CanUsePerm(VIEW, effective_ids, project, [])
+
+
+def CanEditFieldDef(effective_ids, perms, project, field_def):
+  """Return True if a user can edit the given field definition."""
+  if not effective_ids.isdisjoint(field_def.admin_ids):
+    return True  # Field admins can edit that field.
+
+  return perms.CanUsePerm(EDIT_PROJECT, effective_ids, project, [])
+
+
+def CanEditValueForFieldDef(effective_ids, perms, project, field_def):
+  """Return True if a user can edit the given field definition value.
+     This method does not check that a user can edit the project issues."""
+  if not effective_ids:
+    return False
+  if not field_def.is_restricted_field:
+    return True
+  if not effective_ids.isdisjoint(field_def.editor_ids):
+    return True
+  return CanEditFieldDef(effective_ids, perms, project, field_def)
+
+
+def CanViewTemplate(effective_ids, perms, project, template):
+  """Return True if a user can view the given issue template."""
+  if not effective_ids.isdisjoint(template.admin_ids):
+    return True  # template admins can view that template.
+
+  # Members-only templates are only shown to members, other templates are
+  # shown to any user that is generally allowed to view project content.
+  if template.members_only:
+    return framework_bizobj.UserIsInProject(project, effective_ids)
+  else:
+    return perms.CanUsePerm(VIEW, effective_ids, project, [])
+
+
+def CanEditTemplate(effective_ids, perms, project, template):
+  """Return True if a user can edit the given field definition."""
+  if not effective_ids.isdisjoint(template.admin_ids):
+    return True  # Template admins can edit that template.
+
+  return perms.CanUsePerm(EDIT_PROJECT, effective_ids, project, [])
+
+
+def CanViewHotlist(effective_ids, perms, hotlist):
+  """Return True if a user can view the given hotlist."""
+  if not hotlist.is_private or perms.HasPerm(ADMINISTER_SITE, None, None):
+    return True
+
+  return any([user_id in (hotlist.owner_ids + hotlist.editor_ids)
+              for user_id in effective_ids])
+
+
+def CanEditHotlist(effective_ids, perms, hotlist):
+  """Return True if a user is editor(add/remove issues and change rankings)."""
+  return perms.HasPerm(ADMINISTER_SITE, None, None) or any(
+      [user_id in (hotlist.owner_ids + hotlist.editor_ids)
+       for user_id in effective_ids])
+
+
+def CanAdministerHotlist(effective_ids, perms, hotlist):
+  """Return True if user is owner(add/remove members, edit/delete hotlist)."""
+  return perms.HasPerm(ADMINISTER_SITE, None, None) or any(
+      [user_id in hotlist.owner_ids for user_id in effective_ids])
+
+
+def CanCreateHotlist(perms):
+  """Return True if the given user may create a hotlist.
+
+  Args:
+    perms: Permissionset for the current user.
+
+  Returns:
+    True if the user should be allowed to create a hotlist.
+  """
+  if (settings.hotlist_creation_restriction ==
+      site_pb2.UserTypeRestriction.ANYONE):
+    return perms.HasPerm(CREATE_HOTLIST, None, None)
+
+  if (settings.hotlist_creation_restriction ==
+      site_pb2.UserTypeRestriction.ADMIN_ONLY):
+    return perms.HasPerm(ADMINISTER_SITE, None, None)
+
+
+class Error(Exception):
+  """Base class for errors from this module."""
+
+
+class PermissionException(Error):
+  """The user is not authorized to make the current request."""
+
+
+class BannedUserException(Error):
+  """The user has been banned from using our service."""
