summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2022-04-20 10:48:19 +0000
committerGerrit Code Review <review@openstack.org>2022-04-20 10:48:19 +0000
commit493afef940d548d02b997b0514643035a44ee030 (patch)
tree7d7cf2d1133bc98a21d5ccb3d5b0e8d607406e56
parent4d7a733192b395d373d6e955a4fb9cddfb6a1942 (diff)
parent909f3bd3c5585e68da62b511af24f862c7863d6b (diff)
downloadneutron-493afef940d548d02b997b0514643035a44ee030.tar.gz
Merge "[API] Return 403 for POST requests when user is not authorized" into stable/xena19.2.0
-rw-r--r--neutron/pecan_wsgi/hooks/policy_enforcement.py10
-rw-r--r--neutron/tests/functional/pecan_wsgi/test_hooks.py30
2 files changed, 36 insertions, 4 deletions
diff --git a/neutron/pecan_wsgi/hooks/policy_enforcement.py b/neutron/pecan_wsgi/hooks/policy_enforcement.py
index ff1289f87c..24b1cfe86e 100644
--- a/neutron/pecan_wsgi/hooks/policy_enforcement.py
+++ b/neutron/pecan_wsgi/hooks/policy_enforcement.py
@@ -136,13 +136,17 @@ class PolicyHook(hooks.PecanHook):
pluralized=collection)
except oslo_policy.PolicyNotAuthorized:
with excutils.save_and_reraise_exception() as ctxt:
+ controller = utils.get_controller(state)
# If a tenant is modifying it's own object, it's safe to
# return a 403. Otherwise, pretend that it doesn't exist
# to avoid giving away information.
- controller = utils.get_controller(state)
+ # It is also safe to return 403 if it's POST (CREATE)
+ # request.
s_action = controller.plugin_handlers[controller.SHOW]
- if not policy.check(neutron_context, s_action, item,
- pluralized=collection):
+ c_action = controller.plugin_handlers[controller.CREATE]
+ if (action != c_action and
+ not policy.check(neutron_context, s_action, item,
+ pluralized=collection)):
ctxt.reraise = False
msg = _('The resource could not be found.')
raise webob.exc.HTTPNotFound(msg)
diff --git a/neutron/tests/functional/pecan_wsgi/test_hooks.py b/neutron/tests/functional/pecan_wsgi/test_hooks.py
index 582b48a165..e78f3849ea 100644
--- a/neutron/tests/functional/pecan_wsgi/test_hooks.py
+++ b/neutron/tests/functional/pecan_wsgi/test_hooks.py
@@ -150,6 +150,17 @@ class TestPolicyEnforcementHook(test_functional.PecanFunctionalTest):
'validate': {'type:string':
db_const.PROJECT_ID_FIELD_SIZE},
'is_visible': True}
+ },
+ 'admin_mehs': {
+ 'id': {'allow_post': False, 'allow_put': False,
+ 'is_visible': True, 'primary_key': True},
+ 'foo': {'allow_post': True, 'allow_put': True,
+ 'is_visible': True, 'default': ''},
+ 'tenant_id': {'allow_post': True, 'allow_put': False,
+ 'required_by_policy': True,
+ 'validate': {'type:string':
+ db_const.PROJECT_ID_FIELD_SIZE},
+ 'is_visible': True}
}
}
@@ -163,9 +174,15 @@ class TestPolicyEnforcementHook(test_functional.PecanFunctionalTest):
attributes.RESOURCES.update(self.FAKE_RESOURCE)
manager.NeutronManager.set_plugin_for_resource('mehs',
self.mock_plugin)
+ manager.NeutronManager.set_plugin_for_resource('admin_mehs',
+ self.mock_plugin)
fake_controller = resource.CollectionsController('mehs', 'meh')
+ admin_fake_controller = resource.CollectionsController('admin_mehs',
+ 'admin_meh')
manager.NeutronManager.set_controller_for_resource(
'mehs', fake_controller)
+ manager.NeutronManager.set_controller_for_resource(
+ 'admin_mehs', admin_fake_controller)
# Inject policies for the fake resource
policy.init()
policy._ENFORCER.set_rules(
@@ -174,9 +191,20 @@ class TestPolicyEnforcementHook(test_functional.PecanFunctionalTest):
'update_meh': 'rule:admin_only',
'delete_meh': 'rule:admin_only',
'get_meh': 'rule:admin_only or field:mehs:id=xxx',
- 'get_meh:restricted_attr': 'rule:admin_only'}),
+ 'get_meh:restricted_attr': 'rule:admin_only',
+ 'create_admin_meh': 'rule:admin_only',
+ 'get_admin_meh': 'rule:admin_only'}),
overwrite=False)
+ def test_before_on_create_unauthorized_returns_403(self):
+ response = self.app.post_json(
+ '/v2.0/admin_mehs.json',
+ params={'admin_meh': {'foo': 'bar'}},
+ headers={'X-Project-Id': 'tenid'},
+ expect_errors=True)
+ # We expect this operation to fail with 403 error
+ self.assertEqual(403, response.status_int)
+
def test_before_on_create_authorized(self):
# Mock a return value for an hypothetical create operation
self.mock_plugin.create_meh.return_value = {