Commit e36dfd6c93c5a790a11b44d17737f7864a941aa8
1 parent
9f52cf60
Exists in
master
and in
1 other branch
- Fixed simultaneous logins of same user on different devices.
will invalidate older ones.
Showing
4 changed files
with
27 additions
and
21 deletions
Show diff stats
BUGS.md
1 | 1 | |
2 | 2 | # BUGS |
3 | 3 | |
4 | -- esta a permitir 2 logins em simultaneo do mesmo user. fica tudo baralhado... | |
5 | 4 | - shift-enter não está a funcionar |
6 | 5 | - falha intermitent no file handler quando o browser envia 2 GET requests ao mesmo tempo (porquê?) |
7 | 6 | - nos topicos learn.yaml, qd falha acrescenta no fim. nao faz sentido. |
... | ... | @@ -34,6 +33,7 @@ |
34 | 33 | |
35 | 34 | # FIXED |
36 | 35 | |
36 | +- esta a permitir 2 logins em simultaneo do mesmo user. fica tudo baralhado se mxerem em simultaneo... | |
37 | 37 | - errar no ultimo topico nao mostra solucao? |
38 | 38 | - quando a pergunta devolve comments, este é apresentado, mas fica persistente nas tentativas seguintes. devia ser limpo apos a segunda submissao. |
39 | 39 | - na definicao dos topicos, indicar: | ... | ... |
learnapp.py
... | ... | @@ -73,22 +73,22 @@ class LearnApp(object): |
73 | 73 | # login |
74 | 74 | # ------------------------------------------------------------------------ |
75 | 75 | async def login(self, uid, try_pw): |
76 | - if uid.startswith('l'): # remove prefix 'l' | |
77 | - uid = uid[1:] | |
78 | - | |
79 | 76 | with self.db_session() as s: |
80 | 77 | try: |
81 | 78 | name, password = s.query(Student.name, Student.password).filter_by(id=uid).one() |
82 | 79 | except: |
83 | - logger.info(f'User "{uid}" does not exist!') | |
80 | + logger.info(f'User "{uid}" does not exist') | |
84 | 81 | return False |
85 | 82 | |
86 | 83 | pw_ok = await check_password(try_pw, password) # async bcrypt |
84 | + | |
87 | 85 | if pw_ok: |
88 | 86 | if uid in self.online: |
89 | - logger.warning(f'User "{uid}" already logged in, overwriting state') | |
87 | + logger.warning(f'User "{uid}" already logged in, overwriting') | |
88 | + counter = self.online[uid]['counter'] | |
90 | 89 | else: |
91 | - logger.info(f'User "{uid}" logged in successfully') | |
90 | + logger.info(f'User "{uid}" logged in') | |
91 | + counter = 0 | |
92 | 92 | |
93 | 93 | with self.db_session() as s: |
94 | 94 | tt = s.query(StudentTopic).filter_by(student_id=uid) |
... | ... | @@ -102,10 +102,11 @@ class LearnApp(object): |
102 | 102 | 'number': uid, |
103 | 103 | 'name': name, |
104 | 104 | 'state': StudentKnowledge(deps=self.deps, factory=self.factory, state=state), |
105 | + 'counter': counter + 1, # counts simultaneous logins | |
105 | 106 | } |
106 | 107 | |
107 | 108 | else: |
108 | - logger.info(f'User "{uid}" wrong password!') | |
109 | + logger.info(f'User "{uid}" wrong password') | |
109 | 110 | |
110 | 111 | return pw_ok |
111 | 112 | |
... | ... | @@ -313,6 +314,10 @@ class LearnApp(object): |
313 | 314 | # ======================================================================== |
314 | 315 | |
315 | 316 | # ------------------------------------------------------------------------ |
317 | + def get_login_counter(self, uid): | |
318 | + return self.online[uid]['counter'] | |
319 | + | |
320 | + # ------------------------------------------------------------------------ | |
316 | 321 | def get_student_name(self, uid): |
317 | 322 | return self.online[uid].get('name', '') |
318 | 323 | ... | ... |
serve.py
... | ... | @@ -75,13 +75,12 @@ class BaseHandler(tornado.web.RequestHandler): |
75 | 75 | return self.application.learn |
76 | 76 | |
77 | 77 | def get_current_user(self): |
78 | - cookie = self.get_secure_cookie("user") | |
78 | + cookie = self.get_secure_cookie('user') | |
79 | 79 | if cookie: |
80 | - user = cookie.decode('utf-8') | |
81 | - return user | |
82 | - # FIXME if the cookie exists but user is not in learn.online, this will force new login and store new (duplicate?) cookie. is this correct?? | |
83 | - # if user in self.learn.online: | |
84 | - # return user | |
80 | + counter = self.get_secure_cookie('counter') | |
81 | + uid = cookie.decode('utf-8') | |
82 | + if counter.decode('utf-8') == str(self.learn.get_login_counter(uid)): | |
83 | + return uid | |
85 | 84 | |
86 | 85 | # ---------------------------------------------------------------------------- |
87 | 86 | # /auth/login and /auth/logout |
... | ... | @@ -97,10 +96,11 @@ class LoginHandler(BaseHandler): |
97 | 96 | login_ok = await self.learn.login(uid, pw) |
98 | 97 | |
99 | 98 | if login_ok: |
100 | - self.set_secure_cookie("user", str(uid), expires_days=30) | |
101 | - self.redirect(self.get_argument("next", "/")) | |
99 | + self.set_secure_cookie('user', uid) # expires_days=30 | |
100 | + self.set_secure_cookie('counter', str(self.learn.get_login_counter(uid))) | |
101 | + self.redirect('/') | |
102 | 102 | else: |
103 | - self.render("login.html", error='Número ou senha incorrectos') | |
103 | + self.render('login.html', error='Número ou senha incorrectos') | |
104 | 104 | |
105 | 105 | |
106 | 106 | # ---------------------------------------------------------------------------- |
... | ... | @@ -108,7 +108,8 @@ class LogoutHandler(BaseHandler): |
108 | 108 | @tornado.web.authenticated |
109 | 109 | def get(self): |
110 | 110 | self.clear_cookie('user') |
111 | - self.redirect(self.get_argument('next', '/')) | |
111 | + self.clear_cookie('counter') | |
112 | + self.redirect('/') | |
112 | 113 | |
113 | 114 | def on_finish(self): |
114 | 115 | self.learn.logout(self.current_user) |
... | ... | @@ -309,7 +310,7 @@ class QuestionHandler(BaseHandler): |
309 | 310 | } |
310 | 311 | |
311 | 312 | else: |
312 | - logger.error(f'Unknown action: {action}') | |
313 | + logging.error(f'Unknown action: {action}') | |
313 | 314 | |
314 | 315 | self.write(response) |
315 | 316 | ... | ... |
templates/topic.html
... | ... | @@ -78,7 +78,7 @@ |
78 | 78 | |
79 | 79 | <!-- <div class="container"> --> |
80 | 80 | <div class="row"> |
81 | - <div class="col col-9"> | |
81 | + <div class="col col-lg-9"> | |
82 | 82 | <div class="my-5" id="content"> |
83 | 83 | <form action="/question" method="post" id="question_form" autocomplete="off"> |
84 | 84 | {% module xsrf_form_html() %} |
... | ... | @@ -91,7 +91,7 @@ |
91 | 91 | </div> |
92 | 92 | |
93 | 93 | </div> <!-- col --> |
94 | - <div class="col col-3"> | |
94 | + <div class="col col-lg-3"> | |
95 | 95 | <button class="btn btn-primary btn-lg btn-block my-5" id="submit" data-toggle="tooltip" data-placement="right" title="Shift-Enter">Responder</button> |
96 | 96 | |
97 | 97 | <div id="right" style="display: none"> | ... | ... |