diff --git a/owrx/controllers/__init__.py b/owrx/controllers/__init__.py index f0ad9a7..791b7b1 100644 --- a/owrx/controllers/__init__.py +++ b/owrx/controllers/__init__.py @@ -10,6 +10,7 @@ class Controller(object): self.handler = handler self.request = request self.options = options + self.responseCookies = None def send_response( self, content, code=200, content_type="text/html", last_modified: datetime = None, max_age=None, headers=None @@ -25,18 +26,23 @@ class Controller(object): headers["Cache-Control"] = "max-age={0}".format(max_age) for key, value in headers.items(): self.handler.send_header(key, value) + if self.responseCookies is not None: + self.handler.send_header("Set-Cookie", self.responseCookies.output(header="")) self.handler.end_headers() if type(content) == str: content = content.encode() self.handler.wfile.write(content) - def send_redirect(self, location, code=303, cookies=None): + def send_redirect(self, location, code=303): self.handler.send_response(code) - if cookies is not None: - self.handler.send_header("Set-Cookie", cookies.output(header="")) + if self.responseCookies is not None: + self.handler.send_header("Set-Cookie", self.responseCookies.output(header="")) self.handler.send_header("Location", location) self.handler.end_headers() + def set_response_cookies(self, cookies): + self.responseCookies = cookies + def get_body(self, max_size=None): if "Content-Length" not in self.handler.headers: return None diff --git a/owrx/controllers/admin.py b/owrx/controllers/admin.py index f232adf..8777164 100644 --- a/owrx/controllers/admin.py +++ b/owrx/controllers/admin.py @@ -11,16 +11,21 @@ class Authentication(object): def getUser(self, request): if "owrx-session" not in request.cookies: return None - session = SessionStorage.getSharedInstance().getSession(request.cookies["owrx-session"].value) + session_id = request.cookies["owrx-session"].value + storage = SessionStorage.getSharedInstance() + session = storage.getSession(session_id) if session is None: return None if "user" not in session: return None userList = UserList.getSharedInstance() + user = None try: - return userList[session["user"]] + user = userList[session["user"]] + storage.prolongSession(session_id) except KeyError: - return None + pass + return user class AuthorizationMixin(object): diff --git a/owrx/controllers/session.py b/owrx/controllers/session.py index 44f1e14..a140683 100644 --- a/owrx/controllers/session.py +++ b/owrx/controllers/session.py @@ -3,10 +3,16 @@ 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(): @@ -28,10 +34,21 @@ class SessionStorage(object): def getSession(self, key): if key not in self.sessions: return None - return self.sessions[key] + expires, data = self.sessions[key] + if expires < datetime.utcnow(): + del self.sessions[key] + return None + return data def updateSession(self, key, data): - self.sessions[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): @@ -52,7 +69,8 @@ class SessionController(WebpageController): 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.send_redirect(target, cookies=cookie) + 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)