From: Gaozexu Date: Tue, 22 Sep 2015 03:35:37 +0000 (+0800) Subject: Fix UsedLimitsController's authorizer to soft X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=4bdeb045e491a86aeb8a1487798e598a2fa56e2f;p=openstack-build%2Fcinder-build.git Fix UsedLimitsController's authorizer to soft The rule "limits_extension:used_limits" is used by "UsedLimitsController" which is a controller extension and it extends "limits" api. Most of controller extensions authorize user's context by applying the function "extensions.soft_extension_authorizer()", but "UsedLimitsController" applies "extensions.extension_authorizer" and this may cause 403 Forbidden error. In this patch, I changed UsedLimitsController's authorizer to "soft_extension_authorizer". APIImpact Co-Authored-By: ZhuChunzhan Change-Id: I8a4163ca89236b35c2c6ba10bcd98f8c42ef9089 Closes-Bug: #1497868 --- diff --git a/cinder/api/contrib/used_limits.py b/cinder/api/contrib/used_limits.py index 52887ba80..d32967a3e 100644 --- a/cinder/api/contrib/used_limits.py +++ b/cinder/api/contrib/used_limits.py @@ -18,7 +18,7 @@ from cinder import quota QUOTAS = quota.QUOTAS -authorize = extensions.extension_authorizer('limits', 'used_limits') +authorize = extensions.soft_extension_authorizer('limits', 'used_limits') class UsedLimitsController(wsgi.Controller): @@ -26,25 +26,24 @@ class UsedLimitsController(wsgi.Controller): @wsgi.extends def index(self, req, resp_obj): context = req.environ['cinder.context'] - authorize(context) - - quotas = QUOTAS.get_project_quotas(context, context.project_id, - usages=True) - - quota_map = { - 'totalVolumesUsed': 'volumes', - 'totalGigabytesUsed': 'gigabytes', - 'totalSnapshotsUsed': 'snapshots', - 'totalBackupsUsed': 'backups', - 'totalBackupGigabytesUsed': 'backup_gigabytes' - } - - used_limits = {} - for display_name, single_quota in quota_map.items(): - if single_quota in quotas: - used_limits[display_name] = quotas[single_quota]['in_use'] - - resp_obj.obj['limits']['absolute'].update(used_limits) + if authorize(context): + quotas = QUOTAS.get_project_quotas(context, context.project_id, + usages=True) + + quota_map = { + 'totalVolumesUsed': 'volumes', + 'totalGigabytesUsed': 'gigabytes', + 'totalSnapshotsUsed': 'snapshots', + 'totalBackupsUsed': 'backups', + 'totalBackupGigabytesUsed': 'backup_gigabytes' + } + + used_limits = {} + for display_name, single_quota in quota_map.items(): + if single_quota in quotas: + used_limits[display_name] = quotas[single_quota]['in_use'] + + resp_obj.obj['limits']['absolute'].update(used_limits) class Used_limits(extensions.ExtensionDescriptor): diff --git a/cinder/tests/unit/api/contrib/test_used_limits.py b/cinder/tests/unit/api/contrib/test_used_limits.py index 7a2920605..437c2b55e 100644 --- a/cinder/tests/unit/api/contrib/test_used_limits.py +++ b/cinder/tests/unit/api/contrib/test_used_limits.py @@ -13,9 +13,11 @@ # License for the specific language governing permissions and limitations # under the License. +import mock + from cinder.api.contrib import used_limits from cinder.api.openstack import wsgi -from cinder import quota +from cinder import exception from cinder import test from cinder.tests.unit.api import fakes @@ -31,7 +33,9 @@ class UsedLimitsTestCase(test.TestCase): super(UsedLimitsTestCase, self).setUp() self.controller = used_limits.UsedLimitsController() - def test_used_limits(self): + @mock.patch('cinder.quota.QUOTAS.get_project_quotas') + @mock.patch('cinder.policy.enforce') + def test_used_limits(self, _mock_policy_enforce, _mock_get_project_quotas): fake_req = FakeRequest(fakes.FakeRequestContext('fake', 'fake')) obj = { "limits": { @@ -50,17 +54,30 @@ class UsedLimitsTestCase(test.TestCase): for display_name, q in quota_map.items(): limits[q] = {'limit': 2, 'in_use': 1} + _mock_get_project_quotas.return_value = limits - def stub_get_project_quotas(context, project_id, usages=True): - return limits - - self.stubs.Set(quota.QUOTAS, "get_project_quotas", - stub_get_project_quotas) - - self.mox.ReplayAll() + # allow user to access used limits + _mock_policy_enforce.return_value = None self.controller.index(fake_req, res) abs_limits = res.obj['limits']['absolute'] for used_limit, value in abs_limits.items(): self.assertEqual(value, limits[quota_map[used_limit]]['in_use']) + + obj = { + "limits": { + "rate": [], + "absolute": {}, + }, + } + res = wsgi.ResponseObject(obj) + + # unallow user to access used limits + _mock_policy_enforce.side_effect = exception.NotAuthorized + + self.controller.index(fake_req, res) + abs_limits = res.obj['limits']['absolute'] + self.assertNotIn('totalVolumesUsed', abs_limits) + self.assertNotIn('totalGigabytesUsed', abs_limits) + self.assertNotIn('totalSnapshotsUsed', abs_limits)