Add a base resource for v2 API endpoints

This adds a base resource for all v2 API endpoints. For now, this
base resource returns a 403 Forbidden HTTP error in case a user
tries to execute a forbidden action, but it may be extended in the
future.

Change-Id: I7814c0432e8da591b1f971091619a257c4184191
This commit is contained in:
Luka Peschke 2019-05-07 14:43:44 +02:00
parent 8243e18d78
commit cc562d4069
6 changed files with 46 additions and 13 deletions

View File

@ -14,10 +14,10 @@
# under the License.
#
from flask import request
import flask_restful
from oslo_config import cfg
import voluptuous
from cloudkitty.api.v2 import base
from cloudkitty.api.v2 import utils as api_utils
@ -73,7 +73,7 @@ def get_api_versions():
return apis
class CloudkittyAPIRoot(flask_restful.Resource):
class CloudkittyAPIRoot(base.BaseResource):
@api_utils.add_output_schema(voluptuous.Schema({
'versions': [API_VERSION_SCHEMA],

33
cloudkitty/api/v2/base.py Normal file
View File

@ -0,0 +1,33 @@
# 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 flask_restful
from werkzeug import exceptions as http_exceptions
from cloudkitty.common import policy
class BaseResource(flask_restful.Resource):
"""Base class for all cloudkitty v2 API resources.
Returns a 403 Forbidden HTTP code in case a ``PolicyNotAuthorized``
exception is raised by the API method.
"""
def dispatch_request(self, *args, **kwargs):
try:
return super(BaseResource, self).dispatch_request(*args, **kwargs)
except policy.PolicyNotAuthorized:
raise http_exceptions.Forbidden(
"You are not authorized to perform this action")

View File

@ -13,15 +13,15 @@
# under the License.
#
import flask
import flask_restful
import voluptuous
from werkzeug import exceptions as http_exceptions
from cloudkitty.api.v2 import base
from cloudkitty.api.v2 import utils as api_utils
from cloudkitty.common import policy
class Example(flask_restful.Resource):
class Example(base.BaseResource):
@api_utils.add_output_schema({
voluptuous.Required(

View File

@ -120,7 +120,7 @@ def paginated(func):
Example usage::
class Example(flask_restful.Resource):
class Example(base.BaseResource):
@api_utils.paginated
@api_utils.add_output_schema({
@ -145,7 +145,7 @@ def add_output_schema(schema):
Example usage::
class Example(flask_restful.Resource):
class Example(base.BaseResource):
@api_utils.add_output_schema({
voluptuous.Required(

View File

@ -82,7 +82,7 @@
# Return a list of rated resources for a time period and a tenant.
# GET /v1/storage/dataframes
#"storage:list_data_frames": ""
#"storage:list_data_frames": "rule:admin_or_owner"
# Get an example message
# GET /v2/example

View File

@ -52,10 +52,10 @@ of all, we'll create a class with ``get`` and ``post`` methods in
.. code-block:: python
import flask_restful
from cloudkitty.api.v2 import base
class Example(flask_restful.Resource):
class Example(base.BaseResource):
def get(self):
pass
@ -77,13 +77,13 @@ Let's update our ``get`` method in order to use this decorator:
.. code-block:: python
import flask_restful
import voluptuous
from cloudkitty.api.v2 import base
from cloudkitty.api.v2 import utils as api_utils
class Example(flask_restful.Resource):
class Example(base.BaseResource):
@api_utils.add_output_schema({
voluptuous.Required(
@ -220,9 +220,9 @@ However, they can be overriden in ``policy.yaml``. Call them the following way:
import flask
from cloudkitty.common import policy
from cloudkitty.api.v2 import base
class Example(flask_restful.Resource):
class Example(base.BaseResource):
# [...]
def get(self):
policy.authorize(flask.request.context, 'example:get_example', {})