Fix authorization checks for simple_usage.show
* Normal users shouls be allowed to query their own usage info * Fixes bug 921327 * Address bcwaldon's comment about using a default {} in authorize * Remove is_admin references * Rebase and change expected auth failure response from 401 to 403 * Remove policy-related tests * Add back test_verify_show_cant_view_other_tenant, implemented with test policy Change-Id: Ib0ce46419b7aedad34de957bfe2e60b10c5af11c
This commit is contained in:

committed by
Vishvananda Ishaya

parent
13dafc977d
commit
ca22fc9d31
@@ -33,7 +33,8 @@
|
|||||||
"compute_extension:security_groups": [],
|
"compute_extension:security_groups": [],
|
||||||
"compute_extension:server_action_list": [["rule:admin_api"]],
|
"compute_extension:server_action_list": [["rule:admin_api"]],
|
||||||
"compute_extension:server_diagnostics": [["rule:admin_api"]],
|
"compute_extension:server_diagnostics": [["rule:admin_api"]],
|
||||||
"compute_extension:simple_tenant_usage": [["rule:admin_api"]],
|
"compute_extension:simple_tenant_usage:show": [["rule:admin_or_owner"]],
|
||||||
|
"compute_extension:simple_tenant_usage:list": [["rule:admin_api"]],
|
||||||
"compute_extension:users": [["rule:admin_api"]],
|
"compute_extension:users": [["rule:admin_api"]],
|
||||||
"compute_extension:virtual_interfaces": [],
|
"compute_extension:virtual_interfaces": [],
|
||||||
"compute_extension:virtual_storage_arrays": [],
|
"compute_extension:virtual_storage_arrays": [],
|
||||||
|
@@ -29,7 +29,10 @@ from nova import flags
|
|||||||
|
|
||||||
|
|
||||||
FLAGS = flags.FLAGS
|
FLAGS = flags.FLAGS
|
||||||
authorize = extensions.extension_authorizer('compute', 'simple_tenant_usage')
|
authorize_show = extensions.extension_authorizer('compute',
|
||||||
|
'simple_tenant_usage:show')
|
||||||
|
authorize_list = extensions.extension_authorizer('compute',
|
||||||
|
'simple_tenant_usage:list')
|
||||||
|
|
||||||
|
|
||||||
def make_usage(elem):
|
def make_usage(elem):
|
||||||
@@ -110,8 +113,6 @@ class SimpleTenantUsageController(object):
|
|||||||
period_start,
|
period_start,
|
||||||
period_stop,
|
period_stop,
|
||||||
tenant_id)
|
tenant_id)
|
||||||
from nova import log as logging
|
|
||||||
logging.info(instances)
|
|
||||||
rval = {}
|
rval = {}
|
||||||
flavors = {}
|
flavors = {}
|
||||||
|
|
||||||
@@ -212,10 +213,8 @@ class SimpleTenantUsageController(object):
|
|||||||
def index(self, req):
|
def index(self, req):
|
||||||
"""Retrive tenant_usage for all tenants"""
|
"""Retrive tenant_usage for all tenants"""
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
authorize(context)
|
|
||||||
|
|
||||||
if not context.is_admin:
|
authorize_list(context)
|
||||||
return webob.Response(status_int=403)
|
|
||||||
|
|
||||||
(period_start, period_stop, detailed) = self._get_datetime_range(req)
|
(period_start, period_stop, detailed) = self._get_datetime_range(req)
|
||||||
usages = self._tenant_usages_for_period(context,
|
usages = self._tenant_usages_for_period(context,
|
||||||
@@ -229,11 +228,8 @@ class SimpleTenantUsageController(object):
|
|||||||
"""Retrive tenant_usage for a specified tenant"""
|
"""Retrive tenant_usage for a specified tenant"""
|
||||||
tenant_id = id
|
tenant_id = id
|
||||||
context = req.environ['nova.context']
|
context = req.environ['nova.context']
|
||||||
authorize(context)
|
|
||||||
|
|
||||||
if not context.is_admin:
|
authorize_show(context, {'project_id': tenant_id})
|
||||||
if tenant_id != context.project_id:
|
|
||||||
return webob.Response(status_int=403)
|
|
||||||
|
|
||||||
(period_start, period_stop, ignore) = self._get_datetime_range(req)
|
(period_start, period_stop, ignore) = self._get_datetime_range(req)
|
||||||
usage = self._tenant_usages_for_period(context,
|
usage = self._tenant_usages_for_period(context,
|
||||||
|
@@ -379,9 +379,11 @@ def load_standard_extensions(ext_mgr, logger, path, package):
|
|||||||
|
|
||||||
|
|
||||||
def extension_authorizer(api_name, extension_name):
|
def extension_authorizer(api_name, extension_name):
|
||||||
def authorize(context):
|
def authorize(context, target=None):
|
||||||
|
if target == None:
|
||||||
|
target = {}
|
||||||
action = '%s_extension:%s' % (api_name, extension_name)
|
action = '%s_extension:%s' % (api_name, extension_name)
|
||||||
nova.policy.enforce(context, action, {})
|
nova.policy.enforce(context, action, target)
|
||||||
return authorize
|
return authorize
|
||||||
|
|
||||||
|
|
||||||
|
@@ -22,6 +22,8 @@ from lxml import etree
|
|||||||
import webob
|
import webob
|
||||||
|
|
||||||
from nova.api.openstack.compute.contrib import simple_tenant_usage
|
from nova.api.openstack.compute.contrib import simple_tenant_usage
|
||||||
|
from nova import policy
|
||||||
|
from nova.common import policy as common_policy
|
||||||
from nova.compute import api
|
from nova.compute import api
|
||||||
from nova import context
|
from nova import context
|
||||||
from nova import flags
|
from nova import flags
|
||||||
@@ -133,18 +135,6 @@ class SimpleTenantUsageTest(test.TestCase):
|
|||||||
for j in xrange(SERVERS):
|
for j in xrange(SERVERS):
|
||||||
self.assertEqual(int(servers[j]['hours']), HOURS)
|
self.assertEqual(int(servers[j]['hours']), HOURS)
|
||||||
|
|
||||||
def test_verify_index_fails_for_nonadmin(self):
|
|
||||||
req = webob.Request.blank(
|
|
||||||
'/v2/faketenant_0/os-simple-tenant-usage?'
|
|
||||||
'detailed=1&start=%s&end=%s' %
|
|
||||||
(START.isoformat(), STOP.isoformat()))
|
|
||||||
req.method = "GET"
|
|
||||||
req.headers["content-type"] = "application/json"
|
|
||||||
|
|
||||||
res = req.get_response(fakes.wsgi_app(
|
|
||||||
fake_auth_context=self.user_context))
|
|
||||||
self.assertEqual(res.status_int, 403)
|
|
||||||
|
|
||||||
def test_verify_show(self):
|
def test_verify_show(self):
|
||||||
req = webob.Request.blank(
|
req = webob.Request.blank(
|
||||||
'/v2/faketenant_0/os-simple-tenant-usage/'
|
'/v2/faketenant_0/os-simple-tenant-usage/'
|
||||||
@@ -175,9 +165,18 @@ class SimpleTenantUsageTest(test.TestCase):
|
|||||||
req.method = "GET"
|
req.method = "GET"
|
||||||
req.headers["content-type"] = "application/json"
|
req.headers["content-type"] = "application/json"
|
||||||
|
|
||||||
res = req.get_response(fakes.wsgi_app(
|
rules = {
|
||||||
fake_auth_context=self.alt_user_context))
|
"compute_extension:simple_tenant_usage:show":
|
||||||
self.assertEqual(res.status_int, 403)
|
[["role:admin"], ["project_id:%(project_id)s"]]
|
||||||
|
}
|
||||||
|
common_policy.set_brain(common_policy.HttpBrain(rules))
|
||||||
|
|
||||||
|
try:
|
||||||
|
res = req.get_response(fakes.wsgi_app(
|
||||||
|
fake_auth_context=self.alt_user_context))
|
||||||
|
self.assertEqual(res.status_int, 403)
|
||||||
|
finally:
|
||||||
|
policy.reset()
|
||||||
|
|
||||||
|
|
||||||
class SimpleTenantUsageSerializerTest(test.TestCase):
|
class SimpleTenantUsageSerializerTest(test.TestCase):
|
||||||
|
@@ -92,7 +92,8 @@
|
|||||||
"compute_extension:security_groups": [],
|
"compute_extension:security_groups": [],
|
||||||
"compute_extension:server_action_list": [],
|
"compute_extension:server_action_list": [],
|
||||||
"compute_extension:server_diagnostics": [],
|
"compute_extension:server_diagnostics": [],
|
||||||
"compute_extension:simple_tenant_usage": [],
|
"compute_extension:simple_tenant_usage:show": [],
|
||||||
|
"compute_extension:simple_tenant_usage:list": [],
|
||||||
"compute_extension:users": [],
|
"compute_extension:users": [],
|
||||||
"compute_extension:virtual_interfaces": [],
|
"compute_extension:virtual_interfaces": [],
|
||||||
"compute_extension:virtual_storage_arrays": [],
|
"compute_extension:virtual_storage_arrays": [],
|
||||||
|
Reference in New Issue
Block a user