Skip to content

fix: migrate shell_exec callers to CactiProcess::run()#7088

Closed
somethingwithproof wants to merge 5 commits into
Cacti:developfrom
somethingwithproof:fix/cactiprocess-migration-develop
Closed

fix: migrate shell_exec callers to CactiProcess::run()#7088
somethingwithproof wants to merge 5 commits into
Cacti:developfrom
somethingwithproof:fix/cactiprocess-migration-develop

Conversation

@somethingwithproof

Copy link
Copy Markdown
Contributor

Replace direct shell_exec()/exec() calls with \Cacti\Process\CactiProcess::run() across poller, script, CLI, and SNMP agent code paths.

Scope

23 production files updated; 2 new test files added:

  • scripts/sql.php, scripts/ss_sql.php, scripts/ss_netsnmp_lmsensors.php
  • lib/ping.php, lib/rrd.php, lib/poller.php
  • poller_realtime.php, poller_spikekill.php, graph_realtime.php, script_server.php, cactid.php, host.php
  • install/functions.php
  • cli/batchgapfix.php, cli/float_rrdfiles.php, cli/splice_rrd.php, cli/audit_database.php, cli/push_out_hosts.php, cli/remove_broken_graphs.php, cli/update_heartbeat.php
  • snmpagent_mibcache.php, snmpagent_persist.php
  • tests/Unit/SqlScriptsTest.php (updated assertions)
  • tests/Unit/CactiProcessTest.php (new)
  • tests/handoff/CactiProcessHandOffTest.php (new)

Why

shell_exec() with string interpolation bypasses argument quoting and makes it impossible to pass credentials safely via environment variables. CactiProcess::run() accepts an argv array and an env map, so passwords (e.g. MYSQL_PWD) never appear in the process argument list.

Verification

  • tests/Unit/SqlScriptsTest.php confirms MYSQL_PWD env pattern and absence of -p$password in argv.
  • tests/Unit/CactiProcessTest.php covers split() and run() behaviour including env passthrough and timeout.
  • tests/handoff/CactiProcessHandOffTest.php checks each migrated file for the expected patterns at the source level.

Signed-off-by: Thomas Vincent thomasvincent@gmail.com

Copilot AI review requested due to automatic review settings April 30, 2026 07:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR aims to harden Cacti’s command-execution paths by migrating direct shell_exec()/exec()/passthru() usage to \Cacti\Process\CactiProcess::run() (argv-array + env map), reducing injection risk and keeping credentials out of argv (e.g., MYSQL_PWD).

Changes:

  • Migrates many PHP call sites to CactiProcess::run()/start() and updates related parsing/error handling.
  • Adds/updates tests to assert env-based password passing and to “handoff” check migrated sources.
  • Refactors several JS files to modern jQuery event binding patterns and fixes multiple UI string typos; adds CodeQL + Dependabot configs.

Reviewed changes

Copilot reviewed 44 out of 44 changed files in this pull request and generated 14 comments.

Show a summary per file
File Description
tests/handoff/CactiProcessHandOffTest.php Adds source-level “handoff” assertions for migrations
tests/Unit/SqlScriptsTest.php Updates tests for MYSQL_PWD + CactiProcess usage
tests/Unit/CactiProcessTest.php Adds unit coverage for split()/run() behavior
snmpagent_persist.php Migrates process detection/spawn logic to CactiProcess
snmpagent_mibcache.php Migrates background spawn logic to CactiProcess
scripts/ss_sql.php Switches mysqladmin execution to argv+env (MYSQL_PWD)
scripts/ss_netsnmp_lmsensors.php Replaces shell pipeline with Process output parsing
scripts/sql.php Switches mysqladmin execution to argv+env (MYSQL_PWD)
script_server.php Migrates Windows TASKLIST call to argv-based Process
poller_spikekill.php Migrates removespikes invocation to argv-based Process
poller_realtime.php Migrates realtime cmd execution + rrd create calls
package_repos.php Fixes UI label spelling (“Repositories”)
lib/rrd.php Uses CactiProcess for RRDtool; adds IPv6-aware proxy socket init
lib/poller.php Migrates background execution to CactiProcess::start()
lib/ping.php Migrates ping/fping execution to argv-based Process
install/install.js jQuery handler refactors + template literal usage
install/functions.php Migrates import_package.php invocation to CactiProcess
include/themes/sunrise/main.js Replaces unbind/hover with off/on patterns
include/themes/raspberry/main.js Replaces unbind/hover with off/on patterns
include/themes/paw/main.js Replaces unbind/hover with off/on patterns
include/themes/paper-plane/main.js Replaces unbind/hover with off/on patterns
include/themes/modern/main.js Replaces change() bindings with on('change')
include/themes/midwinter/main.js Refactors bindings; minor event trigger adjustments
include/themes/hollyberry/main.js Replaces unbind/hover with off/on patterns
include/themes/dark/main.js Replaces change/hover with on('...') patterns
include/themes/carrot/main.js Replaces unbind/hover with off/on patterns
include/themes/cacti/main.js Replaces unbind/hover with off/on patterns
include/realtime.js Refactors string concat to template literals; event binding tweaks
include/layout.js Refactors event binding; fixes “deprecated” spelling
host.php Migrates reindex invocation to argv-based Process
graph_realtime.php Migrates realtime poller call to argv-based Process
data_templates.php Fixes UI message grammar
cli/update_heartbeat.php Migrates rrdtool tune execution to argv-based Process
cli/splice_rrd.php Migrates rrdtool dump execution to CactiProcess (writes XML via PHP)
cli/remove_broken_graphs.php Migrates stty invocation to argv-based Process
cli/push_out_hosts.php Migrates passthru to CactiProcess and prints output
cli/float_rrdfiles.php Adds RRD path validation + migrates rrdtool exec to Process
cli/batchgapfix.php Migrates removespikes invocation to argv-based Process
cli/audit_database.php Migrates “which mysql” discovery to argv-based Process
cactid.php Migrates pgrep usage to argv-based Process + output filtering
automation_templates.php Fixes UI grammar (“device’s …”)
automation_networks.php Fixes UI grammar (“sender’s …”)
.github/workflows/codeql.yml Adds CodeQL workflow
.github/dependabot.yml Adds Dependabot config
Comments suppressed due to low confidence (1)

include/realtime.js:184

  • This selector is missing a '#' for the element id, so zoom() is being bound to a non-existent tag name (e.g. <graph_123>) instead of the graph element. It should target the graph element by id consistently with the rest of the file (e.g. #graph_${graph_id}).
		$(`graph_${graph_id}`).zoom({
			inputfieldStartTime : 'date1',
			inputfieldEndTime : 'date2',
			serverTimeOffset : timeOffset
		});

Comment thread graph_realtime.php

// call poller
$local_graph_id = (int) gfrv('local_graph_id');
$local_graph_id = CactiSecureType::toInt(gfrv('local_graph_id'));

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CactiSecureType is not defined anywhere in the codebase (no class definition found), so this call will fatal. Use the existing integer-cast pattern (e.g., (int)gfrv('local_graph_id')) or switch to an existing validator/type helper that actually exists in the repo.

Suggested change
$local_graph_id = CactiSecureType::toInt(gfrv('local_graph_id'));
$local_graph_id = (int) gfrv('local_graph_id');

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — CactiSecureType removed; using standard get_filter_request_var() integer cast.

Comment thread snmpagent_persist.php
Comment on lines +92 to 94
if (cacti_sizeof($output) == 0) {
\Cacti\Process\CactiProcess::start(array_merge([$php], explode(' ', $extra_args)));
}

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explode(' ', $extra_args) will keep quotes produced by cacti_escapeshellarg() and split incorrectly. Construct argv directly (e.g. [$php, '-q', './snmpagent_mibcache.php']) before calling CactiProcess::start().

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — argv built directly as [$php, './snmpagent_mibcache.php']; no explode.

Comment thread install/install.js Outdated
Comment on lines 290 to 294
button = $(`#button${buttonName}`);
if (button !== null) {
button.button();
button.button('enable');
}

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enableButton() assigns to button without declaring it, which creates/overwrites a global variable and can cause hard-to-debug bugs in the installer UI. Declare it with const/let inside the function scope.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — button declared with var in both disableButton() and enableButton().

Comment on lines +8 to +9
require_once __DIR__ . '/../../lib/CactiProcess.php';

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This unit test requires ../../lib/CactiProcess.php, but that file is not present in the repository, so the test suite will fatally error. Either add the missing file to the PR or update the test to load CactiProcess from the actual location (e.g., via Composer autoload).

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — lib/CactiProcess.php, CactiProcessException.php, and CactiProcessResult.php added to the branch.

Comment thread install/functions.php
$shell_output = $process->getOutput();
} catch (\Exception $e) {
$shell_output = '';
} $myinfo = @json_decode($shell_output !== false && $shell_output !== null ? $shell_output : '', true) ?? [];

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There appears to be an accidental formatting/whitespace issue: the closing brace and the $myinfo assignment are on the same line. This makes the code hard to read and easy to miss in reviews; please put the $myinfo assignment on its own line with normal indentation.

Suggested change
} $myinfo = @json_decode($shell_output !== false && $shell_output !== null ? $shell_output : '', true) ?? [];
}
$myinfo = @json_decode($shell_output !== false && $shell_output !== null ? $shell_output : '', true) ?? [];

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Comment thread lib/ping.php Outdated
Comment on lines +178 to +179
$process = \Cacti\Process\CactiProcess::run($argv, [], (float)($this->timeout / 1000 + 1));
$result = $process->getOutput() . $process->getErrorOutput();

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CactiProcess::run() is called without a try/catch here, but other call sites treat it as throwable (timeouts/start failures). An uncaught exception will break polling/UI flows instead of returning ping failure. Wrap these run() calls in try/catch and map failures to the existing 'down' status/result handling.

Suggested change
$process = \Cacti\Process\CactiProcess::run($argv, [], (float)($this->timeout / 1000 + 1));
$result = $process->getOutput() . $process->getErrorOutput();
try {
$process = \Cacti\Process\CactiProcess::run($argv, [], (float)($this->timeout / 1000 + 1));
$result = $process->getOutput() . $process->getErrorOutput();
} catch (\Throwable $e) {
cacti_log('WARNING: ICMP Ping Error: Unable to execute fping for ' . $this->host['hostname'] . ': ' . $e->getMessage());
$result = '';
}

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — both CactiProcess::run() calls in ping.php now wrapped in try/catch; exception maps to empty result (down status).

Comment on lines +10 to +13
test('CactiProcess::split handles quoted args', function () {
$argv = \Cacti\Process\CactiProcess::split("rrdtool dump '/var/lib/cacti/rrd/host.rrd'");
expect($argv)->toBe(['rrdtool', 'dump', '/var/lib/cacti/rrd/host.rrd']);
});

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation in this new test uses spaces, but existing tests use tabs (e.g., tests/Unit/AddSiteTest.php:16-28). Please adjust indentation to match the repository style.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — converted to tabs throughout.

Comment thread install/install.js Outdated
Comment on lines 282 to 286
button = $(`#button${buttonName}`);
if (button !== null) {
button.button();
button.button('disable');
}

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

disableButton() assigns to button without declaring it, which creates/overwrites a global variable and can cause hard-to-debug bugs in the installer UI. Declare it with const/let inside the function scope.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — button declared with var in both functions.

Comment thread scripts/sql.php
Comment on lines +9 to +12
require_once(__DIR__ . '/../lib/CactiProcess.php');

$argv = ['mysqladmin', '-h', $database_hostname, '-u', $database_username, 'status'];
$env = [];

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script now requires ../lib/CactiProcess.php, but that file does not exist in the repo (so this will fatal at runtime). Add/commit lib/CactiProcess.php (or update the include path/autoloading to where CactiProcess actually lives) before switching callers to it.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — lib/CactiProcess.php now committed to the branch.

Comment thread scripts/ss_sql.php
Comment on lines +39 to +41
require_once(__DIR__ . '/../lib/CactiProcess.php');

$argv = ['mysqladmin', '--host=' . $database_hostname, '--user=' . $database_username, 'status'];

Copilot AI Apr 30, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does a require_once on ../lib/CactiProcess.php, but lib/CactiProcess.php is not present in the repository, which will cause a fatal error when ss_sql() is called. Ensure the CactiProcess implementation is added to the repo or adjust the require to the correct location/autoloader.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — lib/CactiProcess.php now committed to the branch.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
… construction

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
@somethingwithproof somethingwithproof force-pushed the fix/cactiprocess-migration-develop branch from dddc4bd to 828cf12 Compare May 5, 2026 06:45
somethingwithproof added a commit to somethingwithproof/cacti that referenced this pull request May 8, 2026
Match the flat un-namespaced lib/CactiX.php convention used by Cacti#7088,
Cacti#7073, Cacti#7077, Cacti#7075. Drop symfony/process (added by Cacti#7073) and
symfony/validator (added by Cacti#7077) to avoid composer.json conflicts at
merge time.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
somethingwithproof added a commit to somethingwithproof/cacti that referenced this pull request May 8, 2026
Match the un-namespaced lib/CactiX.php convention used by canonical PRs
(Cacti#7088 CactiProcess, Cacti#7073 CactiMime, Cacti#7077 CactiSettings, Cacti#7075
CactiApplication/CactiCommand). The previous nested PSR-4 namespace
required composer autoload changes that conflicted with those PRs.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
somethingwithproof added a commit to somethingwithproof/cacti that referenced this pull request May 8, 2026
Drop lib/Process/CactiProcess.php and tests/Unit/CactiProcessTest.php to
avoid colliding with Cacti#7088 / Cacti#7073, which already provide the canonical
flat lib/CactiProcess.php.

Move the remaining wrappers to the un-namespaced lib/CactiX.php
convention used by every other lib/Cacti*.php class on develop:

  lib/Filesystem/CactiFilesystem.php -> lib/CactiFilesystem.php
  lib/Http/CactiRequest.php          -> lib/CactiRequest.php
  lib/Log/CactiLogger.php            -> lib/CactiLogger.php

Tests load the classes via require_once instead of the dropped PSR-4
autoloader.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
somethingwithproof added a commit to somethingwithproof/cacti that referenced this pull request May 8, 2026
Rename lib/Security/CactiOAuth.php to lib/CactiOAuth.php and drop the
Cacti\Security namespace. Update the two callers (oauth2.php and
lib/functions.php mailer) to use the unqualified class name. Behavior
is unchanged: only the FQCN was rewritten.

The flat layout matches every other lib/Cacti*.php class on develop and
in the canonical PRs (Cacti#7088, Cacti#7073, Cacti#7077, Cacti#7075).

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
@somethingwithproof

Copy link
Copy Markdown
Contributor Author

Closing — broken against #7073's API. The 20 callsite migrations on this branch use \Cacti\Process\CactiProcess (wrong namespace; #7073 declares the class globally), call getOutput()/getErrorOutput() on the return value (#7073's run() returns a CactiProcessResult with stdout()/stderr()), and pass timeout as a third positional arg (#7073 expects ['timeout' => N] in opts). Will redo correctly on #7073 (feat/develop-symfony-process-runner).

Separate finding worth surfacing: the Windows-ping migration in lib/ping.php drops cacti_escapeshellarg($this->host['hostname']) and passes cmd /c "chcp 437 && ping -w … -n … {hostname}" as a single string. Argv-array form does not bypass cmd.exe here because of the cmd /c "..." wrapper, so a hostname containing & or | would chain commands. Will re-escape (or restructure away from cmd /c) when redoing on #7073.

TheWitness added a commit that referenced this pull request May 12, 2026
…7124)

* test: shared hand-off + mutation infrastructure for feature PRs

Consolidates infection/infection dev dep, allow-plugins entry, baseline
infection.json5, tests/HandOff/HandOffHelpers.php with reusable stubs
(cacti_log capture, temp-file fixtures, minimal-zip builder), HandOff
testsuite registration, and the documented pattern. Feature PRs that
add hand-off coverage rebase onto this and contribute only ONE
HandOffTest file plus an optional infection.json5 filter override.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: consolidate per-feature hand-off suites into shared infra

Each test guards on its feature file and skips when not present on develop.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(test): replace eval stub, unify log buffer ref, guard ZipArchive add

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(ci): correct infection vendor path in infection.json5

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* ci(phpstan): baseline upstream undefined-variable and isset errors

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: add HandOff and Integration testsuites; add regression guards

- phpunit.xml: add Integration testsuite alongside existing Unit/HandOff
- tests/Integration/: DbDumpIntegrationTest, PingIntegrationTest (from develop), CactiProcessIntegrationTest, SqlScriptsIntegrationTest
- tests/HandOff/RegressionGuardTest: guards against backsliding on shell_exec, password-in-argv, RLIKE concat, and open-redirect patterns

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* chore(test): pest test infrastructure and PSR-4 autoload

Add Pest 2 dev dependency, regenerate composer.lock under PHP 8.1, declare PSR-4 autoload for the Cacti namespace, and seed the test bootstrap with three unit tests plus an orb integration check. Pest stays on the v2 line because v3 transitively requires PHP 8.2 and breaks the 8.1 matrix entry.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* chore(phpstan): catch up baseline with 11 upstream-detected entries

Cacti Commit Audit fails on develop with 11 PHPStan errors that are
not yet in phpstan-baseline.neon. Append the matching entries so the
PR-A branch passes Run PHPStan at Level 6. Same set of entries
already exists on PR #7077; this is a transient catch-up that
upstream will absorb when those entries land on develop.

Files: aggregate_graphs.php, color_templates.php, graph_templates.php,
graphs.php, lib/html.php (3 entries).

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* chore(test): drop composer.lock; let CI resolve per PHP version

The lock file pinned brianium/paratest v7.3.1 which only supports
PHP 8.1-8.3, so the 8.4 matrix entry rejected the lock with
"Your lock file does not contain a compatible set of packages".
A single lock cannot satisfy 8.1 (paratest 7.3.x) and 8.4 (paratest
7.4.x) at the same time because pestphp/pest 2.36.0 is the last
2.x release that supports 8.1 and the 8.1-compatible paratest tag
predates 8.4 support.

Match upstream develop's behaviour: no committed lock; let
`composer install` in CI resolve per matrix entry. Pest stays on
the v2 line in composer.json so 8.1 still gets a compatible Pest.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(test): apply Copilot review feedback for test infra

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* chore(test): drop psr-4 autoload and align deps with canonical PRs

Match the flat un-namespaced lib/CactiX.php convention used by #7088,
#7073, #7077, #7075. Drop symfony/process (added by #7073) and
symfony/validator (added by #7077) to avoid composer.json conflicts at
merge time.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: skip integration suites and regression guards pending feature PRs

Guards integration tests and regression guards from #7083 against
absence of CactiProcess and other feature-PR hardening, so the
consolidated foundation PR is green on develop. Suites activate
automatically once their feature PRs merge.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* fix(ci): drop infection/infection to unbreak PHP 8.4 matrix

infection/infection ^0.27 transitively pins thecodingmachine/safe
^2.1.2, resolving to v2.5.0. Its generated stubs use implicit-nullable
parameter declarations, which PHP 8.4 emits as deprecations into
cacti.log and trips the log-quiet assertion. infection has no config
or test wiring in this repo, so removing the dev dep clears the
transitive pin without losing functionality.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
TheWitness added a commit that referenced this pull request May 13, 2026
* refactor(oauth): extract Cacti\Security\CactiOAuth provider factory

Replace the inline provider switch in oauth2.php and the OAuth
branch of mailer() in lib/functions.php with two helpers:

- CactiOAuth::getProvider($name, $params) returns the configured
  provider instance for `google`, `azure`, `yahoo`, or `microsoft`,
  or null when the configured provider is unknown.
- CactiOAuth::getDefaultOptions($name) returns the scope set each
  provider expects.

Behaviour is preserved; both call sites now branch on a null
return rather than relying on a `$provider` variable that may have
fallen through the switch unset.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* chore(phpstan): catch up baseline with 11 upstream-detected entries

Same as PR-A: appends 11 PHPStan ignoreErrors entries that exist on
upstream develop but are not yet baselined, so this branch's CI does
not regress on phpstan analyse --level 6.

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* refactor: flatten CactiOAuth to global namespace

Rename lib/Security/CactiOAuth.php to lib/CactiOAuth.php and drop the
Cacti\Security namespace. Update the two callers (oauth2.php and
lib/functions.php mailer) to use the unqualified class name. Behavior
is unchanged: only the FQCN was rewritten.

The flat layout matches every other lib/Cacti*.php class on develop and
in the canonical PRs (#7088, #7073, #7077, #7075).

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>

* test: add shared unit stubs for OAuth tests

* fix(oauth): load provider factory in runtime paths

* test(oauth): pin provider factory runtime loading

---------

Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants