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:
parent
a10be151ad
commit
c6be78deb6
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"admin": [["role:admin"]],
|
||||
"admin_or_owner": [["role:admin"], ["project_id:%(project_id)s"]],
|
||||
"default": [["rule:admin_or_owner"]],
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"admin": [["role:admin"], ["role:administrator"]],
|
||||
"compute:create": [],
|
||||
"compute:create:attach_network": [],
|
||||
"compute:create:attach_volume": [],
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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": []}""")
|
||||
|
|
Loading…
Reference in New Issue