Hydrate configurationPolicies/{id}/settings for endpoint security/baseline policies so snapshots include real rule data.
Treat those types like Settings Catalog policies in the normalizer so they show the searchable settings table, recognizable categories, and readable choice values (firewall-specific formatting + interface badge parsing).
Improve “General” tab cards: badge lists for platforms/technologies, template reference summary (name/family/version/ID), and ISO timestamps rendered as YYYY‑MM‑DD HH:MM:SS; added regression test for the view.
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local>
Reviewed-on: #23
147 lines
4.6 KiB
PHP
147 lines
4.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Intune;
|
|
|
|
class SettingsCatalogPolicyNormalizer implements PolicyTypeNormalizer
|
|
{
|
|
public function __construct(
|
|
private readonly DefaultPolicyNormalizer $defaultNormalizer,
|
|
) {}
|
|
|
|
public function supports(string $policyType): bool
|
|
{
|
|
return in_array($policyType, ['settingsCatalogPolicy', 'endpointSecurityPolicy', 'securityBaselinePolicy'], true);
|
|
}
|
|
|
|
/**
|
|
* @return array{status: string, settings: array<int, array<string, mixed>>, settings_table?: array<string, mixed>, warnings: array<int, string>}
|
|
*/
|
|
public function normalize(?array $snapshot, string $policyType, ?string $platform = null): array
|
|
{
|
|
return $this->defaultNormalizer->normalize($snapshot, $policyType, $platform);
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function flattenForDiff(?array $snapshot, string $policyType, ?string $platform = null): array
|
|
{
|
|
$normalized = $this->normalize($snapshot ?? [], $policyType, $platform);
|
|
|
|
$map = [];
|
|
|
|
if (isset($normalized['settings_table']['rows']) && is_array($normalized['settings_table']['rows'])) {
|
|
$title = $normalized['settings_table']['title'] ?? 'Settings';
|
|
$prefix = is_string($title) && $title !== '' ? $title.' > ' : '';
|
|
$rows = $normalized['settings_table']['rows'];
|
|
|
|
$baseLabels = array_values(array_filter(array_map(function (mixed $row): ?string {
|
|
if (! is_array($row)) {
|
|
return null;
|
|
}
|
|
|
|
return $this->buildSettingsCatalogDiffLabel($row, includePath: false);
|
|
}, $rows)));
|
|
|
|
$labelCounts = array_count_values($baseLabels);
|
|
|
|
foreach ($rows as $row) {
|
|
if (! is_array($row)) {
|
|
continue;
|
|
}
|
|
|
|
$baseLabel = $this->buildSettingsCatalogDiffLabel($row, includePath: false);
|
|
$label = $baseLabel;
|
|
|
|
if (($labelCounts[$baseLabel] ?? 0) > 1) {
|
|
$path = $row['path'] ?? null;
|
|
$pathLabel = is_string($path) && $path !== '' ? $path : null;
|
|
|
|
$label = $this->buildSettingsCatalogDiffLabel($row, includePath: true);
|
|
|
|
if ($pathLabel !== null) {
|
|
$label .= ' @ '.$pathLabel;
|
|
}
|
|
}
|
|
|
|
$key = $prefix.$label;
|
|
$map[$key] = $row['value'] ?? null;
|
|
}
|
|
}
|
|
|
|
foreach ($normalized['settings'] ?? [] as $block) {
|
|
if (! is_array($block)) {
|
|
continue;
|
|
}
|
|
|
|
$title = $block['title'] ?? null;
|
|
$prefix = is_string($title) && $title !== '' ? $title.' > ' : '';
|
|
|
|
if (($block['type'] ?? null) === 'table') {
|
|
foreach ($block['rows'] ?? [] as $row) {
|
|
if (! is_array($row)) {
|
|
continue;
|
|
}
|
|
|
|
$key = $prefix.($row['path'] ?? $row['label'] ?? 'entry');
|
|
$map[$key] = $row['value'] ?? null;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
|
|
foreach ($block['entries'] ?? [] as $entry) {
|
|
if (! is_array($entry)) {
|
|
continue;
|
|
}
|
|
|
|
$key = $prefix.($entry['key'] ?? 'entry');
|
|
$map[$key] = $entry['value'] ?? null;
|
|
}
|
|
}
|
|
|
|
return $map;
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $row
|
|
*/
|
|
private function buildSettingsCatalogDiffLabel(array $row, bool $includePath): string
|
|
{
|
|
$category = $row['category'] ?? null;
|
|
$definition = $row['definition'] ?? null;
|
|
$definitionId = $row['definition_id'] ?? null;
|
|
|
|
$label = is_string($definition) && $definition !== '' ? $definition : 'Setting';
|
|
|
|
if ($includePath) {
|
|
$path = $row['path'] ?? null;
|
|
|
|
if (is_string($path) && $path !== '') {
|
|
$label = $path;
|
|
}
|
|
|
|
if (
|
|
is_string($label)
|
|
&& is_string($definitionId)
|
|
&& $definitionId !== ''
|
|
&& is_string($definition)
|
|
&& $definition !== ''
|
|
) {
|
|
$parts = explode(' > ', $label);
|
|
|
|
if ($parts !== [] && end($parts) === $definitionId) {
|
|
$parts[count($parts) - 1] = $definition;
|
|
$label = implode(' > ', $parts);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (is_string($category) && $category !== '' && $category !== '-') {
|
|
$label = $category.' > '.$label;
|
|
}
|
|
|
|
return $label;
|
|
}
|
|
}
|