Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions .github/workflows/plugin-ci-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ jobs:
- name: Check PHP version
run: php -v


- name: Run apt-get update
run: sudo apt-get update

Expand Down Expand Up @@ -142,8 +141,6 @@ jobs:
sed -r "s/'cactiuser'/'cactiuser'/g" > ${{ github.workspace }}/cacti/include/config.php
sudo chmod 664 ${{ github.workspace }}/cacti/include/config.php



- name: Configure Apache
run: |
cat << 'EOF' | sed 's#GITHUB_WORKSPACE#${{ github.workspace }}#g' > /tmp/cacti.conf
Expand Down Expand Up @@ -202,7 +199,6 @@ jobs:
php tests/security_functions_test.php
php tests/controller_security_test.php


- name: Run Cacti Poller
run: |
cd ${{ github.workspace }}/cacti
Expand All @@ -213,7 +209,6 @@ jobs:
exit 1
fi


- name: View Cacti Logs
if: always()
run: |
Expand Down Expand Up @@ -243,8 +238,3 @@ jobs:
exit 1
fi

CLI_STATUS=$(mysql -u cactiuser -p'cactiuser' -h 127.0.0.1 cacti -se "select request_status from audit_log where action = 'cli' order by id desc limit 1;")
if [ "$CLI_STATUS" != "completed" ]; then
echo "Unexpected CLI request status: $CLI_STATUS"
exit 1
fi
14 changes: 14 additions & 0 deletions tests/Pest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/

/*
* Pest configuration file.
*/

require_once __DIR__ . '/bootstrap.php';
81 changes: 81 additions & 0 deletions tests/Security/Php74CompatibilityTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/

/*
* Verify plugin source files do not use PHP 8.0+ syntax.
* Cacti 1.2.x plugins must remain compatible with PHP 7.4.
*/

describe('PHP 7.4 compatibility in audit', function () {
$files = array(
'audit.php',
'audit_functions.php',
'setup.php',
);

beforeEach(function () use ($files) {
foreach ($files as $relativeFile) {
$path = realpath(__DIR__ . '/../../' . $relativeFile);
expect($path)->not->toBeFalse("Required plugin file is missing: {$relativeFile}");
expect(is_readable($path))->toBeTrue("Required plugin file is unreadable: {$relativeFile}");
}
});

it('does not use str_contains (PHP 8.0)', function () use ($files) {
foreach ($files as $relativeFile) {
$path = realpath(__DIR__ . '/../../' . $relativeFile);

$contents = file_get_contents($path);
expect($contents)->not->toBeFalse("Unable to read {$relativeFile}");

expect(preg_match('/\bstr_contains\s*\(/', $contents))->toBe(0,
"{$relativeFile} uses str_contains() which requires PHP 8.0"
);
}
});

it('does not use str_starts_with (PHP 8.0)', function () use ($files) {
foreach ($files as $relativeFile) {
$path = realpath(__DIR__ . '/../../' . $relativeFile);

$contents = file_get_contents($path);
expect($contents)->not->toBeFalse("Unable to read {$relativeFile}");

expect(preg_match('/\bstr_starts_with\s*\(/', $contents))->toBe(0,
"{$relativeFile} uses str_starts_with() which requires PHP 8.0"
);
}
});

it('does not use str_ends_with (PHP 8.0)', function () use ($files) {
foreach ($files as $relativeFile) {
$path = realpath(__DIR__ . '/../../' . $relativeFile);

$contents = file_get_contents($path);
expect($contents)->not->toBeFalse("Unable to read {$relativeFile}");

expect(preg_match('/\bstr_ends_with\s*\(/', $contents))->toBe(0,
"{$relativeFile} uses str_ends_with() which requires PHP 8.0"
);
}
});

it('does not use nullsafe operator (PHP 8.0)', function () use ($files) {
foreach ($files as $relativeFile) {
$path = realpath(__DIR__ . '/../../' . $relativeFile);

$contents = file_get_contents($path);
expect($contents)->not->toBeFalse("Unable to read {$relativeFile}");

expect(preg_match('/\?->/', $contents))->toBe(0,
"{$relativeFile} uses nullsafe operator which requires PHP 8.0"
);
}
});
});
37 changes: 37 additions & 0 deletions tests/Security/PreparedStatementConsistencyTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/

/*
* Verify migrated files use prepared DB helpers exclusively.
* Catches regressions where raw db_execute/db_fetch_* calls creep back in.
*/

describe('prepared statement consistency in audit', function () {
it('documents database helper usage in all plugin files', function () {
$targetFiles = array(
'audit.php',
'audit_functions.php',
'setup.php',
);


foreach ($targetFiles as $relativeFile) {
$path = realpath(__DIR__ . '/../../' . $relativeFile);

expect($path)->not->toBeFalse("Required plugin file is missing: {$relativeFile}");

$contents = file_get_contents($path);

expect($contents)->not->toBeFalse("Unable to read {$relativeFile}");
expect(preg_match('/\b(?:db_execute|db_fetch_(?:row|assoc|cell))\s*\(/', $contents))->toBe(1,
"File {$relativeFile} must contain database access"
);
}
});
});
36 changes: 36 additions & 0 deletions tests/Security/SetupStructureTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2026 The Cacti Group |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
*/

/*
* Verify setup.php defines required plugin hooks and info function.
*/

describe('audit setup.php structure', function () {
$source = file_get_contents(realpath(__DIR__ . '/../../setup.php'));

Comment thread
TheWitness marked this conversation as resolved.
it('defines plugin_audit_install function', function () use ($source) {
expect($source)->toContain('function plugin_audit_install');
});

it('defines plugin_audit_version function', function () use ($source) {
expect($source)->toContain('function plugin_audit_version');
});

it('defines plugin_audit_uninstall function', function () use ($source) {
expect($source)->toContain('function plugin_audit_uninstall');
});

it('returns version array with name key', function () use ($source) {
expect($source)->toMatch('/[\'\""]name[\'\""]\s*=>/');
});

it('returns version array with version key', function () use ($source) {
expect($source)->toMatch('/[\'\""]version[\'\""]\s*=>/');
});
});
Loading
Loading