mirror of
https://github.com/spiral-project/ihatemoney.git
synced 2025-04-29 09:52:36 +02:00
Add Handlers for members and bills.
This commit is contained in:
parent
4bb96b28de
commit
ef3d761fc7
3 changed files with 82 additions and 27 deletions
|
@ -5,7 +5,7 @@ import werkzeug
|
||||||
from models import db, Project, Person, Bill
|
from models import db, Project, Person, Bill
|
||||||
from utils import for_all_methods
|
from utils import for_all_methods
|
||||||
|
|
||||||
from rest import RESTResource, DefaultHandler, need_auth # FIXME make it an ext
|
from rest import RESTResource, need_auth # FIXME make it an ext
|
||||||
|
|
||||||
|
|
||||||
api = Blueprint("api", __name__, url_prefix="/api")
|
api = Blueprint("api", __name__, url_prefix="/api")
|
||||||
|
@ -26,22 +26,83 @@ def check_project(*args, **kwargs):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class ProjectHandler(DefaultHandler):
|
class ProjectHandler(object):
|
||||||
|
|
||||||
def get(self, *args, **kwargs):
|
def add(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@need_auth(check_project, "project")
|
||||||
|
def get(self, project):
|
||||||
return "get"
|
return "get"
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
@need_auth(check_project, "project")
|
||||||
|
def delete(self, project):
|
||||||
return "delete"
|
return "delete"
|
||||||
|
|
||||||
|
@need_auth(check_project, "project")
|
||||||
|
def update(self, project):
|
||||||
|
return "update"
|
||||||
|
|
||||||
|
|
||||||
|
class MemberHandler(object):
|
||||||
|
|
||||||
|
def get(self, project, member_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def list(self, project):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def add(self, project):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update(self, project, member_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def delete(self, project, member_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class BillHandler(object):
|
||||||
|
|
||||||
|
def get(self, project, member_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def list(self, project):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def add(self, project):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def update(self, project, member_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def delete(self, project, member_id):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
project_resource = RESTResource(
|
project_resource = RESTResource(
|
||||||
name="project",
|
name="project",
|
||||||
route="/project",
|
route="/project",
|
||||||
app=api,
|
app=api,
|
||||||
actions=["add", "update", "delete", "get"],
|
actions=["add", "update", "delete", "get"],
|
||||||
authentifier=check_project,
|
|
||||||
handler=ProjectHandler())
|
handler=ProjectHandler())
|
||||||
|
|
||||||
|
member_resource = RESTResource(
|
||||||
|
name="member",
|
||||||
|
inject_name="project",
|
||||||
|
route="/project/<project_id>/members",
|
||||||
|
app=api,
|
||||||
|
handler=MemberHandler(),
|
||||||
|
authentifier=check_project)
|
||||||
|
|
||||||
|
bill_resource = RESTResource(
|
||||||
|
name="bill",
|
||||||
|
inject_name="project",
|
||||||
|
route="/project/<project_id>/bills",
|
||||||
|
app=api,
|
||||||
|
handler=BillHandler(),
|
||||||
|
authentifier=check_project)
|
||||||
|
|
||||||
# projects: add, delete, edit, get
|
# projects: add, delete, edit, get
|
||||||
# GET /project/<id> → get
|
# GET /project/<id> → get
|
||||||
# PUT /project/<id> → add & edit
|
# PUT /project/<id> → add & edit
|
||||||
|
|
|
@ -7,7 +7,8 @@ class RESTResource(object):
|
||||||
"list": "GET",
|
"list": "GET",
|
||||||
"add": "POST",}
|
"add": "POST",}
|
||||||
|
|
||||||
def __init__(self, name, route, app, actions, handler, authentifier):
|
def __init__(self, name, route, app, handler, authentifier=None,
|
||||||
|
actions=None, inject_name=None):
|
||||||
"""
|
"""
|
||||||
:name:
|
:name:
|
||||||
name of the resource. This is being used when registering
|
name of the resource. This is being used when registering
|
||||||
|
@ -21,7 +22,7 @@ class RESTResource(object):
|
||||||
Application to register the routes onto
|
Application to register the routes onto
|
||||||
|
|
||||||
:actions:
|
:actions:
|
||||||
Authorized actions.
|
Authorized actions. Optional. None means all.
|
||||||
|
|
||||||
:handler:
|
:handler:
|
||||||
The handler instance which will handle the requests
|
The handler instance which will handle the requests
|
||||||
|
@ -30,12 +31,15 @@ class RESTResource(object):
|
||||||
callable checking the authentication. If specified, all the
|
callable checking the authentication. If specified, all the
|
||||||
methods will be checked against it.
|
methods will be checked against it.
|
||||||
"""
|
"""
|
||||||
|
if not actions:
|
||||||
|
actions = self._VERBS.keys()
|
||||||
|
|
||||||
self._route = route
|
self._route = route
|
||||||
self._handler = handler
|
self._handler = handler
|
||||||
self._name = name
|
self._name = name
|
||||||
self._identifier = "%s_id" % name
|
self._identifier = "%s_id" % name
|
||||||
self._authentifier = authentifier
|
self._authentifier = authentifier
|
||||||
|
self._inject_name = inject_name # FIXME
|
||||||
|
|
||||||
for action in actions:
|
for action in actions:
|
||||||
self.add_url_rule(app, action)
|
self.add_url_rule(app, action)
|
||||||
|
@ -63,7 +67,8 @@ class RESTResource(object):
|
||||||
|
|
||||||
# decorate the view
|
# decorate the view
|
||||||
if self._authentifier:
|
if self._authentifier:
|
||||||
method = need_auth(self._authentifier, self._name)(method)
|
method = need_auth(self._authentifier,
|
||||||
|
self._inject_name or self._name)(method)
|
||||||
|
|
||||||
app.add_url_rule(
|
app.add_url_rule(
|
||||||
self._get_route_for(action),
|
self._get_route_for(action),
|
||||||
|
@ -72,7 +77,7 @@ class RESTResource(object):
|
||||||
methods=[self._VERBS.get(action, "GET")])
|
methods=[self._VERBS.get(action, "GET")])
|
||||||
|
|
||||||
|
|
||||||
def need_auth(authentifier, name=None):
|
def need_auth(authentifier, name=None, remove_attr=True):
|
||||||
"""Decorator checking that the authentifier does not returns false in
|
"""Decorator checking that the authentifier does not returns false in
|
||||||
the current context.
|
the current context.
|
||||||
|
|
||||||
|
@ -88,6 +93,10 @@ def need_auth(authentifier, name=None):
|
||||||
**Optional**, name of the argument to put the object into.
|
**Optional**, name of the argument to put the object into.
|
||||||
If it is not provided, nothing will be added to the kwargs
|
If it is not provided, nothing will be added to the kwargs
|
||||||
of the decorated function
|
of the decorated function
|
||||||
|
|
||||||
|
:remove_attr:
|
||||||
|
Remove or not the `*name*_id` from the kwargs before calling the
|
||||||
|
function
|
||||||
"""
|
"""
|
||||||
def wrapper(func):
|
def wrapper(func):
|
||||||
def wrapped(*args, **kwargs):
|
def wrapped(*args, **kwargs):
|
||||||
|
@ -95,26 +104,10 @@ def need_auth(authentifier, name=None):
|
||||||
if result:
|
if result:
|
||||||
if name:
|
if name:
|
||||||
kwargs[name] = result
|
kwargs[name] = result
|
||||||
|
if remove_attr:
|
||||||
|
del kwargs["%s_id" % name]
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
else:
|
else:
|
||||||
raise werkzeug.exceptions.Forbidden()
|
raise werkzeug.exceptions.Forbidden()
|
||||||
return wrapped
|
return wrapped
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
class DefaultHandler(object):
|
|
||||||
|
|
||||||
def add(self, *args, **kwargs):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def update(self, *args, **kwargs):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def list(self, *args, **kwargs):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get(self, *args, **kwargs):
|
|
||||||
pass
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ app.config.from_object("default_settings")
|
||||||
app.register_blueprint(main)
|
app.register_blueprint(main)
|
||||||
app.register_blueprint(api)
|
app.register_blueprint(api)
|
||||||
|
|
||||||
|
|
||||||
# db
|
# db
|
||||||
db.init_app(app)
|
db.init_app(app)
|
||||||
db.app = app
|
db.app = app
|
||||||
|
|
Loading…
Reference in a new issue