from owrx.controllers.template import WebpageController from urllib.parse import parse_qs, urlencode from uuid import uuid4 from http.cookies import SimpleCookie from owrx.users import UserList from datetime import datetime, timedelta import logging logger = logging.getLogger(__name__) class SessionStorage(object): sharedInstance = None sessionLifetime = timedelta(hours=6) @staticmethod def getSharedInstance(): if SessionStorage.sharedInstance is None: SessionStorage.sharedInstance = SessionStorage() return SessionStorage.sharedInstance def __init__(self): self.sessions = {} def generateKey(self): return str(uuid4()) def startSession(self, data): key = self.generateKey() self.updateSession(key, data) return key def getSession(self, key): if key not in self.sessions: return None expires, data = self.sessions[key] if expires < datetime.utcnow(): del self.sessions[key] return None return data def updateSession(self, key, data): expires = datetime.utcnow() + SessionStorage.sessionLifetime self.sessions[key] = expires, data def prolongSession(self, key): data = self.getSession(key) if data is None: raise KeyError("Invalid session key") self.updateSession(key, data) class SessionController(WebpageController): def loginAction(self): self.serve_template("login.html", **self.template_variables()) def processLoginAction(self): data = parse_qs(self.get_body().decode("utf-8")) data = {k: v[0] for k, v in data.items()} userlist = UserList.getSharedInstance() if "user" in data and "password" in data: if data["user"] in userlist: user = userlist[data["user"]] if user.is_enabled() and user.password.is_valid(data["password"]): key = SessionStorage.getSharedInstance().startSession({"user": user.name}) cookie = SimpleCookie() cookie["owrx-session"] = key target = self.request.query["ref"][0] if "ref" in self.request.query else "/settings" if user.must_change_password: target = "/pwchange?{0}".format(urlencode({"ref": target})) self.set_response_cookies(cookie) self.send_redirect(target) return target = "?{}".format(urlencode({"ref": self.request.query["ref"][0]})) if "ref" in self.request.query else "" self.send_redirect(self.request.path + target) def logoutAction(self): self.send_redirect("logout happening here")