TenantAtlas/app/Services/Intune/WindowsUpdateRingNormalizer.php
Ahmed Darrazi c1fbb4620f feat(rings): Add support for Windows Update Rings
Implements support for syncing, viewing, and restoring Windows Update Ring policies (windowsUpdateRing).

- Adds a WindowsUpdateRingNormalizer to provide a readable view of the policy settings in the Filament UI.

- Adds feature tests for the UI display and restore functionality.

- Verifies that the existing snapshot and restore services correctly handle this policy type.
2025-12-31 21:20:30 +01:00

138 lines
4.0 KiB
PHP

<?php
namespace App\Services\Intune;
use Illuminate\Support\Str;
class WindowsUpdateRingNormalizer implements PolicyTypeNormalizer
{
public function __construct(
private readonly DefaultPolicyNormalizer $defaultNormalizer,
) {}
public function supports(string $policyType): bool
{
return $policyType === 'windowsUpdateRing';
}
/**
* @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
{
$snapshot = $snapshot ?? [];
$normalized = $this->defaultNormalizer->normalize($snapshot, $policyType, $platform);
if ($snapshot === []) {
return $normalized;
}
$normalized['settings'] = array_values(array_filter(
$normalized['settings'],
fn (array $block) => strtolower((string) ($block['title'] ?? '')) !== 'general'
));
$normalized['settings'][] = $this->buildUpdateSettingsBlock($snapshot);
$normalized['settings'][] = $this->buildUserExperienceBlock($snapshot);
$normalized['settings'][] = $this->buildAdvancedOptionsBlock($snapshot);
$normalized['settings'] = array_values(array_filter($normalized['settings']));
return $normalized;
}
/**
* @return array<string, mixed>
*/
public function flattenForDiff(?array $snapshot, string $policyType, ?string $platform = null): array
{
$snapshot = $snapshot ?? [];
$normalized = $this->normalize($snapshot, $policyType, $platform);
return $this->defaultNormalizer->flattenNormalizedForDiff($normalized);
}
private function buildUpdateSettingsBlock(array $snapshot): ?array
{
$keys = [
'allowWindows11Upgrade',
'automaticUpdateMode',
'featureUpdatesDeferralPeriodInDays',
'featureUpdatesPaused',
'featureUpdatesPauseExpiryDateTime',
'qualityUpdatesDeferralPeriodInDays',
'qualityUpdatesPaused',
'qualityUpdatesPauseExpiryDateTime',
'updateWindowsDeviceDriverExclusion',
];
return $this->buildBlock('Update Settings', $snapshot, $keys);
}
private function buildUserExperienceBlock(array $snapshot): ?array
{
$keys = [
'deadlineForFeatureUpdatesInDays',
'deadlineForQualityUpdatesInDays',
'deadlineGracePeriodInDays',
'gracePeriodInDays',
'restartActiveHoursStart',
'restartActiveHoursEnd',
'setActiveHours',
'userPauseAccess',
'userCheckAccess',
];
return $this->buildBlock('User Experience', $snapshot, $keys);
}
private function buildAdvancedOptionsBlock(array $snapshot): ?array
{
$keys = [
'deliveryOptimizationMode',
'prereleaseFeatures',
'servicingChannel',
'microsoftUpdateServiceAllowed',
];
return $this->buildBlock('Advanced Options', $snapshot, $keys);
}
private function buildBlock(string $title, array $snapshot, array $keys): ?array
{
$entries = [];
foreach ($keys as $key) {
if (array_key_exists($key, $snapshot)) {
$entries[] = [
'key' => Str::headline($key),
'value' => $this->formatValue($snapshot[$key]),
];
}
}
if ($entries === []) {
return null;
}
return [
'type' => 'keyValue',
'title' => $title,
'entries' => $entries,
];
}
private function formatValue(mixed $value): mixed
{
if (is_bool($value)) {
return $value ? 'Yes' : 'No';
}
if (is_array($value)) {
return json_encode($value, JSON_PRETTY_PRINT);
}
return $value;
}
}