feat: release regional radar and mailbox integrations
deploy / deploy (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-22 05:12:07 +02:00
parent 598d3ec18a
commit 551d0f46c2
131 changed files with 6209 additions and 336 deletions
+6 -2
View File
@@ -23,6 +23,8 @@ Verplichte stappen:
5. response status/contenttype/grootte controleren;
6. alleen allowlisted headers bewaren.
Webfetches, robotsrequests en IMAP-TLS gebruiken expliciet de bij de release vastgelegde `certifi`-CA-bundel. Hostnaamcontrole en `CERT_REQUIRED` blijven verplicht. Een verouderde Windows-rootstore is daarom geen reden voor `verify=False`; werk de gepinde bundel en lockfile gecontroleerd bij en voer de TLS-negatietests opnieuw uit.
Geen adapter of view mag dit pad omzeilen.
## 3. SSRF
@@ -51,11 +53,13 @@ Resterend risico: klassieke DNS rebinding tussen resolutie en socketconnectie. P
## 5. E-mail
- dedicated mailbox;
- een dedicated mailbox per platform;
- attachments worden genegeerd;
- message identity voorkomt dubbele verwerking;
- platformgebonden import accepteert alleen gelabelde HTTPS-links op het expliciet gekozen jobboarddomein;
- externe tracking-, account-, help-, privacy- en uitschrijflinks worden niet als vacature opgeslagen;
- links worden niet automatisch gevolgd tenzij later door bronpolicy goedgekeurd;
- mailboxcredentials alleen environment/secret;
- mailbox-app-wachtwoorden versleuteld in de database met een afzonderlijke, roteerbare environmentkey;
- raw mail korte retentie;
- log geen volledige onderwerp/body wanneer daarin PII kan staan.
+16 -2
View File
@@ -47,8 +47,10 @@ Voor e-mail:
1. MIME decode zonder attachments;
2. linkextractie met unsubscribe/privacyfilter;
3. platformalias bewaren;
4. oorspronkelijke werkgever proberen te resolveren in een aparte begrensde taak.
3. bij een platformmailbox uitsluitend gelabelde HTTPS-links op het gekozen jobboarddomein aanvaarden;
4. externe tracking-, account-, help-, privacy- en uitschrijflinks verwerpen;
5. platformalias en provenance bewaren;
6. oorspronkelijke werkgever proberen te resolveren in een aparte begrensde taak.
## 3. Minimumvelden
@@ -153,8 +155,20 @@ Automatisch herstel mag veilige selectorvarianten proberen, maar nieuwe logica m
| SmartRecruiters | `*.smartrecruiters.com` | gespecialiseerd listing+detail parser | geen interne API-auth nodig; stop bij CAPTCHA/anti-bot | 30 requests/min per domein |
| Workable | `apply.workable.com` | gespecialiseerd listing+detail parser | alleen publieke vacaturepagina/JSON; geen private endpoints | 30 requests/min per domein |
Gedeelde ATS-hosts zijn geen bronidentiteit: meerdere werkgevers mogen hetzelfde providerdomein gebruiken zolang iedere bron een unieke publieke `base_url` heeft. De scheduler blijft per origin coördineren, zodat deze extra bronrecords de providerlimiet niet omzeilen.
Voor Corda Campus is een begrensde regionale listingadapter beschikbaar. Die leest uitsluitend de expliciete `/jobs/`-kaarten, bewaart de vermelde werkgever en weigert iedere joblink buiten `cordacampus.com`. Vacaturedetail en sollicitatie-URL's worden niet automatisch gevolgd.
Voor elke provider-adapter:
- `supports()` kijkt eerst op host/marker om andere pagina's niet te matchen;
- listingpayloads produceren kandidaten zonder fetch van detail;
- detailpayloads vullen een enkele vacaturestructuur;
- elke veldafklaring krijgt veld-evidence met method-labels en confidence.
## Regionale Mol-adapter (VR-126)
`MolRegionEmployerAdapter` verwerkt uitsluitend vijf vooraf gereviewde HTTPS-lijstroutes rond postcode 2400: SCK CEN, Cipal Schaubroeck, VanRoey, NTX/Netropolix en Thomas More. De adapter doet geen netwerkrequests en accepteert alleen same-host vacaturelinks. Cipal, NTX en Thomas More vereisen een expliciete lokale marker; bij Thomas More wordt bovendien de vaste publieke werkgever-GUID gecontroleerd. VanRoey-detailpaden zijn door robots uitgesloten en worden daarom nooit door VacatureRadar gefetcht; alleen de toegestane overzichtspagina dient als bron.
## Kempen-werkgeversadapter (VR-201)
`KempenEmployerAdapter` voegt zeven gereviewde werkgeversroutes toe voor Ziekenhuis Geel, lokaal bestuur Geel, Stad Turnhout, Group Renotec, Ravago, Sanofi en DAF Trucks Westerlo. Iedere route heeft een vaste HTTPS-host en een toegestaan lijstpad; vacaturelinks moeten same-host zijn. Voor gedeelde of landelijke lijsten blijft alleen een kaart met de expliciete gereviewde vestiging over. Gemeente Mol wordt via de officiële same-host RSS-feed verwerkt. Interessante werkgevers zonder stabiele fail-closed parser blijven als niet-scanbare waaklijstbron zichtbaar.
@@ -2,6 +2,7 @@
- Status: accepted
- Datum: 2026-07-20
- Aangevuld door: ADR-0009
## Context
@@ -9,11 +10,16 @@ Vacatureplatformen bieden nuttige zoekalgoritmes en alerts, terwijl directe scra
## Besluit
Gebruik een dedicated IMAP-mailbox en idempotente MIME/linkextractie. Bewaar platformlinks als bronalias. Volg een link alleen wanneer bronpolicy dat later toestaat; probeer bij voorkeur een oorspronkelijke werkgeverspagina te vinden.
Gebruik per vacatureplatform een dedicated IMAP-mailbox en idempotente MIME/linkextractie. Iedere mailbox heeft een eigen interval en kan vanuit de bronpagina afzonderlijk worden gepauzeerd of ingepland. Bewaar platformlinks als bronalias. Volg een link alleen wanneer bronpolicy dat later toestaat; probeer bij voorkeur een oorspronkelijke werkgeverspagina te vinden.
De gereviewde mailboxcatalogus omvat VDAB, Indeed, LinkedIn, ictjob.be, Jobat, StepStone, Careerjet, Randstad en Robert Half. De gebruiker activeert de officiële jobalert zelf. VacatureRadar logt alleen in op het opgegeven mailboxaccount, beperkt extractie tot gelabelde HTTPS-links op het gekozen platformdomein en gebruikt geen jobboardaccount, zoekbot of directe crawl. Expliciet Brusselse nicheboards zijn in VR-125 uit de configureerbare catalogus verwijderd omdat ze buiten de regionale productscope vallen.
Voor VDAB bestaan twee officiële routes. Door de gebruiker ingestelde [jobalerts](https://www.vdab.be/jobs/job-alerts) mogen onmiddellijk via deze mailboxingang worden verwerkt. De [VDAB Vacature API](https://extranet.vdab.be/api-center-excellence-coe/vacatures-ophalen-met-de-vacatures-api) mag pas als fetchbron worden geactiveerd nadat VDAB het partnership heeft goedgekeurd en de samenwerkingsovereenkomst en credentials beschikbaar zijn. Deze ADR staat geen scraping of gebruik van een verborgen/onbevoegd endpoint toe.
## Gevolgen
- gebruiker stelt alerts eenmalig in;
- parser moet variërende e-mailsjablonen verdragen;
- dedicated mailbox en retentie nodig;
- parser moet variërende e-mailsjablonen verdragen en een onbekende wijziging fail-closed als geen herkenbare vacaturelink behandelen;
- batches en berichtgrootte zijn begrensd en één fout bericht stopt de rest niet;
- dedicated mailbox per platform en retentie nodig;
- geen platformcredentials in VacatureRadar.
@@ -0,0 +1,32 @@
# ADR-0009 — Versleutelde platformmailboxen in de applicatie
- Status: accepted
- Datum: 2026-07-22
## Context
Alerts van VDAB, Indeed, LinkedIn en andere gereviewde jobboards komen in verschillende mailboxaccounts binnen en moeten vaker dan eenmaal per dag verwerkt kunnen worden. Alleen globale environmentcredentials bieden geen bruikbare beheerflow in het platform. Mailbox-app-wachtwoorden zijn secrets en mogen niet leesbaar in de database, logs, taakresultaten of HTML terechtkomen.
## Besluit
- Bewaar één gebruikersgescopeerde `MailboxConnection` per vacatureplatform.
- Ondersteun Gmail, Outlook / Microsoft 365 en een gecontroleerde aangepaste publieke IMAP-host, uitsluitend via IMAP over TLS.
- Versleutel app-wachtwoorden met Fernet/MultiFernet en een afzonderlijke `MAILBOX_CREDENTIAL_KEYS`-sleutellijst. De eerste sleutel versleutelt; volgende sleutels zijn alleen voor decryptie tijdens rotatie.
- Laat de scheduler elke vijf minuten verschuldigde mailboxen selecteren. Iedere mailbox kiest zelf 5, 15, 30, 60, 180 of 360 minuten.
- Gebruik een databaselease per mailbox, idempotentie per mailbox + Message-ID en foutisolatie per mailbox/bericht.
- Alle UI-mutaties zijn login-, user-scope- en CSRF-beveiligd. Het wachtwoordveld wordt nooit opnieuw gevuld.
- Valideer de IMAP-host als publieke host voor de verbinding. Platformlinks uit mail worden niet automatisch gevolgd.
## Sleutelrotatie
1. Voeg de nieuwe sleutel vóór de oude toe aan `MAILBOX_CREDENTIAL_KEYS`.
2. Herstart web, worker en scheduler.
3. Draai `python manage.py rotate_mailbox_credentials`.
4. Verwijder de oude sleutel pas nadat de opdracht slaagt en een mailboxsync is getest.
## Gevolgen
- `cryptography` is een productieafhankelijkheid en staat exact gepind in de lockfile.
- Een databasedump bevat ciphertext en blijft gevoelig; de encryptiesleutel wordt apart in de secretstore/back-up bewaard.
- Zonder expliciete sleutel is mailboxbeheer in productie fail-closed. Alleen DEBUG gebruikt een lokale sleutel afgeleid van de development `SECRET_KEY`.
- Dit is een mailboxlogin, geen login bij een jobboard en geen toestemming voor directe platformfetch.