S1: shared value helpers (parse_dt/coerce_bool) + auto-Secure session cookie
M9 hardening/DRY pass — section S1, commit 1 (the shared-toolkit foundation): - Add src/thoughtsync/common.py with parse_dt() and coerce_bool(): one home for the ISO-date and truthy-flag coercions that were duplicated across modules. notes.py adopts them and deletes _parse_iso_dt, _iso_to_dt and _truthy (rule 22 — old copies removed; callers, incl. tests, updated). - Security: the session cookie is now marked Secure automatically on any request that arrived over HTTPS (directly or via a proxy's X-Forwarded-Proto), via a SecureCookieSessionInterface override. Hardens HTTPS deployments without breaking plain-HTTP LAN installs — no config. Behavior-preserving refactor + one security hardening. The backend serialization layer, the json_error sweep, and the notes.py split follow as their own commits. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
# Small, dependency-free value coercions shared across the blueprints. Kept in one
|
||||
# place so the "parse an ISO date" / "is this flag truthy" logic has a single
|
||||
# definition instead of a near-identical copy per module.
|
||||
|
||||
|
||||
def parse_dt(raw: object) -> datetime | None:
|
||||
"""Parse an ISO-8601 timestamp (accepting a trailing 'Z' for UTC).
|
||||
|
||||
Returns None for anything that isn't a non-empty string or doesn't parse, so
|
||||
callers can treat "absent", "blank", and "malformed" uniformly (a route that
|
||||
wants a 400 on malformed input checks for None itself).
|
||||
"""
|
||||
if not isinstance(raw, str) or not raw:
|
||||
return None
|
||||
try:
|
||||
return datetime.fromisoformat(raw.replace("Z", "+00:00"))
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
def coerce_bool(raw: object) -> bool:
|
||||
"""Truthy for the common flag spellings ('true'/'1'/'yes'/'on', or a real bool).
|
||||
|
||||
Used for query-string booleans (?has_reminder=true) and DB-backed bool settings,
|
||||
which arrive as strings.
|
||||
"""
|
||||
if isinstance(raw, bool):
|
||||
return raw
|
||||
if isinstance(raw, str):
|
||||
return raw.strip().lower() in ("true", "1", "yes", "on")
|
||||
return False
|
||||
Reference in New Issue
Block a user