diff options
Diffstat (limited to 'ihatemoney/api.py')
| -rw-r--r-- | ihatemoney/api.py | 168 |
1 files changed, 84 insertions, 84 deletions
diff --git a/ihatemoney/api.py b/ihatemoney/api.py index 827202c..31ed06c 100644 --- a/ihatemoney/api.py +++ b/ihatemoney/api.py @@ -1,62 +1,68 @@ # -*- coding: utf-8 -*- from flask import Blueprint, request -from flask_rest import RESTResource, need_auth +from flask_restful import Resource, Api, abort from wtforms.fields.core import BooleanField from ihatemoney.models import db, Project, Person, Bill from ihatemoney.forms import (ProjectForm, EditProjectForm, MemberForm, get_billform_for) from werkzeug.security import check_password_hash +from functools import wraps api = Blueprint("api", __name__, url_prefix="/api") +restful_api = Api(api) -def check_project(*args, **kwargs): +def need_auth(f): """Check the request for basic authentication for a given project. - Return the project if the authorization is good, False otherwise + Return the project if the authorization is good, abort the request with a 401 otherwise """ - auth = request.authorization - - # project_id should be contained in kwargs and equal to the username - if auth and "project_id" in kwargs and \ - auth.username == kwargs["project_id"]: - project = Project.query.get(auth.username) - if project and check_password_hash(project.password, auth.password): - return project - return False - - -class ProjectHandler(object): - - def add(self): + @wraps(f) + def wrapper(*args, **kwargs): + auth = request.authorization + project_id = kwargs.get("project_id") + + if auth and project_id and auth.username == project_id: + project = Project.query.get(auth.username) + if project and check_password_hash(project.password, auth.password): + # The whole project object will be passed instead of project_id + kwargs.pop("project_id") + return f(*args, project=project, **kwargs) + abort(401) + return wrapper + + +class ProjectsHandler(Resource): + def post(self): form = ProjectForm(meta={'csrf': False}) if form.validate(): project = form.save() db.session.add(project) db.session.commit() - return 201, project.id - return 400, form.errors + return project.id, 201 + return form.errors, 400 + + +class ProjectHandler(Resource): + method_decorators = [need_auth] - @need_auth(check_project, "project") def get(self, project): - return 200, project + return project - @need_auth(check_project, "project") def delete(self, project): db.session.delete(project) db.session.commit() - return 200, "DELETED" + return "DELETED" - @need_auth(check_project, "project") - def update(self, project): + def put(self, project): form = EditProjectForm(meta={'csrf': False}) if form.validate(): form.update(project) db.session.commit() - return 200, "UPDATED" - return 400, form.errors + return "UPDATED" + return form.errors, 400 class APIMemberForm(MemberForm): @@ -71,98 +77,92 @@ class APIMemberForm(MemberForm): return super(APIMemberForm, self).save(project, person) -class MemberHandler(object): +class MembersHandler(Resource): + method_decorators = [need_auth] - def get(self, project, member_id): - member = Person.query.get(member_id, project) - if not member or member.project != project: - return 404, "Not Found" - return 200, member - - def list(self, project): - return 200, project.members + def get(self, project): + return project.members - def add(self, project): + def post(self, project): form = MemberForm(project, meta={'csrf': False}) if form.validate(): member = Person() form.save(project, member) db.session.commit() - return 201, member.id - return 400, form.errors + return member.id, 201 + return form.errors, 400 + + +class MemberHandler(Resource): + method_decorators = [need_auth] + + def get(self, project, member_id): + member = Person.query.get(member_id, project) + if not member or member.project != project: + return "Not Found", 404 + return member - def update(self, project, member_id): + def put(self, project, member_id): form = APIMemberForm(project, meta={'csrf': False}, edit=True) if form.validate(): member = Person.query.get(member_id, project) form.save(project, member) db.session.commit() - return 200, member - return 400, form.errors + return member + return form.errors, 400 def delete(self, project, member_id): if project.remove_member(member_id): - return 200, "OK" - return 404, "Not Found" + return "OK" + return "Not Found", 404 -class BillHandler(object): - - def get(self, project, bill_id): - bill = Bill.query.get(project, bill_id) - if not bill: - return 404, "Not Found" - return 200, bill +class BillsHandler(Resource): + method_decorators = [need_auth] - def list(self, project): + def get(self, project): return project.get_bills().all() - def add(self, project): + def post(self, project): form = get_billform_for(project, True, meta={'csrf': False}) if form.validate(): bill = Bill() form.save(bill, project) db.session.add(bill) db.session.commit() - return 201, bill.id - return 400, form.errors + return bill.id, 201 + return form.errors, 400 + - def update(self, project, bill_id): +class BillHandler(Resource): + method_decorators = [need_auth] + + def get(self, project, bill_id): + bill = Bill.query.get(project, bill_id) + if not bill: + return "Not Found", 404 + return bill, 200 + + def put(self, project, bill_id): form = get_billform_for(project, True, meta={'csrf': False}) if form.validate(): bill = Bill.query.get(project, bill_id) form.save(bill, project) db.session.commit() - return 200, bill.id - return 400, form.errors + return bill.id, 200 + return form.errors, 400 def delete(self, project, bill_id): bill = Bill.query.delete(project, bill_id) db.session.commit() if not bill: - return 404, "Not Found" - return 200, "OK" - - -project_resource = RESTResource( - name="project", - route="/projects", - app=api, - actions=["add", "update", "delete", "get"], - handler=ProjectHandler()) - -member_resource = RESTResource( - name="member", - inject_name="project", - route="/projects/<project_id>/members", - app=api, - handler=MemberHandler(), - authentifier=check_project) - -bill_resource = RESTResource( - name="bill", - inject_name="project", - route="/projects/<project_id>/bills", - app=api, - handler=BillHandler(), - authentifier=check_project) + return "Not Found", 404 + return "OK", 200 + + +restful_api.add_resource(ProjectsHandler, '/projects') +restful_api.add_resource(ProjectHandler, '/projects/<string:project_id>') +restful_api.add_resource(MembersHandler, "/projects/<string:project_id>/members") +restful_api.add_resource(MemberHandler, "/projects/<string:project_id>/members/<int:member_id>") +restful_api.add_resource(BillsHandler, "/projects/<string:project_id>/bills") +restful_api.add_resource(BillHandler, "/projects/<string:project_id>/bills/<int:bill_id>") |
