summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/nova/policy.json1
-rw-r--r--nova/context.py5
-rw-r--r--nova/policy.py20
-rw-r--r--nova/tests/policy.json1
-rw-r--r--nova/tests/test_context.py6
-rw-r--r--nova/tests/test_policy.py5
6 files changed, 35 insertions, 3 deletions
diff --git a/etc/nova/policy.json b/etc/nova/policy.json
index 3970ce96a..02bf503cd 100644
--- a/etc/nova/policy.json
+++ b/etc/nova/policy.json
@@ -1,4 +1,5 @@
{
+ "admin": [["role:admin"]],
"admin_or_owner": [["role:admin"], ["project_id:%(project_id)s"]],
"default": [["rule:admin_or_owner"]],
diff --git a/nova/context.py b/nova/context.py
index 66697b567..b6fd105eb 100644
--- a/nova/context.py
+++ b/nova/context.py
@@ -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:
diff --git a/nova/policy.py b/nova/policy.py
index 94bbbdd93..acfe830b9 100644
--- a/nova/policy.py
+++ b/nova/policy.py
@@ -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
diff --git a/nova/tests/policy.json b/nova/tests/policy.json
index 6fa0cf4b3..a2d948323 100644
--- a/nova/tests/policy.json
+++ b/nova/tests/policy.json
@@ -1,4 +1,5 @@
{
+ "admin": [["role:admin"], ["role:administrator"]],
"compute:create": [],
"compute:create:attach_network": [],
"compute:create:attach_volume": [],
diff --git a/nova/tests/test_context.py b/nova/tests/test_context.py
index 977095910..0915bf157 100644
--- a/nova/tests/test_context.py
+++ b/nova/tests/test_context.py
@@ -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',
diff --git a/nova/tests/test_policy.py b/nova/tests/test_policy.py
index 41282005a..a85d3e25c 100644
--- a/nova/tests/test_policy.py
+++ b/nova/tests/test_policy.py
@@ -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": []}""")