"""Verify the installed Tea client in a disposable configuration, without tokens in output.""" import argparse import csv import io import json import os from pathlib import Path import subprocess import tempfile import time parser = argparse.ArgumentParser() parser.add_argument('--isolation-only', action='store_true') args = parser.parse_args() tea = '/home/worsch/bin/tea' report = {'native_changes': False, 'client': 'installed Tea 0.9.2', 'profile': 'existing routed workstation development credential; no independent agent identity claim', 'original_tea_configuration_used': False, 'credential_values_emitted': False} secret = os.environ.pop('API_TOKEN', '') with tempfile.TemporaryDirectory(prefix='wp80-tea-proof-') as temporary: os.chmod(temporary, 0o700) environment = dict(os.environ) for key in ['GITEA_SERVER_TOKEN', 'GITEA_SERVER_PASSWORD', 'GITEA_SERVER_USER', 'GITEA_SERVER_URL']: environment.pop(key, None) # Tea documents this child-only configuration location in its own help. environment['XDG_CONFIG_HOME'] = temporary def call(arguments): start = time.monotonic() result = subprocess.run([tea, *arguments], cwd=temporary, env=environment, capture_output=True, text=True, timeout=30) return result, round(time.monotonic() - start, 3) listing, _ = call(['logins', 'list', '-o', 'csv']) rows = list(csv.DictReader(io.StringIO(listing.stdout))) if listing.returncode or rows: raise SystemExit('Tea configuration isolation failed; no login was written') report['configuration_isolation_verified'] = True if args.isolation_only: report['mode'] = 'configuration-isolation-only; no credential or API request' else: if not secret: raise SystemExit('Use the owner-routed --exec transport; API_TOKEN missing') environment['GITEA_SERVER_TOKEN'] = secret login, seconds = call(['logins', 'add', '--name', 'wp80-current', '--url', 'https://forgejo.coulomb.social']) environment.pop('GITEA_SERVER_TOKEN', None) secret = '' report['login_exit_code'] = login.returncode report['login_seconds'] = seconds if login.returncode == 0: for path in Path(temporary).rglob('*'): if path.is_file(): path.chmod(0o600) listing, _ = call(['logins', 'list', '-o', 'csv']) rows = list(csv.DictReader(io.StringIO(listing.stdout))) if listing.returncode or len(rows) != 1 or rows[0].get('URL') != 'https://forgejo.coulomb.social': raise SystemExit('Unexpected current-host configuration; raw output discarded') user = rows[0].get('User', '') if not user or len(user) > 64 or not all(c.isalnum() or c in '._-' for c in user): raise SystemExit('Unexpected identity metadata; raw output discarded') report['api_user'] = user who, seconds = call(['whoami']) report['whoami_exit_code'] = who.returncode report['whoami_seconds'] = seconds report['returned_identity_matches'] = user in who.stdout repo, seconds = call(['repos', '--login', 'wp80-current', '--fields', 'owner,name,permission', '--output', 'csv', 'coulomb/the-custodian']) report['repository_read_exit_code'] = repo.returncode report['repository_read_seconds'] = seconds report['expected_repository_returned'] = 'the-custodian' in repo.stdout and 'coulomb' in repo.stdout report['passed'] = (who.returncode == repo.returncode == 0 and report['returned_identity_matches'] and report['expected_repository_returned']) else: report['passed'] = False report['reason'] = 'Current-host token login failed; raw child output discarded' report['temporary_configuration_removed'] = True print(json.dumps(report, indent=2)) if not args.isolation_only and not report.get('passed'): raise SystemExit(1)