mirror of
https://github.com/complexcaresolutions/dak.c2s.git
synced 2026-03-17 16:03:41 +00:00
fix: mask contact fields for non-admin users, require disclosure for visibility
- Add strasse, plz, ort, email, telefonnummer, mobiltelefon, ansprechpartner to SENSITIVE_FIELDS in backend (nullified without disclosure) - Add visibleTo: 'admin' to all Kontakt fields in frontend fieldConfig - Consolidate _utcnow_naive() usage across all disclosure service functions for consistent naive datetime handling with MySQL Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d900d7864b
commit
5f957ee8ed
3 changed files with 19 additions and 16 deletions
|
|
@ -128,7 +128,10 @@ class CodingUpdate(BaseModel):
|
||||||
ta_uebertherapie: bool = False
|
ta_uebertherapie: bool = False
|
||||||
|
|
||||||
|
|
||||||
SENSITIVE_FIELDS = ("nachname", "vorname", "geburtsdatum", "anrede")
|
SENSITIVE_FIELDS = (
|
||||||
|
"nachname", "vorname", "geburtsdatum", "anrede",
|
||||||
|
"strasse", "plz", "ort", "email", "telefonnummer", "mobiltelefon", "ansprechpartner",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def mask_case_for_mitarbeiter(case_dict: dict, disclosure_granted: bool = False) -> dict:
|
def mask_case_for_mitarbeiter(case_dict: dict, disclosure_granted: bool = False) -> dict:
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,11 @@ from app.models.case import Case
|
||||||
from app.models.user import User
|
from app.models.user import User
|
||||||
|
|
||||||
|
|
||||||
|
def _utcnow_naive() -> datetime:
|
||||||
|
"""Return current UTC time as a naive datetime, matching MySQL DATETIME columns."""
|
||||||
|
return datetime.now(timezone.utc).replace(tzinfo=None)
|
||||||
|
|
||||||
|
|
||||||
def has_active_disclosure(db: Session, case_id: int, user_id: int) -> tuple[bool, Optional[datetime]]:
|
def has_active_disclosure(db: Session, case_id: int, user_id: int) -> tuple[bool, Optional[datetime]]:
|
||||||
"""Check if user has an active (approved, non-expired) disclosure for a case.
|
"""Check if user has an active (approved, non-expired) disclosure for a case.
|
||||||
|
|
||||||
|
|
@ -21,7 +26,7 @@ def has_active_disclosure(db: Session, case_id: int, user_id: int) -> tuple[bool
|
||||||
DisclosureRequest.case_id == case_id,
|
DisclosureRequest.case_id == case_id,
|
||||||
DisclosureRequest.requester_id == user_id,
|
DisclosureRequest.requester_id == user_id,
|
||||||
DisclosureRequest.status == "approved",
|
DisclosureRequest.status == "approved",
|
||||||
DisclosureRequest.expires_at > datetime.now(timezone.utc),
|
DisclosureRequest.expires_at > _utcnow_naive(),
|
||||||
)
|
)
|
||||||
.first()
|
.first()
|
||||||
)
|
)
|
||||||
|
|
@ -89,10 +94,10 @@ def review_disclosure_request(
|
||||||
|
|
||||||
dr.status = new_status
|
dr.status = new_status
|
||||||
dr.reviewed_by = admin_id
|
dr.reviewed_by = admin_id
|
||||||
dr.reviewed_at = datetime.now(timezone.utc)
|
dr.reviewed_at = _utcnow_naive()
|
||||||
|
|
||||||
if new_status == "approved":
|
if new_status == "approved":
|
||||||
dr.expires_at = datetime.now(timezone.utc) + timedelta(hours=24)
|
dr.expires_at = _utcnow_naive() + timedelta(hours=24)
|
||||||
|
|
||||||
# Notify requester
|
# Notify requester
|
||||||
case = db.query(Case).filter(Case.id == dr.case_id).first()
|
case = db.query(Case).filter(Case.id == dr.case_id).first()
|
||||||
|
|
@ -113,11 +118,6 @@ def review_disclosure_request(
|
||||||
return dr
|
return dr
|
||||||
|
|
||||||
|
|
||||||
def _utcnow_naive() -> datetime:
|
|
||||||
"""Return current UTC time as a naive datetime, matching MySQL DATETIME columns."""
|
|
||||||
return datetime.now(timezone.utc).replace(tzinfo=None)
|
|
||||||
|
|
||||||
|
|
||||||
def revoke_disclosure(db: Session, request_id: int, user_id: int, *, admin: bool = False) -> DisclosureRequest:
|
def revoke_disclosure(db: Session, request_id: int, user_id: int, *, admin: bool = False) -> DisclosureRequest:
|
||||||
"""Revoke an active disclosure by setting expires_at to now.
|
"""Revoke an active disclosure by setting expires_at to now.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,13 +41,13 @@ export const CASE_SECTIONS: SectionConfig[] = [
|
||||||
{
|
{
|
||||||
title: 'Kontakt',
|
title: 'Kontakt',
|
||||||
fields: [
|
fields: [
|
||||||
{ key: 'strasse', label: 'Straße', type: 'text', editableBy: 'admin', placeholder: 'Straße + Nr.' },
|
{ key: 'strasse', label: 'Straße', type: 'text', editableBy: 'admin', visibleTo: 'admin', placeholder: 'Straße + Nr.' },
|
||||||
{ key: 'plz', label: 'PLZ', type: 'text', editableBy: 'admin', placeholder: 'PLZ' },
|
{ key: 'plz', label: 'PLZ', type: 'text', editableBy: 'admin', visibleTo: 'admin', placeholder: 'PLZ' },
|
||||||
{ key: 'ort', label: 'Ort', type: 'text', editableBy: 'admin', placeholder: 'Ort' },
|
{ key: 'ort', label: 'Ort', type: 'text', editableBy: 'admin', visibleTo: 'admin', placeholder: 'Ort' },
|
||||||
{ key: 'email', label: 'E-Mail', type: 'text', editableBy: 'admin', placeholder: 'E-Mail' },
|
{ key: 'email', label: 'E-Mail', type: 'text', editableBy: 'admin', visibleTo: 'admin', placeholder: 'E-Mail' },
|
||||||
{ key: 'telefonnummer', label: 'Telefon', type: 'text', editableBy: 'admin', placeholder: 'Telefonnummer' },
|
{ key: 'telefonnummer', label: 'Telefon', type: 'text', editableBy: 'admin', visibleTo: 'admin', placeholder: 'Telefonnummer' },
|
||||||
{ key: 'mobiltelefon', label: 'Mobil', type: 'text', editableBy: 'admin', placeholder: 'Mobilnummer' },
|
{ key: 'mobiltelefon', label: 'Mobil', type: 'text', editableBy: 'admin', visibleTo: 'admin', placeholder: 'Mobilnummer' },
|
||||||
{ key: 'ansprechpartner', label: 'Ansprechpartner', type: 'text', editableBy: 'admin', colSpan: 2, placeholder: 'Ansprechpartner' },
|
{ key: 'ansprechpartner', label: 'Ansprechpartner', type: 'text', editableBy: 'admin', visibleTo: 'admin', colSpan: 2, placeholder: 'Ansprechpartner' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue