aboutsummaryrefslogtreecommitdiff
path: root/budget/api.py
blob: 9d41b3c321e99c1820daac4bae4dbcf5d0521327 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# -*- coding: utf-8 -*-
from flask import *

from models import db, Project, Person, Bill
from forms import (ProjectForm, EditProjectForm, MemberForm, BillForm, 
                   get_billform_for)
from utils import for_all_methods

from flask_rest import RESTResource, need_auth
from werkzeug import Response


api = Blueprint("api", __name__, url_prefix="/api")

def check_project(*args, **kwargs):
    """Check the request for basic authentication for a given project.

    Return the project if the authorization is good, False 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 project.password == auth.password:
            return project
    return False


class ProjectHandler(object):

    def add(self):
        form = ProjectForm(csrf_enabled=False)
        if form.validate():
            project = form.save()
            db.session.add(project)
            db.session.commit()
            return 201, project.id
        return 400, form.errors

    @need_auth(check_project, "project")
    def get(self, project):
        return 200, project

    @need_auth(check_project, "project")
    def delete(self, project):
        db.session.delete(project)
        db.session.commit()
        return 200, "DELETED"

    @need_auth(check_project, "project")
    def update(self, project):
        form = EditProjectForm(csrf_enabled=False)
        if form.validate():
            form.update(project)
            db.session.commit()
            return 200, "UPDATED"
        return 400, form.errors


class MemberHandler(object):

    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 add(self, project):
        form = MemberForm(project, csrf_enabled=False)
        if form.validate():
            member = Person()
            form.save(project, member)
            db.session.commit()
            return 201, member.id
        return 400, form.errors

    def update(self, project, member_id):
        form = MemberForm(project, csrf_enabled=False)
        if form.validate():
            member = Person.query.get(member_id, project)
            form.save(project, member)
            db.session.commit()
            return 200, member
        return 400, form.errors

    def delete(self, project, member_id):
        if project.remove_member(member_id):
            return 200, "OK"
        return 404, "Not Found"


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

    def list(self, project):
        return project.get_bills().all()

    def add(self, project):
        form = get_billform_for(project, True, csrf_enabled=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

    def update(self, project, bill_id):
        form = get_billform_for(project, True, csrf_enabled=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

    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)