Use policy to determine admin context

Currently the logic to determine the admin context is controlled by
the [DEFAULT] admin_roles option but this requires that users set both
policy and the option properly.

This replaces the option by a new policy rule so that users can define
all policy related settings in the policy.yaml file. This also allows
users to create their is_admin rule with not only roles but also with
other elements.

Change-Id: Ib9d003065f943a5382e1079397bfde4292f5dabb
This commit is contained in:
Takashi Kajinami 2023-12-27 10:32:56 +09:00
parent 114601edba
commit be9bd3f3a0
6 changed files with 30 additions and 8 deletions

View File

@ -73,9 +73,6 @@ http_delete_rate = 500
# default datastore
default_datastore = a00000a0-00a0-0a00-00a0-000a000000aa
# Auth
admin_roles = admin
# Users to ignore for user create/list/delete operations
ignore_users = os_admin, root
ignore_dbs = lost+found, mysql, information_schema

View File

@ -0,0 +1,5 @@
---
deprecations:
- |
The ``[DEFAULT] admin_roles`` option has been deprecated in favor of
the new ``context_is_admin`` policy rule.

View File

@ -70,7 +70,9 @@ common_opts = [
help='Whether to provision a Cinder volume for rootdisk.'),
cfg.IntOpt('volume_rootdisk_size', default=10,
help='Size of volume rootdisk for Database instance'),
cfg.ListOpt('admin_roles', default=['admin'],
cfg.ListOpt('admin_roles', default=[],
deprecated_for_removal=True,
deprecated_reason=_('Use the context_is_admin policy rule'),
help='Roles to add to an admin user.'),
cfg.BoolOpt('update_status_on_fail', default=True,
help='Set the service and instance task statuses to ERROR '

View File

@ -12,6 +12,8 @@
from oslo_policy import policy
ADMIN_CTX_POLICY = 'context_is_admin'
PATH_BASE = '/v1.0/{account_id}'
PATH_INSTANCES = PATH_BASE + '/instances'
@ -51,6 +53,10 @@ PATH_MODULES = PATH_BASE + '/modules'
PATH_MODULE = PATH_MODULES + '/{module}'
rules = [
policy.RuleDefault(
ADMIN_CTX_POLICY,
'role:admin',
description='Rule for cloud admin access'),
policy.RuleDefault(
'admin',
'role:admin or is_admin:True',

View File

@ -20,6 +20,7 @@ from oslo_policy import policy
from trove.common import exception as trove_exceptions
from trove.common import policies
from trove.common.policies import base
CONF = cfg.CONF
_ENFORCER = None
@ -51,6 +52,13 @@ def authorize_on_target(context, rule, target):
"BUG: Target must not evaluate to False.")
def check_is_admin(context):
try:
return authorize_on_tenant(context, base.ADMIN_CTX_POLICY)
except trove_exceptions.PolicyNotAuthorized:
return False
def __authorize(context, rule, target=None):
"""Checks authorization of a rule against the target in this context.

View File

@ -37,6 +37,7 @@ from trove.common import context as rd_context
from trove.common import exception
from trove.common.i18n import _
from trove.common import pastedeploy
from trove.common import policy
from trove.common import utils
CONTEXT_KEY = 'trove.context'
@ -541,10 +542,6 @@ class ContextMiddleware(base_wsgi.Middleware):
user_id = request.headers.get('X-User-ID', None)
roles = request.headers.get('X-Role', '').split(',')
is_admin = False
for role in roles:
if role.lower() in self.admin_roles:
is_admin = True
break
limits = self._extract_limits(request.params)
context = rd_context.TroveContext(auth_token=auth_token,
project_id=tenant_id,
@ -554,6 +551,13 @@ class ContextMiddleware(base_wsgi.Middleware):
marker=limits.get('marker'),
service_catalog=service_catalog,
roles=roles)
if self.admin_roles:
for role in roles:
if role.lower() in self.admin_roles:
context.is_admin = True
break
else:
context.is_admin = policy.check_is_admin(context)
request.environ[CONTEXT_KEY] = context
@classmethod