Commit 6dca43f12f26def8cf37796d2f8dd3ddcd795ad7

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

- login shows error messages (unauthorized, already online, wrong password)

- stores browser request headers on login with the test
1 1
2 # BUGS 2 # BUGS
3 3
  4 +- no login, dar mensagem de erro se aluno nao existir??
  5 +- Verificar o processo de logout.
  6 +- permitir remover alunos que estão online para poderem comecar de novo.
4 - grade gives internal server error 7 - grade gives internal server error
5 - reload do teste recomeça a contagem no inicio do tempo. 8 - reload do teste recomeça a contagem no inicio do tempo.
6 - em admin, quando scale_max não é 20, as cores das barras continuam a reflectir a escala 0,20. a tabela teste na DB não tem a escala desse teste. 9 - em admin, quando scale_max não é 20, as cores das barras continuam a reflectir a escala 0,20. a tabela teste na DB não tem a escala desse teste.
perguntations/app.py
@@ -123,11 +123,14 @@ class App(): @@ -123,11 +123,14 @@ class App():
123 logger.info('No tests were generated.') 123 logger.info('No tests were generated.')
124 124
125 # ------------------------------------------------------------------------ 125 # ------------------------------------------------------------------------
126 - async def login(self, uid, try_pw): 126 + async def login(self, uid, try_pw, headers=None):
127 '''login authentication''' 127 '''login authentication'''
  128 + if uid in self.online:
  129 + logger.warning('"%s" already logged in.', uid)
  130 + return 'already_online'
128 if uid not in self.allowed and uid != '0': # not allowed 131 if uid not in self.allowed and uid != '0': # not allowed
129 - logger.warning('"%s" not allowed to login.', uid)  
130 - return False 132 + logger.warning('"%s" unauthorized.', uid)
  133 + return 'unauthorized'
131 134
132 # get name+password from db 135 # get name+password from db
133 with self._db_session() as sess: 136 with self._db_session() as sess:
@@ -142,17 +145,15 @@ class App(): @@ -142,17 +145,15 @@ class App():
142 else: # check password 145 else: # check password
143 pw_ok = await check_password(try_pw, password) # async bcrypt 146 pw_ok = await check_password(try_pw, password) # async bcrypt
144 147
145 - if pw_ok: # success  
146 - self.allowed.discard(uid) # remove from set of allowed students  
147 - if uid in self.online:  
148 - logger.warning('"%s" already logged in.', uid)  
149 - else: # make student online  
150 - self.online[uid] = {'student': {'name': name, 'number': uid}}  
151 - logger.info('"%s" logged in.', uid)  
152 - return True  
153 - # wrong password  
154 - logger.info('"%s" wrong password.', uid)  
155 - return False 148 + if not pw_ok: # wrong password
  149 + logger.info('"%s" wrong password.', uid)
  150 + return 'wrong_password'
  151 +
  152 + # success
  153 + self.allowed.discard(uid) # remove from set of allowed students
  154 + self.online[uid] = {'student': {'name': name, 'number': uid, 'headers': headers}}
  155 + logger.info('"%s" logged in from %s.', uid, headers['remote_ip'])
  156 +
156 157
157 # ------------------------------------------------------------------------ 158 # ------------------------------------------------------------------------
158 def logout(self, uid): 159 def logout(self, uid):
perguntations/serve.py
@@ -190,11 +190,14 @@ class RootHandler(BaseHandler): @@ -190,11 +190,14 @@ class RootHandler(BaseHandler):
190 @tornado.web.authenticated 190 @tornado.web.authenticated
191 async def get(self): 191 async def get(self):
192 ''' 192 '''
193 - Sends test to student or redirects 0 to admin page 193 + Handles GET /
  194 + Sends test to student or redirects 0 to admin page.
  195 + Multiple calls to this function will return the same test.
194 ''' 196 '''
195 197
196 uid = self.current_user 198 uid = self.current_user
197 - logging.info('"%s" GET /', uid) 199 + logging.debug('"%s" GET /', uid)
  200 +
198 if uid == '0': 201 if uid == '0':
199 self.redirect('/admin') 202 self.redirect('/admin')
200 203
@@ -263,6 +266,11 @@ class LoginHandler(BaseHandler): @@ -263,6 +266,11 @@ class LoginHandler(BaseHandler):
263 '''Handles /login''' 266 '''Handles /login'''
264 267
265 _prefix = re.compile(r'[a-z]') 268 _prefix = re.compile(r'[a-z]')
  269 + _error_msg = {
  270 + 'wrong_password': 'Password errada',
  271 + 'already_online': 'Já está online, não pode entrar duas vezes',
  272 + 'unauthorized': 'Não está autorizado a fazer o teste'
  273 + }
266 274
267 def get(self): 275 def get(self):
268 '''Render login page.''' 276 '''Render login page.'''
@@ -272,13 +280,18 @@ class LoginHandler(BaseHandler): @@ -272,13 +280,18 @@ class LoginHandler(BaseHandler):
272 '''Authenticates student and login.''' 280 '''Authenticates student and login.'''
273 uid = self._prefix.sub('', self.get_body_argument('uid')) 281 uid = self._prefix.sub('', self.get_body_argument('uid'))
274 password = self.get_body_argument('pw') 282 password = self.get_body_argument('pw')
275 - login_ok = await self.testapp.login(uid, password) 283 + headers = {
  284 + 'remote_ip': self.request.remote_ip,
  285 + 'user_agent': self.request.headers.get('User-Agent')
  286 + }
  287 +
  288 + error = await self.testapp.login(uid, password, headers)
276 289
277 - if login_ok: 290 + if error is None:
278 self.set_secure_cookie('perguntations_user', str(uid), expires_days=1) 291 self.set_secure_cookie('perguntations_user', str(uid), expires_days=1)
279 self.redirect('/') 292 self.redirect('/')
280 else: 293 else:
281 - self.render('login.html', error='Não autorizado ou senha inválida') 294 + self.render('login.html', error=self._error_msg[error])
282 295
283 296
284 # ---------------------------------------------------------------------------- 297 # ----------------------------------------------------------------------------