diff --git a/infrastructure/abri/abri_client.py b/infrastructure/abri/abri_client.py index bdf246b8e..ab59a6fb2 100644 --- a/infrastructure/abri/abri_client.py +++ b/infrastructure/abri/abri_client.py @@ -254,7 +254,11 @@ class AbriClient: mobile=numbers.mobile, telephone=numbers.telephone, secondary_number=numbers.secondary, - vulnerabilities=(), + vulnerabilities=tuple( + text + for vulnerability in element.findall("Vulnerability") + if (text := (vulnerability.text or "").strip()) + ), ) @staticmethod diff --git a/orchestration/tenant_data_sync_orchestrator.py b/orchestration/tenant_data_sync_orchestrator.py index c5a5ad557..6edff7156 100644 --- a/orchestration/tenant_data_sync_orchestrator.py +++ b/orchestration/tenant_data_sync_orchestrator.py @@ -6,6 +6,22 @@ from etl.hubspot.deal_contacts_client import HubspotDealContactsClient from infrastructure.abri.abri_client import AbriClient +def _vulnerability_description(tenant: Tenant) -> Optional[str]: + """The tenant's distinct vulnerabilities, verbatim and newline-joined. + + Case-insensitively distinct within the tenant, keeping the first-seen + casing and document order. + """ + distinct: List[str] = [] + seen: set[str] = set() + for vulnerability in tenant.vulnerabilities: + if vulnerability.lower() in seen: + continue + seen.add(vulnerability.lower()) + distinct.append(vulnerability) + return "\n".join(distinct) if distinct else None + + def _contact_properties(tenant: Tenant) -> Dict[str, str]: candidates: Dict[str, Optional[str]] = { "firstname": tenant.forenames, @@ -13,6 +29,7 @@ def _contact_properties(tenant: Tenant) -> Dict[str, str]: "mobilephone": tenant.mobile, "phone": tenant.telephone, "secondary_phone_number": tenant.secondary_number, + "vulnerability_description": _vulnerability_description(tenant), } properties = {name: value for name, value in candidates.items() if value} # Always written, so "not vulnerable" is distinguishable from "not synced".