""" DSR Art. 11 Service — handles "data subject not identifiable" rejections. Art. 11 Abs. 1 DSGVO: If the controller is unable to identify the data subject, it is not obligated to obtain additional information solely to comply with Art. 15-20 requests. Common scenario: Website visitor requests access, but only anonymous cookies/IP-hashes are stored — no way to link to a person. """ import logging from datetime import datetime, timezone from typing import Any, Dict from sqlalchemy.orm import Session from compliance.domain import ValidationError logger = logging.getLogger(__name__) class DSRArt11Service: """Handles Art. 11 DSGVO rejections for non-identifiable data subjects.""" def __init__(self, db: Session) -> None: self._db = db def reject_not_identifiable( self, dsr_id: str, tenant_id: str, notes: str = "", ) -> Dict[str, Any]: """Reject DSR because data subject cannot be identified.""" from compliance.db.dsr_models import DSRRequestDB from compliance.services.dsr_workflow_service import _dsr_to_dict, _record_history dsr = ( self._db.query(DSRRequestDB) .filter(DSRRequestDB.id == dsr_id, DSRRequestDB.tenant_id == tenant_id) .first() ) if not dsr: raise ValidationError("DSR not found") if dsr.status in ("completed", "rejected", "cancelled"): raise ValidationError("DSR already closed") now = datetime.now(timezone.utc) reason = ( "Die bei uns gespeicherten Daten (anonymisierte Cookies, IP-Hashes, " "Device-Fingerprints) erlauben keine Identifikation der betroffenen Person. " "Gemaess Art. 11 Abs. 1 DSGVO sind wir nicht verpflichtet, zusaetzliche " "Informationen zu erheben, um die betroffene Person zu identifizieren." ) if notes: reason += f" Ergaenzung: {notes}" _record_history(self._db, dsr, "rejected", comment="Art. 11 DSGVO — Identifikation nicht moeglich") dsr.status = "rejected" dsr.rejection_reason = reason dsr.rejection_legal_basis = "Art. 11 Abs. 1 DSGVO" dsr.identity_verified = False dsr.verification_method = "art11_not_identifiable" dsr.verification_notes = "Daten erlauben keine Identifikation der betroffenen Person" dsr.completed_at = now dsr.updated_at = now self._db.commit() self._db.refresh(dsr) # Send rejection notification self._send_art11_notification(dsr) return _dsr_to_dict(dsr) def _send_art11_notification(self, dsr: Any) -> None: if not dsr.requester_email: return try: from compliance.services.email_delivery_service import EmailDeliveryService delivery = EmailDeliveryService(self._db) variables = { "requester_name": dsr.requester_name or "Antragsteller/in", "reference_number": dsr.request_number or "", "rejection_reason": "Identifikation nicht moeglich — Art. 11 Abs. 1 DSGVO", "legal_basis": "Art. 11 Abs. 1 DSGVO", "sender_name": "Datenschutzbeauftragter", } # Use published dsr_rejection template, fallback to inline delivery.send( tenant_id=str(dsr.tenant_id), template_type="dsr_rejection", recipient=dsr.requester_email, variables=variables, fallback_subject=f"Zu Ihrer Anfrage {dsr.request_number} — Art. 11 DSGVO", fallback_html=f"""

Sehr geehrte/r {dsr.requester_name or 'Antragsteller/in'},

wir koennen die bei uns gespeicherten Daten keiner identifizierbaren Person zuordnen. Gemaess Art. 11 Abs. 1 DSGVO ist eine Auskunftserteilung nicht moeglich.

Mit freundlichen Gruessen
Datenschutzbeauftragter

""", ) except Exception as e: logger.warning("Art. 11 notification failed: %s", e)