deckhand/deckhand/tests/unit/test_policy.py

97 lines
3.3 KiB
Python

# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import falcon
from falcon import testing as falcon_testing
from unittest import mock
from oslo_policy import policy as common_policy
from deckhand.control import base as api_base
import deckhand.policy
from deckhand.tests.unit import base as test_base
from deckhand.tests.unit import dh_fixtures
class PolicyBaseTestCase(test_base.DeckhandTestCase):
def setUp(self):
super(PolicyBaseTestCase, self).setUp()
# The default policies in deckhand.policies are automatically
# registered. Override them with custom rules. '@' allows anyone to
# perform a policy action.
self.rules = {
"deckhand:create_cleartext_documents": [['@']],
"deckhand:list_cleartext_documents": [['rule:admin_api']]
}
self.useFixture(dh_fixtures.RealPolicyFixture(False))
self._set_rules()
def _set_rules(self):
these_rules = common_policy.Rules.from_dict(self.rules)
deckhand.policy._ENFORCER.set_rules(these_rules)
def _enforce_policy(self, action):
api_args = self._get_args()
@deckhand.policy.authorize(action)
def noop(*args, **kwargs):
pass
noop(*api_args)
def _get_args(self):
env = falcon_testing.create_environ(
path='/',
query_string='',
scheme='http',
host='falconframework.org',
port=None,
headers={'Content-Type': 'application/x-yaml'},
app='',
body='',
method='POST',
wsgierrors=None,
file_wrapper=None)
falcon_req = api_base.DeckhandRequest(env)
# Returns the first two arguments that would be passed to any falcon
# on_{HTTP_VERB} method: (self (which is mocked), falcon Request obj).
return (mock.Mock(), falcon_req)
class PolicyPositiveTestCase(PolicyBaseTestCase):
def test_enforce_allowed_action(self):
action = "deckhand:create_cleartext_documents"
self._enforce_policy(action)
class PolicyNegativeTestCase(PolicyBaseTestCase):
def test_enforce_disallowed_action(self):
action = "deckhand:list_cleartext_documents"
error_re = "Policy doesn't allow %s to be performed." % action
e = self.assertRaises(
falcon.HTTPForbidden, self._enforce_policy, action)
self.assertRegexpMatches(error_re, e.description)
def test_enforce_nonexistent_action(self):
action = "example:undefined"
error_re = "Policy %s has not been registered" % action
e = self.assertRaises(
falcon.HTTPForbidden, self._enforce_policy, action)
self.assertRegexpMatches(error_re, e.description)