From ef3d761fc70c1c2bf0d45dde6d2703c73715bf6c Mon Sep 17 00:00:00 2001 From: Alexis Metaireau Date: Sun, 11 Sep 2011 23:00:32 +0200 Subject: [PATCH] Add Handlers for members and bills. --- budget/api.py | 71 ++++++++++++++++++++++++++++++++++++++++++++++---- budget/rest.py | 37 +++++++++++--------------- budget/run.py | 1 + 3 files changed, 82 insertions(+), 27 deletions(-) diff --git a/budget/api.py b/budget/api.py index 70864a65..e768bd98 100644 --- a/budget/api.py +++ b/budget/api.py @@ -5,7 +5,7 @@ import werkzeug from models import db, Project, Person, Bill 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") @@ -26,22 +26,83 @@ def check_project(*args, **kwargs): 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" - def delete(self, *args, **kwargs): + @need_auth(check_project, "project") + def delete(self, project): 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( name="project", route="/project", app=api, actions=["add", "update", "delete", "get"], - authentifier=check_project, handler=ProjectHandler()) +member_resource = RESTResource( + name="member", + inject_name="project", + route="/project//members", + app=api, + handler=MemberHandler(), + authentifier=check_project) + +bill_resource = RESTResource( + name="bill", + inject_name="project", + route="/project//bills", + app=api, + handler=BillHandler(), + authentifier=check_project) + # projects: add, delete, edit, get # GET /project/ → get # PUT /project/ → add & edit diff --git a/budget/rest.py b/budget/rest.py index f1de42f5..5ecee695 100644 --- a/budget/rest.py +++ b/budget/rest.py @@ -7,7 +7,8 @@ class RESTResource(object): "list": "GET", "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 of the resource. This is being used when registering @@ -21,7 +22,7 @@ class RESTResource(object): Application to register the routes onto :actions: - Authorized actions. + Authorized actions. Optional. None means all. :handler: The handler instance which will handle the requests @@ -30,12 +31,15 @@ class RESTResource(object): callable checking the authentication. If specified, all the methods will be checked against it. """ + if not actions: + actions = self._VERBS.keys() self._route = route self._handler = handler self._name = name self._identifier = "%s_id" % name self._authentifier = authentifier + self._inject_name = inject_name # FIXME for action in actions: self.add_url_rule(app, action) @@ -63,7 +67,8 @@ class RESTResource(object): # decorate the view 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( self._get_route_for(action), @@ -72,7 +77,7 @@ class RESTResource(object): 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 the current context. @@ -88,6 +93,10 @@ def need_auth(authentifier, name=None): **Optional**, name of the argument to put the object into. If it is not provided, nothing will be added to the kwargs of the decorated function + + :remove_attr: + Remove or not the `*name*_id` from the kwargs before calling the + function """ def wrapper(func): def wrapped(*args, **kwargs): @@ -95,26 +104,10 @@ def need_auth(authentifier, name=None): if result: if name: kwargs[name] = result + if remove_attr: + del kwargs["%s_id" % name] return func(*args, **kwargs) else: raise werkzeug.exceptions.Forbidden() return wrapped 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 diff --git a/budget/run.py b/budget/run.py index 65c65912..e1711a70 100644 --- a/budget/run.py +++ b/budget/run.py @@ -8,6 +8,7 @@ app.config.from_object("default_settings") app.register_blueprint(main) app.register_blueprint(api) + # db db.init_app(app) db.app = app