Files
ad/molodetz/database/sessions.py
T

67 lines
1.9 KiB
Python

# retoor <retoor@molodetz.nl>
import secrets
from datetime import datetime, timedelta, timezone
from molodetz.database.core import db, generate_uid, now_iso
def create_session(user_uid, max_age_seconds):
token = secrets.token_hex(32)
expires = datetime.now(timezone.utc) + timedelta(seconds=max_age_seconds)
db["sessions"].insert(
{
"uid": generate_uid(),
"token": token,
"user_uid": user_uid,
"created_at": now_iso(),
"expires_at": expires.isoformat(),
"deleted_at": None,
"deleted_by": None,
}
)
return token
def get_session(token):
if not token or "sessions" not in db.tables:
return None
return db["sessions"].find_one(token=token, deleted_at=None)
def hard_delete_session(session_id):
db["sessions"].delete(id=session_id)
def end_session(token, actor):
if "sessions" not in db.tables:
return
row = db["sessions"].find_one(token=token, deleted_at=None)
if row:
db["sessions"].update({"id": row["id"], "deleted_at": now_iso(), "deleted_by": actor}, ["id"])
def prune_expired_sessions(dry_run=False):
if "sessions" not in db.tables:
return 0
stamp = now_iso()
rows = list(db.query("SELECT id FROM sessions WHERE expires_at < :stamp", stamp=stamp))
if not dry_run and rows:
with db:
db.query("DELETE FROM sessions WHERE expires_at < :stamp", stamp=stamp)
return len(rows)
def end_all_sessions_for(user_uid, actor):
if "sessions" not in db.tables:
return 0
stamp = now_iso()
with db:
db.query(
"UPDATE sessions SET deleted_at = :stamp, deleted_by = :actor "
"WHERE user_uid = :user_uid AND deleted_at IS NULL",
stamp=stamp,
actor=actor,
user_uid=user_uid,
)
return 1