import web from views.forms import login_form import models.user from views.utils import get_nav_bar import os, hmac, base64, pickle import hashlib # Get html templates render = web.template.render('templates/') class Login(): # Get the server secret to perform signatures secret = web.config.get('session_parameters')['secret_key'] def GET(self): """ Show the login page :return: The login page showing other users if logged in """ session = web.ctx.session nav = get_nav_bar(session) # Log the user in if the rememberme cookie is set and valid self.check_rememberme() return render.login(nav, login_form, "") def POST(self): """ Log in to the web application and register the session :return: The login page showing other users if logged in """ session = web.ctx.session nav = get_nav_bar(session) data = web.input(username="", password="", remember=False) # Validate login credential with database query password_hash = hashlib.md5(b'TDT4237' + data.password.encode('utf-8')).hexdigest() user = models.user.match_user(data.username, password_hash) # If there is a matching user/password in the database the user is logged in if user: self.login(user[1], user[0], data.remember) raise web.seeother("/") else: return render.login(nav, login_form, "- User authentication failed") def login(self, username, userid, remember): """ Log in to the application """ session = web.ctx.session session.username = username session.userid = userid if remember: rememberme = self.rememberme() web.setcookie('remember', rememberme , 300000000) def check_rememberme(self): """ Validate the rememberme cookie and log in """ username = "" sign = "" # If the user selected 'remember me' they log in automatically try: # Fetch the users cookies if it exists cookies = web.cookies() # Fetch the remember cookie and convert from string to bytes remember_hash = bytes(cookies.remember[2:][:-1], 'ascii') # Decode the hash decode = base64.b64decode(remember_hash) # Load the decoded hash to receive the host signature and the username username, sign = pickle.loads(decode) except AttributeError as e: # The user did not have the stored remember me cookie pass # If the users signed cookie matches the host signature then log in if self.sign_username(username) == sign: userid = models.user.get_user_id_by_name(username) self.login(username, userid, False) def rememberme(self): """ Encode a base64 object consisting of the username signed with the host secret key and the username. Can be reassembled with the hosts secret key to validate user. :return: base64 object consisting of signed username and username """ session = web.ctx.session creds = [ session.username, self.sign_username(session.username) ] return base64.b64encode(pickle.dumps(creds)) @classmethod def sign_username(self, username): """ Sign the current users name with the hosts secret key :return: The users signed name """ secret = base64.b64decode(self.secret) return hmac.HMAC(secret, username.encode('ascii')).hexdigest()