titan-iac/services/communication/guest-name-job.yaml

95 lines
4.2 KiB
YAML

# services/communication/guest-name-job.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
name: guest-name-randomizer
namespace: communication
spec:
schedule: "*/1 * * * *"
suspend: true
jobTemplate:
spec:
backoffLimit: 0
template:
spec:
restartPolicy: Never
containers:
- name: rename
image: python:3.11-slim
env:
- name: SYNAPSE_BASE
value: http://othrys-synapse-matrix-synapse:8008
- name: AUTH_BASE
value: http://matrix-authentication-service:8080
- name: SEEDER_USER
value: othrys-seeder
- name: SEEDER_PASS
valueFrom:
secretKeyRef:
name: atlasbot-credentials-runtime
key: seeder-password
command:
- /bin/sh
- -c
- |
set -euo pipefail
pip install --no-cache-dir requests >/dev/null
python - <<'PY'
import os, random, requests, urllib.parse
ADJ = ["brisk","calm","eager","gentle","merry","nifty","rapid","sunny","witty","zesty"]
NOUN = ["otter","falcon","comet","ember","grove","harbor","meadow","raven","river","summit"]
BASE = os.environ["SYNAPSE_BASE"]
AUTH_BASE = os.environ.get("AUTH_BASE", BASE)
OTHRYS = "!orejZnVfvbAmwQDYba:live.bstein.dev"
def login(user, password):
r = requests.post(f"{AUTH_BASE}/_matrix/client/v3/login", json={
"type": "m.login.password",
"identifier": {"type": "m.id.user", "user": user},
"password": password,
})
r.raise_for_status()
return r.json()["access_token"]
def list_guests(token):
headers = {"Authorization": f"Bearer {token}"}
users = []
from_token = None
while True:
url = f"{BASE}/_synapse/admin/v2/users?local=true&deactivated=false&limit=100"
if from_token:
url += f"&from={from_token}"
res = requests.get(url, headers=headers)
res.raise_for_status()
data = res.json()
for u in data.get("users", []):
disp = u.get("displayname", "")
if u.get("is_guest") and (not disp or disp.isdigit()):
users.append(u["name"])
from_token = data.get("next_token")
if not from_token:
break
return users
def set_displayname(token, user_id, name):
headers = {"Authorization": f"Bearer {token}"}
payload = {"displayname": name}
# Update global profile
r = requests.put(f"{BASE}/_matrix/client/v3/profile/{urllib.parse.quote(user_id)}/displayname", headers=headers, json=payload)
r.raise_for_status()
# Update Othrys member event so clients see the change quickly
state_url = f"{BASE}/_matrix/client/v3/rooms/{urllib.parse.quote(OTHRYS)}/state/m.room.member/{urllib.parse.quote(user_id)}"
r2 = requests.get(state_url, headers=headers)
content = r2.json() if r2.status_code == 200 else {"membership": "join"}
content["displayname"] = name
requests.put(state_url, headers=headers, json=content)
token = login(os.environ["SEEDER_USER"], os.environ["SEEDER_PASS"])
guests = list_guests(token)
for g in guests:
new = f"{random.choice(ADJ)}-{random.choice(NOUN)}"
set_displayname(token, g, new)
PY