This commit is contained in:
mrKamoo
2026-09-30 16:27:32 +02:00
commit 310724708f
147 changed files with 21327 additions and 0 deletions
@@ -0,0 +1,73 @@
<?php
namespace App\Services\Graph;
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use RuntimeException;
/**
* Client Microsoft Graph minimal (flux client credentials, permissions « application »).
* Permissions requises, avec consentement administrateur : User.Read.All, GroupMember.Read.All.
*/
class GraphClient
{
public function __construct(private readonly string $tenantId) {}
public function token(): string
{
return Cache::remember("graph-token:{$this->tenantId}", now()->addMinutes(50), function () {
$res = Http::asForm()->timeout(config('signature.graph.timeout'))
->post("https://login.microsoftonline.com/{$this->tenantId}/oauth2/v2.0/token", [
'client_id' => config('signature.graph.client_id'),
'client_secret' => config('signature.graph.client_secret'),
'scope' => 'https://graph.microsoft.com/.default',
'grant_type' => 'client_credentials',
]);
if (! $res->successful()) {
throw new RuntimeException('Jeton Graph refusé : '.$res->json('error_description', $res->body()));
}
return $res->json('access_token');
});
}
/** GET sur une URL relative (/users…) ou absolue (@odata.nextLink). */
public function get(string $url, array $headers = []): array
{
$full = str_starts_with($url, 'https://') ? $url : config('signature.graph.base_url').$url;
$res = Http::withToken($this->token())
->withHeaders($headers)
->timeout(config('signature.graph.timeout'))
// Nouvel essai sur limitation (429) ou indisponibilité temporaire de Graph.
->retry(3, 2000, fn ($e) => $e instanceof RequestException && in_array($e->response->status(), [429, 503, 504], true), throw: false)
->get($full);
if (! $res->successful()) {
throw new RuntimeException("Graph {$res->status()} sur {$url} : ".$res->body());
}
return $res->json();
}
/**
* Parcourt toutes les pages d'une collection.
* Retourne [éléments, deltaLink|null].
*/
public function all(string $url, array $headers = []): array
{
$items = [];
$delta = null;
$next = $url;
while ($next) {
$page = $this->get($next, $headers);
array_push($items, ...($page['value'] ?? []));
$next = $page['@odata.nextLink'] ?? null;
$delta = $page['@odata.deltaLink'] ?? $delta;
}
return [$items, $delta];
}
}