Commit d4ab394c3f7fcef832451897c50dcaff28f8399d
1 parent
915a24bd
Exists in
master
and in
1 other branch
- removed unused learn.css file.
- added log warning if user already logged in.
Showing
5 changed files
with
33 additions
and
119 deletions
Show diff stats
BUGS.md
| @@ -32,6 +32,7 @@ | @@ -32,6 +32,7 @@ | ||
| 32 | 32 | ||
| 33 | # FIXED | 33 | # FIXED |
| 34 | 34 | ||
| 35 | +- check if user already logged in | ||
| 35 | - mover javascript para ficheiros externos e carregar com script defer src | 36 | - mover javascript para ficheiros externos e carregar com script defer src |
| 36 | - implementar xsrf. Ver [http://www.tornadoweb.org/en/stable/guide/security.html#cross-site-request-forgery-protection]() | 37 | - implementar xsrf. Ver [http://www.tornadoweb.org/en/stable/guide/security.html#cross-site-request-forgery-protection]() |
| 37 | - se refs de um topic estao invalidos, nao carrega esse topico. devia haver um error nos logs a indicar qual o ref invalido. | 38 | - se refs de um topic estao invalidos, nao carrega esse topico. devia haver um error nos logs a indicar qual o ref invalido. |
learnapp.py
| @@ -47,35 +47,36 @@ class LearnApp(object): | @@ -47,35 +47,36 @@ class LearnApp(object): | ||
| 47 | # ------------------------------------------------------------------------ | 47 | # ------------------------------------------------------------------------ |
| 48 | # login | 48 | # login |
| 49 | # ------------------------------------------------------------------------ | 49 | # ------------------------------------------------------------------------ |
| 50 | - def login(self, uid, try_pw): | 50 | + def login(self, uid, pw): |
| 51 | + | ||
| 51 | with self.db_session() as s: | 52 | with self.db_session() as s: |
| 52 | student = s.query(Student).filter(Student.id == uid).one_or_none() | 53 | student = s.query(Student).filter(Student.id == uid).one_or_none() |
| 53 | if student is None: | 54 | if student is None: |
| 54 | logger.info(f'User "{uid}" does not exist!') | 55 | logger.info(f'User "{uid}" does not exist!') |
| 55 | return False # student does not exist | 56 | return False # student does not exist |
| 56 | 57 | ||
| 57 | - hashedtry = bcrypt.hashpw(try_pw.encode('utf-8'), student.password) | ||
| 58 | - if hashedtry != student.password: | ||
| 59 | - logger.info(f'User "{uid}" wrong password!') | ||
| 60 | - return False # wrong password | ||
| 61 | - | ||
| 62 | - # success | ||
| 63 | - logger.info(f'User "{uid}" logged in') | 58 | + if bcrypt.checkpw(pw.encode('utf-8'), student.password): |
| 59 | + if uid in self.online: | ||
| 60 | + logger.warning(f'User "{uid}" already logged in, overwriting state') | ||
| 64 | 61 | ||
| 65 | - tt = s.query(StudentTopic).filter(StudentTopic.student_id == uid) | ||
| 66 | - state = {} | ||
| 67 | - for t in tt: | ||
| 68 | - state[t.topic_id] = { | 62 | + tt = s.query(StudentTopic).filter(StudentTopic.student_id == uid) |
| 63 | + state = {t.topic_id: | ||
| 64 | + { | ||
| 69 | 'level': t.level, | 65 | 'level': t.level, |
| 70 | - 'date': datetime.strptime(t.date, "%Y-%m-%d %H:%M:%S.%f"), | 66 | + 'date': datetime.strptime(t.date, "%Y-%m-%d %H:%M:%S.%f") |
| 67 | + } for t in tt} | ||
| 68 | + | ||
| 69 | + self.online[uid] = { | ||
| 70 | + 'number': student.id, | ||
| 71 | + 'name': student.name, | ||
| 72 | + 'state': StudentKnowledge(self.deps, state=state) | ||
| 71 | } | 73 | } |
| 74 | + logger.info(f'User "{uid}" logged in successfully') | ||
| 75 | + return True | ||
| 72 | 76 | ||
| 73 | - self.online[uid] = { | ||
| 74 | - 'number': student.id, | ||
| 75 | - 'name': student.name, | ||
| 76 | - 'state': StudentKnowledge(self.deps, state=state) | ||
| 77 | - } | ||
| 78 | - return True | 77 | + else: |
| 78 | + logger.info(f'User "{uid}" wrong password!') | ||
| 79 | + return False | ||
| 79 | 80 | ||
| 80 | # ------------------------------------------------------------------------ | 81 | # ------------------------------------------------------------------------ |
| 81 | # logout | 82 | # logout |
| @@ -297,7 +298,7 @@ def build_dependency_graph(config={}): | @@ -297,7 +298,7 @@ def build_dependency_graph(config={}): | ||
| 297 | # if questions not in configuration then load all, preserving order | 298 | # if questions not in configuration then load all, preserving order |
| 298 | if not tnode['questions']: | 299 | if not tnode['questions']: |
| 299 | tnode['questions'] = [q['ref'] for q in loaded_questions] | 300 | tnode['questions'] = [q['ref'] for q in loaded_questions] |
| 300 | - | 301 | + |
| 301 | # make questions factory (without repeating same question) | 302 | # make questions factory (without repeating same question) |
| 302 | tnode['factory'] = {} | 303 | tnode['factory'] = {} |
| 303 | for q in loaded_questions: | 304 | for q in loaded_questions: |
static/css/learn.css
| @@ -1,91 +0,0 @@ | @@ -1,91 +0,0 @@ | ||
| 1 | -body { | ||
| 2 | - margin: 0; | ||
| 3 | - padding-top: 100px; | ||
| 4 | -} | ||
| 5 | - | ||
| 6 | -img { | ||
| 7 | - display: block; | ||
| 8 | - margin: auto; | ||
| 9 | - width: 80%; | ||
| 10 | -} | ||
| 11 | - | ||
| 12 | -/* progress bars have height of 4 pixels */ | ||
| 13 | -.progress { | ||
| 14 | - height: 8px; | ||
| 15 | - border-radius: 0px; | ||
| 16 | -} | ||
| 17 | - | ||
| 18 | -/* make markdown tables beautiful */ | ||
| 19 | -table { | ||
| 20 | - border-collapse: collapse; | ||
| 21 | - margin-left: 50px; | ||
| 22 | -} | ||
| 23 | -thead, tbody, td, th { | ||
| 24 | - padding: 5px; | ||
| 25 | - border-bottom: 1px solid #ddd; | ||
| 26 | -} | ||
| 27 | - | ||
| 28 | -textarea { | ||
| 29 | - font-family: monospace !important; | ||
| 30 | -} | ||
| 31 | - | ||
| 32 | -/* Hack to avoid name clash between pygments and mathjax */ | ||
| 33 | -.MathJax .mo, | ||
| 34 | -.MathJax .mi { | ||
| 35 | - color: inherit; | ||
| 36 | -} | ||
| 37 | - | ||
| 38 | -/* ======================================================================== */ | ||
| 39 | -body,html,.row-offcanvas { | ||
| 40 | - height:100%; | ||
| 41 | -} | ||
| 42 | - | ||
| 43 | - | ||
| 44 | -#sidebar { | ||
| 45 | - width: inherit; | ||
| 46 | - min-width: 220px; | ||
| 47 | - max-width: 220px; | ||
| 48 | - background-color:#f5f5f5; | ||
| 49 | - float: left; | ||
| 50 | - height:100%; | ||
| 51 | - position:relative; | ||
| 52 | - overflow-y:auto; | ||
| 53 | - overflow-x:hidden; | ||
| 54 | -} | ||
| 55 | -#main { | ||
| 56 | - padding-top: 10px; | ||
| 57 | - height:100%; | ||
| 58 | - overflow:auto; | ||
| 59 | -} | ||
| 60 | -#body { | ||
| 61 | - padding-bottom: 50px; | ||
| 62 | -} | ||
| 63 | - | ||
| 64 | -/* https://medium.com/wdstack/bootstrap-sidebar-examples-e363021395ff#.ek5vc75p8 | ||
| 65 | - * off Canvas sidebar | ||
| 66 | - * -------------------------------------------------- | ||
| 67 | - */ | ||
| 68 | -@media screen and (max-width: 768px) { | ||
| 69 | - .row-offcanvas { | ||
| 70 | - position: relative; | ||
| 71 | - -webkit-transition: all 0.25s ease-out; | ||
| 72 | - -moz-transition: all 0.25s ease-out; | ||
| 73 | - transition: all 0.25s ease-out; | ||
| 74 | - width:calc(100% + 220px); | ||
| 75 | - } | ||
| 76 | - | ||
| 77 | - .row-offcanvas-left | ||
| 78 | - { | ||
| 79 | - left: -220px; | ||
| 80 | - } | ||
| 81 | - | ||
| 82 | - .row-offcanvas-left.active { | ||
| 83 | - left: 0; | ||
| 84 | - } | ||
| 85 | - | ||
| 86 | - .sidebar-offcanvas { | ||
| 87 | - position: absolute; | ||
| 88 | - top: 0; | ||
| 89 | - } | ||
| 90 | -} | ||
| 91 | - |
static/css/maintopics.css
static/css/topic.css
| 1 | .progress { | 1 | .progress { |
| 2 | - height: 20px; | 2 | + /*position: fixed;*/ |
| 3 | + top: 0; | ||
| 4 | + height: 90px; | ||
| 3 | border-radius: 0px; | 5 | border-radius: 0px; |
| 4 | } | 6 | } |
| 5 | body { | 7 | body { |
| 6 | margin: 0; | 8 | margin: 0; |
| 7 | - padding-top: 70px; | ||
| 8 | - margin-bottom: 80px; /* Margin bottom by footer height */ | 9 | + padding-top: 0px; |
| 10 | + margin-bottom: 60px; /* Margin bottom by footer height */ | ||
| 9 | } | 11 | } |
| 12 | + | ||
| 10 | .footer { | 13 | .footer { |
| 11 | position: absolute; | 14 | position: absolute; |
| 12 | bottom: 0; | 15 | bottom: 0; |
| 13 | width: 100%; | 16 | width: 100%; |
| 14 | - /* Set the fixed height of the footer here */ | ||
| 15 | - height: 60px; | ||
| 16 | - line-height: 60px; /* Vertically center the text there */ | 17 | + height: 40px; |
| 18 | + line-height: 60px; | ||
| 17 | background-color: #f5f5f5; | 19 | background-color: #f5f5f5; |
| 18 | } | 20 | } |
| 21 | + | ||
| 19 | html { | 22 | html { |
| 20 | position: relative; | 23 | position: relative; |
| 21 | min-height: 100%; | 24 | min-height: 100%; |