Allow advsvc role to create port in foreign tenant

Change [1] introduced support for advsvc role. This added
possibility for user with role advsvc to make CRUD operations
on ports, subnets and networks in foreign tenants.
Due the check in _validate_privileges() it was not working.
This patch fixes that.

Closes-Bug: #1796854

[1] https://review.openstack.org/#/c/101281

Change-Id: I6a3f91337bf8dd32012a75916e3409e30f46b50d
This commit is contained in:
Maciej Józefczyk
2018-10-11 08:57:29 +00:00
committed by Maciej Jozefczyk
parent fe62f2ec7f
commit 00147a7d70
4 changed files with 52 additions and 4 deletions

View File

@@ -3732,7 +3732,8 @@ mac_address-request:
mac_address-request-put: mac_address-request-put:
description: | description: |
The MAC address of the port. The MAC address of the port.
By default, only administrative users can change this value. By default, only administrative users and users with advsvc role
can change this value.
in: body in: body
required: false required: false
type: string type: string
@@ -4432,7 +4433,8 @@ project_id-body-required:
project_id-request: project_id-request:
description: | description: |
The ID of the project that owns the resource. The ID of the project that owns the resource.
Only administrative users can specify a project ID other than their own. Only administrative and users with advsvc role can specify
a project ID other than their own.
You cannot change this value through authorization policies. You cannot change this value through authorization policies.
in: body in: body
required: false required: false

View File

@@ -25,9 +25,10 @@ from neutron_lib import exceptions
def _validate_privileges(context, res_dict): def _validate_privileges(context, res_dict):
if ('project_id' in res_dict and if ('project_id' in res_dict and
res_dict['project_id'] != context.project_id and res_dict['project_id'] != context.project_id and
not context.is_admin): not (context.is_admin or context.is_advsvc)):
msg = _("Specifying 'project_id' or 'tenant_id' other than the " msg = _("Specifying 'project_id' or 'tenant_id' other than the "
"authenticated project in request requires admin privileges") "authenticated project in request requires admin or advsvc "
"privileges")
raise exc.HTTPBadRequest(msg) raise exc.HTTPBadRequest(msg)

View File

@@ -280,3 +280,44 @@ class TestCoreResources(base.BaseTestCase):
for r in TestCoreResources.CORE_DEFS: for r in TestCoreResources.CORE_DEFS:
self.assertIs(r.RESOURCE_ATTRIBUTE_MAP[r.COLLECTION_NAME], self.assertIs(r.RESOURCE_ATTRIBUTE_MAP[r.COLLECTION_NAME],
attributes.RESOURCES[r.COLLECTION_NAME]) attributes.RESOURCES[r.COLLECTION_NAME])
class TestValidatePriviliges(base.BaseTestCase):
def test__validate_privileges_same_tenant(self):
project_id = 'fake_project'
ctx = context.Context(project_id=project_id)
res_dict = {'project_id': project_id}
try:
attributes._validate_privileges(ctx, res_dict)
except exc.HTTPBadRequest:
self.fail("HTTPBadRequest exception should not be raised.")
def test__validate_privileges_user_other_tenant(self):
project_id = 'fake_project'
ctx = context.Context(project_id='fake_project2')
res_dict = {'project_id': project_id}
self.assertRaises(
exc.HTTPBadRequest,
attributes._validate_privileges,
ctx, res_dict)
def test__validate_privileges_admin_other_tenant(self):
project_id = 'fake_project'
ctx = context.Context(project_id='fake_project2',
is_admin=True)
res_dict = {'project_id': project_id}
try:
attributes._validate_privileges(ctx, res_dict)
except exc.HTTPBadRequest:
self.fail("HTTPBadRequest exception should not be raised.")
def test__validate_privileges_advsvc_other_tenant(self):
project_id = 'fake_project'
ctx = context.Context(project_id='fake_project2',
is_advsvc=True)
res_dict = {'project_id': project_id}
try:
attributes._validate_privileges(ctx, res_dict)
except exc.HTTPBadRequest:
self.fail("HTTPBadRequest exception should not be raised.")

View File

@@ -0,0 +1,4 @@
---
fixes:
- Bug `1796854 <https://bugs.launchpad.net/neutron/+bug/1796854>`_ is fixed
by validating if advsvc context is used.