panko/ceilometer/api/controllers/v2/utils.py

91 lines
3.1 KiB
Python

#
# Copyright 2012 New Dream Network, LLC (DreamHost)
# Copyright 2013 IBM Corp.
# Copyright 2013 eNovance <licensing@enovance.com>
# Copyright Ericsson AB 2013. All rights reserved
# Copyright 2014 Hewlett-Packard Company
# Copyright 2015 Huawei Technologies Co., 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.
import functools
from oslo_config import cfg
from oslo_log import log
import pecan
from ceilometer.api.controllers.v2 import base
from ceilometer.api import rbac
from ceilometer.i18n import _, _LI
LOG = log.getLogger(__name__)
cfg.CONF.import_opt('default_api_return_limit', 'ceilometer.api.app',
group='api')
def enforce_limit(limit):
"""Ensure limit is defined and is valid. if not, set a default."""
if limit is None:
limit = cfg.CONF.api.default_api_return_limit
LOG.info(_LI('No limit value provided, result set will be'
' limited to %(limit)d.'), {'limit': limit})
if not limit or limit <= 0:
raise base.ClientSideError(_("Limit must be positive"))
return limit
def get_auth_project(on_behalf_of=None):
auth_project = rbac.get_limited_to_project(pecan.request.headers)
created_by = pecan.request.headers.get('X-Project-Id')
is_admin = auth_project is None
if is_admin and on_behalf_of != created_by:
auth_project = on_behalf_of
return auth_project
# TODO(fabiog): this decorator should disappear and have a more unified
# way of controlling access and scope. Before messing with this, though
# I feel this file should be re-factored in smaller chunks one for each
# controller (e.g. meters and so on ...). Right now its size is
# overwhelming.
def requires_admin(func):
@functools.wraps(func)
def wrapped(*args, **kwargs):
usr_limit, proj_limit = rbac.get_limited_to(pecan.request.headers)
# If User and Project are None, you have full access.
if usr_limit and proj_limit:
# since this decorator get's called out of wsme context
# raising exception results internal error so call abort
# for handling the error
ex = base.ProjectNotAuthorized(proj_limit)
pecan.core.abort(status_code=ex.code, detail=ex.msg)
return func(*args, **kwargs)
return wrapped
def requires_context(func):
@functools.wraps(func)
def wrapped(*args, **kwargs):
req_usr = pecan.request.headers.get('X-User-Id')
proj_usr = pecan.request.headers.get('X-Project-Id')
if ((not req_usr) or (not proj_usr)):
pecan.core.abort(status_code=403,
detail='RBAC Authorization Failed')
return func(*args, **kwargs)
return wrapped