Making sure we allow all content-types for delete calls

Considering we don't care about the accept or content-type
headers for delete calls. This change allows for someone to use
whatever accept header for delete calls to orders and containers
by adding the allow_all_content_type decorator. This provides
better compatiblity across REST clients as some automatically
add the Accept application/json header to their calls. In
addition, this sets add the accept application/json header to
our functional tests. If we're testing how the app handles
headers, then those should be specific tests.

Change-Id: I7fb4ba7c30ade9a5d4392d85b1a367987c851752
This commit is contained in:
John Vrbanac
2015-03-12 15:47:57 -05:00
parent a58a372a7d
commit a9eb91823d
6 changed files with 24 additions and 18 deletions
+2 -1
View File
@@ -67,7 +67,8 @@ class ContainerController(object):
hrefs.convert_to_hrefs(dict_fields)
)
@index.when(method='DELETE', template='')
@index.when(method='DELETE')
@utils.allow_all_content_types
@controllers.handle_exceptions(u._('Container deletion'))
@controllers.enforce_rbac('container:delete')
def on_delete(self, external_project_id, **kwargs):
+1
View File
@@ -104,6 +104,7 @@ class OrderController(object):
updated_meta=body.get('meta'))
@index.when(method='DELETE')
@utils.allow_all_content_types
@controllers.handle_exceptions(u._('Order deletion'))
@controllers.enforce_rbac('order:delete')
def on_delete(self, external_project_id, **kwargs):
+4 -13
View File
@@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import mimetypes
import urllib
import pecan
@@ -31,14 +30,6 @@ from barbican.plugin import util as putil
LOG = utils.getLogger(__name__)
def allow_all_content_types(f):
cfg = pecan.util._cfg(f)
cfg.setdefault('content_types', {})
cfg['content_types'].update((value, '')
for value in mimetypes.types_map.values())
return f
def _secret_not_found():
"""Throw exception indicating secret not found."""
pecan.abort(404, u._('Not Found. Sorry but your secret is in '
@@ -74,7 +65,7 @@ class SecretController(object):
pecan.abort(405) # HTTP 405 Method Not Allowed as default
@index.when(method='GET')
@allow_all_content_types
@utils.allow_all_content_types
@controllers.handle_exceptions(u._('Secret retrieval'))
@controllers.enforce_rbac('secret:get')
def on_get(self, external_project_id, **kwargs):
@@ -135,7 +126,7 @@ class SecretController(object):
return transport_key_model.transport_key
@pecan.expose()
@allow_all_content_types
@utils.allow_all_content_types
@controllers.handle_exceptions(u._('Secret payload retrieval'))
@controllers.enforce_rbac('secret:decrypt')
def payload(self, external_project_id, **kwargs):
@@ -146,7 +137,7 @@ class SecretController(object):
**kwargs)
@index.when(method='PUT')
@allow_all_content_types
@utils.allow_all_content_types
@controllers.handle_exceptions(u._('Secret update'))
@controllers.enforce_rbac('secret:put')
@controllers.enforce_content_types(['application/octet-stream',
@@ -182,7 +173,7 @@ class SecretController(object):
transport_key_id=transport_key_id)
@index.when(method='DELETE')
@allow_all_content_types
@utils.allow_all_content_types
@controllers.handle_exceptions(u._('Secret deletion'))
@controllers.enforce_rbac('secret:delete')
def on_delete(self, external_project_id, **kwargs):
+11
View File
@@ -17,11 +17,13 @@
Common utilities for Barbican.
"""
import mimetypes
import time
import uuid
from oslo_config import cfg
from oslo_log import log
import pecan
from barbican import i18n as u
@@ -38,6 +40,15 @@ CONF.register_opts(host_opts)
API_VERSION = 'v1'
def allow_all_content_types(f):
# Pecan decorator to not limit content types for controller routes
cfg = pecan.util._cfg(f)
cfg.setdefault('content_types', {})
cfg['content_types'].update((value, '')
for value in mimetypes.types_map.values())
return f
def hostname_for_refs(resource=None):
"""Return the HATEOS-style return URI reference for this service."""
ref = ['{base}/{version}'.format(base=CONF.host_href, version=API_VERSION)]
+4 -3
View File
@@ -32,6 +32,7 @@ from barbican.api import app
from barbican.api import controllers
from barbican.common import exception as excep
from barbican.common import hrefs
from barbican.common import utils as barbican_utils
import barbican.context
from barbican.model import models
from barbican.tests import database_utils
@@ -126,7 +127,7 @@ class SecretAllowAllMimeTypesDecoratorTest(utils.BaseTestCase):
self.mimetype_values = set(mimetypes.types_map.values())
@pecan.expose(generic=True)
@controllers.secrets.allow_all_content_types
@barbican_utils.allow_all_content_types
def _empty_pecan_exposed_function(self):
pass
@@ -136,7 +137,7 @@ class SecretAllowAllMimeTypesDecoratorTest(utils.BaseTestCase):
def test_mimetypes_successfully_added_to_mocked_function(self):
empty_function = mock.MagicMock()
empty_function._pecan = {}
func = controllers.secrets.allow_all_content_types(empty_function)
func = barbican_utils.allow_all_content_types(empty_function)
cfg = func._pecan
self.assertEqual(len(self.mimetype_values), len(cfg['content_types']))
@@ -146,7 +147,7 @@ class SecretAllowAllMimeTypesDecoratorTest(utils.BaseTestCase):
def test_decorator_raises_if_function_not_pecan_exposed(self):
self.assertRaises(AttributeError,
controllers.secrets.allow_all_content_types,
barbican_utils.allow_all_content_types,
self._empty_function)
+2 -1
View File
@@ -41,7 +41,8 @@ class BarbicanClient(object):
self.timeout = 10
self.api_version = api_version
self.default_headers = {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
'Accept': 'application/json'
}
self.region = CONF.identity.region