<?php namespace RAP; class GmsClient { private $locator; public function __construct(Locator $locator) { $this->locator = $locator; } public function joinGroups(string $userId1, string $userId2): string { if (!isset($this->locator->config->gms)) { return $userId1; } //create cURL connection $conn = curl_init($this->locator->config->gms->joinEndpoint); //set options curl_setopt($conn, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($conn, CURLOPT_RETURNTRANSFER, true); curl_setopt($conn, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($conn, CURLOPT_FOLLOWLOCATION, 1); // Setting an empty body, otherwise Content-Length will be negative and Spring will answer with 400 curl_setopt($conn, CURLOPT_POSTFIELDS, " "); curl_setopt($conn, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $this->getJoinAccessToken($userId1, $userId2)]); //set data to be posted curl_setopt($conn, CURLOPT_POST, 1); //perform the request $response = curl_exec($conn); $info = curl_getinfo($conn); if ($info['http_code'] === 200) { $joinResult = json_decode($response); curl_close($conn); if (!array_key_exists('mergedId', $joinResult)) { throw new ServerErrorException('GMS join response has an invalid payload'); } return $joinResult->mergedId; } else { //show information regarding the error curl_close($conn); error_log($response); $httpCode = $info['http_code']; if ($httpCode === 0) { throw new ServerErrorException('GMS service is unreachable'); } throw new ServerErrorException('Error: GMS response code: ' . $httpCode); } } private function getJoinAccessToken(int $userId1, int $userId2): string { $gmsId = $this->locator->config->gms->id; $accessToken = new AccessTokenData(); $accessToken->clientId = $gmsId; $accessToken->userId = $userId1; // shorter expiration $accessToken->expirationTime = $accessToken->creationTime + 100; $accessToken->scope = ['openid']; return $this->locator->getTokenBuilder()->getAccessToken($accessToken, function(& $jwt) use($userId2) { $jwt['alt_sub'] = strval($userId2); }); } }