This commit is contained in:
2026-05-27 11:48:31 -04:00
parent 414f85ad05
commit 5aa5af3411
31 changed files with 2165 additions and 0 deletions

135
test_calendar_sa.php Normal file
View File

@ -0,0 +1,135 @@
<?php
// CONFIG — adapte juste cet email:
$impersonate = 'leith.s@ms1timing.com'; // l'utilisateur MS1 à impersonnifier
$jsonPath = __DIR__ . '/application/credentials/service_account.json';
// ---- Helpers ----
function b64url($data)
{
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function http_post_json($url, $fields)
{
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_POSTFIELDS => http_build_query($fields),
CURLOPT_TIMEOUT => 30,
]);
$res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($res === false) {
throw new Exception('cURL error: ' . curl_error($ch));
}
curl_close($ch);
return [$code, $res];
}
function http_get_auth($url, $bearer)
{
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $bearer],
CURLOPT_TIMEOUT => 30,
]);
$res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($res === false) {
throw new Exception('cURL error: ' . curl_error($ch));
}
curl_close($ch);
return [$code, $res];
}
// ---- 1) Charger la clé de service ----
if (!file_exists($jsonPath)) die("Fichier JSON introuvable: $jsonPath\n");
$creds = json_decode(file_get_contents($jsonPath), true);
if (!$creds) die("Impossible de parser le JSON\n");
$client_email = $creds['client_email'];
$private_key = $creds['private_key'];
$token_uri = isset($creds['token_uri']) ? $creds['token_uri'] : 'https://oauth2.googleapis.com/token';
// ---- 2) Construire le JWT (RS256) ----
// Scopes minimum lecture/écriture dévénements:
$scope = 'https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events';
$now = time();
$exp = $now + 3600; // 1h
$iss = $client_email;
$sub = $impersonate; // <- impersonation (DWD)
$aud = $token_uri;
$header = ['alg' => 'RS256', 'typ' => 'JWT'];
$claim = [
'iss' => $iss,
'scope' => $scope,
'aud' => $aud,
'exp' => $exp,
'iat' => $now,
'sub' => $sub
];
$jwt_unsigned = b64url(json_encode($header)) . '.' . b64url(json_encode($claim));
// Signer avec la clé privée
$signature = '';
$ok = openssl_sign($jwt_unsigned, $signature, $private_key, 'sha256WithRSAEncryption');
if (!$ok) {
die("Échec openssl_sign(). Vérifie la private_key.\n");
}
$jwt = $jwt_unsigned . '.' . b64url($signature);
// ---- 3) Échanger le JWT contre un access_token ----
list($code, $body) = http_post_json($token_uri, [
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt
]);
if ($code !== 200) {
echo "Échec token ($code): $body\n";
exit(1);
}
$tok = json_decode($body, true);
$access_token = $tok['access_token'] ?? null;
if (!$access_token) {
die("Pas d'access_token dans la réponse.\n");
}
echo "OK token reçu.\n";
// ---- 4) Appel test non destructif : lister les agendas de l'utilisateur ----
$url = 'https://www.googleapis.com/calendar/v3/users/me/calendarList';
list($code2, $body2) = http_get_auth($url, $access_token);
echo "GET calendarList => HTTP $code2\n";
echo $body2 . "\n";
// ---- 5) Créer un petit événement de test (dans primary) ----
$event = [
'summary' => 'Test CRM↔Google',
'description' => 'Évènement de validation DWD',
'start' => ['dateTime' => date('c', time()+3600)], // +1h
'end' => ['dateTime' => date('c', time()+7200)], // +2h
];
$ch = curl_init('https://www.googleapis.com/calendar/v3/calendars/primary/events');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer '.$access_token,
'Content-Type: application/json'
],
CURLOPT_POSTFIELDS => json_encode($event),
CURLOPT_TIMEOUT => 30,
]);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
echo "POST event => HTTP $code\n$resp\n";