implement session timeout

This commit is contained in:
Jakob Ketterl 2021-05-03 23:07:27 +02:00
parent 041e8930bf
commit fe1a1207e6
3 changed files with 38 additions and 9 deletions

View File

@ -10,6 +10,7 @@ class Controller(object):
self.handler = handler self.handler = handler
self.request = request self.request = request
self.options = options self.options = options
self.responseCookies = None
def send_response( def send_response(
self, content, code=200, content_type="text/html", last_modified: datetime = None, max_age=None, headers=None 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) headers["Cache-Control"] = "max-age={0}".format(max_age)
for key, value in headers.items(): for key, value in headers.items():
self.handler.send_header(key, value) 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() self.handler.end_headers()
if type(content) == str: if type(content) == str:
content = content.encode() content = content.encode()
self.handler.wfile.write(content) 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) self.handler.send_response(code)
if cookies is not None: if self.responseCookies is not None:
self.handler.send_header("Set-Cookie", cookies.output(header="")) self.handler.send_header("Set-Cookie", self.responseCookies.output(header=""))
self.handler.send_header("Location", location) self.handler.send_header("Location", location)
self.handler.end_headers() self.handler.end_headers()
def set_response_cookies(self, cookies):
self.responseCookies = cookies
def get_body(self, max_size=None): def get_body(self, max_size=None):
if "Content-Length" not in self.handler.headers: if "Content-Length" not in self.handler.headers:
return None return None

View File

@ -11,16 +11,21 @@ class Authentication(object):
def getUser(self, request): def getUser(self, request):
if "owrx-session" not in request.cookies: if "owrx-session" not in request.cookies:
return None 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: if session is None:
return None return None
if "user" not in session: if "user" not in session:
return None return None
userList = UserList.getSharedInstance() userList = UserList.getSharedInstance()
user = None
try: try:
return userList[session["user"]] user = userList[session["user"]]
storage.prolongSession(session_id)
except KeyError: except KeyError:
return None pass
return user
class AuthorizationMixin(object): class AuthorizationMixin(object):

View File

@ -3,10 +3,16 @@ from urllib.parse import parse_qs, urlencode
from uuid import uuid4 from uuid import uuid4
from http.cookies import SimpleCookie from http.cookies import SimpleCookie
from owrx.users import UserList from owrx.users import UserList
from datetime import datetime, timedelta
import logging
logger = logging.getLogger(__name__)
class SessionStorage(object): class SessionStorage(object):
sharedInstance = None sharedInstance = None
sessionLifetime = timedelta(hours=6)
@staticmethod @staticmethod
def getSharedInstance(): def getSharedInstance():
@ -28,10 +34,21 @@ class SessionStorage(object):
def getSession(self, key): def getSession(self, key):
if key not in self.sessions: if key not in self.sessions:
return None 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): 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): class SessionController(WebpageController):
@ -52,7 +69,8 @@ class SessionController(WebpageController):
target = self.request.query["ref"][0] if "ref" in self.request.query else "/settings" target = self.request.query["ref"][0] if "ref" in self.request.query else "/settings"
if user.must_change_password: if user.must_change_password:
target = "/pwchange?{0}".format(urlencode({"ref": target})) target = "/pwchange?{0}".format(urlencode({"ref": target}))
self.send_redirect(target, cookies=cookie) self.set_response_cookies(cookie)
self.send_redirect(target)
return return
target = "?{}".format(urlencode({"ref": self.request.query["ref"][0]})) if "ref" in self.request.query else "" target = "?{}".format(urlencode({"ref": self.request.query["ref"][0]})) if "ref" in self.request.query else ""
self.send_redirect(self.request.path + target) self.send_redirect(self.request.path + target)