implement session timeout
This commit is contained in:
		| @@ -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 | ||||||
|   | |||||||
| @@ -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): | ||||||
|   | |||||||
| @@ -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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Jakob Ketterl
					Jakob Ketterl