111 lines
3.7 KiB
PHP
111 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Intune;
|
|
|
|
use App\Models\Policy;
|
|
use App\Models\Tenant;
|
|
use App\Services\Graph\GraphClientInterface;
|
|
use App\Services\Graph\GraphErrorMapper;
|
|
use App\Services\Graph\GraphLogger;
|
|
use Illuminate\Support\Arr;
|
|
use Throwable;
|
|
|
|
class PolicySyncService
|
|
{
|
|
public function __construct(
|
|
private readonly GraphClientInterface $graphClient,
|
|
private readonly GraphLogger $graphLogger,
|
|
) {}
|
|
|
|
/**
|
|
* Sync supported policies for a tenant from Microsoft Graph.
|
|
*
|
|
* @return array<int> IDs of policies synced or created
|
|
*/
|
|
public function syncPolicies(Tenant $tenant, ?array $supportedTypes = null): array
|
|
{
|
|
if (! $tenant->isActive()) {
|
|
throw new \RuntimeException('Tenant is archived or inactive.');
|
|
}
|
|
|
|
$types = $supportedTypes ?? config('tenantpilot.supported_policy_types', []);
|
|
$synced = [];
|
|
$tenantIdentifier = $tenant->tenant_id ?? $tenant->external_id;
|
|
|
|
foreach ($types as $typeConfig) {
|
|
$policyType = $typeConfig['type'];
|
|
$platform = $typeConfig['platform'] ?? null;
|
|
|
|
$this->graphLogger->logRequest('list_policies', [
|
|
'tenant' => $tenantIdentifier,
|
|
'policy_type' => $policyType,
|
|
'platform' => $platform,
|
|
]);
|
|
|
|
try {
|
|
$response = $this->graphClient->listPolicies($policyType, [
|
|
'tenant' => $tenantIdentifier,
|
|
'client_id' => $tenant->app_client_id,
|
|
'client_secret' => $tenant->app_client_secret,
|
|
'platform' => $platform,
|
|
]);
|
|
} catch (Throwable $throwable) {
|
|
throw GraphErrorMapper::fromThrowable($throwable, [
|
|
'policy_type' => $policyType,
|
|
'tenant_id' => $tenant->id,
|
|
'tenant_identifier' => $tenantIdentifier,
|
|
]);
|
|
}
|
|
|
|
$this->graphLogger->logResponse('list_policies', $response, [
|
|
'policy_type' => $policyType,
|
|
'tenant_id' => $tenant->id,
|
|
'tenant' => $tenantIdentifier,
|
|
]);
|
|
|
|
if ($response->failed()) {
|
|
continue;
|
|
}
|
|
|
|
foreach ($response->data as $policyData) {
|
|
$externalId = $policyData['id'] ?? $policyData['external_id'] ?? null;
|
|
|
|
if ($externalId === null) {
|
|
continue;
|
|
}
|
|
|
|
$displayName = $policyData['displayName'] ?? $policyData['name'] ?? 'Unnamed policy';
|
|
$policyPlatform = $platform ?? ($policyData['platform'] ?? null);
|
|
|
|
$existingWithDifferentType = Policy::query()
|
|
->where('tenant_id', $tenant->id)
|
|
->where('external_id', $externalId)
|
|
->where('policy_type', '!=', $policyType)
|
|
->exists();
|
|
|
|
if ($existingWithDifferentType) {
|
|
continue;
|
|
}
|
|
|
|
$policy = Policy::updateOrCreate(
|
|
[
|
|
'tenant_id' => $tenant->id,
|
|
'external_id' => $externalId,
|
|
'policy_type' => $policyType,
|
|
],
|
|
[
|
|
'display_name' => $displayName,
|
|
'platform' => $policyPlatform,
|
|
'last_synced_at' => now(),
|
|
'metadata' => Arr::except($policyData, ['id', 'external_id', 'displayName', 'name', 'platform']),
|
|
]
|
|
);
|
|
|
|
$synced[] = $policy->id;
|
|
}
|
|
}
|
|
|
|
return $synced;
|
|
}
|
|
}
|