diff --git a/solum/api/controllers/v1/extension.py b/solum/api/controllers/v1/extension.py index 6fe4f4aa2..4511ef7ff 100644 --- a/solum/api/controllers/v1/extension.py +++ b/solum/api/controllers/v1/extension.py @@ -18,6 +18,7 @@ import wsmeext.pecan as wsme_pecan from solum.api.controllers.v1.datamodel import extension from solum.api.handlers import extension_handler from solum.common import exception +from solum.common import policy from solum import objects @@ -31,6 +32,8 @@ class ExtensionController(rest.RestController): @wsme_pecan.wsexpose(extension.Extension, wtypes.text) def get(self): """Return this extension.""" + policy.check('show_extension', + pecan.request.security_context) handler = extension_handler.ExtensionHandler( pecan.request.security_context) return extension.Extension.from_db_model(handler.get(self._id), @@ -41,6 +44,8 @@ class ExtensionController(rest.RestController): body=extension.Extension) def put(self, data): """Modify this extension.""" + policy.check('update_extension', + pecan.request.security_context) handler = extension_handler.ExtensionHandler( pecan.request.security_context) obj = handler.update(self._id, @@ -51,6 +56,8 @@ class ExtensionController(rest.RestController): @wsme_pecan.wsexpose(None, wtypes.text, status_code=204) def delete(self): """Delete this extension.""" + policy.check('delete_extension', + pecan.request.security_context) handler = extension_handler.ExtensionHandler( pecan.request.security_context) handler.delete(self._id) @@ -71,6 +78,8 @@ class ExtensionsController(rest.RestController): status_code=201) def post(self, data): """Create a new extension.""" + policy.check('create_extension', + pecan.request.security_context) handler = extension_handler.ExtensionHandler( pecan.request.security_context) obj = handler.create(data.as_dict(objects.registry.Extension)) @@ -80,6 +89,8 @@ class ExtensionsController(rest.RestController): @wsme_pecan.wsexpose([extension.Extension]) def get_all(self): """Return all extensions, based on the query provided.""" + policy.check('get_extensions', + pecan.request.security_context) handler = extension_handler.ExtensionHandler( pecan.request.security_context) return [extension.Extension.from_db_model(obj, pecan.request.host_url) diff --git a/solum/common/policies/__init__.py b/solum/common/policies/__init__.py index 8c8a32b62..e524bd7ea 100644 --- a/solum/common/policies/__init__.py +++ b/solum/common/policies/__init__.py @@ -18,6 +18,7 @@ import itertools from solum.common.policies import assembly from solum.common.policies import base from solum.common.policies import component +from solum.common.policies import extension from solum.common.policies import languagepack from solum.common.policies import operation from solum.common.policies import pipeline @@ -31,6 +32,7 @@ def list_rules(): assembly.list_rules(), base.list_rules(), component.list_rules(), + extension.list_rules(), languagepack.list_rules(), operation.list_rules(), pipeline.list_rules(), diff --git a/solum/common/policies/extension.py b/solum/common/policies/extension.py new file mode 100644 index 000000000..a60c153ac --- /dev/null +++ b/solum/common/policies/extension.py @@ -0,0 +1,55 @@ +# Copyright 2018 ZTE Corporation. +# All 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. + +from oslo_policy import policy + +from solum.common.policies import base + +extension_policies = [ + policy.DocumentedRuleDefault( + name='get_extensions', + check_str=base.RULE_DEFAULT, + description='Return all extensions, based on the query provided.', + operations=[{'path': '/v1/extensions', + 'method': 'GET'}]), + policy.DocumentedRuleDefault( + name='show_extension', + check_str=base.RULE_DEFAULT, + description='Return a extension.', + operations=[{'path': '/v1/extensions/{extension_id}', + 'method': 'GET'}]), + policy.DocumentedRuleDefault( + name='update_extension', + check_str=base.RULE_DEFAULT, + description='Modify this extension.', + operations=[{'path': '/v1/extensions/{extension_id}', + 'method': 'PUT'}]), + policy.DocumentedRuleDefault( + name='create_extension', + check_str=base.RULE_DEFAULT, + description='Create a new extension.', + operations=[{'path': '/v1/extensions', + 'method': 'POST'}]), + policy.DocumentedRuleDefault( + name='delete_extension', + check_str=base.RULE_DEFAULT, + description='Delete a extension.', + operations=[{'path': '/v1/extensions/{extension_id}', + 'method': 'DELETE'}]) +] + + +def list_rules(): + return extension_policies diff --git a/solum/tests/api/controllers/v1/test_extension.py b/solum/tests/api/controllers/v1/test_extension.py index bed39b67d..a217f1a1b 100644 --- a/solum/tests/api/controllers/v1/test_extension.py +++ b/solum/tests/api/controllers/v1/test_extension.py @@ -34,6 +34,7 @@ class TestExtensionController(base.BaseTestCase): objects.load() def test_extension_get(self, handler_mock, resp_mock, request_mock): + self.policy({'show_extension': '@'}) handler_get = handler_mock.return_value.get fake_extension = fakes.FakeExtension() handler_get.return_value = fake_extension @@ -55,6 +56,7 @@ class TestExtensionController(base.BaseTestCase): def test_extension_get_not_found(self, handler_mock, resp_mock, request_mock): + self.policy({'show_extension': '@'}) handler_get = handler_mock.return_value.get handler_get.side_effect = exception.ResourceNotFound( name='extension', extension_id='test_id') @@ -64,6 +66,7 @@ class TestExtensionController(base.BaseTestCase): handler_get.assert_called_once_with('test_id') def test_extension_put(self, handler_mock, resp_mock, request_mock): + self.policy({'update_extension': '@'}) json_update = {'description': 'foo_updated', 'user_id': 'user_id_changed', 'project_id': 'project_id_changed', @@ -79,6 +82,7 @@ class TestExtensionController(base.BaseTestCase): handler_update.assert_called_once_with('test_id', json_update) def test_extension_put_none(self, handler_mock, resp_mock, request_mock): + self.policy({'update_extension': '@'}) request_mock.body = None request_mock.content_type = 'application/json' handler_put = handler_mock.return_value.put @@ -88,6 +92,7 @@ class TestExtensionController(base.BaseTestCase): def test_extension_put_not_found(self, handler_mock, resp_mock, request_mock): + self.policy({'update_extension': '@'}) json_update = {'name': 'test_not_found'} request_mock.body = json.dumps(json_update) request_mock.content_type = 'application/json' @@ -99,6 +104,7 @@ class TestExtensionController(base.BaseTestCase): self.assertEqual(404, resp_mock.status) def test_extension_delete(self, mock_handler, resp_mock, request_mock): + self.policy({'delete_extension': '@'}) handler_delete = mock_handler.return_value.delete handler_delete.return_value = None obj = controller.ExtensionController('test_id') @@ -108,6 +114,7 @@ class TestExtensionController(base.BaseTestCase): def test_extension_delete_not_found(self, mock_handler, resp_mock, request_mock): + self.policy({'delete_extension': '@'}) handler_delete = mock_handler.return_value.delete handler_delete.side_effect = exception.ResourceNotFound( name='extension', extension_id='test_id') @@ -127,6 +134,7 @@ class TestExtensionsController(base.BaseTestCase): objects.load() def test_extensions_get_all(self, handler_mock, resp_mock, request_mock): + self.policy({'get_extensions': '@'}) hand_get_all = handler_mock.return_value.get_all fake_extension = fakes.FakeExtension() hand_get_all.return_value = [fake_extension] @@ -146,6 +154,7 @@ class TestExtensionsController(base.BaseTestCase): self.assertEqual(200, resp_mock.status) def test_extensions_post(self, handler_mock, resp_mock, request_mock): + self.policy({'create_extension': '@'}) json_update = {'name': 'foo', 'description': 'foofoo', 'user_id': 'user_id_test', @@ -162,6 +171,7 @@ class TestExtensionsController(base.BaseTestCase): def test_extensions_post_nodata(self, handler_mock, resp_mock, request_mock): + self.policy({'create_extension': '@'}) request_mock.body = '' request_mock.content_type = 'application/json' handler_create = handler_mock.return_value.create