Files
pyramid/docs/matrix-sdk/13-server-admin-continuwuity.md
T
Bernd Steckmeister 25ed765a03 wip: Sicherungs-Commit aller Änderungen seit April + Arbeitsstruktur (CLAUDE.md, ROADMAP.md, PROGRESS.md, Autopilot)
6 Wochen uncommittete Arbeit (Voice-Channels, LiveKit-Manager, Settings-Modal u.v.m.)
als ein WIP-Commit gesichert, damit nichts verloren geht und der Pi den aktuellen
Stand klonen kann. Thematische Aufarbeitung: siehe ROADMAP M0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPrAGBxBT6GfPXzeWQ4AXb
2026-07-03 05:47:18 +02:00

15 KiB

13 — Server-Administration: Continuwuity

Gilt für: Continuwuity 0.5.x (Fork von Conduwuit, welches ein Fork von Conduit ist)
Homeserver: steggi-matrix.work
WICHTIG: Continuwuity hat KEINE Synapse Admin API (/_synapse/admin/ existiert nicht!)


Inhaltsverzeichnis


Server-Admin vs. Room Power Level

Continuwuity Server-Admin
├── Ermöglicht: Admin-Room-Befehle, Server-API
├── Ermöglicht: User deaktivieren, Räume löschen (Server-Level)
└── NICHT: Automatisch PL 100 in jedem Matrix-Raum!

Matrix Room Power Level 100
├── Gilt pro Raum (in m.room.power_levels State-Event gespeichert)
├── Ermöglicht: Name/Topic/Avatar setzen, Join-Rules ändern, User kicken/bannen
└── Unabhängig vom Server-Admin-Status

Beispiel-Problem:

  • Du bist Server-Admin auf steggi-matrix.work
  • Du hast PL 100 im Space !xyz:steggi-matrix.work
  • Du erstellst einen neuen Channel → Server gibt dir PL 100 als Ersteller
  • Du versuchst join_rules: restricted zu setzen → M_FORBIDDEN
    • Grund: Continuwuity 0.5.x unterstützt MSC3083 möglicherweise nicht vollständig

Admin Room — Befehle

Continuwuity hat einen speziellen Admin-Raum. Als Server-Admin kannst du dort Befehle eingeben:

# Admin-Raum beitreten (normalerweise automatisch eingeladen)
# Raum-Alias: #admins:steggi-matrix.work

# Befehle im Admin-Raum (als Nachricht senden):

!admin help                              # Alle Befehle anzeigen

!admin make_user_admin @user:server      # User zu Server-Admin machen
!admin deactivate_user @user:server      # User deaktivieren
!admin list_users                        # Alle User auflisten

!admin get_room_state !roomId:server     # Room-State anzeigen
!admin delete_room !roomId:server        # Raum löschen

!admin get_mem_usage                     # Server-Speicherverbrauch
!admin server_version                    # Server-Version
# Als curl (Admin-Token erforderlich):
# Admin-Room-ID herausfinden:
curl -s "https://steggi-matrix.work/_matrix/client/v3/directory/room/%23admins%3Asteggi-matrix.work" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"
# → {"room_id": "!adminRoomId:steggi-matrix.work", ...}

Continuwuity Admin HTTP API

# Basis-URL: https://steggi-matrix.work/_conduwuit/admin/v1/
# (Nicht /_synapse/admin/ — das ist Synapse-only!)

# User zu Server-Admin machen
curl -X POST "https://steggi-matrix.work/_conduwuit/admin/v1/make_user_admin" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "@todesneutron:steggi-matrix.work"}'

# Server-Status abfragen
curl "https://steggi-matrix.work/_conduwuit/server/version" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"

# Alternativ — Standard Matrix-Whoami (prüft ob Token gültig):
curl "https://steggi-matrix.work/_matrix/client/v3/account/whoami" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"
# → {"user_id": "@todesneutron:steggi-matrix.work", "is_guest": false}

# Prüfen ob User Server-Admin ist (Conduwuit-spezifisch):
curl "https://steggi-matrix.work/_conduwuit/admin/v1/users/@todesneutron:steggi-matrix.work" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"

Power Level in Räumen erzwingen (als Server-Admin)

Als Server-Admin kannst du via Matrix Client API Power Levels in jedem Raum setzen, auch wenn du kein Mitglied bist (Continuwuity erlaubt das für Server-Admins):

# Schritt 1: Aktuelles Power-Level-Event lesen
ROOM_ID="!raumId:steggi-matrix.work"
TOKEN="J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"
SERVER="https://steggi-matrix.work"

curl "${SERVER}/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.power_levels/" \
  -H "Authorization: Bearer ${TOKEN}"

# Schritt 2: Power Level setzen (users-Map ändern)
curl -X PUT "${SERVER}/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.power_levels/" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "users": {
      "@todesneutron:steggi-matrix.work": 100
    },
    "users_default": 0,
    "events_default": 0,
    "state_default": 50,
    "ban": 50,
    "kick": 50,
    "invite": 0,
    "redact": 50
  }'
// In Flutter / Dart (mit Admin-Token):
// Zuerst aktuellen PL-State lesen:
final currentPl = await client.getRoomStateWithKey(
  roomId,
  EventTypes.RoomPowerLevels,
  '',
);

// Users-Map erweitern und zurückschreiben:
final users = Map<String, dynamic>.from(
  (currentPl['users'] as Map?)?.cast<String, dynamic>() ?? {},
);
users['@todesneutron:steggi-matrix.work'] = 100;

await client.setRoomStateWithKey(
  roomId,
  EventTypes.RoomPowerLevels,
  '',
  {
    ...currentPl,
    'users': users,
  },
);

MSC3083: Restricted Join Rules auf Continuwuity

join_rules: restricted (MSC3083) erlaubt Räumen, nur Space-Mitglieder beizutreten. Continuwuity 0.5.x unterstützt MSC3083 möglicherweise nicht vollständig.

# Testen ob restricted join rules funktionieren:
ROOM_ID="!testRaum:steggi-matrix.work"
TOKEN="J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"
SPACE_ID="!spaceId:steggi-matrix.work"

curl -X PUT "https://steggi-matrix.work/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.join_rules/" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "join_rule": "restricted",
    "allow": [
      {
        "type": "m.room_membership",
        "room_id": "'"${SPACE_ID}"'"
      }
    ]
  }'
# → 200 OK: Unterstützt!
# → M_FORBIDDEN oder M_UNRECOGNIZED: Nicht unterstützt oder PL zu niedrig

Workaround wenn restricted nicht funktioniert:

# Fallback: invite-only (explizit jeden User einladen)
curl -X PUT "https://steggi-matrix.work/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.join_rules/" \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"join_rule": "invite"}'
// In space_admin_dialog.dart — Fallback wenn restricted nicht supported:
try {
  await room.setJoinRules(
    JoinRules.restricted,
    allow: [
      SpaceRoomJoinRulesAllowInner(
        roomId: spaceId,
        type: SpaceRoomJoinRulesAllowInnerType.mRoomMembership,
      ),
    ],
  );
} on MatrixException catch (e) {
  if (e.error == MatrixError.M_FORBIDDEN || e.error == MatrixError.M_UNKNOWN) {
    // Continuwuity unterstützt restricted join rules nicht
    // Fallback zu invite-only:
    await room.setJoinRules(JoinRules.invite);
  } else {
    rethrow;
  }
}

Diagnose: Warum M_FORBIDDEN?

# 1. Prüfen: Welchen Power Level hat mein User in diesem Raum?
ROOM_ID="!raumId:steggi-matrix.work"
TOKEN="J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"

curl "https://steggi-matrix.work/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.power_levels/" \
  -H "Authorization: Bearer ${TOKEN}"
# Antwort zeigt 'users' Map — prüfen ob '@todesneutron:steggi-matrix.work' drin ist

# 2. Prüfen: Was ist state_default?
# Im Antwort-JSON: "state_default": 50 bedeutet: PL 50 nötig für State-Events
# "m.room.join_rules": 100 in events-Map = PL 100 für Join-Rule-Änderung

# 3. Prüfen: Bin ich Mitglied des Raums?
curl "https://steggi-matrix.work/_matrix/client/v3/rooms/${ROOM_ID}/state/m.room.member/%40todesneutron%3Asteggi-matrix.work/" \
  -H "Authorization: Bearer ${TOKEN}"
# → {"membership": "join"} = Mitglied ✅
# → {"errcode": "M_NOT_FOUND"} = Nicht Mitglied ❌ (Server-Admin kann trotzdem State setzen)

# 4. Prüfen: Unterstützt der Server restricted join rules?
curl "https://steggi-matrix.work/_matrix/client/v3/capabilities" \
  -H "Authorization: Bearer ${TOKEN}"
# Antwort: capabilities-Objekt — MSC3083 ist nicht explizit gelistet (kein Standard-Capability)

Häufige Ursachen und Lösungen:

Fehler Ursache Lösung
M_FORBIDDEN beim State-Event PL zu niedrig im Raum Power Level via curl erhöhen (s.o.)
M_FORBIDDEN bei join_rules: restricted MSC3083 nicht unterstützt Fallback zu invite nutzen
M_FORBIDDEN beim Channel erstellen Bug in space_admin_dialog.dart Raum manuell erstellen, dann Space-Child setzen
M_NOT_FOUND Raum nicht bekannt Raum beitreten oder Admin-Join
M_FORBIDDEN bei Power-Level-Änderung PL darf nur gleich/höher gesetzt werden Als Ersteller oder via Admin-API

User-Admin-Status prüfen/setzen

# Prüfen ob User Server-Admin ist:
curl "https://steggi-matrix.work/_matrix/client/v3/account/whoami" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"

# Auf Pi (SSH): User-Datenbank direkt abfragen (Conduwuit/Continuwuity nutzt RocksDB)
# Alternativ: Über Admin-Room-Befehl
# (Im Admin-Room als Nachricht senden:)
# !admin make_user_admin @todesneutron:steggi-matrix.work

# Über HTTP (Conduwuit Admin-Endpoint):
curl -X POST "https://steggi-matrix.work/_conduwuit/admin/v1/make_user_admin" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "@todesneutron:steggi-matrix.work"}'

Raum-Administration via Matrix API

Da kein Synapse-Admin-API existiert, nutze die Standard-Matrix-Client-API mit Admin-Token:

# Raum beitreten (als Admin, auch wenn invite-only):
curl -X POST "https://steggi-matrix.work/_matrix/client/v3/join/!roomId%3Asteggi-matrix.work" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \
  -H "Content-Type: application/json" \
  -d '{}'

# User in Raum einladen:
curl -X POST "https://steggi-matrix.work/_matrix/client/v3/rooms/!roomId%3Asteggi-matrix.work/invite" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \
  -H "Content-Type: application/json" \
  -d '{"user_id": "@user:steggi-matrix.work"}'

# Space-Child-Relation setzen (Channel einem Space hinzufügen):
curl -X PUT "https://steggi-matrix.work/_matrix/client/v3/rooms/!spaceId%3Asteggi-matrix.work/state/m.space.child/!channelId%3Asteggi-matrix.work/" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \
  -H "Content-Type: application/json" \
  -d '{
    "via": ["steggi-matrix.work"],
    "suggested": false
  }'

# Space-Parent-Relation setzen (im Channel-Raum):
curl -X PUT "https://steggi-matrix.work/_matrix/client/v3/rooms/!channelId%3Asteggi-matrix.work/state/m.space.parent/!spaceId%3Asteggi-matrix.work/" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \
  -H "Content-Type: application/json" \
  -d '{
    "via": ["steggi-matrix.work"],
    "canonical": true
  }'

# Alle Mitglieder eines Raums auflisten:
curl "https://steggi-matrix.work/_matrix/client/v3/rooms/!roomId%3Asteggi-matrix.work/members" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"

# Raum verlassen (als User, nicht löschen):
curl -X POST "https://steggi-matrix.work/_matrix/client/v3/rooms/!roomId%3Asteggi-matrix.work/leave" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI" \
  -H "Content-Type: application/json" \
  -d '{}'

Wichtige Unterschiede: Continuwuity vs. Synapse

Feature Synapse Continuwuity 0.5.x
Admin API URL /_synapse/admin/v1/ /_conduwuit/admin/v1/
Admin Room Optional Standard
MSC3083 (restricted join rules) Vollständig ⚠️ Teilweise / experimentell
Spaces (MSC1772) Grundfunktionen
MatrixRTC / MSC3401 (Element Call) ⚠️ Eingeschränkt
Push-Gateway
Server-side search Grundfunktionen
E2EE / Cross-Signing
Presence
Account Deactivation Admin API Admin Room / API
Room Deletion/Purge Admin API Admin Room / API
User Listing Admin API Admin Room / API
Federation
Application Services ⚠️ Eingeschränkt

Continuwuity homeserver.yaml — relevante Einstellungen

# /etc/continuwuity/homeserver.yaml (oder /etc/conduwuit/conduwuit.toml je nach Version)

# Matrix-RTC / LiveKit
# MSC3266: Room Summary
# MSC3401: MatrixRTC
allow_unstable_room_versions: true

# Federation (für Multi-Server-Calls nötig)
allow_federation: true
allow_public_room_directory_without_auth: false

# Push (für Notifications)
# Kein spezieller Config — nutzt Standard-Matrix-Push-API

# TURN-Server für WebRTC
turn_uris:
  - "turn:steggi-matrix.work:3478?transport=udp"
  - "turn:steggi-matrix.work:3478?transport=tcp"
turn_secret: "dein-turn-secret"
turn_username: ""  # leer = HMAC-basiert
turn_password: ""
turn_ttl: 86400

# Registrierung
allow_registration: false  # Kein offener Signup
registration_token: "dein-token"  # Oder token-basiert

# Log-Level
log: "warn,conduwuit=info"

# Performance
rocksdb_parallelism_threads: 4  # Pi 5 hat 4 Cores

# Unter Continuwuity: Admin-User beim ersten Start setzen
# Erster registrierter User wird automatisch Server-Admin
# Auf dem Pi: Config-Datei editieren
ssh steggi@192.168.178.71
sudo nano /etc/continuwuity/homeserver.yaml
# oder:
sudo nano /etc/conduwuit/conduwuit.toml  # Falls TOML-Format

# Service neu starten:
sudo systemctl restart continuwuity
# oder:
sudo systemctl restart conduwuit

# Logs prüfen:
sudo journalctl -u continuwuity -f

Schnell-Diagnose Checkliste

Wenn du M_FORBIDDEN bekommst:

# 1. Token gültig?
curl "https://steggi-matrix.work/_matrix/client/v3/account/whoami" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"

# 2. PL im betroffenen Raum prüfen:
curl "https://steggi-matrix.work/_matrix/client/v3/rooms/!ROOM_ID/state/m.room.power_levels/" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"

# 3. Mitglied des Raums?
curl "https://steggi-matrix.work/_matrix/client/v3/rooms/!ROOM_ID/state/m.room.member/%40todesneutron%3Asteggi-matrix.work/" \
  -H "Authorization: Bearer J5laxTz5Zte9oRB5x8QsyYRQ6b0hAuXI"

# 4. Was genau schlägt fehl? (Antwort-Body lesen!)
# M_FORBIDDEN + "Power level too low" → PL erhöhen
# M_FORBIDDEN + "Not a member" → Raum beitreten
# M_UNRECOGNIZED → Feature nicht unterstützt
# M_FORBIDDEN + "..." → join_rules restricted Problem