Make sure that policy enforcer is initialized before use

In some cases policy.enforce() or policy.check() functions were called
without calling policy.init() before and that could lead to errors like
mentioned in the related bug.
To avoid that and to make it less error prone in future, this patch
moves call of the policy.init() method directly to the enforce() and
check() methods and removes it from all other places. Other modules
should not need to carry about policy initialization at all.

Closes-Bug: #2092659
Change-Id: Ic11992ba3ed91980189efbacdc2a54fba64fcf7c
This commit is contained in:
Slawek Kaplonski
2025-01-08 11:05:29 +01:00
parent 9b7662e951
commit 08afd36e54
5 changed files with 2 additions and 30 deletions

View File

@@ -228,8 +228,6 @@ class Controller:
@db_api.retry_db_errors
def _handle_action(request, id, **kwargs):
arg_list = [request.context, id]
# Ensure policy engine is initialized
policy.init()
# Fetch the resource and verify if the user can access it
try:
parent_id = kwargs.get(self._parent_id_name)
@@ -366,8 +364,6 @@ class Controller:
def index(self, request, **kwargs):
"""Returns a list of the requested entity."""
parent_id = kwargs.get(self._parent_id_name)
# Ensure policy engine is initialized
policy.init()
return self._items(request, True, parent_id)
@db_api.retry_db_errors
@@ -380,8 +376,6 @@ class Controller:
field_list, added_fields = self._do_field_list(
api_common.list_args(request, "fields"))
parent_id = kwargs.get(self._parent_id_name)
# Ensure policy engine is initialized
policy.init()
return {self._resource:
self._view(request.context,
self._item(request,
@@ -458,8 +452,6 @@ class Controller:
items = body[self._collection]
else:
items = [body]
# Ensure policy engine is initialized
policy.init()
# Store requested resource amounts grouping them by tenant
# This won't work with multiple resources. However because of the
# current structure of this controller there will hardly be more than
@@ -577,7 +569,6 @@ class Controller:
action = self._plugin_handlers[self.DELETE]
# Check authz
policy.init()
parent_id = kwargs.get(self._parent_id_name)
obj = self._item(request, id, parent_id=parent_id)
try:
@@ -648,8 +639,6 @@ class Controller:
if (value.get('required_by_policy') or
value.get('primary_key') or
'default' not in value)]
# Ensure policy engine is initialized
policy.init()
parent_id = kwargs.get(self._parent_id_name)
# If the parent_id exist, we should get orig_obj with
# self._parent_id_name field.

View File

@@ -49,7 +49,6 @@ LOG = logging.getLogger(__name__)
def validate_policy(context, policy_name):
policy.init()
policy.enforce(context,
policy_name,
target={'project_id': context.project_id},

View File

@@ -14,7 +14,6 @@
import abc
import collections
import copy
import functools
import itertools
import typing
@@ -92,14 +91,6 @@ ResourceInfo = collections.namedtuple(
EMPTY_RESOURCE_INFO = ResourceInfo(None, None, None, None, None)
def _policy_init(f):
@functools.wraps(f)
def func(self, *args, **kwargs):
policy.init()
return f(self, *args, **kwargs)
return func
class TagResourceNotFound(exceptions.NotFound):
message = _("Resource %(resource)s %(resource_id)s could not be found.")
@@ -191,7 +182,6 @@ class TaggingController:
# This should never be returned.
return EMPTY_RESOURCE_INFO
@_policy_init
def index(self, request, **kwargs):
# GET /v2.0/{parent_resource}/{parent_resource_id}/tags
ctx = request.context
@@ -201,7 +191,6 @@ class TaggingController:
target)
return self.plugin.get_tags(ctx, rinfo.parent_type, rinfo.parent_id)
@_policy_init
def show(self, request, id, **kwargs):
# GET /v2.0/{parent_resource}/{parent_resource_id}/tags/{tag}
# id == tag
@@ -213,7 +202,6 @@ class TaggingController:
target)
return self.plugin.get_tag(ctx, rinfo.parent_type, rinfo.parent_id, id)
@_policy_init
def create(self, request, body, **kwargs):
# POST /v2.0/{parent_resource}/{parent_resource_id}/tags
# body: {"tags": ["aaa", "bbb"]}
@@ -231,7 +219,6 @@ class TaggingController:
rinfo.parent_id, body['tags'])
return result
@_policy_init
def update(self, request, id, **kwargs):
# PUT /v2.0/{parent_resource}/{parent_resource_id}/tags/{tag}
# id == tag
@@ -249,7 +236,6 @@ class TaggingController:
rinfo.parent_id, [id])
return result
@_policy_init
def update_all(self, request, body, **kwargs):
# PUT /v2.0/{parent_resource}/{parent_resource_id}/tags
# body: {"tags": ["aaa", "bbb"]}
@@ -267,7 +253,6 @@ class TaggingController:
rinfo.parent_id, body['tags'])
return result
@_policy_init
def delete(self, request, id, **kwargs):
# DELETE /v2.0/{parent_resource}/{parent_resource_id}/tags/{tag}
# id == tag
@@ -285,7 +270,6 @@ class TaggingController:
rinfo.parent_id, [id])
return result
@_policy_init
def delete_all(self, request, **kwargs):
# DELETE /v2.0/{parent_resource}/{parent_resource_id}/tags
ctx = request.context

View File

@@ -89,7 +89,6 @@ class PolicyHook(hooks.PecanHook):
return
collection = state.request.context.get('collection')
needs_prefetch = state.request.method in ('PUT', 'DELETE')
policy.init()
action = controller.plugin_handlers[
pecan_constants.ACTION_MAP[state.request.method]]
@@ -164,7 +163,6 @@ class PolicyHook(hooks.PecanHook):
return
if not data or (resource not in data and collection not in data):
return
policy.init()
is_single = resource in data
action_type = pecan_constants.ACTION_MAP[state.request.method]
if action_type == 'get':

View File

@@ -474,6 +474,7 @@ def check(context, action, target, plugin=None, might_not_exist=False,
# personas will be supported
if not cfg.CONF.oslo_policy.enforce_new_defaults and context.is_admin:
return True
init()
if might_not_exist and not (_ENFORCER.rules and action in _ENFORCER.rules):
return True
match_rule, target, credentials = _prepare_check(context,
@@ -510,6 +511,7 @@ def enforce(context, action, target, plugin=None, pluralized=None):
# personas will be supported
if not cfg.CONF.oslo_policy.enforce_new_defaults and context.is_admin:
return True
init()
rule, target, context = _prepare_check(context, action, target, pluralized)
try:
result = _ENFORCER.enforce(rule, target, context, action=action,