Commit 27e15117341fa400572d0fca9bf9f74dc3094efb

Authored by Miguel Barão
1 parent 785ca6d2
Exists in master and in 1 other branch dev

- login is now async on the bcrypt function that checks the password.

Showing 2 changed files with 18 additions and 13 deletions   Show diff stats
app.py
... ... @@ -3,6 +3,7 @@
3 3 from os import path
4 4 import logging
5 5 from contextlib import contextmanager # `with` statement in db sessions
  6 +import asyncio
6 7  
7 8 # user installed packages
8 9 import bcrypt
... ... @@ -23,8 +24,11 @@ class AppException(Exception):
23 24 # ============================================================================
24 25 # helper functions
25 26 # ============================================================================
26   -def check_password(try_pw, password):
27   - return password == bcrypt.hashpw(try_pw.encode('utf-8'), password)
  27 +async def check_password(try_pw, password):
  28 + try_pw = try_pw.encode('utf-8')
  29 + loop = asyncio.get_event_loop()
  30 + hashed_pw = await loop.run_in_executor(None, bcrypt.hashpw, try_pw, password)
  31 + return password == hashed_pw
28 32  
29 33 # ============================================================================
30 34 # Application
... ... @@ -69,7 +73,6 @@ class App(object):
69 73 # connect to database and check registered students
70 74 dbfile = path.expanduser(self.testfactory['database'])
71 75 engine = create_engine(f'sqlite:///{dbfile}', echo=False)
72   - # self.Session = scoped_session(sessionmaker(bind=engine)) # FIXME not scoped in tornado
73 76 self.Session = sessionmaker(bind=engine)
74 77  
75 78 try:
... ... @@ -95,7 +98,7 @@ class App(object):
95 98 logger.critical('----------- !!! Server terminated !!! -----------')
96 99  
97 100 # -----------------------------------------------------------------------
98   - def login(self, uid, try_pw):
  101 + async def login(self, uid, try_pw):
99 102 if uid.startswith('l'): # remove prefix 'l'
100 103 uid = uid[1:]
101 104  
... ... @@ -112,7 +115,7 @@ class App(object):
112 115 self.update_student_password(uid, try_pw)
113 116 pw_ok = True
114 117 else: # check password
115   - pw_ok = check_password(try_pw, password)
  118 + pw_ok = await check_password(try_pw, password) # async bcrypt
116 119  
117 120 if pw_ok: # success
118 121 self.allowed.discard(uid) # remove from set of allowed students
... ...
serve.py
... ... @@ -23,6 +23,9 @@ from app import App, AppException
23 23 from tools import load_yaml, md_to_html
24 24  
25 25  
  26 +# -------------------------------------------------------------------------
  27 +# Web Application. Routes to handler classes.
  28 +# -------------------------------------------------------------------------
26 29 class WebApplication(tornado.web.Application):
27 30 def __init__(self, testapp, debug=False):
28 31 handlers = [
... ... @@ -73,13 +76,10 @@ class LoginHandler(BaseHandler):
73 76 self.render('login.html', error='')
74 77  
75 78 # async
76   - def post(self):
  79 + async def post(self):
77 80 uid = self.get_body_argument('uid')
78 81 pw = self.get_body_argument('pw')
79   -
80   - # loop = asyncio.get_event_loop()
81   - # login_ok = await loop.run_in_executor(None, self.testapp.login, uid, pw)
82   - login_ok = self.testapp.login(uid, pw)
  82 + login_ok = await self.testapp.login(uid, pw)
83 83  
84 84 if login_ok:
85 85 self.set_secure_cookie("user", str(uid), expires_days=30)
... ... @@ -151,10 +151,12 @@ class FileHandler(BaseHandler):
151 151  
152 152  
153 153 # -------------------------------------------------------------------------
154   -# FIXME images missing, needs testing
  154 +# Test shown to students
155 155 # -------------------------------------------------------------------------
156 156 class TestHandler(BaseHandler):
157   - templates = {
  157 + SUPPORTED_METHODS = ['GET', 'POST']
  158 +
  159 + _templates = {
158 160 'radio': 'question-radio.html',
159 161 'checkbox': 'question-checkbox.html',
160 162 'text': 'question-text.html',
... ... @@ -175,7 +177,7 @@ class TestHandler(BaseHandler):
175 177 def get(self):
176 178 uid = self.current_user
177 179 t = self.testapp.get_student_test(uid) or self.testapp.generate_test(uid)
178   - self.render('test.html', t=t, md=md_to_html, templ=self.templates)
  180 + self.render('test.html', t=t, md=md_to_html, templ=self._templates)
179 181  
180 182 # POST
181 183 @tornado.web.authenticated
... ...