Files
crm-ms1/v4_ci4/app/Libraries/Radar/GoogleWorkspaceToken.php

103 lines
3.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Libraries\Radar;
/**
* JWT + access token Google Workspace (Domain-Wide Delegation).
* Même pattern que application/libraries/GCalService.php (MSOP-4).
*/
class GoogleWorkspaceToken
{
private string $jsonPath;
private string $tokenUri = 'https://oauth2.googleapis.com/token';
public function __construct(string $jsonPath)
{
$this->jsonPath = $jsonPath;
if (! is_file($this->jsonPath)) {
throw new \RuntimeException('Service account JSON introuvable: ' . $this->jsonPath);
}
}
public function getAccessToken(string $impersonateEmail, string $scopes): string
{
$creds = json_decode((string) file_get_contents($this->jsonPath), true);
if (! is_array($creds) || empty($creds['client_email']) || empty($creds['private_key'])) {
throw new \RuntimeException('service_account.json invalide');
}
$now = time();
$header = ['alg' => 'RS256', 'typ' => 'JWT'];
$claim = [
'iss' => $creds['client_email'],
'scope' => $scopes,
'aud' => $this->tokenUri,
'exp' => $now + 3600,
'iat' => $now,
'sub' => $impersonateEmail,
];
$unsigned = $this->b64url(json_encode($header)) . '.' . $this->b64url(json_encode($claim));
$signature = '';
if (! openssl_sign($unsigned, $signature, $creds['private_key'], OPENSSL_ALGO_SHA256)) {
throw new \RuntimeException('openssl_sign failed');
}
$jwt = $unsigned . '.' . $this->b64url($signature);
[$code, $body] = $this->http(
'POST',
$this->tokenUri,
['Content-Type: application/x-www-form-urlencoded'],
http_build_query([
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt,
])
);
if ($code !== 200) {
throw new \RuntimeException("Token Google error ({$code}): {$body}");
}
$tok = json_decode($body, true);
if (empty($tok['access_token'])) {
throw new \RuntimeException('Pas daccess_token dans la réponse Google');
}
return $tok['access_token'];
}
/**
* @param list<string> $headers
* @return array{0:int,1:string}
*/
public function http(string $method, string $url, array $headers = [], ?string $body = null): array
{
$ch = curl_init($url);
$opts = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_TIMEOUT => 60,
CURLOPT_HTTPHEADER => $headers,
];
if ($body !== null) {
$opts[CURLOPT_POSTFIELDS] = $body;
}
curl_setopt_array($ch, $opts);
$res = curl_exec($ch);
$code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($res === false) {
$err = curl_error($ch);
curl_close($ch);
throw new \RuntimeException('cURL error: ' . $err);
}
curl_close($ch);
return [$code, $res];
}
private function b64url(string $data): string
{
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
}