11 Commits

Author SHA1 Message Date
n0mad1k d09fce309f Ignore project-local notes.md (homelab-specific, not for publication) 2026-07-10 15:03:05 -04:00
n0mad1k 9fd114d1b0 Isolate mock_paths fixture from host MOUNT_ROOT config; simplify probe_target mount check
mock_paths patched TARGET_DIR/PENDING_DIR/etc but not MOUNT_ROOT, so tests leaked the host's real ~/pCloudDrive mount_root config and failed probe_target's mountpoint check. Also drop redundant equality clause since is_relative_to already covers equal paths, and document the mount precondition.
2026-07-10 14:40:36 -04:00
n0mad1k 2853d2e125 Guard probe_target against creating phantom local dirs when mount_root is unmounted 2026-07-10 14:36:20 -04:00
n0mad1k 759d4a6e23 Genericize: drop pCloud terminology, use TARGET_DIR / target_dir
pCloud was never a hard dependency - the tool writes to any local directory.
Renaming makes the tool clearly generic before publishing.

- PCLOUD_TARGET → TARGET_DIR
- probe_pcloud → probe_target
- place_into_pcloud → place_into_target
- pcloud_target config key → target_dir
- COE_MIRROR_PCLOUD_TARGET env var → COE_MIRROR_TARGET_DIR
- Hardcoded default: ~/pCloudDrive/Hacking/ChurchOfMalware → ~/coe-mirror
- Log messages and docstrings updated
- Tests updated to match

DevTrack #1286
2026-07-07 11:12:46 -04:00
n0mad1k 376115a9de Make distributable: config.toml support, blanked Matrix defaults, env creds fallback
- ~/.config/coe-mirror/config.toml (tomllib, Python 3.11+ required)
- Precedence uniform for every key: env var > config file > hardcoded default
- API_BASE, OWNERS, PCLOUD_TARGET, PENDING_DIR, matrix homeserver/room resolved
  via _resolve() helper
- Matrix homeserver/room now default to empty; _send_matrix short-circuits when
  either is blank so forks don't spam the original author's room
- _fetch_creds falls back to COE_MIRROR_MATRIX_USER/PASSWORD env vars when the
  Infisical creds binary is unavailable (required for external distribution)
- CLI subcommands: config init (writes example TOML, won't overwrite), config path
  Bare invocation and 'run' still work unchanged for the systemd timer
- README rewritten as a public quick-start with the precedence table and Matrix
  as opt-in
- Tests: 3 new for config precedence, 1 for Matrix silent no-op when blank,
  2 for creds env fallback (26 total, all pass)

DevTrack #1285
2026-07-07 11:04:07 -04:00
n0mad1k 9ffe38cbbc Mirror all four Church of Malware owners, per-owner pcloud subdirs
- OWNERS list replaces single OWNER: Nightmare_Eclipse, shai_hulud, bikini_mirror, ek0mssavi0r
- PCLOUD_TARGET moves to ChurchOfMalware/ parent, per-owner subdirs at runtime
- Owner threaded through fetch_repos, fetch_branch_sha, download_repo_zip
- Pending filenames get owner__ prefix to prevent cross-owner collisions
- flush_pending strips owner prefix when routing to owner subdir
- Per-owner fetch failure logs and continues; failed_owners reported in notify
- notify groups new files by owner; also picks up flushes done at run start
- Tests: parametrize on OWNERS via monkeypatch, add multi-owner collision and
  per-owner failure isolation tests

DevTrack #1284
2026-07-06 12:35:56 -04:00
Cobra 4d0fbff039 swap to dedicated @coe-mirror-bot for Matrix sends
Replaces shared @intel-bot credentials with a Matrix user created
specifically for this tool. Reads Infisical keys via constants
COE_MIRROR_BOT_USER_KEY and COE_MIRROR_BOT_PASSWORD_KEY so test
assertions track the code rather than hardcoded strings.
2026-06-15 09:31:24 -04:00
n0mad1k 6681779552 Fix type hints and resource management in coe_mirror
- Add precise type hints: Optional[Tuple[str, str]] for _fetch_creds(),
  List[Tuple[str, str, str]] for notify()
- Wrap requests.Session in context manager for proper cleanup
- Remove unreachable return False after retry loop in _send_matrix()
2026-06-14 14:40:14 -04:00
n0mad1k 24d062fc5d Implement real Matrix notification for coe-mirror
Replace stub notify() with full Synapse integration targeting General room.
- Add _send_matrix(), _get_matrix_token(), _matrix_login() helpers
- Implement token cache with 30-min refresh threshold and 401 retry
- Fetch credentials via Infisical (MATRIX_USER, MATRIX_PASSWORD from matrix/)
- Add MATRIX_* env overrides for testing (homeserver, room, token cache path)
- Non-fatal failures: Matrix outage logs warning, does not break mirror run
- Add 5 comprehensive test cases covering success, failure, 401 refresh, env override, chmod 600
- All 18 tests passing
- Update README and notes.md with implementation details
2026-06-14 14:36:14 -04:00
Cobra 745844f721 install.sh: skip pip when requests is already system-wide
PEP 668 Debian 13 systems error out on 'pip install --user'. Runtime
only needs requests; pytest+requests-mock are test-only. Detect the
runtime dep first and fall back to pip only when missing.
2026-06-11 09:37:02 -04:00
Cobra 45a8d6163e coe-mirror: mirror Nightmare_Eclipse Forgejo repos to pCloud
Standalone Python tool. Hits git.churchofmalware.org public API every
12h (00:00/12:00), downloads any repo HEAD whose SHA hasn't already
been snapshotted to pCloud, with local-staging fallback when the FUSE
mount is unavailable. Matrix notification stub for when the home
server is back.

Devil's-advocate findings folded into the design:
  - shutil.copy2 + size verify + unlink, not os.rename, for FUSE safety
  - no pCloud daemon auto-start (no user unit; DISPLAY=:0 unreliable);
    relies on Persistent timer + pending flush for recovery
  - two-call API path retained because the repo list response does not
    include commit.sha

Audit-driven security fixes:
  - repo names whitelist-validated (^[a-zA-Z0-9._-]+$)
  - urllib.parse.quote on all interpolated URL segments
  - same-file no-op guard in place_into_pcloud
  - existence check moved to main() so cached files don't generate
    spurious notify entries

13 pytest tests passing.
2026-06-11 09:34:55 -04:00