Add Starface Chat-Loesch-Script mit README
This commit is contained in:
@@ -0,0 +1,86 @@
|
|||||||
|
# Starface Chat löschen
|
||||||
|
|
||||||
|
Kleines Bash-Script, das den kompletten UCC-Chatverlauf eines einzelnen
|
||||||
|
Starface-Users aus der internen Openfire-Chat-DB löscht. Nötig, weil Starface
|
||||||
|
in der App/Admin-UI selbst keine Möglichkeit bietet, den Chatverlauf eines
|
||||||
|
Users zu löschen — z.B. wenn ein Mitarbeiter das Unternehmen verlässt.
|
||||||
|
|
||||||
|
## Hintergrund
|
||||||
|
|
||||||
|
Starface nutzt für den UCC-Chat einen eingebetteten **Openfire-XMPP-Server**,
|
||||||
|
der dieselbe Postgres-Datenbank (`asterisk`) wie die restliche PBX verwendet.
|
||||||
|
Relevant sind zwei Tabellen (Openfire Monitoring-Plugin):
|
||||||
|
|
||||||
|
- `ofmessagearchive` — die eigentlichen Chat-Nachrichten (`fromjid`, `tojid`, `body`, `sentdate`, ...)
|
||||||
|
- `ofconversation` — Konversations-Header (Zeitraum, Nachrichtenanzahl je `conversationid`)
|
||||||
|
|
||||||
|
Es gibt **keine offizielle API** dafür — die Löschung passiert direkt per SQL
|
||||||
|
auf dem Starface-Server.
|
||||||
|
|
||||||
|
## Voraussetzungen
|
||||||
|
|
||||||
|
- SSH-Zugriff auf den Starface-Server (root oder ein User mit `sudo -u postgres`-Rechten)
|
||||||
|
- `psql` muss installiert sein (bei Starface Standard)
|
||||||
|
- Script liegt/läuft direkt **auf** dem Starface-Server (nicht remote per SQL-Tunnel)
|
||||||
|
|
||||||
|
## Nutzung
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./delete_starface_chat.sh <user_id>
|
||||||
|
```
|
||||||
|
|
||||||
|
Beispiel — Mitarbeiter mit der Starface-Benutzer-ID `0022` verlässt das Unternehmen:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./delete_starface_chat.sh 0022
|
||||||
|
```
|
||||||
|
|
||||||
|
`<user_id>` ist die Starface-Benutzernummer/-ID wie sie intern als JID genutzt
|
||||||
|
wird (JID-Format `<user_id>@<starface-host>`) — einfach die Nummer/den
|
||||||
|
Login-Namen des Users angeben.
|
||||||
|
|
||||||
|
## Was das Script macht
|
||||||
|
|
||||||
|
1. Sucht alle Nachrichten in `ofmessagearchive`, bei denen der angegebene
|
||||||
|
User Absender **oder** Empfänger ist (`fromjid`/`tojid LIKE '<user_id>@%'`).
|
||||||
|
2. **Erstellt zuerst ein Backup** — CSV-Dump aller betroffenen Nachrichten und
|
||||||
|
Konversationen nach `/var/backups/starface_chat_backups/`, bevor irgendwas
|
||||||
|
gelöscht wird.
|
||||||
|
3. Löscht die betroffenen Zeilen aus `ofmessagearchive`.
|
||||||
|
4. Löscht die zugehörigen `ofconversation`-Einträge — aber **nur**, wenn nach
|
||||||
|
dem Löschen wirklich keine Nachricht mehr auf diese `conversationid`
|
||||||
|
verweist (Konversations-Header bleibt sonst stehen).
|
||||||
|
5. Gibt am Ende die verbleibende Nachrichtenanzahl für den User aus (sollte `0` sein).
|
||||||
|
|
||||||
|
Alles läuft in **einer Transaktion** (`BEGIN` / `COMMIT`) — entweder alles
|
||||||
|
oder nichts.
|
||||||
|
|
||||||
|
## Wichtige Einschränkung: gemeinsame Konversation
|
||||||
|
|
||||||
|
Openfire speichert eine Konversation zwischen zwei Usern als **eine
|
||||||
|
gemeinsame** Nachrichten-Historie — es gibt **keine getrennten Kopien** pro
|
||||||
|
Teilnehmer (kein "Postfach pro User").
|
||||||
|
|
||||||
|
Das heißt konkret: Löscht man z.B. User `0022`, der einen Chat mit User `0005`
|
||||||
|
hatte, verschwindet dieser Chat **für beide Seiten** — nicht nur bei `0022`.
|
||||||
|
Andere Chats von `0005` mit anderen Kollegen (ohne `0022`) bleiben davon
|
||||||
|
unberührt.
|
||||||
|
|
||||||
|
Es gibt technisch keinen Weg, "nur die Hälfte" eines Chats zu löschen, ohne
|
||||||
|
die Nachrichten zu duplizieren oder zu anonymisieren (Body/Name ersetzen statt
|
||||||
|
Zeile zu löschen) — das macht dieses Script bewusst nicht, da vollständige
|
||||||
|
Löschung (z.B. aus DSGVO-Gründen beim Austritt eines Mitarbeiters) hier das
|
||||||
|
Ziel war.
|
||||||
|
|
||||||
|
## Sicherheit
|
||||||
|
|
||||||
|
- Backup **vor** jeder Löschung, automatisch, ungefragt.
|
||||||
|
- Input-Validierung: `user_id` darf nur `A-Za-z0-9._-` enthalten (keine SQL-Injection über das Argument).
|
||||||
|
- `set -euo pipefail` — Script bricht bei jedem Fehler sofort ab.
|
||||||
|
- Bei `0` gefundenen Nachrichten: Script beendet sich ohne jede Aktion.
|
||||||
|
|
||||||
|
## Wiederherstellung aus dem Backup
|
||||||
|
|
||||||
|
Die CSV-Backups liegen unter `/var/backups/starface_chat_backups/` und lassen
|
||||||
|
sich bei Bedarf mit `\copy ... FROM ... WITH CSV HEADER` wieder in die
|
||||||
|
jeweilige Tabelle zurückspielen.
|
||||||
Executable
+98
@@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# delete_starface_chat.sh — loescht den kompletten Chat-Verlauf eines Starface-Users
|
||||||
|
# aus der Openfire-Chat-DB (Postgres, Datenbank "asterisk").
|
||||||
|
#
|
||||||
|
# Aufruf:
|
||||||
|
# ./delete_starface_chat.sh <user_id>
|
||||||
|
#
|
||||||
|
# <user_id> ist die Starface-Benutzer-ID wie sie im JID-Format verwendet wird,
|
||||||
|
# z.B. "0001" (JID dann 0001@<starface-ip>). Einfach die Nummer/den Login-Namen
|
||||||
|
# des Users angeben, wie er in Starface als Benutzer-ID gefuehrt wird.
|
||||||
|
#
|
||||||
|
# Was das Script macht:
|
||||||
|
# 1. Findet alle Konversationen (ofconversation) in denen der User als
|
||||||
|
# Absender oder Empfaenger vorkommt (fromjid/tojid LIKE '<user_id>@%').
|
||||||
|
# 2. Sichert ALLE betroffenen Zeilen aus ofmessagearchive + ofconversation
|
||||||
|
# als CSV-Backup nach /var/backups/starface_chat_backups/ BEVOR irgendwas
|
||||||
|
# geloescht wird.
|
||||||
|
# 3. Loescht die Nachrichten aus ofmessagearchive.
|
||||||
|
# 4. Loescht die zugehoerigen ofconversation-Eintraege, aber NUR wenn nach
|
||||||
|
# dem Loeschen keine Nachricht mehr auf diese conversationid verweist
|
||||||
|
# (falls doch noch andere Nutzer/Nachrichten dranhaengen, bleibt der
|
||||||
|
# Konversations-Header stehen, nur ohne die geloeschten Nachrichten).
|
||||||
|
#
|
||||||
|
# Muss LOKAL auf dem Starface-Server laufen (braucht sudo-Zugriff auf den
|
||||||
|
# postgres-User, psql muss installiert sein — ist bei Starface Standard).
|
||||||
|
#
|
||||||
|
# WICHTIG: Loescht die GEMEINSAME Konversation. Openfire speichert eine
|
||||||
|
# Konversation zwischen zwei Usern als EINE gemeinsame History (keine
|
||||||
|
# getrennten Kopien pro Teilnehmer). D.h. loescht man z.B. User 0022, dann
|
||||||
|
# verschwindet auch bei dessen Chatpartnern (z.B. 0005) genau dieser eine
|
||||||
|
# Chat mit 0022 — alle anderen Chats von 0005 mit anderen Usern bleiben
|
||||||
|
# unberuehrt. Das ist technisch bedingt und so gewollt (siehe README).
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
USER_ID="${1:-}"
|
||||||
|
|
||||||
|
if [[ -z "$USER_ID" ]]; then
|
||||||
|
echo "Usage: $0 <user_id>" >&2
|
||||||
|
echo "Beispiel: $0 0001" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Nur alphanumerisch + . _ - erlauben (keine SQL-Injection ueber das Argument)
|
||||||
|
if [[ ! "$USER_ID" =~ ^[A-Za-z0-9._-]+$ ]]; then
|
||||||
|
echo "Fehler: user_id enthaelt ungueltige Zeichen: '$USER_ID'" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
JID_PATTERN="${USER_ID}@%"
|
||||||
|
TS="$(date +%Y%m%d_%H%M%S)"
|
||||||
|
BACKUP_DIR="/var/backups/starface_chat_backups"
|
||||||
|
MSG_BACKUP="${BACKUP_DIR}/chat_backup_${USER_ID}_${TS}_messages.csv"
|
||||||
|
CONV_BACKUP="${BACKUP_DIR}/chat_backup_${USER_ID}_${TS}_conversations.csv"
|
||||||
|
|
||||||
|
mkdir -p "$BACKUP_DIR"
|
||||||
|
chmod 777 "$BACKUP_DIR" # postgres-OS-User braucht Schreibzugriff fuer \copy
|
||||||
|
|
||||||
|
PSQL="sudo -u postgres psql -d asterisk -v ON_ERROR_STOP=1"
|
||||||
|
|
||||||
|
echo "== Starface Chat-Loeschung fuer User '${USER_ID}' =="
|
||||||
|
|
||||||
|
MSG_COUNT=$($PSQL -t -A -c "SELECT count(*) FROM ofmessagearchive WHERE fromjid LIKE '${JID_PATTERN}' OR tojid LIKE '${JID_PATTERN}';")
|
||||||
|
echo "Gefundene Nachrichten: ${MSG_COUNT}"
|
||||||
|
|
||||||
|
if [[ "$MSG_COUNT" -eq 0 ]]; then
|
||||||
|
echo "Keine Nachrichten fuer diesen User gefunden — nichts zu tun."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Erstelle Backup..."
|
||||||
|
$PSQL -c "\copy (SELECT * FROM ofmessagearchive WHERE fromjid LIKE '${JID_PATTERN}' OR tojid LIKE '${JID_PATTERN}') TO '${MSG_BACKUP}' WITH CSV HEADER"
|
||||||
|
$PSQL -c "\copy (SELECT * FROM ofconversation WHERE conversationid IN (SELECT DISTINCT conversationid FROM ofmessagearchive WHERE fromjid LIKE '${JID_PATTERN}' OR tojid LIKE '${JID_PATTERN}')) TO '${CONV_BACKUP}' WITH CSV HEADER"
|
||||||
|
echo "Backup gespeichert:"
|
||||||
|
echo " ${MSG_BACKUP}"
|
||||||
|
echo " ${CONV_BACKUP}"
|
||||||
|
|
||||||
|
echo "Loesche Nachrichten + verwaiste Konversationen..."
|
||||||
|
$PSQL <<SQL
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TEMP TABLE affected_conv AS
|
||||||
|
SELECT DISTINCT conversationid FROM ofmessagearchive
|
||||||
|
WHERE fromjid LIKE '${JID_PATTERN}' OR tojid LIKE '${JID_PATTERN}';
|
||||||
|
|
||||||
|
DELETE FROM ofmessagearchive
|
||||||
|
WHERE fromjid LIKE '${JID_PATTERN}' OR tojid LIKE '${JID_PATTERN}';
|
||||||
|
|
||||||
|
-- Konversationen nur loeschen wenn wirklich keine Nachricht mehr uebrig ist
|
||||||
|
DELETE FROM ofconversation
|
||||||
|
WHERE conversationid IN (SELECT conversationid FROM affected_conv)
|
||||||
|
AND conversationid NOT IN (SELECT DISTINCT conversationid FROM ofmessagearchive);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
SQL
|
||||||
|
|
||||||
|
REMAINING=$($PSQL -t -A -c "SELECT count(*) FROM ofmessagearchive WHERE fromjid LIKE '${JID_PATTERN}' OR tojid LIKE '${JID_PATTERN}';")
|
||||||
|
echo "Fertig. Verbleibende Nachrichten fuer '${USER_ID}': ${REMAINING}"
|
||||||
Reference in New Issue
Block a user