mirror of
https://github.com/chatmail/relay.git
synced 2026-05-19 12:28:06 +00:00
delete inactive users works
This commit is contained in:
@@ -3,18 +3,22 @@ from pathlib import Path
|
|||||||
import iniconfig
|
import iniconfig
|
||||||
|
|
||||||
|
|
||||||
def read_config(inipath):
|
def read_config(inipath, mail_basedir=None):
|
||||||
cfg = iniconfig.IniConfig(inipath)
|
cfg = iniconfig.IniConfig(inipath)
|
||||||
return Config(inipath, params=cfg.sections["params"])
|
params = cfg.sections["params"]
|
||||||
|
if mail_basedir is None:
|
||||||
|
mail_basedir = Path(f"/home/vmail/mail/{params['mail_domain']}")
|
||||||
|
return Config(inipath, params=params, mail_basedir=mail_basedir)
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
def __init__(self, inipath, params):
|
def __init__(self, inipath, params, mail_basedir):
|
||||||
self._inipath = inipath
|
self._inipath = inipath
|
||||||
self.mail_domain = params["mail_domain"]
|
self.mail_domain = params["mail_domain"]
|
||||||
self.max_user_send_per_minute = int(params["max_user_send_per_minute"])
|
self.max_user_send_per_minute = int(params["max_user_send_per_minute"])
|
||||||
self.max_mailbox_size = params["max_mailbox_size"]
|
self.max_mailbox_size = params["max_mailbox_size"]
|
||||||
self.delete_mails_after = params["delete_mails_after"]
|
self.delete_mails_after = params["delete_mails_after"]
|
||||||
|
self.delete_inactive_users_after = int(params["delete_inactive_users_after"])
|
||||||
self.username_min_length = int(params["username_min_length"])
|
self.username_min_length = int(params["username_min_length"])
|
||||||
self.username_max_length = int(params["username_max_length"])
|
self.username_max_length = int(params["username_max_length"])
|
||||||
self.password_min_length = int(params["password_min_length"])
|
self.password_min_length = int(params["password_min_length"])
|
||||||
@@ -27,7 +31,7 @@ class Config:
|
|||||||
self.privacy_mail = params.get("privacy_mail")
|
self.privacy_mail = params.get("privacy_mail")
|
||||||
self.privacy_pdo = params.get("privacy_pdo")
|
self.privacy_pdo = params.get("privacy_pdo")
|
||||||
self.privacy_supervisor = params.get("privacy_supervisor")
|
self.privacy_supervisor = params.get("privacy_supervisor")
|
||||||
self.mail_basedir = Path(f"/home/vmail/mail/{self.mail_domain}")
|
self.mail_basedir = mail_basedir
|
||||||
|
|
||||||
def _getbytefile(self):
|
def _getbytefile(self):
|
||||||
return open(self._inipath, "rb")
|
return open(self._inipath, "rb")
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import time
|
|||||||
|
|
||||||
from .config import read_config
|
from .config import read_config
|
||||||
from .database import Database
|
from .database import Database
|
||||||
from .doveauth import get_stale_users
|
from .doveauth import iter_userdb_lastlogin_before
|
||||||
|
|
||||||
|
|
||||||
def remove_user(db, config, user):
|
def remove_user(db, config, user):
|
||||||
@@ -18,11 +18,14 @@ def remove_user(db, config, user):
|
|||||||
conn.execute("DELETE FROM users WHERE addr = ?", (user,))
|
conn.execute("DELETE FROM users WHERE addr = ?", (user,))
|
||||||
|
|
||||||
|
|
||||||
|
def delete_inactive_users(db, config):
|
||||||
|
cutoff_date = time.time() - config.delete_inactive_users_after * 86400
|
||||||
|
for user in iter_userdb_lastlogin_before(db, cutoff_date):
|
||||||
|
remove_user(db, config, user)
|
||||||
|
print(f"Deleted user: {user}")
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
db = Database(sys.argv[1])
|
db = Database(sys.argv[1])
|
||||||
config = read_config(sys.argv[2])
|
config = read_config(sys.argv[2])
|
||||||
cutoff_date = time.time() - config.delete_accounts_after * 86400
|
delete_inactive_users(db, config)
|
||||||
|
|
||||||
for user in get_stale_users(db, cutoff_date):
|
|
||||||
remove_user(db, config, user)
|
|
||||||
print(f"Deleted user: {user}")
|
|
||||||
@@ -8,18 +8,21 @@ mail_domain = {mail_domain}
|
|||||||
#
|
#
|
||||||
|
|
||||||
#
|
#
|
||||||
# Account Restrictions
|
# Restrictions on user addresses
|
||||||
#
|
#
|
||||||
|
|
||||||
# how many mails a user can send out per minute
|
# how many mails a user can send out per minute
|
||||||
max_user_send_per_minute = 60
|
max_user_send_per_minute = 60
|
||||||
|
|
||||||
# maximum mailbox size of a chatmail account
|
# maximum mailbox size of a chatmail address
|
||||||
max_mailbox_size = 100M
|
max_mailbox_size = 100M
|
||||||
|
|
||||||
# days after which mails are unconditionally deleted
|
# days after which mails are unconditionally deleted
|
||||||
delete_mails_after = 20
|
delete_mails_after = 20
|
||||||
|
|
||||||
|
# days after which users without a login are deleted (database and mails)
|
||||||
|
delete_inactive_users_after = 25
|
||||||
|
|
||||||
# minimum length a username must have
|
# minimum length a username must have
|
||||||
username_min_length = 9
|
username_min_length = 9
|
||||||
|
|
||||||
@@ -29,7 +32,7 @@ username_max_length = 9
|
|||||||
# minimum length a password must have
|
# minimum length a password must have
|
||||||
password_min_length = 9
|
password_min_length = 9
|
||||||
|
|
||||||
# list of chatmail accounts which can send outbound un-encrypted mail
|
# list of chatmail addresses which can send outbound un-encrypted mail
|
||||||
passthrough_senders =
|
passthrough_senders =
|
||||||
|
|
||||||
# list of e-mail recipients for which to accept outbound un-encrypted mails
|
# list of e-mail recipients for which to accept outbound un-encrypted mails
|
||||||
|
|||||||
@@ -17,7 +17,9 @@ def make_config(tmp_path):
|
|||||||
|
|
||||||
def make_conf(mail_domain):
|
def make_conf(mail_domain):
|
||||||
write_initial_config(inipath, mail_domain=mail_domain)
|
write_initial_config(inipath, mail_domain=mail_domain)
|
||||||
return read_config(inipath)
|
basedir = tmp_path.joinpath(f"vmail/{mail_domain}")
|
||||||
|
basedir.mkdir(parents=True, exist_ok=True)
|
||||||
|
return read_config(inipath, mail_basedir=basedir)
|
||||||
|
|
||||||
return make_conf
|
return make_conf
|
||||||
|
|
||||||
|
|||||||
34
chatmaild/src/chatmaild/tests/test_delete_inactive_users.py
Normal file
34
chatmaild/src/chatmaild/tests/test_delete_inactive_users.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
from time import time as now
|
||||||
|
|
||||||
|
from chatmaild.doveauth import lookup_passdb
|
||||||
|
from chatmaild.delete_inactive_users import delete_inactive_users
|
||||||
|
|
||||||
|
|
||||||
|
def test_remove_stale_users(db, example_config):
|
||||||
|
old = now() - (example_config.delete_inactive_users_after * 86400) - 1000
|
||||||
|
new = old + 1001
|
||||||
|
|
||||||
|
def create_user(addr, last_login):
|
||||||
|
lookup_passdb(db, example_config, addr, "q9mr3faue", last_login=last_login)
|
||||||
|
md = example_config.get_user_maildir(addr)
|
||||||
|
md.mkdir(parents=True)
|
||||||
|
md.joinpath("cur").mkdir()
|
||||||
|
md.joinpath("cur", "something").mkdir()
|
||||||
|
|
||||||
|
for i in range(10):
|
||||||
|
create_user(f"oldold{i:03}@chat.example.org", last_login=old)
|
||||||
|
|
||||||
|
remain = []
|
||||||
|
for i in range(5):
|
||||||
|
create_user(f"newnew{i:03}@chat.example.org", last_login=new)
|
||||||
|
|
||||||
|
udir = example_config.get_user_maildir("oldold001@chat.example.org")
|
||||||
|
assert udir.exists()
|
||||||
|
|
||||||
|
delete_inactive_users(db, example_config)
|
||||||
|
|
||||||
|
for p in udir.parent.iterdir():
|
||||||
|
assert not p.name.startswith("old")
|
||||||
|
|
||||||
|
for addr in remain:
|
||||||
|
assert example_config.get_user_maildir(addr).exists()
|
||||||
Reference in New Issue
Block a user