RBAC support based on oslo.policy
This commit adds support for RBAC using oslo.policy. This allows Zaqar for having a fine-grained access control to the resources it exposes. As of this patch, the implementation allows to have access control in a per-operation basis rather than specific resources. Co-Authored-by: Thomas Herve <therve@redhat.com> Co-Authored-by: Flavio Percoco <flaper87@gmail.com> blueprint: fine-grained-permissions Change-Id: I90374a11815ac2bd9d31768588719d2d4c4e7f5d
This commit is contained in:
parent
e061305356
commit
d08f4913ca
@ -37,6 +37,7 @@ ZAQAR_DIR=$DEST/zaqar
|
||||
ZAQARCLIENT_DIR=$DEST/python-zaqarclient
|
||||
ZAQAR_CONF_DIR=/etc/zaqar
|
||||
ZAQAR_CONF=$ZAQAR_CONF_DIR/zaqar.conf
|
||||
ZAQAR_POLICY_CONF=$ZAQAR_CONF_DIR/policy.json
|
||||
ZAQAR_UWSGI_CONF=$ZAQAR_CONF_DIR/uwsgi.conf
|
||||
ZAQAR_API_LOG_DIR=/var/log/zaqar
|
||||
ZAQAR_API_LOG_FILE=$ZAQAR_API_LOG_DIR/queues.log
|
||||
@ -112,6 +113,10 @@ function configure_zaqar {
|
||||
[ ! -d $ZAQAR_CONF_DIR ] && sudo mkdir -m 755 -p $ZAQAR_CONF_DIR
|
||||
sudo chown $USER $ZAQAR_CONF_DIR
|
||||
|
||||
if [[ -f $ZAQAR_DIR/etc/policy.json.sample ]]; then
|
||||
cp -p $ZAQAR_DIR/etc/policy.json.sample $ZAQAR_POLICY_CONF
|
||||
fi
|
||||
|
||||
[ ! -d $ZAQAR_API_LOG_DIR ] && sudo mkdir -m 755 -p $ZAQAR_API_LOG_DIR
|
||||
sudo chown $USER $ZAQAR_API_LOG_DIR
|
||||
|
||||
|
45
etc/policy.json.sample
Normal file
45
etc/policy.json.sample
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"context_is_admin": "role:admin",
|
||||
"admin_or_owner": "is_admin:True or project_id:%(project_id)s",
|
||||
"default": "rule:admin_or_owner",
|
||||
|
||||
"queues:get_all": "",
|
||||
"queues:create": "",
|
||||
"queues:get": "",
|
||||
"queues:delete": "",
|
||||
"queues:update": "",
|
||||
"queues:stats": "",
|
||||
|
||||
"messages:get_all": "",
|
||||
"messages:create": "",
|
||||
"messages:get": "",
|
||||
"messages:delete": "",
|
||||
"messages:delete_all": "",
|
||||
|
||||
"claims:get_all": "",
|
||||
"claims:create": "",
|
||||
"claims:get": "",
|
||||
"claims:delete": "",
|
||||
"claims:update": "",
|
||||
|
||||
"subscription:get_all": "",
|
||||
"subscription:create": "",
|
||||
"subscription:get": "",
|
||||
"subscription:delete": "",
|
||||
"subscription:update": "",
|
||||
|
||||
"pools:get_all": "rule:context_is_admin",
|
||||
"pools:create": "rule:context_is_admin",
|
||||
"pools:get": "rule:context_is_admin",
|
||||
"pools:delete": "rule:context_is_admin",
|
||||
"pools:update": "rule:context_is_admin",
|
||||
|
||||
"flavors:get_all": "",
|
||||
"flavors:create": "rule:context_is_admin",
|
||||
"flavors:get": "",
|
||||
"flavors:delete": "rule:context_is_admin",
|
||||
"flavors:update": "rule:context_is_admin",
|
||||
|
||||
"ping:get": "",
|
||||
"health:get": "rule:context_is_admin"
|
||||
}
|
@ -21,6 +21,7 @@ oslo.i18n>=1.5.0 # Apache-2.0
|
||||
oslo.log>=1.8.0 # Apache-2.0
|
||||
oslo.serialization>=1.4.0 # Apache-2.0
|
||||
oslo.utils>=2.0.0 # Apache-2.0
|
||||
oslo.policy>=0.5.0 # Apache-2.0
|
||||
SQLAlchemy<1.1.0,>=0.9.9
|
||||
enum34;python_version=='2.7' or python_version=='2.6'
|
||||
trollius>=1.0
|
||||
|
@ -200,7 +200,19 @@ def inject_context(req, resp, params):
|
||||
"""
|
||||
client_id = req.get_header('Client-ID')
|
||||
project_id = params.get('project_id', None)
|
||||
request_id = req.headers.get('X-Openstack-Request-ID'),
|
||||
auth_token = req.headers.get('X-AUTH-TOKEN')
|
||||
user = req.headers.get('X-USER-ID')
|
||||
tenant = req.headers.get('X-TENANT-ID')
|
||||
|
||||
roles = req.headers.get('X-ROLES')
|
||||
roles = roles and roles.split(',') or []
|
||||
|
||||
ctxt = context.RequestContext(project_id=project_id,
|
||||
client_id=client_id)
|
||||
client_id=client_id,
|
||||
request_id=request_id,
|
||||
auth_token=auth_token,
|
||||
user=user,
|
||||
tenant=tenant,
|
||||
roles=roles)
|
||||
req.env['zaqar.context'] = ctxt
|
||||
|
@ -26,7 +26,7 @@ class RequestContext(context.RequestContext):
|
||||
auth_token=None, user=None, tenant=None, domain=None,
|
||||
user_domain=None, project_domain=None, is_admin=False,
|
||||
read_only=False, show_deleted=False, request_id=None,
|
||||
instance_uuid=None, **kwargs):
|
||||
instance_uuid=None, roles=None, **kwargs):
|
||||
super(RequestContext, self).__init__(auth_token=auth_token,
|
||||
user=user,
|
||||
tenant=tenant,
|
||||
@ -39,6 +39,7 @@ class RequestContext(context.RequestContext):
|
||||
request_id=request_id)
|
||||
self.project_id = project_id
|
||||
self.client_id = client_id
|
||||
self.roles = roles
|
||||
if overwrite or not hasattr(context._request_store, 'context'):
|
||||
self.update_store()
|
||||
|
||||
@ -49,6 +50,8 @@ class RequestContext(context.RequestContext):
|
||||
ctx = super(RequestContext, self).to_dict()
|
||||
ctx.update({
|
||||
'project_id': self.project_id,
|
||||
'client_id': self.client_id
|
||||
'client_id': self.client_id,
|
||||
'tenant': self.tenant,
|
||||
'roles': self.roles
|
||||
})
|
||||
return ctx
|
||||
|
45
zaqar/tests/etc/policy.json
Normal file
45
zaqar/tests/etc/policy.json
Normal file
@ -0,0 +1,45 @@
|
||||
{
|
||||
"context_is_admin": "role:admin",
|
||||
"admin_or_owner": "is_admin:True or project_id:%(project_id)s",
|
||||
"default": "rule:admin_or_owner",
|
||||
|
||||
"queues:get_all": "",
|
||||
"queues:create": "",
|
||||
"queues:get": "",
|
||||
"queues:delete": "",
|
||||
"queues:update": "",
|
||||
"queues:stats": "",
|
||||
|
||||
"messages:get_all": "",
|
||||
"messages:create": "",
|
||||
"messages:get": "",
|
||||
"messages:delete": "",
|
||||
"messages:delete_all": "",
|
||||
|
||||
"claims:get_all": "",
|
||||
"claims:create": "",
|
||||
"claims:get": "",
|
||||
"claims:delete": "",
|
||||
"claims:update": "",
|
||||
|
||||
"subscription:get_all": "",
|
||||
"subscription:create": "",
|
||||
"subscription:get": "",
|
||||
"subscription:delete": "",
|
||||
"subscription:update": "",
|
||||
|
||||
"pools:get_all": "rule:context_is_admin",
|
||||
"pools:create": "rule:context_is_admin",
|
||||
"pools:get": "rule:context_is_admin",
|
||||
"pools:delete": "rule:context_is_admin",
|
||||
"pools:update": "rule:context_is_admin",
|
||||
|
||||
"flavors:get_all": "",
|
||||
"flavors:create": "rule:context_is_admin",
|
||||
"flavors:get": "",
|
||||
"flavors:delete": "rule:context_is_admin",
|
||||
"flavors:update": "rule:context_is_admin",
|
||||
|
||||
"ping:get": "",
|
||||
"health:get": "rule:context_is_admin"
|
||||
}
|
57
zaqar/tests/unit/transport/test_acl.py
Normal file
57
zaqar/tests/unit/transport/test_acl.py
Normal file
@ -0,0 +1,57 @@
|
||||
# Copyright (c) 2015 Catalyst IT Ltd.
|
||||
#
|
||||
# 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 collections import namedtuple
|
||||
|
||||
from oslo_policy import policy
|
||||
|
||||
from zaqar import context
|
||||
from zaqar.tests import base
|
||||
from zaqar.transport import acl
|
||||
from zaqar.transport.wsgi import errors
|
||||
|
||||
|
||||
class TestAcl(base.TestBase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestAcl, self).setUp()
|
||||
ctx = context.RequestContext()
|
||||
request_class = namedtuple("Request", ("env",))
|
||||
self.request = request_class({"zaqar.context": ctx})
|
||||
|
||||
def _set_policy(self, json):
|
||||
acl.setup_policy(self.conf)
|
||||
rules = policy.Rules.load_json(json)
|
||||
acl.ENFORCER.set_rules(rules, use_conf=False)
|
||||
|
||||
def test_policy_allow(self):
|
||||
@acl.enforce("queues:get_all")
|
||||
def test(ign, request):
|
||||
pass
|
||||
|
||||
json = '{"queues:get_all": ""}'
|
||||
self._set_policy(json)
|
||||
|
||||
test(None, self.request)
|
||||
|
||||
def test_policy_deny(self):
|
||||
@acl.enforce("queues:get_all")
|
||||
def test(ign, request):
|
||||
pass
|
||||
|
||||
json = '{"queues:get_all": "!"}'
|
||||
self._set_policy(json)
|
||||
|
||||
self.assertRaises(errors.HTTPForbidden, test, None, self.request)
|
@ -53,6 +53,9 @@ class TestBase(testing.TestBase):
|
||||
|
||||
self.headers = {
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-ROLES': 'admin',
|
||||
'X-USER-ID': 'a12d157c7d0d41999096639078fd11fc',
|
||||
'X-TENANT-ID': 'abb69142168841fcaa2785791b92467f',
|
||||
}
|
||||
|
||||
def tearDown(self):
|
||||
|
@ -52,10 +52,10 @@ class TestMessagesMongoDB(base.V2Base):
|
||||
self.assertEqual(self.srmock.status, falcon.HTTP_201)
|
||||
|
||||
self.project_id = '7e55e1a7e'
|
||||
self.headers = {
|
||||
self.headers.update({
|
||||
'Client-ID': str(uuid.uuid4()),
|
||||
'X-Project-ID': self.project_id
|
||||
}
|
||||
})
|
||||
|
||||
# TODO(kgriffs): Add support in self.simulate_* for a "base path"
|
||||
# so that we don't have to concatenate against self.url_prefix
|
||||
|
44
zaqar/transport/acl.py
Normal file
44
zaqar/transport/acl.py
Normal file
@ -0,0 +1,44 @@
|
||||
# Copyright (c) 2015 Catalyst IT Ltd.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Policy enforcer of Zaqar"""
|
||||
|
||||
import functools
|
||||
|
||||
from oslo_policy import policy
|
||||
|
||||
ENFORCER = None
|
||||
|
||||
|
||||
def setup_policy(conf):
|
||||
global ENFORCER
|
||||
|
||||
ENFORCER = policy.Enforcer(conf)
|
||||
|
||||
|
||||
def enforce(rule):
|
||||
# Late import to prevent cycles
|
||||
from zaqar.transport.wsgi import errors
|
||||
|
||||
def decorator(func):
|
||||
@functools.wraps(func)
|
||||
def handler(*args, **kwargs):
|
||||
ctx = args[1].env['zaqar.context']
|
||||
ENFORCER.enforce(rule, {}, ctx.to_dict(), do_raise=True,
|
||||
exc=errors.HTTPForbidden)
|
||||
|
||||
return func(*args, **kwargs)
|
||||
return handler
|
||||
|
||||
return decorator
|
@ -25,6 +25,7 @@ from zaqar.common import decorators
|
||||
from zaqar.common.transport.wsgi import helpers
|
||||
from zaqar.i18n import _
|
||||
from zaqar import transport
|
||||
from zaqar.transport import acl
|
||||
from zaqar.transport import auth
|
||||
from zaqar.transport import validation
|
||||
from zaqar.transport.wsgi import v1_0
|
||||
@ -117,6 +118,8 @@ class Driver(transport.DriverBase):
|
||||
|
||||
self.app = auth.SignedHeadersAuth(self.app, auth_app)
|
||||
|
||||
acl.setup_policy(self._conf)
|
||||
|
||||
def _error_handler(self, exc, request, response, params):
|
||||
if isinstance(exc, falcon.HTTPError):
|
||||
raise exc
|
||||
|
@ -55,3 +55,13 @@ class HTTPDocumentTypeNotSupported(HTTPBadRequestBody):
|
||||
|
||||
def __init__(self):
|
||||
super(HTTPDocumentTypeNotSupported, self).__init__(self.DESCRIPTION)
|
||||
|
||||
|
||||
class HTTPForbidden(falcon.HTTPForbidden):
|
||||
"""Wraps falcon.HTTPForbidden with a contextual title."""
|
||||
|
||||
TITLE = _(u'Not authorized')
|
||||
DESCRIPTION = _(u'You are not authorized to complete this action.')
|
||||
|
||||
def __init__(self):
|
||||
super(HTTPForbidden, self).__init__(self.TITLE, self.DESCRIPTION)
|
||||
|
@ -19,6 +19,7 @@ import six
|
||||
|
||||
from zaqar.i18n import _
|
||||
from zaqar.storage import errors as storage_errors
|
||||
from zaqar.transport import acl
|
||||
from zaqar.transport import utils
|
||||
from zaqar.transport import validation
|
||||
from zaqar.transport.wsgi import errors as wsgi_errors
|
||||
@ -53,6 +54,7 @@ class CollectionResource(object):
|
||||
'grace': default_grace_ttl,
|
||||
}
|
||||
|
||||
@acl.enforce("claims:create")
|
||||
def on_post(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Claims collection POST - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
@ -125,6 +127,7 @@ class ItemResource(object):
|
||||
('grace', int, default_grace_ttl),
|
||||
)
|
||||
|
||||
@acl.enforce("claims:get")
|
||||
def on_get(self, req, resp, project_id, queue_name, claim_id):
|
||||
LOG.debug(u'Claim item GET - claim: %(claim_id)s, '
|
||||
u'queue: %(queue_name)s, project: %(project_id)s',
|
||||
@ -162,6 +165,7 @@ class ItemResource(object):
|
||||
resp.body = utils.to_json(meta)
|
||||
# status defaults to 200
|
||||
|
||||
@acl.enforce("claims:update")
|
||||
def on_patch(self, req, resp, project_id, queue_name, claim_id):
|
||||
LOG.debug(u'Claim Item PATCH - claim: %(claim_id)s, '
|
||||
u'queue: %(queue_name)s, project:%(project_id)s' %
|
||||
@ -196,6 +200,7 @@ class ItemResource(object):
|
||||
description = _(u'Claim could not be updated.')
|
||||
raise wsgi_errors.HTTPServiceUnavailable(description)
|
||||
|
||||
@acl.enforce("claims:delete")
|
||||
def on_delete(self, req, resp, project_id, queue_name, claim_id):
|
||||
LOG.debug(u'Claim item DELETE - claim: %(claim_id)s, '
|
||||
u'queue: %(queue_name)s, project: %(project_id)s' %
|
||||
|
@ -21,6 +21,7 @@ from zaqar.common.api.schemas import flavors as schema
|
||||
from zaqar.common import utils as common_utils
|
||||
from zaqar.i18n import _
|
||||
from zaqar.storage import errors
|
||||
from zaqar.transport import acl
|
||||
from zaqar.transport import utils as transport_utils
|
||||
from zaqar.transport.wsgi import errors as wsgi_errors
|
||||
from zaqar.transport.wsgi import utils as wsgi_utils
|
||||
@ -38,6 +39,7 @@ class Listing(object):
|
||||
self._ctrl = flavors_controller
|
||||
self._pools_ctrl = pools_controller
|
||||
|
||||
@acl.enforce("flavors:get_all")
|
||||
def on_get(self, request, response, project_id):
|
||||
"""Returns a flavor listing as objects embedded in an object:
|
||||
|
||||
@ -113,6 +115,7 @@ class Resource(object):
|
||||
'capabilities': validator_type(schema.patch_capabilities),
|
||||
}
|
||||
|
||||
@acl.enforce("flavors:get")
|
||||
def on_get(self, request, response, project_id, flavor):
|
||||
"""Returns a JSON object for a single flavor entry:
|
||||
|
||||
@ -140,6 +143,7 @@ class Resource(object):
|
||||
|
||||
response.body = transport_utils.to_json(data)
|
||||
|
||||
@acl.enforce("flavors:create")
|
||||
def on_put(self, request, response, project_id, flavor):
|
||||
"""Registers a new flavor. Expects the following input:
|
||||
|
||||
@ -170,6 +174,7 @@ class Resource(object):
|
||||
dict(flavor=flavor, pool=data['pool']))
|
||||
raise falcon.HTTPBadRequest(_('Unable to create'), description)
|
||||
|
||||
@acl.enforce("flavors:delete")
|
||||
def on_delete(self, request, response, project_id, flavor):
|
||||
"""Deregisters a flavor.
|
||||
|
||||
@ -180,6 +185,7 @@ class Resource(object):
|
||||
self._ctrl.delete(flavor, project=project_id)
|
||||
response.status = falcon.HTTP_204
|
||||
|
||||
@acl.enforce("flavors:update")
|
||||
def on_patch(self, request, response, project_id, flavor):
|
||||
"""Allows one to update a flavors's pool and/or capabilities.
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
from oslo_log import log as logging
|
||||
|
||||
from zaqar.i18n import _
|
||||
from zaqar.transport import acl
|
||||
from zaqar.transport import utils
|
||||
from zaqar.transport.wsgi import errors as wsgi_errors
|
||||
|
||||
@ -29,6 +30,7 @@ class Resource(object):
|
||||
def __init__(self, driver):
|
||||
self._driver = driver
|
||||
|
||||
@acl.enforce("health:get")
|
||||
def on_get(self, req, resp, **kwargs):
|
||||
try:
|
||||
resp_dict = self._driver.health()
|
||||
|
@ -20,6 +20,7 @@ import six
|
||||
from zaqar.common.transport.wsgi import helpers as wsgi_helpers
|
||||
from zaqar.i18n import _
|
||||
from zaqar.storage import errors as storage_errors
|
||||
from zaqar.transport import acl
|
||||
from zaqar.transport import utils
|
||||
from zaqar.transport import validation
|
||||
from zaqar.transport.wsgi import errors as wsgi_errors
|
||||
@ -149,6 +150,7 @@ class CollectionResource(object):
|
||||
# Interface
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
@acl.enforce("messages:create")
|
||||
def on_post(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Messages collection POST - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
@ -213,6 +215,7 @@ class CollectionResource(object):
|
||||
resp.body = utils.to_json(body)
|
||||
resp.status = falcon.HTTP_201
|
||||
|
||||
@acl.enforce("messages:get_all")
|
||||
def on_get(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Messages collection GET - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
@ -237,6 +240,7 @@ class CollectionResource(object):
|
||||
resp.body = utils.to_json(response)
|
||||
# status defaults to 200
|
||||
|
||||
@acl.enforce("messages:delete_all")
|
||||
def on_delete(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Messages collection DELETE - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
@ -306,6 +310,7 @@ class ItemResource(object):
|
||||
def __init__(self, message_controller):
|
||||
self._message_controller = message_controller
|
||||
|
||||
@acl.enforce("messages:get")
|
||||
def on_get(self, req, resp, project_id, queue_name, message_id):
|
||||
LOG.debug(u'Messages item GET - message: %(message)s, '
|
||||
u'queue: %(queue)s, project: %(project)s',
|
||||
@ -336,6 +341,7 @@ class ItemResource(object):
|
||||
resp.body = utils.to_json(message)
|
||||
# status defaults to 200
|
||||
|
||||
@acl.enforce("messages:delete")
|
||||
def on_delete(self, req, resp, project_id, queue_name, message_id):
|
||||
|
||||
LOG.debug(u'Messages item DELETE - message: %(message)s, '
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
import falcon
|
||||
|
||||
from zaqar.transport import acl
|
||||
|
||||
|
||||
class Resource(object):
|
||||
|
||||
@ -22,9 +24,11 @@ class Resource(object):
|
||||
def __init__(self, driver):
|
||||
self._driver = driver
|
||||
|
||||
@acl.enforce("ping:get")
|
||||
def on_get(self, req, resp, **kwargs):
|
||||
resp.status = (falcon.HTTP_204 if self._driver.is_alive()
|
||||
else falcon.HTTP_503)
|
||||
|
||||
@acl.enforce("ping:get")
|
||||
def on_head(self, req, resp, **kwargs):
|
||||
resp.status = falcon.HTTP_204
|
||||
|
@ -45,6 +45,7 @@ from zaqar.common import utils as common_utils
|
||||
from zaqar.i18n import _
|
||||
from zaqar.storage import errors
|
||||
from zaqar.storage import utils as storage_utils
|
||||
from zaqar.transport import acl
|
||||
from zaqar.transport import utils as transport_utils
|
||||
from zaqar.transport.wsgi import errors as wsgi_errors
|
||||
from zaqar.transport.wsgi import utils as wsgi_utils
|
||||
@ -61,6 +62,7 @@ class Listing(object):
|
||||
def __init__(self, pools_controller):
|
||||
self._ctrl = pools_controller
|
||||
|
||||
@acl.enforce("pools:get_all")
|
||||
def on_get(self, request, response, project_id):
|
||||
"""Returns a pool listing as objects embedded in an object:
|
||||
|
||||
@ -128,6 +130,7 @@ class Resource(object):
|
||||
'create': validator_type(schema.create)
|
||||
}
|
||||
|
||||
@acl.enforce("pools:get")
|
||||
def on_get(self, request, response, project_id, pool):
|
||||
"""Returns a JSON object for a single pool entry:
|
||||
|
||||
@ -153,6 +156,7 @@ class Resource(object):
|
||||
|
||||
response.body = transport_utils.to_json(data)
|
||||
|
||||
@acl.enforce("pools:create")
|
||||
def on_put(self, request, response, project_id, pool):
|
||||
"""Registers a new pool. Expects the following input:
|
||||
|
||||
@ -181,6 +185,7 @@ class Resource(object):
|
||||
response.status = falcon.HTTP_201
|
||||
response.location = request.path
|
||||
|
||||
@acl.enforce("pools:delete")
|
||||
def on_delete(self, request, response, project_id, pool):
|
||||
"""Deregisters a pool.
|
||||
|
||||
@ -201,6 +206,7 @@ class Resource(object):
|
||||
|
||||
response.status = falcon.HTTP_204
|
||||
|
||||
@acl.enforce("pools:update")
|
||||
def on_patch(self, request, response, project_id, pool):
|
||||
"""Allows one to update a pool's weight, uri, and/or options.
|
||||
|
||||
|
@ -19,12 +19,12 @@ import six
|
||||
|
||||
from zaqar.i18n import _
|
||||
from zaqar.storage import errors as storage_errors
|
||||
from zaqar.transport import acl
|
||||
from zaqar.transport import utils
|
||||
from zaqar.transport import validation
|
||||
from zaqar.transport.wsgi import errors as wsgi_errors
|
||||
from zaqar.transport.wsgi import utils as wsgi_utils
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -37,6 +37,7 @@ class ItemResource(object):
|
||||
self._queue_controller = queue_controller
|
||||
self._message_controller = message_controller
|
||||
|
||||
@acl.enforce("queues:get")
|
||||
def on_get(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Queue metadata GET - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
@ -58,6 +59,7 @@ class ItemResource(object):
|
||||
resp.body = utils.to_json(resp_dict)
|
||||
# status defaults to 200
|
||||
|
||||
@acl.enforce("queues:create")
|
||||
def on_put(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Queue item PUT - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
@ -93,6 +95,7 @@ class ItemResource(object):
|
||||
resp.status = falcon.HTTP_201 if created else falcon.HTTP_204
|
||||
resp.location = req.path
|
||||
|
||||
@acl.enforce("queues:delete")
|
||||
def on_delete(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Queue item DELETE - queue: %(queue)s, '
|
||||
u'project: %(project)s',
|
||||
@ -116,6 +119,7 @@ class CollectionResource(object):
|
||||
self._queue_controller = queue_controller
|
||||
self._validate = validate
|
||||
|
||||
@acl.enforce("queues:get_all")
|
||||
def on_get(self, req, resp, project_id):
|
||||
LOG.debug(u'Queue collection GET - project: %(project)s',
|
||||
{'project': project_id})
|
||||
|
@ -19,6 +19,7 @@ import six
|
||||
|
||||
from zaqar.i18n import _
|
||||
from zaqar.storage import errors as storage_errors
|
||||
from zaqar.transport import acl
|
||||
from zaqar.transport import utils
|
||||
from zaqar.transport import validation
|
||||
from zaqar.transport.wsgi import errors as wsgi_errors
|
||||
@ -36,6 +37,7 @@ class ItemResource(object):
|
||||
self._validate = validate
|
||||
self._subscription_controller = subscription_controller
|
||||
|
||||
@acl.enforce("subscription:get")
|
||||
def on_get(self, req, resp, project_id, queue_name, subscription_id):
|
||||
LOG.debug(u'Subscription GET - subscription id: %(subscription_id)s,'
|
||||
u' project: %(project)s, queue: %(queue)s',
|
||||
@ -58,6 +60,7 @@ class ItemResource(object):
|
||||
resp.body = utils.to_json(resp_dict)
|
||||
# status defaults to 200
|
||||
|
||||
@acl.enforce("subscription:delete")
|
||||
def on_delete(self, req, resp, project_id, queue_name, subscription_id):
|
||||
LOG.debug(u'Subscription DELETE - '
|
||||
u'subscription id: %(subscription_id)s,'
|
||||
@ -76,6 +79,7 @@ class ItemResource(object):
|
||||
|
||||
resp.status = falcon.HTTP_204
|
||||
|
||||
@acl.enforce("subscription:update")
|
||||
def on_patch(self, req, resp, project_id, queue_name, subscription_id):
|
||||
LOG.debug(u'Subscription PATCH - subscription id: %(subscription_id)s,'
|
||||
u' project: %(project)s, queue: %(queue)s',
|
||||
@ -117,6 +121,7 @@ class CollectionResource(object):
|
||||
self._subscription_controller = subscription_controller
|
||||
self._validate = validate
|
||||
|
||||
@acl.enforce("subscription:get_all")
|
||||
def on_get(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Subscription collection GET - project: %(project)s, '
|
||||
u'queue: %(queue)s',
|
||||
@ -162,6 +167,7 @@ class CollectionResource(object):
|
||||
resp.body = utils.to_json(response_body)
|
||||
# status defaults to 200
|
||||
|
||||
@acl.enforce("subscription:create")
|
||||
def on_post(self, req, resp, project_id, queue_name):
|
||||
LOG.debug(u'Subscription item POST - project: %(project)s, '
|
||||
u'queue: %(queue)s',
|
||||
|
Loading…
Reference in New Issue
Block a user