11 KiB
Plan — Mailbox Permission Scanning
Voorstel voor het uitbreiden van Clearview met mailbox-rechten scanning naast de bestaande SharePoint-scan. Status: voorstel, nog niet geïmplementeerd.
1. Scope & aanpak
In Exchange Online zijn dit de relevante permissie-categorieën:
| Permissie | Bron | Waarop |
|---|---|---|
| Full Access / Read | Get-MailboxPermission |
hele mailbox |
| Send As | Get-RecipientPermission |
identiteit |
| Send on Behalf | mailbox-property GrantSendOnBehalfTo |
identiteit |
| Folder delegaties (Calendar, Inbox) | Get-MailboxFolderPermission |
per folder |
Microsoft Graph dekt dit slechts gedeeltelijk (vooral folder-permissies). De volledige set vereist Exchange Online PowerShell met certificaat-auth (Connect-ExchangeOnline -CertificateThumbprint ... -AppId ... -Organization ...). Dat sluit goed aan op het bestaande cert-model van Clearview — dezelfde Azure-app kan zowel Sites.FullControl.All (SharePoint) als Exchange.ManageAsApp (Exchange) krijgen.
Voorgestelde aanpak: EXO PowerShell aanroepen vanuit Python via pwsh subprocess, JSON-output retour. Alternatief is pure Graph, maar dan mist Send As / Send on Behalf grotendeels.
Deviation-baseline voor mailboxen: anders dan SharePoint heeft een mailbox geen "root vs. child" hiërarchie waar een baseline uit volgt. Voorstel: rapporteer alle non-default permissies (filter standaard-entries als NT AUTHORITY\SELF, S-1-5-10, default folder-permissies "Default"/"Anonymous=None") als deviation. Dus géén delta-vergelijk, maar wel dezelfde dedup-logica per (principal, role).
2. Layout-wijzigingen frontend
Huidige website is volledig op SharePoint gemodelleerd (één scanflow, één resultaattabel) en bestaat uit één lange single-page met alle panels (Tenants, Start New Scan, Scan Jobs, Job Details) onder elkaar. Voorstel: opsplitsen in pagina's met een vaste linker zijbalk zoals AlertHub gebruikt.
a. Sidebar-layout (geïnspireerd op AlertHub)
Vaste zijbalk links (~200px, donkere achtergrond, logo bovenaan, account-blok onderaan):
┌────────────┬──────────────────────────────────┐
│ Clearview │ │
│ ───────── │ (page content) │
│ Dashboard │ │
│ Scan Jobs │ │
│ ───────── │ │
│ SharePoint │ │
│ New Scan │ │
│ Mailboxes │ │
│ New Scan │ │
│ ───────── │ │
│ Tenants │ │
│ Settings │ │
│ ───────── │ │
│ Manual │ │
│ Changelog │ │
│ ───────── │ │
│ [account] │ │
└────────────┴──────────────────────────────────┘
Items:
- Dashboard — hero/KPI's (Tenants, Jobs, Active Jobs) — huidige
herosectie - Scan Jobs — gecombineerde lijst van alle jobs (filter op type/tenant) + Job Details als detail-view (klik op job → toont onder lijst óf als aparte route)
- SharePoint → New Scan — formulier alleen voor SharePoint-scans (URLs / CSV)
- Mailboxes → New Scan — formulier alleen voor mailbox-scans (UPNs / CSV)
- Tenants — huidige tenants-panel
- Settings — placeholder voor toekomstige instellingen (timeouts, env-overrides als die exposed worden)
- Manual / Changelog — statische docs als die online beschikbaar moeten komen
- Account-blok onderaan: huidige sessie / build-versie
Implementatie blijft vanilla HTML/JS/CSS (geen React-introductie — dat zou een grote scope-uitbreiding zijn). Concreet:
index.htmlhoudt alle secties als<section data-route="...">, default verborgen- Hash-based routing in
app.js(#/jobs,#/scan/sharepoint,#/scan/mailbox,#/tenants, …) styles.csskrijgt grid-layout met sidebar + content area- Geen page reloads; navigatie wisselt zichtbaarheid van secties en update active-state in de sidebar
Voordelen tegenover de huidige single-scroll:
- Scan-typen visueel gescheiden — voorkomt verwarring tussen SharePoint- en Mailbox-formulieren
- Schaalt naar meer scan-types (OneDrive, Teams) zonder dat de pagina nóg langer wordt
- Visuele consistentie met AlertHub binnen jouw productenfamilie
b. Scan-formulier per type (gescheiden pagina's)
- SharePoint-pagina: huidige URLs/CSV-formulier, ongewijzigd qua velden
- Mailbox-pagina: invoerveld voor UPN/email (één per regel), géén "skip default sites"
- CSV-import per pagina, met geschikte kolomdetectie (
URL/Site URLversusUserPrincipalName/Email/Mailbox)
c. Jobs-pagina
- Gecombineerde tabel met alle jobs ongeacht type
- Nieuwe kolom Type (SharePoint / Mailbox)
- Tenant-filter blijft, extra filter op type
- Klik op een job opent de detail-view (sectie eronder of dedicated route
#/jobs/{id})
d. Job Details (binnen Jobs-pagina)
- Sectie heading wordt dynamisch: "Targets" blijft, maar URL-kolom wordt "Mailbox" voor mailbox-jobs
- Permission Deviations tabel krijgt voor mailbox-jobs andere kolommen:
- Mailbox · Folder (leeg voor mailbox-level) · Permission Type (FullAccess/SendAs/SendOnBehalf/Folder) · Principal · Access Rights
- SharingLinks-blok wordt verborgen voor mailbox-jobs
- Site-filter wordt mailbox-filter
e. Tenants-pagina
- In de onboarding-instructies een extra stap erbij: API permission
Office 365 Exchange Online → Exchange.ManageAsApp+ roleExchange Administratortoekennen aan de service principal. Voor de geautomatiseerde flow betekent dit een extra Graph-call (rol-toekenning kan niet altijd, dus mogelijk handmatige stap). - Statuskolom
Authtoont al cert/secret; voorstel: extra capability-badge per tenant (SP,EXO) zodat zichtbaar is welke scans mogelijk zijn.
3. Backend-optimalisatie / herstructurering
scanner.py is nu één bestand met SharePoint-specifieke logica én generieke helpers (auth, HTTP, dedup, role-name normalization). Voorstel:
src/clearview_app/scanners/
__init__.py # dispatcher: scan(target_type, ...)
common.py # AuthConfig, DeviationRecord, ScanResult, ProbeResult,
# MSAL token cache, _request_json, _iter_paged,
# _deduplicate_hierarchical, role-name normalization
sharepoint.py # huidige scan_site_for_deviations + probe_site + resolve_sharing_link_members
mailbox.py # nieuw: scan_mailbox_for_deviations + probe_mailbox
# roept pwsh aan met EXO-script en parseert JSON
exo_scripts/
get-permissions.ps1 # connect + get mailbox/recipient/folder permissions, output JSON
probe.ps1 # lichtgewicht: Get-EXOMailbox -Identity x | select Identity
Voordelen:
scanner.pywas richting 540 regels en mengt concerns; opsplitsen maakt testen makkelijkerworker.pykrijgt één dispatcher-call:scan(target_type, target, auth, progress)ipv. directe import van SharePoint-specifieke functies- Toekomstige scan-types (OneDrive, Teams) passen in hetzelfde patroon
Worker.py moet leren: per target weten welke scanner aan te roepen op basis van scan_targets.target_type (of scan_jobs.scan_type).
4. Datamodel
Minimale, niet-brekende wijzigingen — toegepast via bestaand _ensure_schema_columns():
| Tabel | Nieuwe kolom | Default |
|---|---|---|
scan_jobs |
scan_type VARCHAR(32) |
'sharepoint' |
scan_targets |
(geen — site_url blijft, bevat UPN voor mailbox-jobs; of hernoem naar target met DB-view voor compat) |
— |
permission_deviations |
permission_type VARCHAR(32) NULL |
NULL (voor SP-rows) |
permission_deviations |
object_type krijgt nieuwe waarden: Mailbox, MailboxFolder |
— |
Vraag: liever site_url houden als generieke "target identifier" (compacter, geen migratie), of nu hernoemen? Eerste optie is mijn voorstel.
5. API-endpoints
Bestaand blijft werken. Toevoegingen:
POST /api/scan-jobs payload krijgt optioneel "scan_type": "sharepoint"|"mailbox"
en "mailboxes": [...] naast/ipv "site_urls"
POST /api/scan-jobs/import-csv extra "scan_type" form-field
GET /api/scan-jobs?scan_type=mailbox filter
Nieuwe response-velden in ScanJobDetail: scan_type, en deviations krijgen permission_type.
6. Onboarding & runtime-vereisten
- Container: PowerShell 7 (
pwsh) en deExchangeOnlineManagementPS-module installeren in de Docker image. Dit voegt ~150MB toe. Acceptabel? - Azure-app: extra permission
Office 365 Exchange Online → Exchange.ManageAsApp+ Entra-rol "Exchange Administrator" voor de service principal. In Mode A (automated) kan het permission-deel via Graph, het rol-deel meestal niet — handmatige bevestigingsstap nodig. - Probe: voor mailboxen één kleine call (
Get-EXOMailbox -Identity <upn> -Properties Identityvia een korter PS-script) om vroeg te falen op auth/rol.
7. Implementatiestappen (volgorde)
- Backend refactor: scanner-module opsplitsen, geen functionele wijziging (groen test)
- Datamodel:
scan_type+permission_typetoevoegen, default'sharepoint' - Frontend layout-refactor: sidebar + hash-routing introduceren, bestaande functionaliteit (alleen SharePoint) verdelen over pagina's. Nog géén mailbox-UI.
- Mailbox-scanner: PS-scripts + Python-wrapper + dispatcher; alleen via API testbaar
- API: scan-job creatie uitbreiden met
scan_type/mailboxes - Frontend: Mailboxes-pagina toevoegen + dynamische kolommen in Job Details
- Onboarding-tekst en build (Dockerfile voor
pwsh) - Documentatie: TECHNICAL.md + changelog-develop.md
Open vragen
- PowerShell-route akkoord, of liever Graph-only (incompleter, maar pure Python)?
- Eén scan-type per job (voorstel), of mengbare jobs (SharePoint + mailboxen door elkaar)?
- Baseline voor mailbox: alle non-default rechten als deviation rapporteren (voorstel), of moet er een "expected baseline" per mailbox/tenant configureerbaar worden?
- Image-grootte: is +150 MB voor
pwsh+ EXO-module aanvaardbaar? site_urlkolom hergebruiken als generieke target-identifier, of nu hernoemen naartarget?