Fix filtering on dataframe endpoints
This fixes filtering on "GET /v1/dataframes" and "GET /v2/dataframes" by ensuring that non-admin users will only have access to their data. Change-Id: Id3da0cc4dae50edb77ec1ef3b446616617d2a49e Story: 2006749 Task: 37232
This commit is contained in:
parent
bc9962c948
commit
b4408cf085
|
@ -59,8 +59,10 @@ class DataFramesController(rest.RestController):
|
|||
scope_key = CONF.collect.scope_key
|
||||
backend = pecan.request.storage_backend
|
||||
dataframes = []
|
||||
filters = {scope_key: tenant_id} if tenant_id else None
|
||||
|
||||
if pecan.request.context.is_admin:
|
||||
filters = {scope_key: tenant_id} if tenant_id else None
|
||||
else:
|
||||
filters = {scope_key: project_id}
|
||||
try:
|
||||
resp = backend.retrieve(
|
||||
begin, end,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# under the License.
|
||||
#
|
||||
import flask
|
||||
from oslo_config import cfg
|
||||
import voluptuous
|
||||
from werkzeug import exceptions as http_exceptions
|
||||
|
||||
|
@ -23,6 +24,11 @@ from cloudkitty import dataframe
|
|||
from cloudkitty import tzutils
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
CONF.import_opt('scope_key', 'cloudkitty.collector', 'collect')
|
||||
|
||||
|
||||
class DataFrameList(base.BaseResource):
|
||||
@api_utils.add_input_schema('body', {
|
||||
voluptuous.Required('dataframes'): [dataframe.DataFrame.from_dict],
|
||||
|
@ -61,7 +67,7 @@ class DataFrameList(base.BaseResource):
|
|||
limit=100,
|
||||
begin=None,
|
||||
end=None,
|
||||
filters={}):
|
||||
filters=None):
|
||||
|
||||
policy.authorize(
|
||||
flask.request.context,
|
||||
|
@ -72,7 +78,18 @@ class DataFrameList(base.BaseResource):
|
|||
begin = begin or tzutils.get_month_start()
|
||||
end = end or tzutils.get_next_month()
|
||||
|
||||
metric_types = [filters.pop('type')] if 'type' in filters else None
|
||||
if filters and 'type' in filters:
|
||||
metric_types = [filters.pop('type')]
|
||||
else:
|
||||
metric_types = None
|
||||
|
||||
if not flask.request.context.is_admin:
|
||||
scope_key = CONF.collect.scope_key
|
||||
if filters:
|
||||
filters[scope_key] = flask.request.context.project_id
|
||||
else:
|
||||
filters = {scope_key: flask.request.context.project_id}
|
||||
|
||||
results = self._storage.retrieve(
|
||||
begin=begin, end=end,
|
||||
filters=filters,
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
# Copyright 2019 Objectif Libre
|
||||
#
|
||||
# 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 unittest
|
||||
|
||||
import mock
|
||||
|
||||
from cloudkitty.api.v2.dataframes import dataframes
|
||||
from cloudkitty import tzutils
|
||||
|
||||
|
||||
class TestDataframeListEndpoint(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestDataframeListEndpoint, self).setUp()
|
||||
self.endpoint = dataframes.DataFrameList()
|
||||
|
||||
def test_non_admin_request_is_filtered_on_project_id(self):
|
||||
policy_mock = mock.patch('cloudkitty.common.policy.authorize')
|
||||
with mock.patch.object(self.endpoint._storage, 'retrieve') as ret_mock:
|
||||
with policy_mock, mock.patch('flask.request') as fmock:
|
||||
ret_mock.return_value = {'total': 42, 'dataframes': []}
|
||||
fmock.args.lists.return_value = []
|
||||
fmock.context.is_admin = False
|
||||
fmock.context.project_id = 'test-project'
|
||||
self.endpoint.get()
|
||||
ret_mock.assert_called_once_with(
|
||||
begin=tzutils.get_month_start(),
|
||||
end=tzutils.get_next_month(),
|
||||
metric_types=None,
|
||||
filters={'project_id': 'test-project'},
|
||||
offset=0,
|
||||
limit=100,
|
||||
)
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
security:
|
||||
- |
|
||||
Data filtering on the ``GET /v1/dataframes`` and `` GET /v2/dataframes``
|
||||
has been fixed. It was previously possible for users to retrieve data
|
||||
from other scopes through these endpoints.
|
Loading…
Reference in New Issue