Reduzieren des Power Levels von Puppet-Benutzern von Matrix-Bridges

  • 2 Min. Lesezeit
  • Tags: 
  • dev
  • matrix

Ich bin momentan Mitglied der AG Administration im Hackerspace Bremen. Wir betreiben für unsere Mitglieder:innen einen föderierten Matrix-Homeserver. Dieser Dienst ist noch relativ neu, und wir nutzen die mautrix-discord Bridge mit “double puppeting” um einige Räume eines legacy Discord-Servers nach Matrix zu bridgen, sodass User, die noch nicht auf Matrix umgestiegen sind weiterhin die Möglichkeit haben, an unseren Chats teilzunehmen. Die Bridge erzeugt für alle Discord-Benutzer im Matrix “Puppet-User” und leitet Nachrichten in beide Richtungen entsprechend weiter.

Versehentlich hatte ich einem dieser Puppet-User einen Power Level von 100 in einem der Matrix-Räume gegeben. In Matrix erreicht man eine Patt-Situation, sobald man mit einem anderen Benutzer auf demselben Power Level steht. Die Benutzer können sich die Berechtigung nicht mehr gegenseitig enziehen, nur noch sich selber und Benutzern mit niedrigerem Power Level.

Die Vergabe dieser Berechtigung an einen Puppet-User hat zwar keine unmittelbar negativen Folgen, der Zustand hat mich jedoch nicht glücklich gemacht und ich suchte nach Möglichkeiten, meinen Fehler rückgängig zu machen. Glücklicherweise war Tulir durch den Verweis auf das Matrix Application Service API im Support-Raum #discord:maunium.net sehr hilfreich. Mit dem Access Token der Bridge selber können im Namen aller Puppet-User Events verschickt werden.

Es ist natürlich möglich, von Hand eigene curl-Aufrufe zu konstruieren, ich habe aber etwas besser reproduzierbares mit mautrix-python (auch von Tulir) ausprobiert. Hier nun die Befehle, die am Ende zum Erfolg geführt haben.

Nach der Installation des Paketes eine asyncio Shell öffnen (python -m asyncio) und diese Befehle ausführen, um ein ClientAPI-Objekt zu erzeugen. Die Werte nach Bedarf anpassen:

>>> from mautrix.client import ClientAPI
>>> puppet_user = "@discord_...:hackerspace-bremen.de"
>>> base_url = "https://matrix.hackerspace-bremen.de"
>>> as_token = "..."  # Taken from the bridges registration.yaml
>>> client = ClientAPI(puppet_user, base_url=base_url, token=as_token, as_user_id=puppet_user)

Sicherstellen, dass der Client funktioniert. Zum Beispiel, indem man die aktuellen Räume des Users abfragt:

>>> await client.get_joined_rooms()
['!room_id_1:hackerspace-bremen.de', '!room_id_2:hackerspace-bremen.de', ...]

Wenn diese richtig aussehen, kann für einen Raum der Power Level des Benutzers geändert werden. Um die Power Level in einem Raum zu ändern muss ein komplettes m.room.power_levels-Event an den Raum geschickt werden. Am einfachsten ist es, das aktuelle Event des Raums zu nehmen und zu bearbeiten.

>>> room_id = "!room_id_1:hackerspace-bremen.de"
>>> states = await client.get_state(room_id)
>>> len(states)
22

Das aktuelle m.room.power_levels-Event finden:

>>> power_state = [s for s in states if s.type.t == "m.room.power_levels"][0]

Das Event bearbeiten und den Power Level des Puppet-Benutzers auf 0 setzen:

>>> power_state.content.users[puppet_user] = 0

Anschließend das Event zurück zum Server senden:

>>> from mautrix.types import EventType, EventContent
>>> await client.send_state_event(room_id, EventType.ROOM_POWER_LEVELS, power_state.content)
'$...'

Wenn alles geklappt hat, hat der Puppet-Benutzer nun wieder den Power Level 0.