summaryrefslogtreecommitdiff
path: root/src/jwebmail
diff options
context:
space:
mode:
Diffstat (limited to 'src/jwebmail')
-rw-r--r--src/jwebmail/__init__.py2
-rw-r--r--src/jwebmail/read_mails.py75
2 files changed, 68 insertions, 9 deletions
diff --git a/src/jwebmail/__init__.py b/src/jwebmail/__init__.py
index 875bcb5..442590b 100644
--- a/src/jwebmail/__init__.py
+++ b/src/jwebmail/__init__.py
@@ -36,7 +36,7 @@ else:
toml_read_file = dict(load=toml_load, text=True)
-__version__ = "2.3.0.dev4"
+__version__ = "2.4.0.dev0"
csrf = CSRFProtect()
diff --git a/src/jwebmail/read_mails.py b/src/jwebmail/read_mails.py
index 404a242..05c6e10 100644
--- a/src/jwebmail/read_mails.py
+++ b/src/jwebmail/read_mails.py
@@ -35,6 +35,9 @@ class RedisTimeoutSession:
def get(self, key):
return self.conn.getex(f"jwm:user:{key}", self.timeout)
+ def close(self):
+ self.conn.close()
+
class MysqlTimeoutSession:
def __init__(self, username, passwd, timeout, database="jwebmaildb1", port=3306):
@@ -76,14 +79,72 @@ class MysqlTimeoutSession:
self.conn.commit()
return row[0]
+ def close(self):
+ self.conn.close()
+
+
+class SqliteTimeoutSession:
+ def __init__(self, _username, _passwd, timeout, database):
+ import sqlite3
+
+ self.timeout = timeout
+
+ self.conn = sqlite3.connect(database, autocommit=False)
+ cur = self.conn.cursor()
+ cur.execute(
+ "CREATE TABLE IF NOT EXISTS session (user text PRIMARY KEY, password text, timeout real NOT NULL) STRICT"
+ )
+ cur.execute("CREATE INDEX IF NOT EXISTS timeout_idx ON session (timeout)")
+
+ def set(self, key, value):
+ timeout = datetime.now() + timedelta(seconds=self.timeout)
+
+ with closing(self.conn.cursor()) as cur:
+ cur.execute(
+ "REPLACE INTO session VALUES (?, ?, unixepoch(?, 'subsec'))",
+ [key, value, timeout],
+ )
+ self.conn.commit()
+
+ def get(self, key):
+ with closing(self.conn.cursor()) as cur:
+ cur.execute("DELETE FROM session WHERE timeout < unixepoch('subsec')")
+ cur.execute("SELECT password FROM session WHERE user = ?", [key])
+ row = cur.fetchone()
+
+ if row is None:
+ self.conn.commit()
+ return None
+ else:
+ timeout = datetime.now() + timedelta(seconds=self.timeout)
+ cur.execute(
+ "UPDATE session SET timeout = unixepoch(?, 'subsec') WHERE user = ?",
+ [timeout, key],
+ )
+ self.conn.commit()
+ return row[0]
+
+ def close(self):
+ self.conn.close()
+
def select_timeout_session():
session_type = current_app.config["JWEBMAIL"]["READ_MAILS"]["SESSION_TYPE"]
+ user = "jwebmail"
+ passwd = current_app.config["JWEBMAIL"]["READ_MAILS"]["SESSION_STORE_PASSWD"]
+ args = dict()
+ db_name = current_app.config["JWEBMAIL"]["READ_MAILS"].get("SESSION_STORE_DB_NAME")
+ if db_name:
+ args["database"] = db_name
+
if session_type == "REDIS":
- return RedisTimeoutSession
+ return RedisTimeoutSession(user, passwd, EXPIRATION_SEC)
elif session_type == "MYSQL":
- return MysqlTimeoutSession
+ return MysqlTimeoutSession(user, passwd, EXPIRATION_SEC, **args)
+ elif session_type == "SQLITE":
+ args.setdefault("database", "/var/local/lib/jwebmail/jwebmail.sqlite3")
+ return SqliteTimeoutSession(user, passwd, EXPIRATION_SEC, **args)
else:
raise ValueError(f"unknown session_type {session_type!r}")
@@ -104,17 +165,15 @@ def login(username, password):
def add_user(user: JWebmailUser):
- passwd = current_app.config["JWEBMAIL"]["READ_MAILS"]["SESSION_STORE_PASSWD"]
-
- r = select_timeout_session()("jwebmail", passwd, EXPIRATION_SEC)
+ r = select_timeout_session()
r.set(user.get_id(), user.password)
+ r.close()
def load_user(username: str) -> JWebmailUser:
- ss_password = current_app.config["JWEBMAIL"]["READ_MAILS"]["SESSION_STORE_PASSWD"]
-
- r = select_timeout_session()("jwebmail", ss_password, EXPIRATION_SEC)
+ r = select_timeout_session()
passwd = r.get(username)
+ r.close()
if passwd is None:
return None
return JWebmailUser(username, passwd)