Fixes #14session-cookie
| @@ -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) | |||
| ); | |||
| @@ -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): | |||
| @@ -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 | |||
| @@ -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 | |||