# Copyright 2018 The LUCI Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

load('@stdlib//internal/luci/lib/validate.star', 'validate')


# TODO(vadimsh): Add support for 'anonymous' when/if needed.


# See https://chromium.googlesource.com/infra/luci/luci-py/+/master/appengine/components/components/auth/model.py
_GROUP_RE = r'^([a-z\-]+/)?[0-9a-zA-Z_][0-9a-zA-Z_\-\.\ @]{1,80}[0-9a-zA-Z_\-\.]$'
_USER_RE = r'^[0-9a-zA-Z_\-\.\+\%]+@[0-9a-zA-Z_\-\.]+$'


# A constructor for acl.role structs.
#
# Such structs are seen through public API as predefined symbols, e.g.
# acl.LOGDOG_READER. There's no way for an end-user to define a new role.
#
# Expected to be used as roles in acl.entry(role=...) definitions, and maybe
# printed (when debugging).
#
# Fields:
#   name: name of the role.
#   project_level_only: True if the role can be set only in project(...) rule.
#   groups_only: True if the role should be assigned only to groups, not users.
_role_ctor = genstruct('acl.role')


# A constructor for acl.entry structs.
#
# Such structs are created via public acl.entry(...) API. To make their
# printable representation useful and not confusing to end users, their
# structure somewhat resembles acl.entry(...) arguments list.
#
# They are not convenient though when generating configs. For that reason
# there's another representation of ACLs: as a list of elementary
# (role, principal) tuples, where principals can be of few different types
# (e.g. groups or users). Internal API function 'normalize_acls' converts
# from the user-friendly acl.entry representation to the generator-friendly
# acl.elementary representation.
#
# Fields:
#   roles: a list of acl.role in the entry, at least one.
#   users: a list of user emails to apply roles to, may be empty.
#   groups: a list of group names to apply roles to, may be empty.
_entry_ctor = genstruct('acl.entry')


# A constructor for acl.elementary structs.
#
# This is conceptually a sum type: (Role, User | Group). For convenience it is
# represented as a triple where either 'user' or 'group' is set, but not both.
#
# Fields:
#   role: an acl.role, always set.
#   user: an user email.
#   group: a group name.
_elementary_ctor = genstruct('acl.elementary')


def _role(name, project_level_only=False, groups_only=False):
  """Defines a role.

  Internal API. Only predefined roles are available publicly, see the bottom of
  this file.

  Args:
    name: string name of the role.
    project_level_only: True if it can be used only in project(...) ACLs.
    groups_only: True if role supports only group-based ACL (not user-based).

  Returns:
    acl.role struct.
  """
  return _role_ctor(
      name = name,
      project_level_only = project_level_only,
      groups_only = groups_only,
  )


def _entry(roles, groups=None, users=None):
  """An ACL entry: assigns given role (or roles) to given individuals or groups.

  Specifying an empty ACL entry is allowed. It is ignored everywhere. Useful for
  things like:

      core.project(
          acl = [
              acl.entry(acl.PROJECT_CONFIGS_READER, groups = [
                  # TODO: fill me in
              ])
          ]
      )

  Args:
    roles: a single role (as acl.role) or a list of roles to assign.
    groups: a single group name or a list of groups to assign the role to.
    users: a single user email or a list of emails to assign the role to.

  Returns:
    acl.entry struct, consider it opaque.
  """
  if ctor(roles) == _role_ctor:
    roles = [roles]
  elif roles != None and type(roles) != 'list':
    validate.struct('roles', roles, _role_ctor)

  if type(groups) == 'string':
    groups = [groups]
  elif groups != None and type(groups) != 'list':
    validate.string('groups', groups, regexp=_GROUP_RE)

  if type(users) == 'string':
    users = [users]
  elif users != None and type(users) != 'list':
    validate.string('users', users, regexp=_USER_RE)

  roles = validate.list('roles', roles, required=True)
  groups = validate.list('groups', groups)
  users = validate.list('users', users)

  for r in roles:
    validate.struct('roles', r, _role_ctor)
  for g in groups:
    validate.string('groups', g, regexp=_GROUP_RE)
  for u in users:
    validate.string('users', u, regexp=_USER_RE)

  # Some ACLs (e.g. LogDog) can be formulated only in terms of groups,
  # check this.
  for r in roles:
    if r.groups_only and users:
      fail('role %s can be assigned only to groups, not individual users' % r.name)

  return _entry_ctor(
      roles = roles,
      groups = groups,
      users = users,
  )


def _validate_acls(acls, project_level=False):
  """Validates the given list of acl.entry structs.

  Checks that project level roles are set only on the project level.

  Args:
    acls: an iterable of acl.entry structs to validate, or None.
    project_level: True to accept project_level_only=True roles.

  Returns:
    A list of validated acl.entry structs or [], never None.
  """
  acls = validate.list('acls', acls)
  for e in acls:
    validate.struct('acls', e, _entry_ctor)
    for r in e.roles:
      if r.project_level_only and not project_level:
        fail('bad "acls": role %s can only be set at the project level' % r.name)
  return acls


def _normalize_acls(acls):
  """Expands, dedups and sorts ACLs from the given list of acl.entry structs.

  Expands plural 'roles', 'groups' and 'users' fields in acl.entry into multiple
  acl.elementary structs: elementary pairs of (role, principal), where principal
  is either a user or a group.

  Args:
    acls: an iterable of acl.entry structs to expand, assumed to be validated.

  Returns:
    A sorted deduped list of acl.elementary structs.
  """
  out = []
  for e in acls:
    for r in e.roles:
      for u in e.users:
        out.append(_elementary_ctor(role=r, user=u, group=None))
      for g in e.groups:
        out.append(_elementary_ctor(role=r, user=None, group=g))
  return sorted(set(out), key=_sort_key)


def _sort_key(e):
  """acl.elementary -> tuple to sort it by."""
  return (e.role.name, 'u:' + e.user if e.user else 'g:' + e.group)


################################################################################


# Helper to avoid retyping role names.
def _roles_dict(l):
  return {r.name: r for r in l}


# Public API exposed to end-users and to other LUCI modules.
acl = struct(
    entry = _entry,

    # All predefined roles.
    **_roles_dict([
        # Reading contents of project configs through LUCI Config API/UI.
        _role('PROJECT_CONFIGS_READER', project_level_only=True),

        # Reading logs under project's logdog prefix.
        _role('LOGDOG_READER', project_level_only=True, groups_only=True),
        # Writing logs under project's logdog prefix.
        _role('LOGDOG_WRITER', project_level_only=True, groups_only=True),

        # Fetching info about a build, searching for builds in a bucket.
        _role('BUILDBUCKET_READER'),
        # Same as BUILDBUCKET_READER + scheduling and canceling builds.
        _role('BUILDBUCKET_TRIGGERER'),
        # Have full access to the bucket (should be used rarely).
        _role('BUILDBUCKET_OWNER'),

        # Viewing Scheduler jobs, invocations and their debug logs.
        _role('SCHEDULER_READER'),
        # Same as SCHEDULER_READER + ability to trigger jobs.
        _role('SCHEDULER_TRIGGERER'),
        # Have full access to jobs, including ability to abort them.
        _role('SCHEDULER_OWNER'),
    ])
)


# Additional internal API used by other LUCI modules.
aclimpl = struct(
    validate_acls = _validate_acls,
    normalize_acls = _normalize_acls,
)
