diff --git a/app.py b/app.py index ec04bbe..a95cd9c 100644 --- a/app.py +++ b/app.py @@ -3,6 +3,7 @@ from os import path import logging from contextlib import contextmanager # `with` statement in db sessions +import asyncio # user installed packages import bcrypt @@ -23,8 +24,11 @@ class AppException(Exception): # ============================================================================ # helper functions # ============================================================================ -def check_password(try_pw, password): - return password == bcrypt.hashpw(try_pw.encode('utf-8'), password) +async def check_password(try_pw, password): + try_pw = try_pw.encode('utf-8') + loop = asyncio.get_event_loop() + hashed_pw = await loop.run_in_executor(None, bcrypt.hashpw, try_pw, password) + return password == hashed_pw # ============================================================================ # Application @@ -69,7 +73,6 @@ class App(object): # connect to database and check registered students dbfile = path.expanduser(self.testfactory['database']) engine = create_engine(f'sqlite:///{dbfile}', echo=False) - # self.Session = scoped_session(sessionmaker(bind=engine)) # FIXME not scoped in tornado self.Session = sessionmaker(bind=engine) try: @@ -95,7 +98,7 @@ class App(object): logger.critical('----------- !!! Server terminated !!! -----------') # ----------------------------------------------------------------------- - def login(self, uid, try_pw): + async def login(self, uid, try_pw): if uid.startswith('l'): # remove prefix 'l' uid = uid[1:] @@ -112,7 +115,7 @@ class App(object): self.update_student_password(uid, try_pw) pw_ok = True else: # check password - pw_ok = check_password(try_pw, password) + pw_ok = await check_password(try_pw, password) # async bcrypt if pw_ok: # success self.allowed.discard(uid) # remove from set of allowed students diff --git a/serve.py b/serve.py index 3e3fe7b..4b9a56c 100755 --- a/serve.py +++ b/serve.py @@ -23,6 +23,9 @@ from app import App, AppException from tools import load_yaml, md_to_html +# ------------------------------------------------------------------------- +# Web Application. Routes to handler classes. +# ------------------------------------------------------------------------- class WebApplication(tornado.web.Application): def __init__(self, testapp, debug=False): handlers = [ @@ -73,13 +76,10 @@ class LoginHandler(BaseHandler): self.render('login.html', error='') # async - def post(self): + async def post(self): uid = self.get_body_argument('uid') pw = self.get_body_argument('pw') - - # loop = asyncio.get_event_loop() - # login_ok = await loop.run_in_executor(None, self.testapp.login, uid, pw) - login_ok = self.testapp.login(uid, pw) + login_ok = await self.testapp.login(uid, pw) if login_ok: self.set_secure_cookie("user", str(uid), expires_days=30) @@ -151,10 +151,12 @@ class FileHandler(BaseHandler): # ------------------------------------------------------------------------- -# FIXME images missing, needs testing +# Test shown to students # ------------------------------------------------------------------------- class TestHandler(BaseHandler): - templates = { + SUPPORTED_METHODS = ['GET', 'POST'] + + _templates = { 'radio': 'question-radio.html', 'checkbox': 'question-checkbox.html', 'text': 'question-text.html', @@ -175,7 +177,7 @@ class TestHandler(BaseHandler): def get(self): uid = self.current_user t = self.testapp.get_student_test(uid) or self.testapp.generate_test(uid) - self.render('test.html', t=t, md=md_to_html, templ=self.templates) + self.render('test.html', t=t, md=md_to_html, templ=self._templates) # POST @tornado.web.authenticated -- libgit2 0.21.2