# 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.

"""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 mrproto import project_pb2
from mrproto import site_pb2
from mrproto import tracker_pb2
from mrproto 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'

# 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
]

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, 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,

    # Non-members users can read archived projects with access == ANYONE.
    (
        USER_ROLE, project_pb2.ProjectState.ARCHIVED,
        project_pb2.ProjectAccess.ANYONE):
        READ_ONLY_PERMISSIONSET,

    # Anonymous users can only read projects with access == ANYONE,
    # regardless of state.
    (
        ANON_ROLE, project_pb2.ProjectState.LIVE,
        project_pb2.ProjectAccess.ANYONE):
        READ_ONLY_PERMISSIONSET,
    (
        ANON_ROLE, project_pb2.ProjectState.ARCHIVED,
        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 a 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 view 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 and
      project and project.state != project_pb2.ProjectState.ARCHIVED):
    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 CanEditProjectConfig(mr, services):
  """ Special function to check if a user can edit a project config.

  This function accounts for special edge cases pertaining only to project
  configuration editing permissions, such as checking if a project is frozen
  for config edits or if a user is in the allowlist of users who can override
  a config freeze.

  Args:
    mr: MonorailRequest object.
    services: reference to database layer.

  Returns:
    True if the user can edit the project.
  """
  if mr.project.project_id not in settings.config_freeze_project_ids:
    return mr.perms.CanUsePerm(
        EDIT_PROJECT, mr.auth.effective_ids, mr.project, [])

  effective_users = services.user.GetUsersByIDs(
      mr.cnxn, list(mr.auth.effective_ids))

  for _, user in effective_users.items():
    if user.email in settings.config_freeze_override_users.get(
        mr.project.project_id, {}):
      return True

  return False


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(mr, services, component_def, config):
  """ Checks if the currently logged in user can edit a component.

  Args:
    mr: MonorailRequest object.
    services: reference to database layer.
    component_def: the component to check permissions for.
    config: project config of the project the component is in.

  Returns:
    True if a user can edit the given component definition."""
  if mr.project.project_id in settings.config_freeze_project_ids:
    return CanEditProjectConfig(mr, services)

  if not mr.auth.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 mr.auth.effective_ids.isdisjoint(parent.admin_ids):
      return True

  return CanEditProjectConfig(mr, services)


def CanEditComponentDefLegacy(
    effective_ids, perms, project, component_def, config):
  """ Legacy version of CanEditComponentDef for codepaths without access to mr.
  This function is entirely used in API clients.

  Args:
    effective_ids: Set containing IDs for the user and their groups
      linked accounts, etc.
    perms: PermissionSet for current user.
    project: the project the component is in.
    component_def: the component to check permissions for.
    config: project config of the project the component is in.

  Returns:
    True if a user can edit the given component definition."""
  # Do not bother checking if API client users are allowlisted to override
  # the config freeze. Only human users are currently being allowlisted.
  if project and project.project_id in settings.config_freeze_project_ids:
    return False

  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."""
