Files
RustProxy/tools/checks/certificate_api_0319.py
T
2026-10-12 14:57:37 +02:00

69 lines
4.6 KiB
Python
Executable File

#!/usr/bin/env python3
"""0.31.9 Certificate API source/OpenAPI/UI contracts; no Rust runtime claims."""
import json
from pathlib import Path
import tomllib
root = Path(__file__).resolve().parents[2]
read = lambda path: (root / path).read_text(encoding='utf-8')
version = tomllib.loads(read('Cargo.toml'))['package']['version']
assert version == '0.31.9', version
spec = json.loads(read('src/admin/openapi.json'))
assert spec['info']['version'] == version
paths = spec['paths']
assert set(paths['/api/certificate-api/{key_id}']) == {'get', 'patch', 'delete'}
assert set(paths['/api/certificate-api/{key_id}/regenerate']) == {'post'}
for method, path in [('get', '/api/certificate-api/{key_id}'), ('patch', '/api/certificate-api/{key_id}'),
('post', '/api/certificate-api/{key_id}/regenerate')]:
operation = paths[path][method]
assert operation['security'] == ([{'AdminSession': []}] if method == 'get' else [{'AdminSession': [], 'CsrfToken': []}])
assert operation['parameters'][0]['name'] == 'key_id'
assert '401' in operation['responses'] and '404' in operation['responses']
edit = spec['components']['schemas']['CertificateApiEdit']
assert edit['additionalProperties'] is False
assert set(edit['required']) == {'comment', 'certificate_ids', 'allow_deploy'}
assert not {'token', 'token_hash', 'key_id'} & edit['properties'].keys()
assert set(spec['components']['schemas']['CertificateApiDetailResult']['properties']) == {'credential'}
assert set(spec['components']['schemas']['CertificateApiRegenerateResult']['properties']) == {'credential', 'token'}
assert 'readOnly' in spec['components']['schemas']['CertificateApiRegenerateResult']['properties']['token']
backend = read('src/admin/certificate_api.rs')
router = read('src/admin/router.rs')
db = read('src/db/certificate_api.rs')
assert 'include!("certificate_api.rs")' in read('src/admin/mod.rs')
for symbol in ('certificate_api_detail', 'certificate_api_edit', 'certificate_api_regenerate'):
assert f'async fn {symbol}(' in backend
assert symbol in router
assert 'deny_unknown_fields' in backend
read_source = backend.split('async fn certificate_api_detail(')[1].split('async fn certificate_api_edit(')[0]
edit_source = backend.split('async fn certificate_api_edit(')[1].split('async fn certificate_api_regenerate(')[0]
regenerate_source = backend.split('async fn certificate_api_regenerate(')[1].split('async fn certificate_api_revoke(')[0]
assert '"token"' not in read_source
assert '"token"' not in edit_source and '"token_hash"' not in edit_source
assert '"token": token' in regenerate_source
assert 'auth::random_secret()' in regenerate_source
assert '"certificate_api.invalid_certificate_ids"' in edit_source
update_source = db.split('pub async fn edit_certificate_api_credential(')[1].split('pub async fn regenerate_certificate_api_token(')[0]
rotate_source = db.split('pub async fn regenerate_certificate_api_token(')[1].split('pub async fn revoke_certificate_api_credential(')[0]
assert 'SET comment = ?' in update_source
assert 'SET token_hash' not in update_source
assert 'SET token_hash = ?, created_at = ?, last_used_at = NULL' in rotate_source
assert 'certificate_api.edit' in update_source and 'certificate_api.regenerate' in rotate_source
assert 'WHERE key_id = ?' in rotate_source
assert 'certificate_api_operation(method: &Method' in router or 'fn certificate_api_operation(method: &Method' in read('src/admin/access.rs') + router
assert 'if method != Method::POST' in router
panel = read('src/admin/web/certificate-api.js')
assert 'include_str!("web/certificate-api.js")' in router
for marker in ('function certificateApiDetailNode(', 'beginCertificateApiEdit(', 'certificateApiEditingKey',
'method: "PATCH"', '/regenerate', 'showCertificateApiSecret(data.token || "")',
'clearCertificateApiSecret()', 'token-field', 'certificateApiTokenHidden'):
assert marker in panel, marker
for item in ('certificate-api-save', 'certificate-api-cancel-edit', 'certificate-api-secret', 'certificate-api-token-field'):
assert f'id="{item}"' in read('src/admin/web/index.html')
for language in ('en_US', 'pl_pl'):
strings = json.loads(read(f'langs/{language}.json'))['translations']
for key in ('certificateApiView', 'certificateApiEdit', 'certificateApiSave', 'certificateApiRegenerate',
'certificateApiRegenerateConfirm', 'certificateApiTokenHidden', 'certificateApiCreatedAt'):
assert strings.get(key), (language, key)
assert '0.31.9' in read('docs/TEST_REPORT.md')
print('PASS: 0.31.9 per-credential API routes, separated metadata editing/token regeneration, OpenAPI security, UI and locales (source-only).')