2 from urllib import unquote
3 from bibleverses.webutils import HttpResponse, dispatch
4 from bibleverses import db
8 MSG_NO_EMAIL_ADDRESS = 1
11 MSG_EMAIL_NOT_FOUND = 4
12 MSG_PASSWORD_INCORRECT = 5
16 class JsonResponse(HttpResponse):
17 def __init__(self, obj):
18 super(JsonResponse, self).__init__()
19 self.content = simplejson.dumps(obj)
20 self.content_type = "text/javascript"
22 def success(**kwargs):
23 kwargs['success'] = True
24 return JsonResponse(kwargs)
26 def failure(**kwargs):
27 kwargs['success'] = False
28 return JsonResponse(kwargs)
30 def authentication_error():
31 return failure(error="Authentication error")
33 ##### Decorators ######
36 def wrapper(*args, **kwargs):
38 return func(*args, **kwargs)
40 return JsonResponse({"error": str(e)})
43 def never_cache(func):
44 def wrapper(*args, **kwargs):
45 resp = func(*args, **kwargs)
46 resp.headers['Cache-Control'] = "no-cache, no-store, private";
50 def require_user(func):
51 """Adds user as attribute of request object if correct creds,
52 otherwise returns authentication_error()"""
53 def wrapper(request, *args, **kwargs):
54 user = get_user_from_request(request)
56 return authentication_error()
59 return func(request, *args, **kwargs)
65 def __init__(self, uid, email, password):
68 self.password = password
70 def create(email, password):
71 db.execute("INSERT INTO users values (NULL, %s, %s);", email, password)
72 create = staticmethod(create)
75 q = db.execute("SELECT id, email, password FROM users WHERE email = %s;", email)
77 return User(q[0][0], q[0][1], q[0][2])
80 retrieve = staticmethod(retrieve)
82 def checkPassword(self, password):
83 return self.password == password
86 return [row[0] for row in
87 db.execute("SELECT verseref FROM verses WHERE userid = %s ORDER BY verseref;", self.id)]
89 def add_verse(self, verseref):
90 if len(db.execute("SELECT id FROM verses WHERE verseref = %s AND userid = %s;", verseref, self.id)) == 0:
91 db.execute("INSERT INTO verses (id, userid, verseref) VALUES (NULL, %s, %s);", self.id, verseref)
93 def delete_verse(self, verseref):
94 db.execute("DELETE FROM verses WHERE verseref = %s AND userid = %s;", verseref, self.id)
96 ##### View functions ####
98 def register(request):
99 email = request.POST.get('email', '').strip()
100 password = request.POST.get('password', '').strip()
102 retval = failure(validation=[MSG_NO_EMAIL_ADDRESS, "Email address was not supplied"])
103 elif len(password) == 0:
104 retval = failure(validation=[MSG_NO_PASSWORD, "Password not supplied"])
106 if User.retrieve(email) is not None:
107 retval = failure(validation=[MSG_EMAIL_TAKEN, "Email address already taken."])
110 User.create(email, password)
113 retval = failure(error=str(e))
117 email = request.POST.get('email', '').strip()
118 password = request.POST.get('password', '').strip()
120 user = User.retrieve(email)
122 if user.checkPassword(password):
125 return failure(validation=[MSG_PASSWORD_INCORRECT, "Password is incorrect."])
127 return failure(validation=[MSG_EMAIL_NOT_FOUND, "Email address not found."])
129 def get_user_from_request(request):
130 email = unquote(request.get_cookie('email', ''))
131 password = unquote(request.get_cookie('password',''))
132 u = User.retrieve(email)
133 if u is not None and u.checkPassword(password):
139 return success(verselist=request.user.get_verses())
140 verses = require_user(verses)
142 def addverse(request):
143 verseref = request.POST.get('verse')
144 if verseref is None or verseref == '':
146 request.user.add_verse(verseref)
147 return success(verse=verseref)
148 addverse = require_user(addverse)
150 def removeverse(request):
151 verseref = request.POST.get('verse')
152 if verseref is None or verseref == '':
154 request.user.delete_verse(verseref)
155 return success(verse=verseref)
156 removeverse = require_user(removeverse)
158 ##### Database creation/upgrade #####
163 id integer PRIMARY KEY,
168 CREATE TABLE verses (
169 id integer PRIMARY KEY,
172 foreign key (userid) REFERENCES users(id)
187 def upgrade1(request):
189 res = db.execute("SELECT value FROM metainfo WHERE name='dbversion';");
192 CREATE TABLE metainfo (
193 name text PRIMARY KEY,
197 db.execute("INSERT INTO metainfo (name, value) VALUES ('dbversion', '2');")
199 for (email, password) in db.execute("SELECT email, password FROM users;"):
200 db.execute("UPDATE users SET password = %s WHERE email = %s;", sha.sha(email+password).hexdigest(), email)
201 # Otherwise don't need to upgrade
205 return HttpResponse(content=\
224 """ % (req.method, req.path, req.GET, req.POST, req.COOKIES, req.environ),
225 content_type="text/plain")
228 #############################################
231 ('^/register/$', register),
232 ('^/login/$', login),
233 ('^/verses/$', verses),
234 ('^/addverse/$', addverse),
235 ('^/removeverse/$', removeverse),
236 ('^/debug/$', debug),
237 # ('^/initdb/$', initdb),
238 # ('^/dropdb/$', dropdb),
239 # ('^/upgrade1/$', upgrade1),
242 urls = [(regex, catch_all(never_cache(f))) for regex, f in urls]