From c9f8bfe1b841a52117880a1225ecb814afa712a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Sun, 10 Jun 2018 15:33:21 +0300 Subject: [PATCH] Start implementing sessions --- database.py | 2 +- server.py | 5 +++-- session.py | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 session.py diff --git a/database.py b/database.py index 66aab05..60de1a1 100644 --- a/database.py +++ b/database.py @@ -71,7 +71,7 @@ def add_user(db, *, username, password, email, parent, status): # Generate a user ID while True: # SQLite uses 64 bit signed ints, so generate at max 2⁶³-1 - userid = csprng.randrange(2**63) + userid = csprng.randrange(2 << 63) # Check that the user ID is unique cursor.execute('SELECT id FROM users WHERE id = ?;', (userid,)) diff --git a/server.py b/server.py index 2e5ef70..1ef8295 100644 --- a/server.py +++ b/server.py @@ -5,6 +5,7 @@ import urllib.parse import config import database import generate_html +import session class HTTPRequestHandler(http.server.BaseHTTPRequestHandler): server_version = 'Buranun/0.0' @@ -26,7 +27,7 @@ class HTTPRequestHandler(http.server.BaseHTTPRequestHandler): self.send_header('Content-Type', 'text/plain; charset=utf-8') self.send_header('Content-Length', length) - # TODO: Make this more sensical + # TODO: Make the max-age more sensical sent_cookies = http.cookies.SimpleCookie() sent_cookies['buranun_session'] = buranun_session sent_cookies['buranun_session']['path'] = config.url_prefix if config.url_prefix != '' else '/' @@ -80,7 +81,7 @@ class HTTPRequestHandler(http.server.BaseHTTPRequestHandler): password_correct = database.check_password(db, userid, password) if password_correct: - self.__redirect(buranun_session = 'dihutenosa') + self.__redirect(buranun_session = session.new_session(userid)) else: # TODO: Have it forward the user back to the page where they were at html = generate_html.login(self.path, retrying = True) diff --git a/session.py b/session.py new file mode 100644 index 0000000..99421b2 --- /dev/null +++ b/session.py @@ -0,0 +1,39 @@ +import random +import threading + +csprng = random.SystemRandom() + +sessions_lock = threading.Lock() +max_sessions = 1024 +sessions = {} + +def new_session(userid): + """Creates a new session and returns its ID""" + with sessions_lock: + while True: + sessionid = csprng.randrange(2 << 256) + + # Check that the ID is unique + if sessionid not in sessions: + break + + # Do we have too many sessions? + # TODO: Implement the limit per-user + if len(sessions) >= max_sessions: + # Yes, drop a random one + # TODO: Have some LRU thing here + delete_id = random.choice(list(sessions.keys())) + del sessions[delete_id] + + sessions[sessionid] = userid + + return sessionid + +def get_userid(sessionid): + """Returns the user associated with session ID + Returns None if no user was found""" + with sessions_lock: + if sessionid in sessions: + return sessions[sessiondid] + + return None