Start implementing sessions

This commit is contained in:
Juhani Krekelä 2018-06-10 15:33:21 +03:00
parent fb9b6ba258
commit c9f8bfe1b8
3 changed files with 43 additions and 3 deletions

View File

@ -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,))

View File

@ -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)

39
session.py Normal file
View File

@ -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