Skip to content
Draft
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
1 change: 1 addition & 0 deletions .github/workflows/php-formatting-behavior.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0
persist-credentials: false
- uses: ./.github/actions/setup-php-composer
Expand Down
10 changes: 10 additions & 0 deletions .github/workflows/pr-php-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ on:
- '**.php'
- 'tests/phpunit.xml'
- 'tests/e2e/**'
- 'cacti.sql'
- 'install/templates/**'
- 'resource/snmp_queries/**'
- 'tests/fixtures/snmp-coverage/**'
- '.dockerignore'
- 'composer.json'
- 'composer.lock'
- 'package.json'
- 'package-lock.json'
- 'build/**'
- 'tests/Helpers/RequestCoverage.php'
- 'tests/tools/check_changed_php_coverage.py'
- 'tests/tools/test_check_changed_php_coverage.py'
Expand Down
5 changes: 4 additions & 1 deletion lib/Auth/LoginResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ public static function failure(string $error, bool $isCredentialFailure = false)
return new self(false, null, $error, isCredentialFailure: $isCredentialFailure);
}

public static function authenticated(string $username, array $claims = [], ?array $user = null, bool $rememberMe = false): self {
public static function authenticated(string $username,
array $claims = [],
?array $user = null,
bool $rememberMe = false): self {
return new self(true, $user, '', $username, $claims, $rememberMe);
}
}
18 changes: 14 additions & 4 deletions lib/Auth/OpenIdLoginProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,9 @@ public function complete(): LoginResult {

if (!$token['success']) {
if ($this->debugEnabled) {
cacti_log('OIDC: token exchange failed for provider \'' . $this->getName() . '\': ' . $token['error'], false, 'AUTH');
cacti_log('OIDC: token exchange failed for provider \'' . $this->getName() . '\': ' . $token['error'],
false,
'AUTH');
}

return LoginResult::failure(__('Access Denied! Login Failed.'));
Expand Down Expand Up @@ -166,7 +168,11 @@ public function complete(): LoginResult {
// fetch; only trust it when its subject matches the already-verified
// ID token, or a substituted/inconsistent response could overwrite
// identity claims such as sub/preferred_username.
if (is_array($decoded) && isset($decoded['sub'], $claims['sub']) && hash_equals((string) $claims['sub'], (string) $decoded['sub'])) {
if (is_array($decoded) &&
isset($decoded['sub'],
$claims['sub']) &&
hash_equals((string) $claims['sub'],
(string) $decoded['sub'])) {
$claims = array_merge($claims, $decoded);
}
}
Expand Down Expand Up @@ -269,7 +275,10 @@ protected function discover(): array {

$discovery = json_decode($response['body'], true);

if (!is_array($discovery) || empty($discovery['authorization_endpoint']) || empty($discovery['token_endpoint']) || empty($discovery['jwks_uri'])) {
if (!is_array($discovery) ||
empty($discovery['authorization_endpoint']) ||
empty($discovery['token_endpoint']) ||
empty($discovery['jwks_uri'])) {
throw new \RuntimeException('Invalid OpenID discovery document');
}

Expand Down Expand Up @@ -297,6 +306,7 @@ protected function discover(): array {
}

protected function redirectUri(): string {
return rtrim((string) read_config_option('base_url'), '/') . '/login_sso.php?action=callback&realm=' . (1000 + $this->getId());
return rtrim((string) read_config_option('base_url'),
'/') . '/login_sso.php?action=callback&realm=' . (1000 + $this->getId());
}
}
4 changes: 3 additions & 1 deletion lib/CactiEmailChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public function __construct(?callable $mailer = null) {
$this->mailer = Closure::fromCallable($mailer);
}

public function notify(Notification $notification, RecipientInterface $recipient, ?string $transportName = null) : void {
public function notify(Notification $notification,
RecipientInterface $recipient,
?string $transportName = null) : void {
if (!$recipient instanceof EmailRecipientInterface || trim($recipient->getEmail()) === '') {
throw new LogicException('The Cacti email channel needs an email recipient.');
}
Expand Down
5 changes: 4 additions & 1 deletion lib/CactiMd5FileFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
use Symfony\Component\Finder\Exception\DirectoryNotFoundException;

final class CactiMd5FileFinder {
public function findHashes(string $basePath, string $ignoreRegex, array $excludedDirectories = [], ?Closure $debug = null) : array {
public function findHashes(string $basePath,
string $ignoreRegex,
array $excludedDirectories = [],
?Closure $debug = null) : array {
if (!is_dir($basePath) || !is_readable($basePath)) {
throw new DirectoryNotFoundException("The directory '$basePath' does not exist or is not readable.");
}
Expand Down
6 changes: 5 additions & 1 deletion lib/CactiProcessLock.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ final class CactiProcessLock {
private LockInterface $lock;
private ?PDO $connection;

public function __construct(LockFactory $factory, string $tasktype, string $taskname, int $taskid, ?PDO $connection = null) {
public function __construct(LockFactory $factory,
string $tasktype,
string $taskname,
int $taskid,
?PDO $connection = null) {
$this->lock = $factory->createLock(self::key($tasktype, $taskname, $taskid), self::TTL);
$this->connection = $connection;
}
Expand Down
139 changes: 120 additions & 19 deletions lib/aggregate.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@
*
* @return string The constructed URL as a hyperlink.
*/
function aggregate_build_children_url(int $local_graph_id, int $graph_start = -1, int $graph_end = -1, int $rra_id = -1) : string {
function aggregate_build_children_url(int $local_graph_id,
int $graph_start = -1,
int $graph_end = -1,
int $rra_id = -1) : string {
aggregate_prune_graphs($local_graph_id);

$aggregate_data = db_fetch_row_prepared('SELECT *
Expand All @@ -61,7 +64,21 @@ function aggregate_build_children_url(int $local_graph_id, int $graph_start = -1
$graph_select .= $graph . '%2C';
}

return "<a class='hyperLink aggregates' href='" . htmle(CACTI_PATH_URL . 'graph_view.php?reset=1&page=1&graph_template_id=-1&host_id=-1&filter=&style=selective&action=preview' . ($graph_start >= 0 ? '&graph_start=' . $graph_start : '') . ($graph_end >= 0 ? '&graph_end=' . $graph_end : '') . ($rra_id >= 0 ? '&rra_id=' . $rra_id : '') . '&' . $graph_select) . "'><i class='drillDown ti ti-sitemap-filled expandAggregate' title='" . __esc('Display Graphs from this Aggregate') . "'></i></a><br>" . PHP_EOL;
return "<a class='hyperLink aggregates' href='" .
htmle(CACTI_PATH_URL .
'graph_view.php?reset=1&page=1&graph_template_id=-1&host_id=-1&filter=&style=selective&action=preview' .
($graph_start >= 0 ? '&graph_start=' .
$graph_start : '') .
($graph_end >= 0 ? '&graph_end=' .
$graph_end : '') .
($rra_id >= 0 ? '&rra_id=' .
$rra_id : '') .
'&' .
$graph_select) .
"'><i class='drillDown ti ti-sitemap-filled expandAggregate' title='" .
__esc('Display Graphs from this Aggregate') .
"'></i></a><br>" .
PHP_EOL;
}
}

Expand All @@ -87,7 +104,9 @@ function api_aggregate_convert_template(array $graphs) : void {

// without a valid template the saves below would write null template fields
if (!cacti_sizeof($aggregate_template)) {
raise_message('aggregate_template_error', __('The selected Aggregate Template was not found! No graphs were migrated.'), MESSAGE_LEVEL_ERROR);
raise_message('aggregate_template_error',
__('The selected Aggregate Template was not found! No graphs were migrated.'),
MESSAGE_LEVEL_ERROR);

return;
}
Expand All @@ -98,7 +117,8 @@ function api_aggregate_convert_template(array $graphs) : void {
$save['local_graph_id'] = $graph;
$save['aggregate_template_id'] = $aggregate_template_id;
$save['template_propogation'] = 'on';
$save['title_format'] = db_fetch_cell_prepared('SELECT title_cache FROM graph_templates_graph WHERE local_graph_id = ?', [$graph]);
$save['title_format'] = db_fetch_cell_prepared('SELECT title_cache FROM graph_templates_graph WHERE local_graph_id = ?',
[$graph]);
$save['graph_template_id'] = $aggregate_template['graph_template_id'];
$save['gprint_prefix'] = $aggregate_template['gprint_prefix'];
$save['graph_type'] = $aggregate_template['graph_type'];
Expand Down Expand Up @@ -422,8 +442,15 @@ function aggregate_error_handler(int $errno, string $errmsg, string $filename, i
*
* @return int The next available sequence id
*/
function get_next_sequence(int $id, string $field, string $table_name, string $group_query, string $key_field = 'id') : int {
cacti_log(__FUNCTION__ . ' called. Id: ' . $id . ' field: ' . $field . ' table: ' . $table_name, true, 'AGGREGATE', POLLER_VERBOSITY_DEVDBG);
function get_next_sequence(int $id,
string $field,
string $table_name,
string $group_query,
string $key_field = 'id') : int {
cacti_log(__FUNCTION__ . ' called. Id: ' . $id . ' field: ' . $field . ' table: ' . $table_name,
true,
'AGGREGATE',
POLLER_VERBOSITY_DEVDBG);

if (empty($id)) {
$data = db_fetch_row("SELECT max($field)+1 AS seq FROM $table_name WHERE $group_query");
Expand Down Expand Up @@ -517,7 +544,16 @@ function aggregate_is_stacked_graph(int $_local_graph_id) : bool {
* @return void
*/
function aggregate_conditional_convert_graph_type(int $_graph_id, int $_old_type, int $_new_type) : void {
cacti_log(__FUNCTION__ . ' called: graph: ' . $_graph_id . ' old item type: ' . $_old_type . ' new item type: ' . $_new_type, true, 'AGGREGATE', POLLER_VERBOSITY_DEVDBG);
cacti_log(__FUNCTION__ .
' called: graph: ' .
$_graph_id .
' old item type: ' .
$_old_type .
' new item type: ' .
$_new_type,
true,
'AGGREGATE',
POLLER_VERBOSITY_DEVDBG);

if (!empty($_graph_id) && !empty($_old_type)) {
// fetch the first item of requested graph_type
Expand Down Expand Up @@ -547,7 +583,16 @@ function aggregate_conditional_convert_graph_type(int $_graph_id, int $_old_type
* @return int The resulting graph type after applying the change.
*/
function aggregate_change_graph_type(int $graph_index, int $old_graph_type, int $new_graph_type) : int {
cacti_log(__FUNCTION__ . ' called. Index ' . $graph_index . ' old type ' . $old_graph_type . ' Graph Type: ' . $new_graph_type, true, 'AGGREGATE', POLLER_VERBOSITY_DEVDBG);
cacti_log(__FUNCTION__ .
' called. Index ' .
$graph_index .
' old type ' .
$old_graph_type .
' Graph Type: ' .
$new_graph_type,
true,
'AGGREGATE',
POLLER_VERBOSITY_DEVDBG);

/* LEGEND entries and xRULEs stay unchanged
* xRULEs honestly do not make much sense on an aggregated graph, though */
Expand Down Expand Up @@ -653,7 +698,10 @@ function aggregate_change_graph_type(int $graph_index, int $old_graph_type, int
* @return void
*/
function duplicate_color_template(int $_color_template_id, string $color_template_title) : void {
cacti_log(__FUNCTION__ . ' called. Color Template Id: ' . $_color_template_id . ' Title: ' . $color_template_title, true, 'AGGREGATE', POLLER_VERBOSITY_DEVDBG);
cacti_log(__FUNCTION__ . ' called. Color Template Id: ' . $_color_template_id . ' Title: ' . $color_template_title,
true,
'AGGREGATE',
POLLER_VERBOSITY_DEVDBG);

// fetch data from table color_templates
$color_template = db_fetch_row_prepared('SELECT *
Expand All @@ -675,7 +723,16 @@ function duplicate_color_template(int $_color_template_id, string $color_templat
// substitute the title variable
$save['name'] = str_replace('<template_title>', $color_template['name'], $color_template_title);

cacti_log(__FUNCTION__ . ' called. Id:' . $_color_template_id . ' Title: ' . $color_template_title . ' Replaced: ' . $save['name'], true, 'AGGREGATE', POLLER_VERBOSITY_DEVDBG);
cacti_log(__FUNCTION__ .
' called. Id:' .
$_color_template_id .
' Title: ' .
$color_template_title .
' Replaced: ' .
$save['name'],
true,
'AGGREGATE',
POLLER_VERBOSITY_DEVDBG);

$new_color_template_id = sql_save($save, 'color_templates', 'color_template_id');

Expand All @@ -688,7 +745,16 @@ function duplicate_color_template(int $_color_template_id, string $color_templat
$save['color_id'] = $color_template_item['color_id'];
$save['sequence'] = $color_template_item['sequence'];

cacti_log(__FUNCTION__ . ' called. Id:' . $new_color_template_id . ' Color: ' . $save['color_id'] . ' sequence: ' . $save['sequence'], true, 'AGGREGATE', POLLER_VERBOSITY_DEBUG);
cacti_log(__FUNCTION__ .
' called. Id:' .
$new_color_template_id .
' Color: ' .
$save['color_id'] .
' sequence: ' .
$save['sequence'],
true,
'AGGREGATE',
POLLER_VERBOSITY_DEBUG);

$new_color_template_item_id = sql_save($save, 'color_template_items', 'color_template_item_id');
}
Expand Down Expand Up @@ -728,7 +794,10 @@ function aggregate_cdef_make0() : int {
// save the cdef itself
$new_cdef_id = sql_save($save, 'cdef');

cacti_log(__FUNCTION__ . ' created new cdef: ' . $new_cdef_id . ' name: ' . $magic, true, 'AGGREGATE', POLLER_VERBOSITY_DEBUG);
cacti_log(__FUNCTION__ . ' created new cdef: ' . $new_cdef_id . ' name: ' . $magic,
true,
'AGGREGATE',
POLLER_VERBOSITY_DEBUG);

// create a new cdef item entry
$save = [];
Expand Down Expand Up @@ -805,7 +874,16 @@ function aggregate_prepare_cdef_totalling(array $graph_template_items, array $cd
function aggregate_cdef_totalling(int $_new_graph_id, int $_graph_item_sequence, int $_total_type) : bool {
include_once(CACTI_PATH_LIBRARY . '/cdef.php');

cacti_log(__FUNCTION__ . ' called. Working on Graph: ' . $_new_graph_id . ' sequence: ' . $_graph_item_sequence . ' totalling: ' . $_total_type, true, 'AGGREGATE', POLLER_VERBOSITY_DEVDBG);
cacti_log(__FUNCTION__ .
' called. Working on Graph: ' .
$_new_graph_id .
' sequence: ' .
$_graph_item_sequence .
' totalling: ' .
$_total_type,
true,
'AGGREGATE',
POLLER_VERBOSITY_DEVDBG);

$graph_template_items = [];

Expand All @@ -827,7 +905,10 @@ function aggregate_cdef_totalling(int $_new_graph_id, int $_graph_item_sequence,
return false;
}

cacti_log(__FUNCTION__ . " totalling query: graph=$_new_graph_id seq=$_graph_item_sequence", true, 'AGGREGATE', POLLER_VERBOSITY_DEBUG);
cacti_log(__FUNCTION__ . " totalling query: graph=$_new_graph_id seq=$_graph_item_sequence",
true,
'AGGREGATE',
POLLER_VERBOSITY_DEBUG);
}

// now get the list of cdefs
Expand Down Expand Up @@ -861,7 +942,9 @@ function aggregate_cdef_totalling(int $_new_graph_id, int $_graph_item_sequence,
$prepared = aggregate_prepare_cdef_totalling($graph_template_items, $cdefs);

if ($prepared['invalid_cdef_id'] !== null) {
cacti_log(__FUNCTION__ . ' could not apply totals due to invalid or empty CDEF id ' . $prepared['invalid_cdef_id'], true, 'AGGREGATE');
cacti_log(__FUNCTION__ . ' could not apply totals due to invalid or empty CDEF id ' . $prepared['invalid_cdef_id'],
true,
'AGGREGATE');

return false;
}
Expand All @@ -879,7 +962,10 @@ function aggregate_cdef_totalling(int $_new_graph_id, int $_graph_item_sequence,
$cdef_name = $totalling_item['cdef_name'];
$cdef_text = $totalling_item['cdef_text'];

cacti_log(__FUNCTION__ . ' cdef id: ' . $cdef_id . ' name: ' . $cdef_name . ' value: ' . $cdef_text, true, 'AGGREGATE', POLLER_VERBOSITY_DEBUG);
cacti_log(__FUNCTION__ . ' cdef id: ' . $cdef_id . ' name: ' . $cdef_name . ' value: ' . $cdef_text,
true,
'AGGREGATE',
POLLER_VERBOSITY_DEBUG);

// new cdef
$new_cdef_text = 'INVALID'; // in case sth goes wrong
Expand All @@ -899,7 +985,10 @@ function aggregate_cdef_totalling(int $_new_graph_id, int $_graph_item_sequence,
$new_cdef_id = '';

foreach ($cdefs as $cdef) {
cacti_log(__FUNCTION__ . ' verify matching cdef: ' . $cdef['id'] . ' on: ' . $cdef['cdef_text'], true, 'AGGREGATE', POLLER_VERBOSITY_DEBUG);
cacti_log(__FUNCTION__ . ' verify matching cdef: ' . $cdef['id'] . ' on: ' . $cdef['cdef_text'],
true,
'AGGREGATE',
POLLER_VERBOSITY_DEBUG);

if ($cdef['cdef_text'] === $new_cdef_text) {
$new_cdef_id = $cdef['id'];
Expand Down Expand Up @@ -935,7 +1024,16 @@ function aggregate_cdef_totalling(int $_new_graph_id, int $_graph_item_sequence,
// save the cdef itself
$new_cdef_id = sql_save($save, 'cdef');

cacti_log(__FUNCTION__ . ' created new cdef: ' . $new_cdef_id . ' name: ' . $new_cdef_name . ' value: ' . $new_cdef_text, true, 'AGGREGATE', POLLER_VERBOSITY_DEBUG);
cacti_log(__FUNCTION__ .
' created new cdef: ' .
$new_cdef_id .
' name: ' .
$new_cdef_name .
' value: ' .
$new_cdef_text,
true,
'AGGREGATE',
POLLER_VERBOSITY_DEBUG);

// create a new cdef item entry
$save = [];
Expand Down Expand Up @@ -963,7 +1061,10 @@ function aggregate_cdef_totalling(int $_new_graph_id, int $_graph_item_sequence,
WHERE id = ?',
[$new_cdef_id, $graph_template_item['id']]);

cacti_log(__FUNCTION__ . ' updated new cdef id: ' . $new_cdef_id . ' for item: ' . $graph_template_item['id'], true, 'AGGREGATE', POLLER_VERBOSITY_DEBUG);
cacti_log(__FUNCTION__ . ' updated new cdef id: ' . $new_cdef_id . ' for item: ' . $graph_template_item['id'],
true,
'AGGREGATE',
POLLER_VERBOSITY_DEBUG);
}
}

Expand Down
Loading
Loading