mirror of
https://github.com/Cacti/cacti.git
synced 2026-11-02 18:17:00 +09:00
* log user action (create, delete, locked, ..) * change log * update changelog * style(auth): apply coding standards to user action logging Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * Audit password changes only after successful account saves Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(auth): sanitize audit fields and confirm account removals Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: cover native account audit state transitions Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: synchronize native coverage fixture dispatch Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(auth): audit only confirmed account persistence Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: measure coverage at the exact PR revision Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> Co-authored-by: Petr Macek <petr.macek@kostax.cz>
48 lines
1.8 KiB
PHP
48 lines
1.8 KiB
PHP
<?php
|
|
// Copyright (C) 2004-2026 The Cacti Group. GPL-2.0-or-later.
|
|
|
|
// Loaded only by the disposable E2E image when coverage is explicitly enabled.
|
|
$requestCoverageDirectory = getenv('CACTI_PR_RAW_COVERAGE');
|
|
|
|
if ($requestCoverageDirectory !== false && $requestCoverageDirectory !== '') {
|
|
if (!function_exists('xdebug_start_code_coverage')) {
|
|
throw new RuntimeException('Request coverage requires Xdebug.');
|
|
}
|
|
xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);
|
|
register_shutdown_function(static function () use ($requestCoverageDirectory) : void {
|
|
$data = xdebug_get_code_coverage();
|
|
|
|
foreach ($GLOBALS['cacti_fixture_source_map'] ?? [] as $temporary => $original) {
|
|
foreach ($data[$temporary] ?? [] as $line => $hits) {
|
|
$data[$original][$line] = max($hits, $data[$original][$line] ?? -2);
|
|
}
|
|
unset($data[$temporary]);
|
|
}
|
|
$root = realpath(dirname(__DIR__, 2));
|
|
$hashes = [];
|
|
$htmlSpans = [];
|
|
|
|
foreach ($data as $file => $lines) {
|
|
if (!str_starts_with($file, $root . '/') || str_contains($file, '/vendor/')) {
|
|
unset($data[$file]);
|
|
|
|
continue;
|
|
}
|
|
$hashes[$file] = hash_file('sha256', $file);
|
|
$htmlSpans[$file] = [];
|
|
|
|
// Zend records a literal HTML output opcode at the end of its block.
|
|
foreach (token_get_all(file_get_contents($file)) as $token) {
|
|
if (is_array($token) && $token[0] === T_INLINE_HTML) {
|
|
$htmlSpans[$file][] = [$token[2], $token[2] + substr_count($token[1], "\n")];
|
|
}
|
|
}
|
|
}
|
|
$path = $requestCoverageDirectory . '/' . getmypid() . '-' . bin2hex(random_bytes(8)) . '.json';
|
|
|
|
if (file_put_contents($path, json_encode(['root' => $root, 'coverage' => $data, 'hashes' => $hashes, 'html_spans' => $htmlSpans], JSON_THROW_ON_ERROR)) === false) {
|
|
throw new RuntimeException('Could not preserve request coverage.');
|
|
}
|
|
});
|
|
}
|