Skip to content

Commit 1f120b5

Browse files
sdaguemriedem
authored andcommitted
Verify project id for flavor access calls
This includes project id verification for flavor access calls. Closes-Bug: #1544989 Implements bp:validate-project-with-keystone Change-Id: I2620c3ebc2a6dc131946602f8aa36ec0b6e782e0
1 parent 7f050fe commit 1f120b5

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed

api-ref/source/os-flavor-access.inc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ Normal response codes: 200
5757
Error response codes: badRequest(400), unauthorized(401), forbidden(403),
5858
itemNotFound(404), conflict(409)
5959

60+
- 400 - BadRequest - if the `tenant` is not found in your OpenStack
61+
deployment, a 400 is returned to prevent typos on the API call.
62+
6063
Request
6164
-------
6265

@@ -100,6 +103,9 @@ Normal response codes: 200
100103
Error response codes: badRequest(400), unauthorized(401), forbidden(403),
101104
itemNotFound(404), conflict(409)
102105

106+
- 400 - BadRequest - if the `tenant` is not found in your OpenStack
107+
deployment, a 400 is returned to prevent typos on the API call.
108+
103109
Request
104110
-------
105111

@@ -128,4 +134,3 @@ Response
128134

129135
.. literalinclude:: ../../doc/api_samples/flavor-access/flavor-access-remove-tenant-resp.json
130136
:language: javascript
131-

nova/api/openstack/compute/flavor_access.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from nova.api.openstack import common
2222
from nova.api.openstack.compute.schemas import flavor_access
2323
from nova.api.openstack import extensions
24+
from nova.api.openstack import identity
2425
from nova.api.openstack import wsgi
2526
from nova.api import validation
2627
from nova import exception
@@ -95,6 +96,7 @@ def _add_tenant_access(self, req, id, body):
9596

9697
vals = body['addTenantAccess']
9798
tenant = vals['tenant']
99+
identity.verify_project_id(context, tenant)
98100

99101
flavor = common.get_flavor(context, id)
100102

@@ -120,6 +122,7 @@ def _remove_tenant_access(self, req, id, body):
120122

121123
vals = body['removeTenantAccess']
122124
tenant = vals['tenant']
125+
identity.verify_project_id(context, tenant)
123126

124127
# NOTE(gibi): We have to load a flavor from the db here as
125128
# flavor.remove_access() will try to emit a notification and that needs

nova/tests/unit/api/openstack/compute/test_flavor_access.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,34 @@ def test_delete_tenant_access_with_no_tenant(self, mock_api_get):
383383
self.assertRaises(self.validation_ex,
384384
remove_access, req, '2', body=body)
385385

386+
@mock.patch('nova.api.openstack.identity.verify_project_id',
387+
side_effect=exc.HTTPBadRequest(
388+
explanation="Project ID proj2 is not a valid project."))
389+
def test_add_tenant_access_with_invalid_tenant(self, mock_verify):
390+
"""Tests the case that the tenant does not exist in Keystone."""
391+
req = fakes.HTTPRequest.blank(self._prefix + '/flavors/2/action',
392+
use_admin_context=True)
393+
body = {'addTenantAccess': {'tenant': 'proj2'}}
394+
self.assertRaises(exc.HTTPBadRequest,
395+
self.flavor_action_controller._add_tenant_access,
396+
req, '2', body=body)
397+
mock_verify.assert_called_once_with(
398+
req.environ['nova.context'], 'proj2')
399+
400+
@mock.patch('nova.api.openstack.identity.verify_project_id',
401+
side_effect=exc.HTTPBadRequest(
402+
explanation="Project ID proj2 is not a valid project."))
403+
def test_remove_tenant_access_with_invalid_tenant(self, mock_verify):
404+
"""Tests the case that the tenant does not exist in Keystone."""
405+
req = fakes.HTTPRequest.blank(self._prefix + '/flavors/2/action',
406+
use_admin_context=True)
407+
body = {'removeTenantAccess': {'tenant': 'proj2'}}
408+
self.assertRaises(exc.HTTPBadRequest,
409+
self.flavor_action_controller._remove_tenant_access,
410+
req, '2', body=body)
411+
mock_verify.assert_called_once_with(
412+
req.environ['nova.context'], 'proj2')
413+
386414

387415
class FlavorAccessPolicyEnforcementV21(test.NoDBTestCase):
388416

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
fixes:
33
- |
4-
API calls to /os-quota-sets/* will now attempt to validate the
5-
project_id being opperated on with keystone. If the user has
6-
enough permissions in user, and the keystone project does not
7-
exist, a 400 will be returned to prevent invalidate quota data
8-
from being put in the Nova database. This fixes an effective
9-
silent error where this would be stored even if this was not a
4+
API calls to ``/os-quota-sets`` and flavor access will now attempt
5+
to validate the project_id being operated on with Keystone. If
6+
the user token has enough permissions to perform
7+
``GET /v3/projects/{project_id}``, and the Keystone project
8+
does not exist, a 400 BadRequest will be returned to prevent invalid
9+
project data from being put in the Nova database. This fixes an effective
10+
silent error where the project_id would be stored even if it was not a
1011
valid project_id in the system.

0 commit comments

Comments
 (0)