feat(infra): auto-commit con 86 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
---
|
||||
name: synapse_admin_client
|
||||
kind: function
|
||||
lang: go
|
||||
domain: infra
|
||||
version: "0.1.0"
|
||||
purity: impure
|
||||
signature: "func NewSynapseAdminClient(homeserver, adminToken string) *SynapseAdminClient"
|
||||
description: "REST client for the Synapse Admin API (/_synapse/admin/v1 and v2). Wraps user management (list/get/deactivate/reset-password), room management (list/get/delete with purge), and device management (list/delete) with Bearer auth and structured error wrapping."
|
||||
tags: [matrix, synapse, admin, rest, client, infra, matrix-mas]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
imports:
|
||||
- "bytes"
|
||||
- "context"
|
||||
- "encoding/json"
|
||||
- "fmt"
|
||||
- "io"
|
||||
- "net/http"
|
||||
- "net/url"
|
||||
- "strconv"
|
||||
- "time"
|
||||
tested: true
|
||||
tests:
|
||||
- "ListUsers parses + counts"
|
||||
- "GetUser inexistente -> error contiene M_NOT_FOUND"
|
||||
- "DeactivateUser ok"
|
||||
- "DeleteRoom devuelve delete_id"
|
||||
- "ListUserDevices parses array"
|
||||
- "HTTP 403 -> error con errcode M_FORBIDDEN"
|
||||
test_file_path: "functions/infra/synapse_admin_client_test.go"
|
||||
file_path: "functions/infra/synapse_admin_client.go"
|
||||
params:
|
||||
- name: homeserver
|
||||
desc: "Base URL of the Synapse homeserver, e.g. https://matrix-af2f3d.organic-machine.com (no trailing slash)"
|
||||
- name: adminToken
|
||||
desc: "Access token of a Synapse user with admin:true. NOT a MAS/OIDC token — must be a legacy Synapse session token"
|
||||
output: "*SynapseAdminClient ready to call ListUsers, DeactivateUser, ListRooms, DeleteRoom, ListUserDevices, etc."
|
||||
---
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```go
|
||||
ctx := context.Background()
|
||||
|
||||
c := NewSynapseAdminClient(
|
||||
"https://matrix-af2f3d.organic-machine.com",
|
||||
"syt_admin_token_xxx",
|
||||
)
|
||||
|
||||
// List first 100 users
|
||||
res, err := c.ListUsers(ctx, ListUsersFilter{Limit: 100})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for _, u := range res.Users {
|
||||
fmt.Printf("%s admin=%v deactivated=%v\n", u.UserID, u.Admin, u.Deactivated)
|
||||
}
|
||||
|
||||
// Paginate with NextToken
|
||||
if res.NextToken != nil {
|
||||
res2, _ := c.ListUsers(ctx, ListUsersFilter{From: *res.NextToken, Limit: 100})
|
||||
_ = res2
|
||||
}
|
||||
|
||||
// Deactivate + erase a user
|
||||
err = c.DeactivateUser(ctx, "@badactor:server", true)
|
||||
|
||||
// Delete a room with purge
|
||||
deleteID, err := c.DeleteRoom(ctx, "!spamroom:server", "spam cleanup", true, true)
|
||||
fmt.Println("delete_id:", deleteID) // poll /_synapse/admin/v2/rooms/delete_status/{deleteID}
|
||||
|
||||
// List devices for a user
|
||||
devices, err := c.ListUserDevices(ctx, "@alice:server")
|
||||
for _, d := range devices {
|
||||
fmt.Printf(" device %s last seen %s\n", d.DeviceID, d.LastSeenIP)
|
||||
}
|
||||
```
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Usar en `matrix_admin_panel` (issue 0163) para construir el panel de administración del homeserver: listar usuarios, desactivar cuentas, inspeccionar rooms, purgar rooms spam, ver y eliminar dispositivos. También válida para scripts de operación del homeserver (bulk deactivation, room cleanup) que necesiten la Admin API sin pasar por el cliente Matrix regular.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Admin Bearer NO es OIDC token**: Synapse Admin API NO acepta tokens MAS/OIDC regulares — requiere `access_token` de un usuario con `admin: true` en la tabla `users` de Synapse. Obtenerlo via una sesión creada con password legacy (antes de MSC3861) o via `mas-cli manage create-session --admin`. Con MAS activo, el flow de obtención de admin tokens cambia — ver documentación de MAS.
|
||||
- **DeleteRoom es async**: devuelve `delete_id` inmediatamente. El estado real se consulta via `GET /_synapse/admin/v2/rooms/delete_status/{deleteID}` — ese endpoint NO está implementado en v0.1.0. Suficiente para lanzar la operación; la comprobación de finalización es TODO.
|
||||
- **Rate limiting**: la Admin API aplica rate limits. >10 calls/s puede recibir 429. No hay retry-with-backoff en v0.1.0 — implementar en el consumidor si se hacen operaciones bulk.
|
||||
- **Pagination**: iterar hasta que `NextToken == nil`. El campo `next_token` puede estar ausente en la última página — el cliente lo mapea a `nil` correctamente.
|
||||
- **DeactivateUser con erase=true**: borra perfil, inhabilita el MXID permanentemente y bloquea su reúso. Operación irreversible en Synapse.
|
||||
- **userID format**: usar MXID completo `@user:server`. La función aplica `url.PathEscape` automáticamente — no hace falta pre-encodear.
|
||||
- **HTTPClient custom**: para timeouts distintos al default de 30s, pasar un `*http.Client` al campo `HTTPClient` del struct directamente (no hay opción en el constructor).
|
||||
|
||||
## Notas
|
||||
|
||||
Sólo usa stdlib (net/http, encoding/json, net/url, context). Sin dependencias externas.
|
||||
Endpoints base siempre `/_synapse/admin` (no `/_matrix/client`).
|
||||
Reference in New Issue
Block a user