From 7ea80562f15f748e8a397474ab635cabaa4e31ed Mon Sep 17 00:00:00 2001 From: Jim Seconde Date: Wed, 15 Jan 2025 12:19:08 +0000 Subject: [PATCH 1/5] Added shim layer --- src/OpenTok/OpenTok.php | 40 ++++++++++++++++++++++++++----- src/OpenTok/Util/Client.php | 20 ++++++++++++++++ src/OpenTok/Util/Validators.php | 18 ++++++++++++++ tests/OpenTokTest/OpenTokTest.php | 32 +++++++++++++++++++++++-- tests/OpenTokTest/test.key | 28 ++++++++++++++++++++++ 5 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 tests/OpenTokTest/test.key diff --git a/src/OpenTok/OpenTok.php b/src/OpenTok/OpenTok.php index 72506734..66cc29a1 100644 --- a/src/OpenTok/OpenTok.php +++ b/src/OpenTok/OpenTok.php @@ -35,17 +35,35 @@ class OpenTok private $apiSecret; /** @internal */ private $client; - /** @internal */ + + /** + * @var array + * @internal + * Options that can override the defaults. Additionally, you can set the keys + * application_id & private_key_path to strings that will then override the default + * OpenTok Client behaviour when making requests to the Vonage Video API. + */ public $options; /** @internal */ public function __construct($apiKey, $apiSecret, $options = array()) { + $validateKeys = true; + Validators::validateVonageJwtArguments($options); + $apiUrl = 'https://api.opentok.com'; + + if (array_key_exists('application_id', $options) && array_key_exists('private_key_path', $options)) { + $validateKeys = false; + $apiUrl = 'https://video.api.vonage.com'; + } + // unpack optional arguments (merging with default values) into named variables $defaults = array( - 'apiUrl' => 'https://api.opentok.com', + 'apiUrl' => $apiUrl, 'client' => null, - 'timeout' => null // In the future we should set this to 2 + 'timeout' => null, // In the future we should set this to 2 + 'application_id' => null, + 'private_key_path' => null, ); $this->options = array_merge($defaults, array_intersect_key($options, $defaults)); @@ -53,8 +71,11 @@ public function __construct($apiKey, $apiSecret, $options = array()) list($apiUrl, $client, $timeout) = array_values($this->options); // validate arguments - Validators::validateApiKey($apiKey); - Validators::validateApiSecret($apiSecret); + if ($validateKeys) { + Validators::validateApiKey($apiKey); + Validators::validateApiSecret($apiSecret); + } + Validators::validateApiUrl($apiUrl); Validators::validateClient($client); Validators::validateDefaultTimeout($timeout); @@ -116,9 +137,16 @@ public function __construct($apiKey, $apiSecret, $options = array()) * @param bool $legacy By default, OpenTok uses SHA256 JWTs for authentication. Switching * legacy to true will create a deprecated T1 token for backwards compatibility. * + * Optionally, you can set $vonage to true and it will generate a Vonage Video token if you are using + * the shim behaviour. + * * @return string The token string. */ - public function generateToken(string $sessionId, array $options = array(), bool $legacy = false): string + public function generateToken( + string $sessionId, + array $options = array(), + bool $legacy = false + ): string { // Note, JWT generation disabled due to a backend bug regarding `exp` claims being mandatory - CRT // if ($legacy) { diff --git a/src/OpenTok/Util/Client.php b/src/OpenTok/Util/Client.php index 9771b332..af04f8e6 100755 --- a/src/OpenTok/Util/Client.php +++ b/src/OpenTok/Util/Client.php @@ -36,6 +36,7 @@ use OpenTok\Exception\ForceDisconnectAuthenticationException; use OpenTok\Exception\ForceDisconnectUnexpectedValueException; +use Vonage\JWT\TokenGenerator; /** * @internal @@ -46,6 +47,8 @@ class Client protected $apiKey; protected $apiSecret; + protected $applicationId = null; + protected $privateKeyPath = null; protected $configured = false; /** @@ -64,6 +67,14 @@ public function configure($apiKey, $apiSecret, $apiUrl, $options = array()) $this->apiKey = $apiKey; $this->apiSecret = $apiSecret; + if (array_key_exists('application_id', $options) || array_key_exists('private_key_path', $options)) { + if (!is_null($options['application_id']) && !is_null($options['private_key_path'])) { + $this->applicationId = $options['application_id']; + $this->privateKeyPath = $options['private_key_path']; + $apiUrl = 'https://video.api.vonage.com'; + } + } + if (isset($this->options['client'])) { $this->client = $options['client']; } else { @@ -124,6 +135,14 @@ public function isConfigured() private function createAuthHeader() { + if (!is_null($this->applicationId) && !is_null($this->privateKeyPath)) { + $projectRoot = dirname(__DIR__, 3); // Adjust the number of dirname() calls if necessary to match your + // project structure. + $privateKeyFullPath = $projectRoot . DIRECTORY_SEPARATOR . $this->privateKeyPath; + $tokenGenerator = new TokenGenerator($this->applicationId, file_get_contents($privateKeyFullPath)); + return $tokenGenerator->generate(); + } + $token = array( 'ist' => 'project', 'iss' => $this->apiKey, @@ -131,6 +150,7 @@ private function createAuthHeader() 'exp' => time() + (5 * 60), 'jti' => uniqid('', true), ); + return JWT::encode($token, $this->apiSecret, 'HS256'); } diff --git a/src/OpenTok/Util/Validators.php b/src/OpenTok/Util/Validators.php index 6607b45f..0e2475b0 100755 --- a/src/OpenTok/Util/Validators.php +++ b/src/OpenTok/Util/Validators.php @@ -34,6 +34,24 @@ public static function validateApiKey($apiKey) } } + public static function validateVonageJwtArguments(array $options) + { + if (!isset($data['application_id']) && !isset($data['private_key_path'])) { + return; + } + + if (isset($data['application_id']) && isset($data['private_key_path'])) { + if (is_string($data['application_id']) && is_string($data['private_key_path'])) { + return; + }; + } + + // If one key is present but not the other, validation fails + throw new InvalidArgumentException( + 'You are attempting to use the Vonage Video API. Both application_id and private key paths must be in options and both strings.' + ); + } + public static function validateForceMuteAllOptions(array $options) { $validOptions = [ diff --git a/tests/OpenTokTest/OpenTokTest.php b/tests/OpenTokTest/OpenTokTest.php index 4920acbc..088216a2 100644 --- a/tests/OpenTokTest/OpenTokTest.php +++ b/tests/OpenTokTest/OpenTokTest.php @@ -758,9 +758,37 @@ public function testWillCreateLegacyT1DirectlyToBypassExpBug(): void $this->assertEquals('T1', substr($token, 0, 2)); } + public function testWillHitVonageVideoWithVonageJwt(): void + { + // All of this manual DRY exists because the hardcoded setup helper methods + // were not written to handle this sort of behaviour overriding. + $mocks = [ + 'code' => 200, + 'headers' => [ + 'Content-Type' => 'application/json' + ], + 'path' => 'v2/project/APIKEY/archive/session' + ]; + + $customAgent = [ + 'application_id' => 'abc123', + 'private_key_path' => './tests/OpenTokTest/test.key', + ]; + + $this->setupOTWithMocks([$mocks], $customAgent); + + $sessionId = '2_MX44NTQ1MTF-flR1ZSBOb3YgMTIgMDk6NDA6NTkgUFNUIDIwMTN-MC43NjU0Nzh-'; + $archive = $this->opentok->startArchive($sessionId, ['maxBitrate' => 2000000]); + + $this->assertCount(1, $this->historyContainer); + + $request = $this->historyContainer[0]['request']; + $this->assertEquals('POST', strtoupper($request->getMethod())); + } + /** * Makes sure that a JWT is generated for the client-side token - * + * * Currently disabled due to the backend requiring an `exp` claim, which was * not required on T1s. Uncomment when the backend is fixed. - CRT */ @@ -1319,7 +1347,7 @@ public function testGetsArchiveWithMaxBitrate(): void $request = $this->historyContainer[0]['request']; $this->assertEquals('GET', strtoupper($request->getMethod())); - $this->assertEquals('/v2/project/'.$this->API_KEY.'/archive/'.$archiveId, $request->getUri()->getPath()); + $this->assertEquals('/v2/project/' . $this->API_KEY . '/archive/' . $archiveId, $request->getUri()->getPath()); $this->assertEquals('api.opentok.com', $request->getUri()->getHost()); $this->assertEquals('https', $request->getUri()->getScheme()); diff --git a/tests/OpenTokTest/test.key b/tests/OpenTokTest/test.key new file mode 100644 index 00000000..cc62733d --- /dev/null +++ b/tests/OpenTokTest/test.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCy3YiiZ206+/7j +oDzF9qGHhFuxEGuGL1ufGm0LvCiOgNJpV4KGatjdminomS0PwI6v9Gz3r4mYBxeR +3xXV3xPpr3yEDu+ivQN8oMei4ttg++nuyk26gjAdEvz5uSQBV5lWvgjR6tlSPb/j +ca4d5AymuWmT110qcQ+ui7eoOWAfQIWj5Tlqk6YyXUnoMlD4c2c9/hOJZR51VF1n +diDONkHplqjzGfdHxDxCBXsIW1wi8h6PVHH54rDmYay1ojRVPJ7b2RBu8vgvWYoR +du6cY8Bp/1skQUEvtOBhFN62vAZ12s91jFO+plzyA9oDfAXVguW0yRWj5GNJmtPZ +YIcynpjvAgMBAAECggEAM1tzq3n5/Zk0jyRHvum5aKFi+HzH+t/nNVBPpjJxDLXF +dLTJSBIu0bY9uUkeDKtT7QbIMPgokEvdAyfka6PhYlRecsadHQObmDHMEKOFrRu4 +CDXzSo2uBfMZSxTTV0VRRHxNKQT/QGN1kPdnsLJ1xXtwaqBIYnLTN2FrqvRKer4+ +molQK8v838q4tOVT0ZKjIFHX+zyebKqJDOsCO+jDnrKIw3VTID6iZ0DNwGp5xNJT +HOLiT7CQM7Lg7fMdQp9xQxrGWJFw26cuvewmBuPdZRdqc8indgT5pq+VIZkLeTAB +XMnf0W35abwIUlfMIvhVZOiaeZzMwzNuV/Qp9GPFAQKBgQDzVpWxefxmTyHCWXz4 +2m+wojoxEBgn6GRdvUbji7vyRRlmGZRNVybwqqxXyCq3RYdIwV55Ihk7O0mmO4g+ +ESuDchZaMxouzXzDKz8jyoG6Gxymd8QJetnA8ctFwUGnTrK3sCxnTAjphGSf1PlT +vdev+f6T/QT0MT7qxUloDC9hAQKBgQC8LCF6OaFlZdi/kKPFcXbYIxFWRCdiun/A +xAL3+UsMllF53aZcWnIsm9rv0sKhPfrTGCp0eLUyinZzjxzdGDeb5hqafWVArXfT +xj4NC5uQVO2w0HGqB0BpZkBCtiyu25Pw0xPvXlcvwCBYcIDvJuf0hwiGBBKPk1b8 +LjlkbfoJ7wKBgQDZsU499gmtZYGoIvLAlnpxJNC2b9WMbkTL77bpfmrntJWiV6Pr +BNrbV3TTG0nLp7H9jrB74dt8t++NfZjHHgk1kO0aSLlVwZOp7piP5mzkF7kr291P +Nc505FubzeZ0TN1po3w19TnL3xs+OgPLvPymfBoaPrMd2qiU02Z2ZOBGAQKBgA9V +GTU4VOpKLisNwgpogGKEGPmKfBsTTy2JyyQhb/gKl4Dyioej5wGzgVdhOPKidjmV +EoCDBWCk35ny40swmfdd/HTyGrn2aHkdAhlWBMrx4Jwzn89W3+y2pC3LYkCtK5TH +3iv25+vAH+KU6CyUYvoNtqgU1N5WBxRtP8frHiCJAoGAOtq0v8K2KKrEI6L/jHhJ +eNZVUWdGQTZx33vvt5lIboxrNyajaBo25LpmmEAKOhgD61ivHJNrxVDkOMKNx2xt +WnLZvQr7M62SdjWFmcFuY/xRbaX6IOW6C9qps3MdtJeFVw9P6z7udXfXHsCEbQvd +YyR0bVDYLxbCAdYjs7PyCA8= +-----END PRIVATE KEY----- From a227aced822780ac7adbb76e35b51c5b1492962b Mon Sep 17 00:00:00 2001 From: Jim Seconde Date: Wed, 15 Jan 2025 12:20:11 +0000 Subject: [PATCH 2/5] Docs --- README.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/README.md b/README.md index a1515090..03787656 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,24 @@ $options = [ 'client' => new CustomOpenTokClient(), 'timeout' => 10, ] +$opentok = new OpenTok($apiKey, $apiSecret, $options); +``` +#### Migrating to Vonage Video API + +There is some useful behaviour on initialization in this SDK that will help as a stopgap before switching out from the +legacy TokBok API to the new, Vonage Video API. To do this, you add a `private_key_path` and +`application_id` into the `$options`. Note that the SDK will read the private key path from the root directory of +the SDK, so you will need to adjust the directory structures accordingly. + +```php +use OpenTok\OpenTok; +use MyCompany\CustomOpenTokClient; + +$options = [ + 'application_id' => 'your_application_id', + 'private_key_path' => './path-to-your.key' +] + $opentok = new OpenTok($apiKey, $apiSecret, $options); ``` From 86e591bbe18b18e63657ac470b5a0ecb5b7b8347 Mon Sep 17 00:00:00 2001 From: Jim Seconde Date: Mon, 24 Feb 2025 15:07:02 +0000 Subject: [PATCH 3/5] WIP, close to working test but no end to end test --- sample/Archiving/README.md | 2 +- src/OpenTok/Archive.php | 2 - src/OpenTok/ArchiveList.php | 2 - src/OpenTok/Broadcast.php | 2 - src/OpenTok/OpenTok.php | 29 ++-- src/OpenTok/Util/Client.php | 17 +-- src/OpenTok/Util/Validators.php | 53 ++++--- tests/OpenTokTest/ArchiveTest.php | 2 +- tests/OpenTokTest/BroadcastTest.php | 35 +---- tests/OpenTokTest/OpenTokTest.php | 141 ++++++++++-------- tests/OpenTokTest/SessionTest.php | 8 +- tests/OpenTokTest/SipCallTest.php | 4 +- .../OpenTokTest/Validators/ValidatorsTest.php | 37 ++--- 13 files changed, 145 insertions(+), 189 deletions(-) diff --git a/sample/Archiving/README.md b/sample/Archiving/README.md index d4b6d009..df237c0a 100644 --- a/sample/Archiving/README.md +++ b/sample/Archiving/README.md @@ -19,7 +19,7 @@ Next, input your own API Key and API Secret into the `run-demo` script file: ``` export API_KEY=0000000 - export API_SECRET=abcdef1234567890abcdef01234567890abcdef + export API_SECRET=b60d0b2568f3ea9731bd9d3f71be263ce19f802f ``` Finally, start the PHP CLI development server (requires PHP >= 5.4) using the `run-demo` script diff --git a/src/OpenTok/Archive.php b/src/OpenTok/Archive.php index 14cb0c68..27438157 100644 --- a/src/OpenTok/Archive.php +++ b/src/OpenTok/Archive.php @@ -144,8 +144,6 @@ public function __construct($archiveData, $options = array()) $this->client = isset($client) ? $client : new Client(); if (!$this->client->isConfigured()) { - Validators::validateApiKey($apiKey); - Validators::validateApiSecret($apiSecret); Validators::validateApiUrl($apiUrl); $this->client->configure($apiKey, $apiSecret, $apiUrl); diff --git a/src/OpenTok/ArchiveList.php b/src/OpenTok/ArchiveList.php index 2a927e9d..d9a51bc6 100644 --- a/src/OpenTok/ArchiveList.php +++ b/src/OpenTok/ArchiveList.php @@ -49,8 +49,6 @@ public function __construct($archiveListData, $options = array()) $this->client = isset($client) ? $client : new Client(); if (!$this->client->isConfigured()) { - Validators::validateApiKey($apiKey); - Validators::validateApiSecret($apiSecret); Validators::validateApiUrl($apiUrl); $this->client->configure($apiKey, $apiSecret, $apiUrl); diff --git a/src/OpenTok/Broadcast.php b/src/OpenTok/Broadcast.php index 9745a24b..0ea809fb 100644 --- a/src/OpenTok/Broadcast.php +++ b/src/OpenTok/Broadcast.php @@ -147,8 +147,6 @@ public function __construct($broadcastData, $options = array()) $this->client = $options['client'] ?? new Client(); if (!$this->client->isConfigured()) { - Validators::validateApiKey($options['apiKey']); - Validators::validateApiSecret($options['apiSecret']); Validators::validateApiUrl($options['apiUrl']); $this->client->configure($options['apiKey'], $options['apiSecret'], $options['apiUrl']); diff --git a/src/OpenTok/OpenTok.php b/src/OpenTok/OpenTok.php index 6b808612..c9027343 100644 --- a/src/OpenTok/OpenTok.php +++ b/src/OpenTok/OpenTok.php @@ -25,6 +25,9 @@ * and the API secret for your OpenTok Video API account. Do not * publicly share your API secret. You will use it with the OpenTok() constructor (only on your web * server) to create OpenTok sessions. +* +* If you set api_key to a VONAGE_APPLICATION_ID and api_secret to a VONAGE_PRIVATE_KEY_PATH, the SDK +* will hit Vonage Video with Vonage Auth instead. *

* Be sure to include the entire OpenTok server SDK on your web server. */ @@ -37,24 +40,25 @@ class OpenTok /** @internal */ private $client; + /** + * @var bool + * Override to determine whether to hit Vonage servers with Vonage Auth in requests + */ + private $vonage = false; + /** * @var array * @internal - * Options that can override the defaults. Additionally, you can set the keys - * application_id & private_key_path to strings that will then override the default - * OpenTok Client behaviour when making requests to the Vonage Video API. */ public $options; /** @internal */ public function __construct($apiKey, $apiSecret, $options = array()) { - $validateKeys = true; - Validators::validateVonageJwtArguments($options); $apiUrl = 'https://api.opentok.com'; - if (array_key_exists('application_id', $options) && array_key_exists('private_key_path', $options)) { - $validateKeys = false; + if (Validators::isVonageKeypair($apiKey, $apiSecret)) { + $this->vonage = true; $apiUrl = 'https://video.api.vonage.com'; } @@ -63,20 +67,12 @@ public function __construct($apiKey, $apiSecret, $options = array()) 'apiUrl' => $apiUrl, 'client' => null, 'timeout' => null, // In the future we should set this to 2 - 'application_id' => null, - 'private_key_path' => null, ); $this->options = array_merge($defaults, array_intersect_key($options, $defaults)); list($apiUrl, $client, $timeout) = array_values($this->options); - // validate arguments - if ($validateKeys) { - Validators::validateApiKey($apiKey); - Validators::validateApiSecret($apiSecret); - } - Validators::validateApiUrl($apiUrl); Validators::validateClient($client); Validators::validateDefaultTimeout($timeout); @@ -138,9 +134,6 @@ public function __construct($apiKey, $apiSecret, $options = array()) * @param bool $legacy By default, OpenTok uses SHA256 JWTs for authentication. Switching * legacy to true will create a T1 token for backwards compatibility. * - * Optionally, you can set $vonage to true and it will generate a Vonage Video token if you are using - * the shim behaviour. - * * @return string The token string. */ public function generateToken(string $sessionId, array $payload = array(), bool $legacy = false): string diff --git a/src/OpenTok/Util/Client.php b/src/OpenTok/Util/Client.php index af04f8e6..0b4bb33a 100755 --- a/src/OpenTok/Util/Client.php +++ b/src/OpenTok/Util/Client.php @@ -47,8 +47,6 @@ class Client protected $apiKey; protected $apiSecret; - protected $applicationId = null; - protected $privateKeyPath = null; protected $configured = false; /** @@ -67,14 +65,6 @@ public function configure($apiKey, $apiSecret, $apiUrl, $options = array()) $this->apiKey = $apiKey; $this->apiSecret = $apiSecret; - if (array_key_exists('application_id', $options) || array_key_exists('private_key_path', $options)) { - if (!is_null($options['application_id']) && !is_null($options['private_key_path'])) { - $this->applicationId = $options['application_id']; - $this->privateKeyPath = $options['private_key_path']; - $apiUrl = 'https://video.api.vonage.com'; - } - } - if (isset($this->options['client'])) { $this->client = $options['client']; } else { @@ -135,11 +125,8 @@ public function isConfigured() private function createAuthHeader() { - if (!is_null($this->applicationId) && !is_null($this->privateKeyPath)) { - $projectRoot = dirname(__DIR__, 3); // Adjust the number of dirname() calls if necessary to match your - // project structure. - $privateKeyFullPath = $projectRoot . DIRECTORY_SEPARATOR . $this->privateKeyPath; - $tokenGenerator = new TokenGenerator($this->applicationId, file_get_contents($privateKeyFullPath)); + if (Validators::isVonageKeypair($this->apiKey, $this->apiSecret)) { + $tokenGenerator = new TokenGenerator($this->apiKey, file_get_contents($this->apiSecret)); return $tokenGenerator->generate(); } diff --git a/src/OpenTok/Util/Validators.php b/src/OpenTok/Util/Validators.php index 0e2475b0..2475517a 100755 --- a/src/OpenTok/Util/Validators.php +++ b/src/OpenTok/Util/Validators.php @@ -13,6 +13,7 @@ use OpenTok\Exception\InvalidArgumentException; use JohnStevenson\JsonWorks\Document; use JohnStevenson\JsonWorks\Utils as JsonUtils; +use RuntimeException; /** * @internal @@ -25,31 +26,44 @@ class Validators public const STREAM_MODES = ['auto', 'manual']; - public static function validateApiKey($apiKey) + public static function isVonageKeypair($apiKey, $apiSecret): bool { - if (!(is_string($apiKey) || is_int($apiKey))) { - throw new InvalidArgumentException( - 'The apiKey was not a string nor an integer: ' . print_r($apiKey, true) - ); + if (!is_string($apiKey) || !is_string($apiSecret)) { + throw new InvalidArgumentException("API Key and API Secret must be strings."); + } + + $isOpenTokKey = preg_match('/^\d+$/', $apiKey); + $isOpenTokSecret = preg_match('/^[a-f0-9]{40}$/i', $apiSecret); + + if ($isOpenTokKey && $isOpenTokSecret) { + return false; + } + + $isVonageApplicationId = preg_match('/^[a-f0-9\-]{36}$/i', $apiKey); + $isVonagePrivateKey = self::isValidPrivateKey($apiSecret); + + if ($isVonageApplicationId && $isVonagePrivateKey) { + return true; } + + // Mixed formats or invalid formats - throw an exception + throw new InvalidArgumentException("Invalid Vonage Keypair credentials provided."); } - public static function validateVonageJwtArguments(array $options) + private static function isValidPrivateKey(string $filePath): bool { - if (!isset($data['application_id']) && !isset($data['private_key_path'])) { - return; + if (!file_exists($filePath) || !is_readable($filePath)) { + throw new InvalidArgumentException("Private key file does not exist or is not readable."); } - if (isset($data['application_id']) && isset($data['private_key_path'])) { - if (is_string($data['application_id']) && is_string($data['private_key_path'])) { - return; - }; + $keyContents = file_get_contents($filePath); + + if ($keyContents === false) { + throw new RuntimeException("Failed to read private key file."); } - // If one key is present but not the other, validation fails - throw new InvalidArgumentException( - 'You are attempting to use the Vonage Video API. Both application_id and private key paths must be in options and both strings.' - ); + // Check if it contains a valid private RSA key header + return (bool) preg_match('/^-----BEGIN PRIVATE KEY-----[\s\S]+-----END PRIVATE KEY-----$/m', trim($keyContents)); } public static function validateForceMuteAllOptions(array $options) @@ -74,13 +88,6 @@ public static function validateForceMuteAllOptions(array $options) } } - public static function validateApiSecret($apiSecret) - { - if (!(is_string($apiSecret))) { - throw new InvalidArgumentException('The apiSecret was not a string: ' . print_r($apiSecret, true)); - } - } - public static function validateApiUrl($apiUrl) { if (!(is_string($apiUrl) && filter_var($apiUrl, FILTER_VALIDATE_URL))) { diff --git a/tests/OpenTokTest/ArchiveTest.php b/tests/OpenTokTest/ArchiveTest.php index 7747bf1b..78a33c32 100644 --- a/tests/OpenTokTest/ArchiveTest.php +++ b/tests/OpenTokTest/ArchiveTest.php @@ -62,7 +62,7 @@ public function setupArchives($streamMode) private function setupOTWithMocks($mocks) { $this->API_KEY = defined('API_KEY') ? API_KEY : '12345678'; - $this->API_SECRET = defined('API_SECRET') ? API_SECRET : '0123456789abcdef0123456789abcdef0123456789'; + $this->API_SECRET = defined('API_SECRET') ? API_SECRET : 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; if (is_array($mocks)) { $responses = TestHelpers::mocksToResponses($mocks, self::$mockBasePath); diff --git a/tests/OpenTokTest/BroadcastTest.php b/tests/OpenTokTest/BroadcastTest.php index 72f8abea..85afc410 100644 --- a/tests/OpenTokTest/BroadcastTest.php +++ b/tests/OpenTokTest/BroadcastTest.php @@ -69,7 +69,7 @@ public function setupBroadcasts($streamMode) private function setupOTWithMocks($mocks) { $this->API_KEY = defined('API_KEY') ? API_KEY : '12345678'; - $this->API_SECRET = defined('API_SECRET') ? API_SECRET : '0123456789abcdef0123456789abcdef0123456789'; + $this->API_SECRET = defined('API_SECRET') ? API_SECRET : 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; if (is_array($mocks)) { $responses = TestHelpers::mocksToResponses($mocks, self::$mockBasePath); @@ -98,39 +98,6 @@ private function setupOTWithMocks($mocks) $handlerStack->push($history); } - public function testCannotCreateBroadcastWithAddInvalidApiKey(): void - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('The apiKey was not a string nor an integer: '); - - $broadcastObject = new Broadcast($this->broadcastData, [ - 'apiKey' => new Client() - ]); - } - - public function testCannotCreateBroadcastWithInvalidApiSecret(): void - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('The apiSecret was not a string: OpenTok\Util\Client Object'); - - $broadcastObject = new Broadcast($this->broadcastData, [ - 'apiKey' => 'test', - 'apiSecret' => new Client() - ]); - } - - public function testCannotCreateBroadcastWithInvalidApiUrl(): void - { - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('The optional apiUrl was not a string: '); - - $broadcastObject = new Broadcast($this->broadcastData, [ - 'apiKey' => 'validKey', - 'apiSecret' => 'validSecret', - 'apiUrl' => 'test' - ]); - } - private function setupOT() { return $this->setupOTWithMocks([]); diff --git a/tests/OpenTokTest/OpenTokTest.php b/tests/OpenTokTest/OpenTokTest.php index acef87b2..4778944a 100644 --- a/tests/OpenTokTest/OpenTokTest.php +++ b/tests/OpenTokTest/OpenTokTest.php @@ -5,6 +5,9 @@ use Firebase\JWT\JWT; use Firebase\JWT\Key; use Lcobucci\JWT\Configuration; +use Lcobucci\JWT\Signer\Hmac\Sha256; +use Lcobucci\JWT\Signer\Key\InMemory; +use Lcobucci\JWT\Token; use Lcobucci\JWT\Token\Plain; use OpenTok\Render; use OpenTok\Role; @@ -19,6 +22,7 @@ use OpenTok\Util\Client; use GuzzleHttp\Middleware; use GuzzleHttp\HandlerStack; +use OpenTok\Util\Validators; use PHPUnit\Framework\TestCase; use GuzzleHttp\Handler\MockHandler; use OpenTok\Exception\InvalidArgumentException; @@ -46,10 +50,10 @@ public static function setUpBeforeClass(): void self::$mockBasePath = __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'mock' . DIRECTORY_SEPARATOR; } - private function setupOTWithMocks($mocks, $customAgent = false): void + private function setupOTWithMocks($mocks, $customAgent = false, $vonageVideo = false): void { $this->API_KEY = defined('API_KEY') ? API_KEY : '12345678'; - $this->API_SECRET = defined('API_SECRET') ? API_SECRET : '0123456789abcdef0123456789abcdef0123456789'; + $this->API_SECRET = defined('API_SECRET') ? API_SECRET : 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; if (is_array($mocks)) { $responses = TestHelpers::mocksToResponses($mocks, self::$mockBasePath); @@ -67,11 +71,19 @@ private function setupOTWithMocks($mocks, $customAgent = false): void $clientOptions = array_merge($clientOptions, $customAgent); } + $apiUrl = 'https://api.opentok.com'; + + if ($vonageVideo === true) { + $apiUrl = 'https://video.vonage.com'; + $this->API_KEY = '1ab38a10-ed9d-4e2b-8b14-95e52d76a13c'; + $this->API_SECRET = __DIR__ . '/test.key'; + } + $this->client = new Client(); $this->client->configure( $this->API_KEY, $this->API_SECRET, - 'https://api.opentok.com', + $apiUrl, $clientOptions ); @@ -133,6 +145,47 @@ public function testCanStartRender(): void $this->assertEquals('started', $render->status); } + public function testCanUseVonageAuth(): void + { + $this->setupOTWithMocks([[ + 'code' => 200, + 'headers' => [ + 'Content-Type' => 'application/json' + ], + 'path' => 'v2/project/APIKEY/render/render_start' + ]], null, true); + + $render = $this->opentok->startRender( + '2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4', + 'e2343f23456g34709d2443a234', + 'https://webapp.customer.com', + 2900, + '1280x720', + 'https://sendcallbacks.to.me', + [ + 'name' => 'Composed stream for live event' + ] + ); + + $this->assertInstanceOf(Render::class, $render); + $this->assertEquals('2_MX4xMDBfjE0Mzc2NzY1NDgwMTJ-TjMzfn4', $render->sessionId); + $this->assertEquals('started', $render->status); + + $request = $this->historyContainer[0]['request']; + $authString = $request->getHeaderLine('X-OPENTOK-AUTH'); + + $privateKey = file_get_contents($this->API_SECRET); + + $config = Configuration::forAsymmetricSigner( + new Sha256(), + InMemory::plainText($privateKey), // Use private key for decoding + InMemory::plainText($privateKey) // Use private key for verification + ); + + $token = $config->parser()->parse($authString); + $this->assertInstanceOf(Token::class, $token); + } + public function testCanGetRender(): void { $this->setupOTWithMocks([[ @@ -582,7 +635,7 @@ public function testGeneratesToken(): void // This sessionId is a fixture designed by using a known but bogus apiKey and apiSecret $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); // Act @@ -613,7 +666,7 @@ public function testGeneratesTokenWithRole(): void // This sessionId is a fixture designed by using a known but bogus apiKey and apiSecret $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); // Act @@ -643,7 +696,7 @@ public function testGeneratesTokenWithExpireTime(): void // This sessionId is a fixture designed by using a known but bogus apiKey and apiSecret $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); // Act @@ -674,7 +727,7 @@ public function testGeneratesTokenWithData(): void // This sessionId is a fixture designed by using a known but bogus apiKey and apiSecret $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); // Act @@ -708,7 +761,7 @@ public function testGeneratesTokenWithInitialLayoutClassList(): void // This sessionId is a fixture designed by using a known but bogus apiKey and apiSecret $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); $initialLayouClassList = array('focus', 'main'); @@ -746,7 +799,7 @@ public function testFailsWhenGeneratingTokenUsingInvalidRole(): void public function testWillCreateLegacyT1WhenRequested(): void { - $openTok = new OpenTok('12345678', '0123456789abcdef0123456789abcdef0123456789'); + $openTok = new OpenTok('12345678', 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'); $token = $openTok->generateToken('1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI', [], true); $this->assertEquals('T1', substr($token, 0, 2)); @@ -754,58 +807,20 @@ public function testWillCreateLegacyT1WhenRequested(): void public function testWillCreateLegacyT1DirectlyToBypassExpBug(): void { - $openTok = new OpenTok('12345678', '0123456789abcdef0123456789abcdef0123456789'); + $openTok = new OpenTok('12345678', 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'); $token = $openTok->generateToken('1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI', [], true); $this->assertEquals('T1', substr($token, 0, 2)); } - public function testWillHitVonageVideoWithVonageJwt(): void - { - // All of this manual DRY exists because the hardcoded setup helper methods - // were not written to handle this sort of behaviour overriding. - $mocks = [ - 'code' => 200, - 'headers' => [ - 'Content-Type' => 'application/json' - ], - 'path' => 'v2/project/APIKEY/archive/session' - ]; - - $customAgent = [ - 'application_id' => 'abc123', - 'private_key_path' => './tests/OpenTokTest/test.key', - ]; - - $this->setupOTWithMocks([$mocks], $customAgent); - - $sessionId = '2_MX44NTQ1MTF-flR1ZSBOb3YgMTIgMDk6NDA6NTkgUFNUIDIwMTN-MC43NjU0Nzh-'; - $archive = $this->opentok->startArchive($sessionId, ['maxBitrate' => 2000000]); - - $this->assertCount(1, $this->historyContainer); - - $request = $this->historyContainer[0]['request']; - $this->assertEquals('POST', strtoupper($request->getMethod())); - } - - /** - * Makes sure that a JWT is generated for the client-side token - * - * Currently disabled due to the backend requiring an `exp` claim, which was - * not required on T1s. Uncomment when the backend is fixed. - CRT - */ - // public function testWillCreateJwt(): void - // { - // $openTok = new OpenTok('my-api-key', 'my-super-long-and-cool-api-secret'); - // $token = $openTok->generateToken('some-token-value'); public function testWillGenerateSha256Token(): void { - $openTok = new OpenTok('12345678', '0123456789abcdef0123456789abcdef0123456789'); + $openTok = new OpenTok('12345678', 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'); $token = $openTok->generateToken('1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'); $this->assertNotEquals('T1', substr($token, 0, 2)); - $decoded = JWT::decode($token, new Key('0123456789abcdef0123456789abcdef0123456789', 'HS256')); + $decoded = JWT::decode($token, new Key('b60d0b2568f3ea9731bd9d3f71be263ce19f802f', 'HS256')); $decodedArray = (array) $decoded; $this->assertEquals('12345678', $decodedArray['iss']); @@ -1463,7 +1478,7 @@ public function testListsArchivesWithSessionId(): void $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); // Act @@ -2370,7 +2385,7 @@ public function testSipCall(): void $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $bogusToken = 'T1==TEST'; $bogusSipUri = 'sip:john@doe.com'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); @@ -2395,7 +2410,7 @@ public function testSipCallWithAuth(): void $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $bogusToken = 'T1==TEST'; $bogusSipUri = 'sip:john@doe.com'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); @@ -2433,7 +2448,7 @@ public function testFailedSipCall(): void $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $bogusToken = 'T1==TEST'; $bogusSipUri = 'sip:john@doe.com'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); @@ -2667,7 +2682,7 @@ public function testSignalData(): void $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); @@ -2704,7 +2719,7 @@ public function testSignalWithConnectionId(): void $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $connectionId = 'da9cb410-e29b-4c2d-ab9e-fe65bf83fcaf'; $payload = array( 'type' => 'rest', @@ -2743,7 +2758,7 @@ public function testSignalWithEmptyPayload(): void $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $payload = array(); $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); @@ -2765,7 +2780,7 @@ public function testSignalConnectionException(): void $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $connectionId = 'da9cb410-e29b-4c2d-ab9e-fe65bf83fcaf'; $payload = array( 'type' => 'rest', @@ -2788,7 +2803,7 @@ public function testSignalUnexpectedValueException(): void $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $connectionId = 'da9cb410-e29b-4c2d-ab9e-fe65bf83fcaf'; $payload = array( 'type' => 'rest', @@ -2816,7 +2831,7 @@ public function testListStreams(): void $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); @@ -2942,7 +2957,7 @@ public function testDefaultTimeoutDefaultsToNull(): void */ public function testDefaultTimeoutCanBeOverriden(): void { - $opentok = new OpenTok('1234', 'abd', ['timeout' => 400]); + $opentok = new OpenTok('4349501', 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f', ['timeout' => 400]); $opentokReflection = new \ReflectionClass($opentok); $opentokClient = $opentokReflection->getProperty('client'); @@ -2965,7 +2980,7 @@ public function testDefaultTimeoutErrorsIfNotNumeric(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Default Timeout must be a number greater than zero'); - new OpenTok('1234', 'abd', ['timeout' => 'bob']); + new OpenTok('4349501', 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f', ['timeout' => 'bob']); } /** @@ -2975,7 +2990,7 @@ public function testDefaultTimeoutErrorsIfLessThanZero(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Default Timeout must be a number greater than zero'); - new OpenTok('1234', 'abd', ['timeout' => -1]); + new OpenTok('4349501', 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f', ['timeout' => -1]); } public function testCanStartCaptions(): void diff --git a/tests/OpenTokTest/SessionTest.php b/tests/OpenTokTest/SessionTest.php index ac12a69b..c98fa8d6 100644 --- a/tests/OpenTokTest/SessionTest.php +++ b/tests/OpenTokTest/SessionTest.php @@ -24,7 +24,7 @@ public static function setUpBeforeClass(): void public function setUp(): void { $this->API_KEY = defined('API_KEY') ? API_KEY : '12345678'; - $this->API_SECRET = defined('API_SECRET') ? API_SECRET : '0123456789abcdef0123456789abcdef0123456789'; + $this->API_SECRET = defined('API_SECRET') ? API_SECRET : 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $this->opentok = new OpenTok($this->API_KEY, $this->API_SECRET); } @@ -152,7 +152,7 @@ public function testGeneratesToken() { $sessionId = '1_MX4xMjM0NTY3OH4-VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI'; $bogusApiKey = '12345678'; - $bogusApiSecret = '0123456789abcdef0123456789abcdef0123456789'; + $bogusApiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; $opentok = new OpenTok($bogusApiKey, $bogusApiSecret); $session = new Session($opentok, $sessionId); @@ -173,6 +173,4 @@ public function testGeneratesToken() $this->assertNotEmpty($decodedToken['sig']); $this->assertEquals(hash_hmac('sha1', $decodedToken['dataString'], $bogusApiSecret), $decodedToken['sig']); } - -} - +} \ No newline at end of file diff --git a/tests/OpenTokTest/SipCallTest.php b/tests/OpenTokTest/SipCallTest.php index 45318a94..2a785756 100644 --- a/tests/OpenTokTest/SipCallTest.php +++ b/tests/OpenTokTest/SipCallTest.php @@ -11,14 +11,14 @@ public function testSipCallAttributes(): void $sipCallData = [ 'id' => '1_MX4xMjM0NTY3OH4', 'connectionId' => 'VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI', - 'streamId' => '0123456789abcdef0123456789abcdef0123456789' + 'streamId' => 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f' ]; $sipCall = new SipCall($sipCallData); $this->assertEquals('1_MX4xMjM0NTY3OH4', $sipCall->id); $this->assertEquals('VGh1IEZlYiAyNyAwNDozODozMSBQU1QgMjAxNH4wLjI0NDgyMjI', $sipCall->connectionId); - $this->assertEquals('0123456789abcdef0123456789abcdef0123456789', $sipCall->streamId); + $this->assertEquals('b60d0b2568f3ea9731bd9d3f71be263ce19f802f', $sipCall->streamId); $this->assertNull($sipCall->observeForceMute); } } \ No newline at end of file diff --git a/tests/OpenTokTest/Validators/ValidatorsTest.php b/tests/OpenTokTest/Validators/ValidatorsTest.php index c5e73906..488bc572 100644 --- a/tests/OpenTokTest/Validators/ValidatorsTest.php +++ b/tests/OpenTokTest/Validators/ValidatorsTest.php @@ -9,39 +9,34 @@ class ValidatorsTest extends TestCase { - public function testWillValidateStringApiKey(): void + public function testIsVonageKeypair(): void { - $this->expectNotToPerformAssertions(); - $apiKey = '47347801'; - Validators::validateApiKey($apiKey); + $apiKey = '1ab38a10-ed9d-4e2b-8b14-95e52d76a13c'; + $apiSecret = __DIR__ . '/../test.key'; + $this->assertTrue(Validators::isVonageKeypair($apiKey, $apiSecret)); } - public function testWillValidateIntegerApiKey(): void + public function testIsNotVonageKeypair(): void { - $this->expectNotToPerformAssertions(); - $apiKey = 47347801; - Validators::validateApiKey($apiKey); + $apiKey = '4349501'; + $apiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; + $this->assertFalse(Validators::isVonageKeypair($apiKey, $apiSecret)); } - public function testWillInvalidateApiKey(): void + public function testVonageKeypairFailsWithOnlyAppId(): void { $this->expectException(InvalidArgumentException::class); - $apiKey = [47347801]; - Validators::validateApiKey($apiKey); - } - - public function testWillValidateApiSecret(): void - { - $this->expectNotToPerformAssertions(); - $secret = 'cdff574f0b071230be098e279d16931116c43fcf'; - Validators::validateApiSecret($secret); + $apiKey = '1ab38a10-ed9d-4e2b-8b14-95e52d76a13c'; + $apiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; + Validators::isVonageKeypair($apiKey, $apiSecret); } - public function testWillInvalidateApiSecret(): void + public function testVonageKeypairFailsWithOnlyPrivateKey(): void { $this->expectException(InvalidArgumentException::class); - $secret = 3252556; - Validators::validateApiSecret($secret); + $apiKey = '1ab38a10-ed9d-4e2b-8b14-95e52d76a13c'; + $apiSecret = 'b60d0b2568f3ea9731bd9d3f71be263ce19f802f'; + Validators::isVonageKeypair($apiKey, $apiSecret); } public function testWillValidateApiUrl(): void From 984955e717065e358415279a35c4b6dc9ed9144f Mon Sep 17 00:00:00 2001 From: Jim Seconde Date: Tue, 25 Feb 2025 16:18:27 +0000 Subject: [PATCH 4/5] Finished testing the video implementation --- tests/OpenTokTest/OpenTokTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/OpenTokTest/OpenTokTest.php b/tests/OpenTokTest/OpenTokTest.php index 4778944a..d451b97e 100644 --- a/tests/OpenTokTest/OpenTokTest.php +++ b/tests/OpenTokTest/OpenTokTest.php @@ -8,7 +8,6 @@ use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\Signer\Key\InMemory; use Lcobucci\JWT\Token; -use Lcobucci\JWT\Token\Plain; use OpenTok\Render; use OpenTok\Role; use OpenTok\Layout; @@ -184,6 +183,7 @@ public function testCanUseVonageAuth(): void $token = $config->parser()->parse($authString); $this->assertInstanceOf(Token::class, $token); + $this->assertEquals($this->API_KEY, $token->claims()->get('application_id')); } public function testCanGetRender(): void From 3497cc3569f753e68ce6833f313a4ef5ec086a0f Mon Sep 17 00:00:00 2001 From: Chris Tankersley Date: Wed, 26 Feb 2025 12:57:38 -0500 Subject: [PATCH 5/5] Update README.md --- README.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 03787656..c727ac45 100644 --- a/README.md +++ b/README.md @@ -88,22 +88,26 @@ $opentok = new OpenTok($apiKey, $apiSecret, $options); #### Migrating to Vonage Video API There is some useful behaviour on initialization in this SDK that will help as a stopgap before switching out from the -legacy TokBok API to the new, Vonage Video API. To do this, you add a `private_key_path` and -`application_id` into the `$options`. Note that the SDK will read the private key path from the root directory of -the SDK, so you will need to adjust the directory structures accordingly. +legacy TokBok API to the new, Vonage Video API. To do this, you can pass in an Application ID for the API Key, and the path to +a Vonage private key as the API Secret. ```php use OpenTok\OpenTok; use MyCompany\CustomOpenTokClient; -$options = [ - 'application_id' => 'your_application_id', - 'private_key_path' => './path-to-your.key' -] +$applicationID = '61bb2dae-9b69-400c-9abb-642d082af5fc'; +$privateKey = './private.key'; -$opentok = new OpenTok($apiKey, $apiSecret, $options); +$opentok = new OpenTok($applicationID, $privateKey); ``` +The SDK will notice that the authentiction has changed, and will automatically start to forward requests to the Vonage API Routes +instead of the OpenTok API Routes. All requests and responses in your code should be exactly the same as they are on the +OpenTok API. + +**NOTE:** The SDK will read the private key path from the root directory of your project (generally one level above the docroot +of your application), so you will need to make sure that the path provided is either absolute, or relative to your project root. + ### Creating Sessions To create an OpenTok Session, use the `createSession($options)` method of the