smal: add e2ee setup tool
This commit is contained in:
parent
5c29242109
commit
0136565ed8
5 changed files with 132 additions and 8 deletions
|
|
@ -41,6 +41,7 @@ mxlogout = "pymxutils.mxutils:logout"
|
||||||
mxclearaccount = "pymxutils.mxutils:clearaccount"
|
mxclearaccount = "pymxutils.mxutils:clearaccount"
|
||||||
mxserverinfo = "pymxutils.mxutils:serverinfo"
|
mxserverinfo = "pymxutils.mxutils:serverinfo"
|
||||||
mxpassitem = "pymxutils.mxutils:passitem"
|
mxpassitem = "pymxutils.mxutils:passitem"
|
||||||
smalsetup = "mxsmal.smalsetup:smalsetup"
|
smalsetup = "mxsmal.smalsetup.smalsetup:smalsetup"
|
||||||
|
e2eesetup = "mxsmal.smalsetup.e2eesetup:e2eesetup"
|
||||||
demobot = "demobot:main"
|
demobot = "demobot:main"
|
||||||
simplebot = "demobot.simple:main"
|
simplebot = "demobot.simple:main"
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
from .smalsetup import smalsetup
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# Copyright (C) 2026 saces@c-base.org
|
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
|
||||||
import sys
|
|
||||||
from .smalsetup import smalsetup
|
|
||||||
|
|
||||||
sys.exit(smalsetup())
|
|
||||||
36
mxsmal/src/mxsmal/smalsetup/e2eebot.py
Normal file
36
mxsmal/src/mxsmal/smalsetup/e2eebot.py
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Copyright (C) 2026 saces@c-base.org
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
import logging
|
||||||
|
from mxsmal.bot import SMALBot
|
||||||
|
from pygomx.apiv0 import ApiV0Api
|
||||||
|
|
||||||
|
# setup logging, we want timestamps
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format="%(asctime)s.%(msecs)03d %(levelname)s %(name)s - %(funcName)s: %(message)s",
|
||||||
|
datefmt="%Y-%m-%d %H:%M:%S",
|
||||||
|
)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
logger.setLevel(level=logging.INFO)
|
||||||
|
|
||||||
|
|
||||||
|
# TODO this should be an App, not a Bot
|
||||||
|
class E2eeBot(SMALBot):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("¿")
|
||||||
|
|
||||||
|
async def on_startup(self):
|
||||||
|
print("e2eeBot started.")
|
||||||
|
res = ApiV0Api.self_sign(self.client_id)
|
||||||
|
print(res)
|
||||||
|
print("e2eeBot done?.")
|
||||||
|
|
||||||
|
async def on_sys(self, ntf):
|
||||||
|
print("Got a system notification: ", ntf)
|
||||||
|
|
||||||
|
async def on_event(self, evt):
|
||||||
|
print("Got an event: ", evt)
|
||||||
|
|
||||||
|
async def on_message(self, msg):
|
||||||
|
print("Got a mesage: ", msg)
|
||||||
94
mxsmal/src/mxsmal/smalsetup/e2eesetup.py
Normal file
94
mxsmal/src/mxsmal/smalsetup/e2eesetup.py
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
# Copyright (C) 2026 saces@c-base.org
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
from datetime import datetime
|
||||||
|
import getpass
|
||||||
|
import os
|
||||||
|
import json
|
||||||
|
from functools import partial, wraps
|
||||||
|
|
||||||
|
import click
|
||||||
|
from pygomx.errors import PygomxAPIError
|
||||||
|
|
||||||
|
from pygomx.apiv0 import ApiV0
|
||||||
|
from pygomx.cliv0 import CliV0
|
||||||
|
|
||||||
|
from .e2eebot import E2eeBot
|
||||||
|
|
||||||
|
|
||||||
|
def catch_exception(func=None, *, handle):
|
||||||
|
if not func:
|
||||||
|
return partial(catch_exception, handle=handle)
|
||||||
|
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
except handle as e:
|
||||||
|
raise click.ClickException(e)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@click.option(
|
||||||
|
"--mxpass",
|
||||||
|
"mxpassfile",
|
||||||
|
metavar="filepath",
|
||||||
|
default=".mxpass",
|
||||||
|
help="mxpass file name",
|
||||||
|
)
|
||||||
|
@catch_exception(handle=(PygomxAPIError))
|
||||||
|
def e2eesetup(mxpassfile):
|
||||||
|
"""Utility for smalbot e2ee setup"""
|
||||||
|
|
||||||
|
cli = CliV0.from_mxpass(mxpassfile, "*", "*", "*")
|
||||||
|
|
||||||
|
# we need to know who we are and the device id needs to be known too
|
||||||
|
whoami = cli.Whoami()
|
||||||
|
|
||||||
|
# check for other devices
|
||||||
|
devices = cli.Generic("GET", ["_matrix", "client", "v3", "devices"])
|
||||||
|
|
||||||
|
if len(devices["devices"]) > 1:
|
||||||
|
click.echo(f"Other devices found for '{whoami['user_id']}'")
|
||||||
|
click.echo(f"This device: {whoami['device_id']}")
|
||||||
|
click.echo("Other devices:")
|
||||||
|
other_devices_list = []
|
||||||
|
for device in devices["devices"]:
|
||||||
|
# print(device)
|
||||||
|
if device["device_id"] != whoami["device_id"]:
|
||||||
|
other_devices_list.append(device["device_id"])
|
||||||
|
click.echo(
|
||||||
|
f" {device['device_id']} ({device['display_name']}) - {datetime.fromtimestamp(device['last_seen_ts']/1000)} from {device['last_seen_ip']}"
|
||||||
|
)
|
||||||
|
click.echo()
|
||||||
|
if click.confirm("Do you want to log them out?"):
|
||||||
|
|
||||||
|
cli.Generic(
|
||||||
|
"POST",
|
||||||
|
["_matrix", "client", "v3", "delete_devices"],
|
||||||
|
{
|
||||||
|
"devices": other_devices_list,
|
||||||
|
"auth": {
|
||||||
|
"type": "m.login.password",
|
||||||
|
"password": getpass.getpass(prompt="Password: "),
|
||||||
|
"identifier": {
|
||||||
|
"type": "m.id.user",
|
||||||
|
"user": whoami["user_id"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
click.echo("Well done!")
|
||||||
|
# TODO maybe check for master key and reset it too.
|
||||||
|
|
||||||
|
# TODO the config thingy comes here, for now a lot of stuff is hard coded to make it work
|
||||||
|
|
||||||
|
# Start the bot to setup e2ee, the real bot will not be startd
|
||||||
|
|
||||||
|
e2eeBot = E2eeBot()
|
||||||
|
|
||||||
|
e2eeBot.run(sync=False)
|
||||||
|
|
||||||
|
print("Huhu Bämm!")
|
||||||
Loading…
Add table
Add a link
Reference in a new issue