mirror of
https://github.com/chatmail/relay.git
synced 2026-05-13 09:24:43 +00:00
Compare commits
28 Commits
greeterbot
...
rspamd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c9abfbde3 | ||
|
|
95de87a325 | ||
|
|
5366df8dc6 | ||
|
|
0a6db5161d | ||
|
|
62e25e44fd | ||
|
|
ce9fe920dc | ||
|
|
c171866faf | ||
|
|
7758c94e31 | ||
|
|
66debb9245 | ||
|
|
3542232393 | ||
|
|
536c12d989 | ||
|
|
265403e110 | ||
|
|
fd679af577 | ||
|
|
ecbf135549 | ||
|
|
7b90b936dd | ||
|
|
17a919ee53 | ||
|
|
1b15ec0eae | ||
|
|
bf863f05b6 | ||
|
|
a2316beab1 | ||
|
|
28fc91f5f3 | ||
|
|
67062677b0 | ||
|
|
faf8ffe678 | ||
|
|
5821098699 | ||
|
|
542d63888a | ||
|
|
449f8a014c | ||
|
|
57764d0cf5 | ||
|
|
c39a79e26a | ||
|
|
b6622fc68e |
@@ -10,10 +10,6 @@ dependencies = [
|
|||||||
"iniconfig",
|
"iniconfig",
|
||||||
"deltachat-rpc-server",
|
"deltachat-rpc-server",
|
||||||
"deltachat-rpc-client",
|
"deltachat-rpc-client",
|
||||||
"ConfigArgParse",
|
|
||||||
"deltachat",
|
|
||||||
"setuptools>=60",
|
|
||||||
"setuptools-scm>=8",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.setuptools]
|
[tool.setuptools]
|
||||||
@@ -26,7 +22,6 @@ where = ['src']
|
|||||||
doveauth = "chatmaild.doveauth:main"
|
doveauth = "chatmaild.doveauth:main"
|
||||||
filtermail = "chatmaild.filtermail:main"
|
filtermail = "chatmaild.filtermail:main"
|
||||||
echobot = "chatmaild.echo:main"
|
echobot = "chatmaild.echo:main"
|
||||||
greeterbot = "chatmaild.greeterbot:main"
|
|
||||||
chatmail-metrics = "chatmaild.metrics:main"
|
chatmail-metrics = "chatmaild.metrics:main"
|
||||||
|
|
||||||
[project.entry-points.pytest11]
|
[project.entry-points.pytest11]
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 35 KiB |
@@ -46,17 +46,11 @@ class Connection:
|
|||||||
)
|
)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_user_list(self) -> set[str]:
|
|
||||||
"""Get a set of all users."""
|
|
||||||
q = "SELECT addr from users"
|
|
||||||
return set([tup[0] for tup in self._sqlconn.execute(q).fetchall()])
|
|
||||||
|
|
||||||
|
|
||||||
class Database:
|
class Database:
|
||||||
def __init__(self, path: str, read_only=False):
|
def __init__(self, path: str):
|
||||||
self.path = Path(path)
|
self.path = Path(path)
|
||||||
if not read_only:
|
self.ensure_tables()
|
||||||
self.ensure_tables()
|
|
||||||
|
|
||||||
def _get_connection(
|
def _get_connection(
|
||||||
self, write=False, transaction=False, closing=False
|
self, write=False, transaction=False, closing=False
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ def is_allowed_to_create(config: Config, user, cleartext_password) -> bool:
|
|||||||
len(localpart) > config.username_max_length
|
len(localpart) > config.username_max_length
|
||||||
or len(localpart) < config.username_min_length
|
or len(localpart) < config.username_min_length
|
||||||
):
|
):
|
||||||
if localpart not in ("echo", "hello"):
|
if localpart != "echo":
|
||||||
logging.warning(
|
logging.warning(
|
||||||
"localpart %s has to be between %s and %s chars long",
|
"localpart %s has to be between %s and %s chars long",
|
||||||
localpart,
|
localpart,
|
||||||
|
|||||||
Binary file not shown.
@@ -1,132 +0,0 @@
|
|||||||
import time
|
|
||||||
|
|
||||||
import deltachat
|
|
||||||
from deltachat.tracker import ConfigureFailed
|
|
||||||
from time import sleep
|
|
||||||
import tempfile
|
|
||||||
import os
|
|
||||||
import configargparse
|
|
||||||
import pkg_resources
|
|
||||||
import secrets
|
|
||||||
|
|
||||||
from chatmaild.database import Database
|
|
||||||
from chatmaild.config import read_config
|
|
||||||
from chatmaild.newemail import ALPHANUMERIC_PUNCT, CONFIG_PATH
|
|
||||||
|
|
||||||
PASSDB_PATH = "/home/vmail/passdb.sqlite"
|
|
||||||
|
|
||||||
|
|
||||||
def setup_account(data_dir: str, debug: bool) -> deltachat.Account:
|
|
||||||
"""Create a deltachat account with a given addr/password combination.
|
|
||||||
|
|
||||||
:param data_dir: the directory where the data(base) is stored.
|
|
||||||
:param debug: whether to show log messages for the account.
|
|
||||||
:return: the deltachat account object.
|
|
||||||
"""
|
|
||||||
chatmail_config = read_config(CONFIG_PATH)
|
|
||||||
addr = "hello@" + chatmail_config.mail_domain
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.mkdir(os.path.join(data_dir, addr))
|
|
||||||
except FileExistsError:
|
|
||||||
pass
|
|
||||||
db_path = os.path.join(data_dir, addr, "db.sqlite")
|
|
||||||
|
|
||||||
ac = deltachat.Account(db_path)
|
|
||||||
if debug:
|
|
||||||
ac.add_account_plugin(deltachat.events.FFIEventLogger(ac))
|
|
||||||
|
|
||||||
ac.set_config("mvbox_move", "0")
|
|
||||||
ac.set_config("sentbox_watch", "0")
|
|
||||||
ac.set_config("bot", "1")
|
|
||||||
ac.set_config("mdns_enabled", "0")
|
|
||||||
|
|
||||||
if not ac.is_configured():
|
|
||||||
cleartext_password = "".join(
|
|
||||||
secrets.choice(ALPHANUMERIC_PUNCT)
|
|
||||||
for _ in range(chatmail_config.password_min_length + 3)
|
|
||||||
)
|
|
||||||
ac.set_config("mail_pw", cleartext_password)
|
|
||||||
ac.set_config("addr", addr)
|
|
||||||
|
|
||||||
configtracker = ac.configure()
|
|
||||||
try:
|
|
||||||
configtracker.wait_finish()
|
|
||||||
except ConfigureFailed:
|
|
||||||
print(
|
|
||||||
"configuration setup failed for %s with password:\n%s"
|
|
||||||
% (ac.get_config("addr"), ac.get_config("mail_pw"))
|
|
||||||
)
|
|
||||||
raise
|
|
||||||
|
|
||||||
ac.start_io()
|
|
||||||
avatar = pkg_resources.resource_filename(__name__, "avatar.jpg")
|
|
||||||
ac.set_avatar(avatar)
|
|
||||||
ac.set_config("displayname", f"Hello at {chatmail_config.mail_domain}!")
|
|
||||||
return ac
|
|
||||||
|
|
||||||
|
|
||||||
class GreetBot:
|
|
||||||
def __init__(self, passdb, account):
|
|
||||||
self.db = Database(passdb, read_only=True)
|
|
||||||
self.account = account
|
|
||||||
self.domain = account.get_config("addr").split("@")[1]
|
|
||||||
with self.db.read_connection() as conn:
|
|
||||||
self.existing_users = conn.get_user_list()
|
|
||||||
|
|
||||||
def greet_users(self):
|
|
||||||
with self.db.read_connection() as conn:
|
|
||||||
users = conn.get_user_list()
|
|
||||||
new_users = users.difference(self.existing_users)
|
|
||||||
self.existing_users = users
|
|
||||||
time.sleep(20) # wait until Delta is configured on the user side
|
|
||||||
for user in new_users:
|
|
||||||
for ci_prefix in ["ac1_", "ac2_", "ac3_", "ac4_", "ac5_", "ci-"]:
|
|
||||||
if user.startswith(ci_prefix):
|
|
||||||
continue
|
|
||||||
if user not in [c.addr for c in self.account.get_contacts()]:
|
|
||||||
print("Inviting", user)
|
|
||||||
contact = self.account.create_contact(user)
|
|
||||||
chat = contact.create_chat()
|
|
||||||
chat.send_text(
|
|
||||||
"Welcome to %s! Here you can try out Delta Chat." % (self.domain,)
|
|
||||||
)
|
|
||||||
chat.send_text(
|
|
||||||
"I prepared some webxdc apps for you, if you are interested:"
|
|
||||||
)
|
|
||||||
chat.send_file(pkg_resources.resource_filename(__name__, "editor.xdc"))
|
|
||||||
chat.send_file(
|
|
||||||
pkg_resources.resource_filename(__name__, "tower-builder.xdc")
|
|
||||||
)
|
|
||||||
chat.send_text(
|
|
||||||
"You can visit https://webxdc.org/apps to discover more apps! "
|
|
||||||
"Some of these games you can also play with friends, directly in the chat."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
args = configargparse.ArgumentParser()
|
|
||||||
args.add_argument("--db_path", help="location of the Delta Chat database")
|
|
||||||
args.add_argument(
|
|
||||||
"--passdb", default=PASSDB_PATH, help="location of the chatmail passdb"
|
|
||||||
)
|
|
||||||
args.add_argument("--show-ffi", action="store_true", help="print Delta Chat log")
|
|
||||||
ops = args.parse_args()
|
|
||||||
|
|
||||||
# ensuring account data directory
|
|
||||||
if ops.db_path is None:
|
|
||||||
tempdir = tempfile.TemporaryDirectory(prefix="hellobot")
|
|
||||||
ops.db_path = tempdir.name
|
|
||||||
elif not os.path.exists(ops.db_path):
|
|
||||||
os.mkdir(ops.db_path)
|
|
||||||
|
|
||||||
ac = setup_account(ops.db_path, ops.show_ffi)
|
|
||||||
greeter = GreetBot(ops.passdb, ac)
|
|
||||||
print("waiting for new chatmail users...")
|
|
||||||
while 1:
|
|
||||||
greeter.greet_users()
|
|
||||||
sleep(5)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
[Unit]
|
|
||||||
Description=Chatmail greeterbot, a Delta Chat bot to greet new users
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStart={execpath} --passdb {passdb_path} --db_path /home/vmail/greeterbot/ --show-ffi
|
|
||||||
User=vmail
|
|
||||||
Restart=always
|
|
||||||
RestartSec=30
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
Binary file not shown.
@@ -101,13 +101,11 @@ def _install_remote_venv_with_chatmaild(config) -> None:
|
|||||||
"doveauth",
|
"doveauth",
|
||||||
"filtermail",
|
"filtermail",
|
||||||
"echobot",
|
"echobot",
|
||||||
"greeterbot",
|
|
||||||
):
|
):
|
||||||
params = dict(
|
params = dict(
|
||||||
execpath=f"{remote_venv_dir}/bin/{fn}",
|
execpath=f"{remote_venv_dir}/bin/{fn}",
|
||||||
config_path=remote_chatmail_inipath,
|
config_path=remote_chatmail_inipath,
|
||||||
remote_venv_dir=remote_venv_dir,
|
remote_venv_dir=remote_venv_dir,
|
||||||
passdb_path="/home/vmail/passdb.sqlite",
|
|
||||||
)
|
)
|
||||||
source_path = importlib.resources.files("chatmaild").joinpath(f"{fn}.service.f")
|
source_path = importlib.resources.files("chatmaild").joinpath(f"{fn}.service.f")
|
||||||
content = source_path.read_text().format(**params).encode()
|
content = source_path.read_text().format(**params).encode()
|
||||||
|
|||||||
Reference in New Issue
Block a user