diff --git a/mysql/sql/init.sql b/mysql/sql/init.sql index 21936a5..165cbe6 100644 --- a/mysql/sql/init.sql +++ b/mysql/sql/init.sql @@ -17,6 +17,7 @@ CREATE TABLE users ( CREATE TABLE cookies ( token VARCHAR(100) UNIQUE NOT NULL, userid INT UNSIGNED NOT NULL, + expiry INT NOT NULL, PRIMARY KEY (token), FOREIGN KEY (userid) REFERENCES users(userid) ); diff --git a/src/app/models/session.py b/src/app/models/session.py index 12345a9..eb65e25 100644 --- a/src/app/models/session.py +++ b/src/app/models/session.py @@ -2,7 +2,7 @@ from models.database import db import mysql.connector -def set_cookie(userid, token): +def set_cookie(userid, token, expiry): """ Register a persistant login token for an user :param userid: The ID of the user @@ -10,10 +10,10 @@ def set_cookie(userid, token): """ db.connect() cursor = db.cursor() - query = ("INSERT INTO cookies (userid, token) VALUES (%s, %s)") + query = ("INSERT INTO cookies (userid, token, expiry) VALUES (%s, %s, %s)") try: - cursor.execute(query, (userid, token)) + cursor.execute(query, (userid, token, expiry)) db.commit() except mysql.connector.Error as err: print("Failed executing query: {}".format(err)) @@ -31,14 +31,16 @@ def get_cookie(token): """ db.connect() cursor = db.cursor() - query = ("SELECT userid FROM cookies WHERE token = %s") + query = ("SELECT userid, expiry FROM cookies WHERE token = %s") userid = None + expiry = None try: cursor.execute(query, (token,)) users = cursor.fetchall() if len(users): userid = users[0][0] + expiry = users[0][1] except mysql.connector.Error as err: print("Failed executing query: {}".format(err)) cursor.fetchall() @@ -47,7 +49,7 @@ def get_cookie(token): cursor.close() db.close() - return userid + return userid, expiry def delete_cookie(token): diff --git a/src/app/views/login.py b/src/app/views/login.py index 15fb410..6866d37 100644 --- a/src/app/views/login.py +++ b/src/app/views/login.py @@ -6,10 +6,14 @@ from views.utils import get_nav_bar import random import string import hashlib +import time # Get html templates render = web.template.render('templates/') +# The remember cookie should be valid for a week +remember_timeout = 3600*24*7 + class Login(): @@ -58,8 +62,8 @@ class Login(): session.username = username session.userid = userid if remember: - rememberme = self.rememberme() - web.setcookie('remember', rememberme , 300000000) + rememberme = self.rememberme(remember_timeout) + web.setcookie('remember', rememberme , remember_timeout) def check_rememberme(self): """ @@ -72,17 +76,17 @@ class Login(): cookies = web.cookies() # Fetch the remember cookie and convert from string to bytes remember_token = cookies.remember - userid = models.session.get_cookie(remember_token) - except AttributeError as e: + userid, expiry = models.session.get_cookie(remember_token) + except AttributeError: # The user did not have the stored remember me cookie pass # If the users signed cookie matches the host signature then log in - if userid is not None: + if userid is not None and expiry > time.time(): username = models.user.get_user_name_by_id(userid) self.login(username, userid, False) - def rememberme(self): + def rememberme(self, timeout): """ Generate a random token for the user, and store it in the database. """ @@ -91,8 +95,8 @@ class Login(): while True: token = ''.join(random.SystemRandom().choice(alphabet) for _ in range(20)) - if models.session.get_cookie(token) is None: + if models.session.get_cookie(token)[0] is None: break - models.session.set_cookie(session.userid, token) + models.session.set_cookie(session.userid, token, int(time.time() + timeout)) return token diff --git a/src/app/views/logout.py b/src/app/views/logout.py index 839a1c4..56fafc3 100644 --- a/src/app/views/logout.py +++ b/src/app/views/logout.py @@ -13,8 +13,12 @@ class Logout: Log out of the application (kill session and reset variables) :return: Redirect to main page """ - remember_token = web.cookies().remember - models.session.delete_cookie(remember_token) + try: + remember_token = web.cookies().remember + models.session.delete_cookie(remember_token) + except AttributeError: + # The user did not have the stored remember me cookie + pass session = web.ctx.session session.username = None