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:
@@ -14,10 +14,10 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
from flask import request
|
from flask import request
|
||||||
import flask_restful
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
import voluptuous
|
import voluptuous
|
||||||
|
|
||||||
|
from cloudkitty.api.v2 import base
|
||||||
from cloudkitty.api.v2 import utils as api_utils
|
from cloudkitty.api.v2 import utils as api_utils
|
||||||
|
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ def get_api_versions():
|
|||||||
return apis
|
return apis
|
||||||
|
|
||||||
|
|
||||||
class CloudkittyAPIRoot(flask_restful.Resource):
|
class CloudkittyAPIRoot(base.BaseResource):
|
||||||
|
|
||||||
@api_utils.add_output_schema(voluptuous.Schema({
|
@api_utils.add_output_schema(voluptuous.Schema({
|
||||||
'versions': [API_VERSION_SCHEMA],
|
'versions': [API_VERSION_SCHEMA],
|
||||||
|
33
cloudkitty/api/v2/base.py
Normal file
33
cloudkitty/api/v2/base.py
Normal 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")
|
@@ -13,15 +13,15 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
#
|
#
|
||||||
import flask
|
import flask
|
||||||
import flask_restful
|
|
||||||
import voluptuous
|
import voluptuous
|
||||||
from werkzeug import exceptions as http_exceptions
|
from werkzeug import exceptions as http_exceptions
|
||||||
|
|
||||||
|
from cloudkitty.api.v2 import base
|
||||||
from cloudkitty.api.v2 import utils as api_utils
|
from cloudkitty.api.v2 import utils as api_utils
|
||||||
from cloudkitty.common import policy
|
from cloudkitty.common import policy
|
||||||
|
|
||||||
|
|
||||||
class Example(flask_restful.Resource):
|
class Example(base.BaseResource):
|
||||||
|
|
||||||
@api_utils.add_output_schema({
|
@api_utils.add_output_schema({
|
||||||
voluptuous.Required(
|
voluptuous.Required(
|
||||||
|
@@ -120,7 +120,7 @@ def paginated(func):
|
|||||||
|
|
||||||
Example usage::
|
Example usage::
|
||||||
|
|
||||||
class Example(flask_restful.Resource):
|
class Example(base.BaseResource):
|
||||||
|
|
||||||
@api_utils.paginated
|
@api_utils.paginated
|
||||||
@api_utils.add_output_schema({
|
@api_utils.add_output_schema({
|
||||||
@@ -145,7 +145,7 @@ def add_output_schema(schema):
|
|||||||
|
|
||||||
Example usage::
|
Example usage::
|
||||||
|
|
||||||
class Example(flask_restful.Resource):
|
class Example(base.BaseResource):
|
||||||
|
|
||||||
@api_utils.add_output_schema({
|
@api_utils.add_output_schema({
|
||||||
voluptuous.Required(
|
voluptuous.Required(
|
||||||
|
@@ -82,7 +82,7 @@
|
|||||||
|
|
||||||
# Return a list of rated resources for a time period and a tenant.
|
# Return a list of rated resources for a time period and a tenant.
|
||||||
# GET /v1/storage/dataframes
|
# GET /v1/storage/dataframes
|
||||||
#"storage:list_data_frames": ""
|
#"storage:list_data_frames": "rule:admin_or_owner"
|
||||||
|
|
||||||
# Get an example message
|
# Get an example message
|
||||||
# GET /v2/example
|
# GET /v2/example
|
||||||
|
@@ -52,10 +52,10 @@ of all, we'll create a class with ``get`` and ``post`` methods in
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import flask_restful
|
from cloudkitty.api.v2 import base
|
||||||
|
|
||||||
|
|
||||||
class Example(flask_restful.Resource):
|
class Example(base.BaseResource):
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
pass
|
pass
|
||||||
@@ -77,13 +77,13 @@ Let's update our ``get`` method in order to use this decorator:
|
|||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
import flask_restful
|
|
||||||
import voluptuous
|
import voluptuous
|
||||||
|
|
||||||
|
from cloudkitty.api.v2 import base
|
||||||
from cloudkitty.api.v2 import utils as api_utils
|
from cloudkitty.api.v2 import utils as api_utils
|
||||||
|
|
||||||
|
|
||||||
class Example(flask_restful.Resource):
|
class Example(base.BaseResource):
|
||||||
|
|
||||||
@api_utils.add_output_schema({
|
@api_utils.add_output_schema({
|
||||||
voluptuous.Required(
|
voluptuous.Required(
|
||||||
@@ -220,9 +220,9 @@ However, they can be overriden in ``policy.yaml``. Call them the following way:
|
|||||||
import flask
|
import flask
|
||||||
|
|
||||||
from cloudkitty.common import policy
|
from cloudkitty.common import policy
|
||||||
|
from cloudkitty.api.v2 import base
|
||||||
|
|
||||||
|
class Example(base.BaseResource):
|
||||||
class Example(flask_restful.Resource):
|
|
||||||
# [...]
|
# [...]
|
||||||
def get(self):
|
def get(self):
|
||||||
policy.authorize(flask.request.context, 'example:get_example', {})
|
policy.authorize(flask.request.context, 'example:get_example', {})
|
||||||
|
Reference in New Issue
Block a user