Webhook¶
Un webhook invia una richiesta POST JSON a un indirizzo esterno quando
succede qualcosa su una bacheca. Si configura per bacheca (permesso
board.manage) dalla bacheca o con l'API.
Eventi¶
| Evento | Quando |
|---|---|
task.created |
task creata (dal Kanban, dall'API, da una riunione o da un link pubblico) |
task.updated |
task modificata o completata da TaskWorkflow |
task.moved |
task spostata in un altro stato; il payload ha anche from_list |
task.completed |
task diventata done |
task.deleted, task.restored |
task nel cestino e ripristinata |
comment.created |
nuovo commento |
ping |
solo per il pulsante "Prova" |
Un webhook ascolta gli eventi scelti alla creazione (Webhook::events).
Consegna¶
WebhookDispatchertrova i webhook della bacheca interessati all'evento e costruisce il payload: task (uuid, titolo, stato, priorità, avanzamento, date, stato conis_done, assegnatari), bacheca ed eventuale commento.- Crea una
WebhookDeliveryin attesa e accoda unDeliverWebhookJob. WebhookDeliveryService::attempt()invia la richiesta con:X-GesTask-EventeX-GesTask-Delivery(uuid della consegna, ripetuto anche nel corpo comedelivery);X-GesTask-Signature: sha256=<HMAC del corpo>se il webhook ha un segreto;- autenticazione Basic, se configurata;
- timeout di 3 secondi per la connessione e 5 in tutto.
- Una risposta non 2xx è un fallimento. Si salvano codice, i primi 2000 caratteri della risposta, errore e durata.
Gli header X-Gestick-* del vecchio nome sono inviati ancora, duplicati, per
compatibilità.
Verificare la firma¶
Chi riceve calcola l'HMAC SHA-256 del corpo grezzo con il segreto condiviso e lo
confronta, in tempo costante, con il valore dopo sha256=.
Tentativi¶
- Dopo un fallimento si riprova dopo 1 minuto, 5 minuti, 30 minuti, 2 ore e 6
ore, fino a
params['webhooks']['maxAttempts'](5). php yii webhook/retry(ogni 5 minuti) riprova le consegne scadute.php yii webhook/prune(ogni giorno) elimina le consegne più vecchie diretentionDays(30).- Dall'interfaccia si può riconsegnare a mano una consegna e inviare un
pingdi prova, che parte subito.
Protezione SSRF¶
Un webhook non deve poter raggiungere la rete interna. OutboundUrlGuard
controlla l'indirizzo al salvataggio e di nuovo a ogni invio:
- solo
httpehttps, senza credenziali nell'URL; - tutti gli IP risolti devono essere pubblici: niente reti private, riservate, CGNAT, link-local, loopback, ULA o IPv4 mappati in IPv6;
- la connessione è fissata sull'IP verificato (
CURLOPT_RESOLVE), senza redirect e solo HTTP/HTTPS, così un DNS che cambia risposta non aggira il controllo.
Per un servizio interno legittimo si aggiunge il nome host a
params['outboundRequests']['allowedHosts']; allowPrivateNetworks disattiva
il controllo ed è da usare solo su installazioni isolate. La stessa protezione
vale per le notifiche Slack e le iscrizioni Web Push.