85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
import glob
|
|
import os
|
|
import shutil
|
|
import sqlite3
|
|
import tempfile
|
|
import time
|
|
|
|
FIREFOX_COOKIE_PATHS = [
|
|
"~/.mozilla/firefox/*/cookies.sqlite",
|
|
"~/snap/firefox/common/.mozilla/firefox/*/cookies.sqlite",
|
|
"~/.var/app/org.mozilla.firefox/.mozilla/firefox/*/cookies.sqlite",
|
|
"~/.var/app/org.mozilla.firefox/config/mozilla/firefox/*/cookies.sqlite",
|
|
]
|
|
|
|
NO_COOKIE_MSG = (
|
|
"Bitte in Firefox bei tralgo.app einloggen und "
|
|
"'Für 30 Tage merken' aktivieren."
|
|
)
|
|
EXPIRED_MSG = (
|
|
"Deine tralgo.app Sitzung ist abgelaufen. "
|
|
"Bitte erneut in Firefox einloggen und 'Für 30 Tage merken' aktivieren."
|
|
)
|
|
|
|
|
|
def find_cookies():
|
|
"""Return (dict of cookie name→value, error_str).
|
|
On success error_str is None; on failure dict is None."""
|
|
all_dbs = []
|
|
for pattern in FIREFOX_COOKIE_PATHS:
|
|
all_dbs.extend(glob.glob(os.path.expanduser(pattern)))
|
|
|
|
if not all_dbs:
|
|
return None, NO_COOKIE_MSG
|
|
|
|
best_expiry = -1
|
|
best_cookies = None
|
|
|
|
for db_path in all_dbs:
|
|
tmp = None
|
|
try:
|
|
tmp = tempfile.mktemp(suffix="_tralgo_cookies.sqlite")
|
|
shutil.copy2(db_path, tmp)
|
|
cookies = _read_tralgo_cookies(tmp)
|
|
if not cookies:
|
|
continue
|
|
max_expiry = max(v["expiry"] for v in cookies.values())
|
|
if max_expiry > best_expiry:
|
|
best_expiry = max_expiry
|
|
best_cookies = cookies
|
|
except Exception:
|
|
pass
|
|
finally:
|
|
if tmp and os.path.exists(tmp):
|
|
try:
|
|
os.unlink(tmp)
|
|
except OSError:
|
|
pass
|
|
|
|
if best_cookies is None:
|
|
return None, NO_COOKIE_MSG
|
|
|
|
now = int(time.time())
|
|
if best_expiry < now:
|
|
return None, EXPIRED_MSG
|
|
|
|
return {name: data["value"] for name, data in best_cookies.items()}, None
|
|
|
|
|
|
def _read_tralgo_cookies(db_path):
|
|
conn = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True)
|
|
try:
|
|
cur = conn.cursor()
|
|
cur.execute(
|
|
"SELECT name, value, expiry FROM moz_cookies "
|
|
"WHERE host LIKE '%tralgo.app%' "
|
|
"AND (name LIKE 'wordpress_logged_in%' OR name LIKE 'wp2fa_device%')"
|
|
)
|
|
rows = cur.fetchall()
|
|
finally:
|
|
conn.close()
|
|
|
|
if not rows:
|
|
return {}
|
|
return {row[0]: {"value": row[1], "expiry": row[2]} for row in rows}
|