aeat.adapters.persistence.storage._path_safety module

Typed path-containment helpers for the persistence substrate.

The wider project ships core.paths.resolve_relative_subpath() and core.paths.resolve_record_json_path() which raise plain ValueError on traversal violations. New persistence code uses the typed wrappers in this module instead so:

  • the failure carries the registered PathContainmentError code (INTEGRITY_STORAGE_PATH_CONTAINMENT) and lands in the standard CLI error envelope;

  • callers can write narrow except PathContainmentError clauses rather than broad except ValueError;

  • PathContainmentError still inherits from ValueError so callers that handle Python path-shape errors remain correct.

safe_subpath(root, relative_path, *, context)[source]

Resolve relative_path under root and enforce containment.

Wraps core.paths.resolve_relative_subpath(). Any ValueError raised by the wrapped helper is re-raised as a localized PathContainmentError with the same diagnostic args message and __cause__.

Parameters:
  • root (Path) – Configured root directory the path must stay under.

  • relative_path (str) – Forward-slash-separated relative path.

  • context (str) – Stable label embedded in the error message; used for log diagnostics.

Return type:

Path

Returns:

The resolved absolute Path known to live under root.

Raises:

PathContainmentError – On any traversal or shape violation.

safe_record_path(root, record_id, *, context)[source]

Resolve a record-id-keyed JSON file under root.

Wraps core.paths.resolve_record_json_path() and re-raises its ValueError as a localized PathContainmentError.

Parameters:
  • root (Path) – Configured root directory.

  • record_id (str) – Simple filename token; the helper enforces a strict allow-list of characters so traversal sequences cannot slip through.

  • context (str) – Stable label embedded in the error message.

Return type:

Path

Returns:

The resolved absolute Path of <root>/<record_id>.json.

Raises:

PathContainmentError – When record_id is not a safe token or when the resolved path escapes root.

safe_repository_id(token, *, context)[source]

Reject repository-id tokens that would compose into an unsafe filename.

Repositories store records as <store_dir>/<token>.envelope.json. A token containing a path separator, a dot-prefix, or one of the relative-path tokens ("." / "..") would either escape the store dir or collide with a hidden file. This helper is the early-rejection layer at the public-method boundary; the substrate’s safe_record_path() enforces containment downstream.

The validation is intentionally minimal — non-empty, no path separator, no dot-token. It does not claim knowledge of any domain-specific id alphabet (UUIDs, AEAT CSVs, modelo numerics, etc.) so a single helper covers every governance repository.

Parameters:
  • token (str) – The free-string id supplied by the repository caller.

  • context (str) – Stable label ("submission_id" / "draft_id" / etc.) embedded in the error message. Lets the failure message remain byte-identical to the per-domain validators it replaces.

Return type:

str

Returns:

token unchanged. Returning the validated value lets the helper appear inline (safe_repository_id(record_id, ...) as both check and pass-through).

Raises:

PathContainmentError – When token is empty, contains a path separator, is the bare . / .. token, or starts with a dot.