Remove hard-coded 'admin' role checking and use policy instead

bug 1037786

This change removed hard-coded 'admin' role checking, and use policy check to
decide is_admin at the time of context construction. And also set
default admin role to 'admin', in policy template, to keep backward
compatibility.

Change-Id: I56b45bfdfba1b8e1391bde7fec3d4cf26c66324c
This commit is contained in:
unicell 2012-08-18 14:23:01 +08:00
parent a10be151ad
commit c6be78deb6
6 changed files with 35 additions and 3 deletions

View File

@ -1,4 +1,5 @@
{
"admin": [["role:admin"]],
"admin_or_owner": [["role:admin"], ["project_id:%(project_id)s"]],
"default": [["rule:admin_or_owner"]],

View File

@ -24,6 +24,7 @@ import copy
from nova.openstack.common import local
from nova.openstack.common import log as logging
from nova.openstack.common import timeutils
from nova import policy
from nova import utils
@ -66,9 +67,7 @@ class RequestContext(object):
self.roles = roles or []
self.is_admin = is_admin
if self.is_admin is None:
self.is_admin = 'admin' in [x.lower() for x in self.roles]
elif self.is_admin and 'admin' not in self.roles:
self.roles.append('admin')
self.is_admin = policy.check_admin_role(self.roles)
self.read_deleted = read_deleted
self.remote_address = remote_address
if not timestamp:

View File

@ -92,3 +92,23 @@ def enforce(context, action, target):
policy.enforce(match_list, target, credentials,
exception.PolicyNotAuthorized, action=action)
def check_admin_role(roles):
"""Whether or not roles contains 'admin' role according to policy setting.
"""
init()
action = 'admin'
match_list = ('rule:%s' % action,)
target = {}
credentials = {'roles': roles}
try:
policy.enforce(match_list, target, credentials,
exception.PolicyNotAuthorized, action=action)
except exception.PolicyNotAuthorized:
return False
return True

View File

@ -1,4 +1,5 @@
{
"admin": [["role:admin"], ["role:administrator"]],
"compute:create": [],
"compute:create:attach_network": [],
"compute:create:attach_volume": [],

View File

@ -26,6 +26,12 @@ class ContextTestCase(test.TestCase):
roles=['admin', 'weasel'])
self.assertEquals(ctxt.is_admin, True)
def test_request_context_sets_is_admin_by_role(self):
ctxt = context.RequestContext('111',
'222',
roles=['administrator'])
self.assertEquals(ctxt.is_admin, True)
def test_request_context_sets_is_admin_upcase(self):
ctxt = context.RequestContext('111',
'222',

View File

@ -49,6 +49,11 @@ class PolicyFileTestCase(test.TestCase):
tmpfilename = os.path.join(tmpdir, 'policy')
self.flags(policy_file=tmpfilename)
# NOTE(uni): context construction invokes policy check to determin
# is_admin or not. As a side-effect, policy reset is needed here
# to flush existing policy cache.
policy.reset()
action = "example:test"
with open(tmpfilename, "w") as policyfile:
policyfile.write("""{"example:test": []}""")