Consistently use utils functions for policy auth

The check_policy function exists in api utils, along with other more
complex policy utility functions. This change replaces direct calls to
authorize with calls to check_policy.

Having authorize calls consolidated in api utils may help with the
upcoming secure-rbac work.

Change-Id: If4779b08b9f360f4c2f4675c605aa519f6ea4778
This commit is contained in:
Steve Baker 2020-12-14 13:16:00 +13:00
parent a58b88c737
commit 8669837ea2
13 changed files with 47 additions and 105 deletions

View File

@ -26,7 +26,6 @@ from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import policy
from ironic import objects
METRICS = metrics_utils.get_metrics_logger(__name__)
@ -266,18 +265,17 @@ class AllocationsController(pecan.rest.RestController):
return convert_with_links(rpc_allocation, fields=fields)
def _authorize_create_allocation(self, allocation):
cdict = api.request.context.to_policy_values()
try:
policy.authorize('baremetal:allocation:create', cdict, cdict)
api_utils.check_policy('baremetal:allocation:create')
self._check_allowed_allocation_fields(allocation)
except exception.HTTPForbidden:
cdict = api.request.context.to_policy_values()
owner = cdict.get('project_id')
if not owner or (allocation.get('owner')
and owner != allocation.get('owner')):
raise
policy.authorize('baremetal:allocation:create_restricted',
cdict, cdict)
api_utils.check_policy('baremetal:allocation:create_restricted')
self._check_allowed_allocation_fields(allocation)
allocation['owner'] = owner
@ -460,8 +458,7 @@ class NodeAllocationController(pecan.rest.RestController):
@method.expose()
@args.validate(fields=args.string_list)
def get_all(self, fields=None):
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:allocation:get', cdict, cdict)
api_utils.check_policy('baremetal:allocation:get')
result = self.inner._get_allocations_collection(self.parent_node_ident,
fields=fields)
@ -476,8 +473,7 @@ class NodeAllocationController(pecan.rest.RestController):
@method.expose(status_code=http_client.NO_CONTENT)
def delete(self):
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:allocation:delete', cdict, cdict)
api_utils.check_policy('baremetal:allocation:delete')
rpc_node = api_utils.get_rpc_node_with_suffix(self.parent_node_ident)
allocations = objects.Allocation.list(

View File

@ -21,7 +21,6 @@ from ironic.api.controllers.v1 import utils as api_utils
from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common import policy
from ironic import objects
METRICS = metrics_utils.get_metrics_logger(__name__)
@ -57,8 +56,7 @@ class NodeBiosController(rest.RestController):
@method.expose()
def get_all(self):
"""List node bios settings."""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:node:bios:get', cdict, cdict)
api_utils.check_policy('baremetal:node:bios:get')
node = api_utils.get_rpc_node(self.node_ident)
settings = objects.BIOSSettingList.get_by_node_id(
@ -73,8 +71,7 @@ class NodeBiosController(rest.RestController):
:param setting_name: Logical name of the setting to retrieve.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:node:bios:get', cdict, cdict)
api_utils.check_policy('baremetal:node:bios:get')
node = api_utils.get_rpc_node(self.node_ident)
try:

View File

@ -29,7 +29,6 @@ from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import policy
from ironic import objects
METRICS = metrics_utils.get_metrics_logger(__name__)
@ -157,8 +156,7 @@ class ChassisController(rest.RestController):
:param fields: Optional, a list with a specified set of fields
of the resource to be returned.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:chassis:get', cdict, cdict)
api_utils.check_policy('baremetal:chassis:get')
api_utils.check_allow_specify_fields(fields)
@ -183,8 +181,7 @@ class ChassisController(rest.RestController):
:param sort_key: column to sort results by. Default: id.
:param sort_dir: direction to sort. "asc" or "desc". Default: asc.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:chassis:get', cdict, cdict)
api_utils.check_policy('baremetal:chassis:get')
# /detail should only work against collections
parent = api.request.path.split('/')[:-1][-1]
@ -205,8 +202,7 @@ class ChassisController(rest.RestController):
:param fields: Optional, a list with a specified set of fields
of the resource to be returned.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:chassis:get', cdict, cdict)
api_utils.check_policy('baremetal:chassis:get')
api_utils.check_allow_specify_fields(fields)
rpc_chassis = objects.Chassis.get_by_uuid(api.request.context,
@ -223,8 +219,7 @@ class ChassisController(rest.RestController):
:param chassis: a chassis within the request body.
"""
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:chassis:create', cdict, cdict)
api_utils.check_policy('baremetal:chassis:create')
# NOTE(yuriyz): UUID is mandatory for notifications payload
if not chassis.get('uuid'):
@ -250,8 +245,7 @@ class ChassisController(rest.RestController):
:param patch: a json PATCH document to apply to this chassis.
"""
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:chassis:update', cdict, cdict)
api_utils.check_policy('baremetal:chassis:update')
api_utils.patch_validate_allowed_fields(
patch, CHASSIS_SCHEMA['properties'])
@ -282,8 +276,7 @@ class ChassisController(rest.RestController):
:param chassis_uuid: UUID of a chassis.
"""
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:chassis:delete', cdict, cdict)
api_utils.check_policy('baremetal:chassis:delete')
rpc_chassis = objects.Chassis.get_by_uuid(context, chassis_uuid)
notify.emit_start_notification(context, rpc_chassis, 'delete')

View File

@ -22,7 +22,6 @@ from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import policy
import ironic.conf
from ironic import objects
@ -122,8 +121,7 @@ class ConductorsController(rest.RestController):
:param detail: Optional, boolean to indicate whether retrieve a list
of conductors with detail.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:conductor:get', cdict, cdict)
api_utils.check_policy('baremetal:conductor:get')
if not api_utils.allow_expose_conductors():
raise exception.NotFound()
@ -149,8 +147,7 @@ class ConductorsController(rest.RestController):
:param fields: Optional, a list with a specified set of fields
of the resource to be returned.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:conductor:get', cdict, cdict)
api_utils.check_policy('baremetal:conductor:get')
if not api_utils.allow_expose_conductors():
raise exception.NotFound()

View File

@ -25,7 +25,6 @@ from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import policy
from ironic.drivers import base as driver_base
@ -206,8 +205,7 @@ class DriverPassthruController(rest.RestController):
:raises: DriverNotFound if the driver name is invalid or the
driver cannot be loaded.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:driver:vendor_passthru', cdict, cdict)
api_utils.check_policy('baremetal:driver:vendor_passthru')
if driver_name not in _VENDOR_METHODS:
topic = api.request.rpcapi.get_topic_for_driver(driver_name)
@ -230,8 +228,7 @@ class DriverPassthruController(rest.RestController):
:param data: body of data to supply to the specified method.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:driver:vendor_passthru', cdict, cdict)
api_utils.check_policy('baremetal:driver:vendor_passthru')
topic = api.request.rpcapi.get_topic_for_driver(driver_name)
resp = api_utils.vendor_passthru(driver_name, method, topic,
@ -262,9 +259,8 @@ class DriverRaidController(rest.RestController):
:raises: DriverNotFound, if driver is not loaded on any of the
conductors.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:driver:get_raid_logical_disk_properties',
cdict, cdict)
api_utils.check_policy(
'baremetal:driver:get_raid_logical_disk_properties')
if not api_utils.allow_raid_config():
raise exception.NotAcceptable()
@ -305,9 +301,7 @@ class DriversController(rest.RestController):
# will break from a single-line doc string.
# This is a result of a bug in sphinxcontrib-pecanwsme
# https://github.com/dreamhost/sphinxcontrib-pecanwsme/issues/8
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:driver:get', cdict, cdict)
api_utils.check_policy('baremetal:driver:get')
api_utils.check_allow_driver_detail(detail)
api_utils.check_allow_filter_driver_type(type)
if type not in (None, 'classic', 'dynamic'):
@ -332,8 +326,7 @@ class DriversController(rest.RestController):
# retrieving a list of drivers using the current sqlalchemy schema, but
# this path must be exposed for Pecan to route any paths we might
# choose to expose below it.
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:driver:get', cdict, cdict)
api_utils.check_policy('baremetal:driver:get')
hw_type_dict = api.request.dbapi.get_active_hardware_type_dict()
for name, hosts in hw_type_dict.items():
@ -355,8 +348,7 @@ class DriversController(rest.RestController):
:raises: DriverNotFound (HTTP 404) if the driver name is invalid or
the driver cannot be loaded.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:driver:get_properties', cdict, cdict)
api_utils.check_policy('baremetal:driver:get_properties')
if driver_name not in _DRIVER_PROPERTIES:
topic = api.request.rpcapi.get_topic_for_driver(driver_name)

View File

@ -16,12 +16,10 @@ from ironic_lib import metrics_utils
from oslo_log import log
import pecan
from ironic import api
from ironic.api.controllers.v1 import utils as api_utils
from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common import policy
METRICS = metrics_utils.get_metrics_logger(__name__)
@ -104,7 +102,6 @@ class EventsController(pecan.rest.RestController):
def post(self, evts):
if not api_utils.allow_expose_events():
raise exception.NotFound()
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:events:post', cdict, cdict)
api_utils.check_policy('baremetal:events:post')
for e in evts['events']:
LOG.debug("Received external event: %s", e)

View File

@ -506,8 +506,7 @@ class IndicatorController(rest.RestController):
mod:`ironic.common.indicator_states`.
"""
cdict = pecan.request.context.to_policy_values()
policy.authorize('baremetal:node:set_indicator_state', cdict, cdict)
api_utils.check_policy('baremetal:node:set_indicator_state')
rpc_node = api_utils.get_rpc_node(node_ident)
topic = pecan.request.rpcapi.get_topic_for(rpc_node)
@ -529,8 +528,7 @@ class IndicatorController(rest.RestController):
:returns: a dict with the "state" key and one of
mod:`ironic.common.indicator_states` as a value.
"""
cdict = pecan.request.context.to_policy_values()
policy.authorize('baremetal:node:get_indicator_state', cdict, cdict)
api_utils.check_policy('baremetal:node:get_indicator_state')
rpc_node = api_utils.get_rpc_node(node_ident)
topic = pecan.request.rpcapi.get_topic_for(rpc_node)
@ -553,8 +551,7 @@ class IndicatorController(rest.RestController):
(from `get_supported_indicators`) as values.
"""
cdict = pecan.request.context.to_policy_values()
policy.authorize('baremetal:node:get_indicator_state', cdict, cdict)
api_utils.check_policy('baremetal:node:get_indicator_state')
rpc_node = api_utils.get_rpc_node(node_ident)
topic = pecan.request.rpcapi.get_topic_for(rpc_node)
@ -1995,8 +1992,7 @@ class NodesController(rest.RestController):
raise exception.OperationNotPermitted()
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:node:create', cdict, cdict)
api_utils.check_policy('baremetal:node:create')
reject_fields_in_newer_versions(node)

View File

@ -30,7 +30,6 @@ from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import policy
from ironic.common import states as ir_states
from ironic import objects
@ -501,8 +500,7 @@ class PortsController(rest.RestController):
raise exception.OperationNotPermitted()
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:port:create', cdict, cdict)
api_utils.check_policy('baremetal:port:create')
# NOTE(lucasagomes): Create the node_id attribute on-the-fly
# to satisfy the api -> rpc object

View File

@ -27,7 +27,6 @@ from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import policy
from ironic.common import states as ir_states
from ironic import objects
@ -269,8 +268,7 @@ class PortgroupsController(pecan.rest.RestController):
if not api_utils.allow_portgroups():
raise exception.NotFound()
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:portgroup:get', cdict, cdict)
api_utils.check_policy('baremetal:portgroup:get')
api_utils.check_allowed_portgroup_fields(fields)
api_utils.check_allowed_portgroup_fields([sort_key])
@ -308,8 +306,7 @@ class PortgroupsController(pecan.rest.RestController):
if not api_utils.allow_portgroups():
raise exception.NotFound()
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:portgroup:get', cdict, cdict)
api_utils.check_policy('baremetal:portgroup:get')
api_utils.check_allowed_portgroup_fields([sort_key])
# NOTE: /detail should only work against collections
@ -335,8 +332,7 @@ class PortgroupsController(pecan.rest.RestController):
if not api_utils.allow_portgroups():
raise exception.NotFound()
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:portgroup:get', cdict, cdict)
api_utils.check_policy('baremetal:portgroup:get')
if self.parent_node_ident:
raise exception.OperationNotPermitted()
@ -360,8 +356,7 @@ class PortgroupsController(pecan.rest.RestController):
raise exception.NotFound()
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:portgroup:create', cdict, cdict)
api_utils.check_policy('baremetal:portgroup:create')
if self.parent_node_ident:
raise exception.OperationNotPermitted()
@ -414,8 +409,7 @@ class PortgroupsController(pecan.rest.RestController):
raise exception.NotFound()
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:portgroup:update', cdict, cdict)
api_utils.check_policy('baremetal:portgroup:update')
if self.parent_node_ident:
raise exception.OperationNotPermitted()
@ -511,8 +505,7 @@ class PortgroupsController(pecan.rest.RestController):
raise exception.NotFound()
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:portgroup:delete', cdict, cdict)
api_utils.check_policy('baremetal:portgroup:delete')
if self.parent_node_ident:
raise exception.OperationNotPermitted()

View File

@ -25,7 +25,6 @@ from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import policy
from ironic.common import states
from ironic.common import utils
from ironic import objects
@ -95,8 +94,7 @@ class LookupController(rest.RestController):
if not api_utils.allow_ramdisk_endpoints():
raise exception.NotFound()
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:driver:ipa_lookup', cdict, cdict)
api_utils.check_policy('baremetal:driver:ipa_lookup')
# Validate the list of MAC addresses
if addresses is None:
@ -187,8 +185,7 @@ class HeartbeatController(rest.RestController):
raise exception.InvalidParameterValue(
_('Field "agent_version" not recognised'))
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:node:ipa_heartbeat', cdict, cdict)
api_utils.check_policy('baremetal:node:ipa_heartbeat')
if (agent_verify_ca is not None
and not api_utils.allow_verify_ca_in_heartbeat()):

View File

@ -24,7 +24,6 @@ from ironic.api.controllers.v1 import volume_connector
from ironic.api.controllers.v1 import volume_target
from ironic.api import method
from ironic.common import exception
from ironic.common import policy
def convert(node_ident=None):
@ -72,8 +71,7 @@ class VolumeController(rest.RestController):
if not api_utils.allow_volume():
raise exception.NotFound()
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:volume:get', cdict, cdict)
api_utils.check_policy('baremetal:volume:get')
return convert(self.parent_node_ident)

View File

@ -27,7 +27,6 @@ from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import policy
from ironic import objects
METRICS = metrics_utils.get_metrics_logger(__name__)
@ -180,8 +179,7 @@ class VolumeConnectorsController(rest.RestController):
:raises: InvalidParameterValue if sort key is invalid for sorting.
:raises: InvalidParameterValue if both fields and detail are specified.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:volume:get', cdict, cdict)
api_utils.check_policy('baremetal:volume:get')
if fields is None and not detail:
fields = _DEFAULT_RETURN_FIELDS
@ -212,8 +210,7 @@ class VolumeConnectorsController(rest.RestController):
:raises: VolumeConnectorNotFound if no volume connector exists with
the specified UUID.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:volume:get', cdict, cdict)
api_utils.check_policy('baremetal:volume:get')
if self.parent_node_ident:
raise exception.OperationNotPermitted()
@ -241,8 +238,7 @@ class VolumeConnectorsController(rest.RestController):
same UUID already exists
"""
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:volume:create', cdict, cdict)
api_utils.check_policy('baremetal:volume:create')
if self.parent_node_ident:
raise exception.OperationNotPermitted()
@ -298,8 +294,7 @@ class VolumeConnectorsController(rest.RestController):
volume connector is not powered off.
"""
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:volume:update', cdict, cdict)
api_utils.check_policy('baremetal:volume:update')
if self.parent_node_ident:
raise exception.OperationNotPermitted()
@ -375,8 +370,7 @@ class VolumeConnectorsController(rest.RestController):
volume connector is not powered off.
"""
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:volume:delete', cdict, cdict)
api_utils.check_policy('baremetal:volume:delete')
if self.parent_node_ident:
raise exception.OperationNotPermitted()

View File

@ -27,7 +27,6 @@ from ironic.api import method
from ironic.common import args
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import policy
from ironic import objects
METRICS = metrics_utils.get_metrics_logger(__name__)
@ -189,8 +188,7 @@ class VolumeTargetsController(rest.RestController):
:raises: InvalidParameterValue if sort key is invalid for sorting.
:raises: InvalidParameterValue if both fields and detail are specified.
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:volume:get', cdict, cdict)
api_utils.check_policy('baremetal:volume:get')
if fields is None and not detail:
fields = _DEFAULT_RETURN_FIELDS
@ -222,8 +220,7 @@ class VolumeTargetsController(rest.RestController):
node.
:raises: VolumeTargetNotFound if no volume target with this UUID exists
"""
cdict = api.request.context.to_policy_values()
policy.authorize('baremetal:volume:get', cdict, cdict)
api_utils.check_policy('baremetal:volume:get')
if self.parent_node_ident:
raise exception.OperationNotPermitted()
@ -251,8 +248,7 @@ class VolumeTargetsController(rest.RestController):
UUID exists
"""
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:volume:create', cdict, cdict)
api_utils.check_policy('baremetal:volume:create')
if self.parent_node_ident:
raise exception.OperationNotPermitted()
@ -305,8 +301,7 @@ class VolumeTargetsController(rest.RestController):
volume target is not powered off.
"""
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:volume:update', cdict, cdict)
api_utils.check_policy('baremetal:volume:update')
if self.parent_node_ident:
raise exception.OperationNotPermitted()
@ -379,8 +374,7 @@ class VolumeTargetsController(rest.RestController):
volume target is not powered off.
"""
context = api.request.context
cdict = context.to_policy_values()
policy.authorize('baremetal:volume:delete', cdict, cdict)
api_utils.check_policy('baremetal:volume:delete')
if self.parent_node_ident:
raise exception.OperationNotPermitted()