From 18ed0b0940da01eb25d5b6c56e0ac92d09a0b566 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Mon, 4 Jun 2012 18:49:19 -0500 Subject: [PATCH] Use openstack-common's policy module Reworks nova to use the new policy module in openstack-common. Change-Id: Iea8651bad85f26804285616330107d9d5f23e6cb --- nova/{ => openstack}/common/policy.py | 28 +++++++++++++++---- nova/policy.py | 8 ++---- .../contrib/test_simple_tenant_usage.py | 2 +- nova/tests/compute/test_compute.py | 4 +-- nova/tests/test_policy.py | 7 ++--- openstack-common.conf | 2 +- 6 files changed, 32 insertions(+), 19 deletions(-) rename nova/{ => openstack}/common/policy.py (88%) diff --git a/nova/common/policy.py b/nova/openstack/common/policy.py similarity index 88% rename from nova/common/policy.py rename to nova/openstack/common/policy.py index ec944a1ccb6f..203995a3d2f1 100644 --- a/nova/common/policy.py +++ b/nova/openstack/common/policy.py @@ -18,12 +18,12 @@ """Common Policy Engine Implementation""" import json +import logging import urllib import urllib2 -class NotAuthorized(Exception): - pass +LOG = logging.getLogger(__name__) _BRAIN = None @@ -45,7 +45,8 @@ def reset(): _BRAIN = None -def enforce(match_list, target_dict, credentials_dict): +def enforce(match_list, target_dict, credentials_dict, exc=None, + *args, **kwargs): """Enforces authorization of some rules against credentials. :param match_list: nested tuples of data to match against @@ -106,14 +107,24 @@ def enforce(match_list, target_dict, credentials_dict): Credentials dicts contain as much information as we can about the user performing the action. - :raises NotAuthorized: if the check fails + :param exc: exception to raise + Class of the exception to raise if the check fails. Any remaining + arguments passed to enforce() (both positional and keyword arguments) + will be passed to the exception class. If exc is not provided, returns + False. + + :return: True if the policy allows the action + :return: False if the policy does not allow the action and exc is not set """ global _BRAIN if not _BRAIN: _BRAIN = Brain() if not _BRAIN.check(match_list, target_dict, credentials_dict): - raise NotAuthorized() + if exc: + raise exc(*args, **kwargs) + return False + return True class Brain(object): @@ -132,7 +143,12 @@ class Brain(object): self.rules[key] = match def _check(self, match, target_dict, cred_dict): - match_kind, match_value = match.split(':', 1) + try: + match_kind, match_value = match.split(':', 1) + except Exception: + LOG.exception(_("Failed to understand rule %(match)r") % locals()) + # If the rule is invalid, fail closed + return False try: f = getattr(self, '_check_%s' % match_kind) except AttributeError: diff --git a/nova/policy.py b/nova/policy.py index e976831f3432..8c501da9e509 100644 --- a/nova/policy.py +++ b/nova/policy.py @@ -19,10 +19,10 @@ import os.path -from nova.common import policy from nova import exception from nova import flags from nova.openstack.common import cfg +from nova.openstack.common import policy from nova import utils @@ -90,7 +90,5 @@ def enforce(context, action, target): match_list = ('rule:%s' % action,) credentials = context.to_dict() - try: - policy.enforce(match_list, target, credentials) - except policy.NotAuthorized: - raise exception.PolicyNotAuthorized(action=action) + policy.enforce(match_list, target, credentials, + exception.PolicyNotAuthorized, action=action) diff --git a/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py b/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py index c3c28e9e4c82..cc5475de149f 100644 --- a/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py +++ b/nova/tests/api/openstack/compute/contrib/test_simple_tenant_usage.py @@ -22,10 +22,10 @@ from lxml import etree import webob from nova.api.openstack.compute.contrib import simple_tenant_usage -from nova.common import policy as common_policy from nova.compute import api from nova import context from nova import flags +from nova.openstack.common import policy as common_policy from nova import policy from nova import test from nova.tests.api.openstack import fakes diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py index 6a55b7dc0b98..ad6720c4292f 100644 --- a/nova/tests/compute/test_compute.py +++ b/nova/tests/compute/test_compute.py @@ -26,7 +26,6 @@ import time import mox import nova -import nova.common.policy from nova import compute from nova.compute import aggregate_states from nova.compute import api as compute_api @@ -44,6 +43,7 @@ from nova.image import fake as fake_image from nova import log as logging from nova.notifier import test_notifier from nova.openstack.common import importutils +from nova.openstack.common import policy as common_policy import nova.policy from nova import quota from nova import rpc @@ -3945,7 +3945,7 @@ class ComputePolicyTestCase(BaseTestCase): nova.policy.reset() def _set_rules(self, rules): - nova.common.policy.set_brain(nova.common.policy.HttpBrain(rules)) + common_policy.set_brain(common_policy.HttpBrain(rules)) def test_actions_are_prefixed(self): self.mox.StubOutWithMock(nova.policy, 'enforce') diff --git a/nova/tests/test_policy.py b/nova/tests/test_policy.py index f4219d74dc40..8ee9d0f219e5 100644 --- a/nova/tests/test_policy.py +++ b/nova/tests/test_policy.py @@ -21,11 +21,10 @@ import os.path import StringIO import urllib2 -from nova.common import policy as common_policy -import nova.common.policy from nova import context from nova import exception from nova import flags +from nova.openstack.common import policy as common_policy from nova import policy from nova import test from nova import utils @@ -169,8 +168,8 @@ class DefaultPolicyTestCase(test.TestCase): self.context = context.RequestContext('fake', 'fake') def _set_brain(self, default_rule): - brain = nova.common.policy.HttpBrain(self.rules, default_rule) - nova.common.policy.set_brain(brain) + brain = common_policy.HttpBrain(self.rules, default_rule) + common_policy.set_brain(brain) def tearDown(self): super(DefaultPolicyTestCase, self).tearDown() diff --git a/openstack-common.conf b/openstack-common.conf index 61690b895b0f..504500632334 100644 --- a/openstack-common.conf +++ b/openstack-common.conf @@ -1,7 +1,7 @@ [DEFAULT] # The list of modules to copy from openstack-common -modules=cfg,excutils,local,importutils,iniparser,jsonutils,setup +modules=cfg,excutils,local,importutils,iniparser,jsonutils,setup,policy # The base module to hold the copy of openstack.common base=nova