Skip to content

Commit 7ea8056

Browse files
committed
Added shim layer
1 parent 3f10580 commit 7ea8056

File tree

5 files changed

+130
-8
lines changed

5 files changed

+130
-8
lines changed

src/OpenTok/OpenTok.php

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,26 +35,47 @@ class OpenTok
3535
private $apiSecret;
3636
/** @internal */
3737
private $client;
38-
/** @internal */
38+
39+
/**
40+
* @var array
41+
* @internal
42+
* Options that can override the defaults. Additionally, you can set the keys
43+
* application_id & private_key_path to strings that will then override the default
44+
* OpenTok Client behaviour when making requests to the Vonage Video API.
45+
*/
3946
public $options;
4047

4148
/** @internal */
4249
public function __construct($apiKey, $apiSecret, $options = array())
4350
{
51+
$validateKeys = true;
52+
Validators::validateVonageJwtArguments($options);
53+
$apiUrl = 'https://api.opentok.com';
54+
55+
if (array_key_exists('application_id', $options) && array_key_exists('private_key_path', $options)) {
56+
$validateKeys = false;
57+
$apiUrl = 'https://video.api.vonage.com';
58+
}
59+
4460
// unpack optional arguments (merging with default values) into named variables
4561
$defaults = array(
46-
'apiUrl' => 'https://api.opentok.com',
62+
'apiUrl' => $apiUrl,
4763
'client' => null,
48-
'timeout' => null // In the future we should set this to 2
64+
'timeout' => null, // In the future we should set this to 2
65+
'application_id' => null,
66+
'private_key_path' => null,
4967
);
5068

5169
$this->options = array_merge($defaults, array_intersect_key($options, $defaults));
5270

5371
list($apiUrl, $client, $timeout) = array_values($this->options);
5472

5573
// validate arguments
56-
Validators::validateApiKey($apiKey);
57-
Validators::validateApiSecret($apiSecret);
74+
if ($validateKeys) {
75+
Validators::validateApiKey($apiKey);
76+
Validators::validateApiSecret($apiSecret);
77+
}
78+
5879
Validators::validateApiUrl($apiUrl);
5980
Validators::validateClient($client);
6081
Validators::validateDefaultTimeout($timeout);
@@ -116,9 +137,16 @@ public function __construct($apiKey, $apiSecret, $options = array())
116137
* @param bool $legacy By default, OpenTok uses SHA256 JWTs for authentication. Switching
117138
* legacy to true will create a deprecated T1 token for backwards compatibility.
118139
*
140+
* Optionally, you can set $vonage to true and it will generate a Vonage Video token if you are using
141+
* the shim behaviour.
142+
*
119143
* @return string The token string.
120144
*/
121-
public function generateToken(string $sessionId, array $options = array(), bool $legacy = false): string
145+
public function generateToken(
146+
string $sessionId,
147+
array $options = array(),
148+
bool $legacy = false
149+
): string
122150
{
123151
// Note, JWT generation disabled due to a backend bug regarding `exp` claims being mandatory - CRT
124152
// if ($legacy) {

src/OpenTok/Util/Client.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636

3737
use OpenTok\Exception\ForceDisconnectAuthenticationException;
3838
use OpenTok\Exception\ForceDisconnectUnexpectedValueException;
39+
use Vonage\JWT\TokenGenerator;
3940

4041
/**
4142
* @internal
@@ -46,6 +47,8 @@ class Client
4647

4748
protected $apiKey;
4849
protected $apiSecret;
50+
protected $applicationId = null;
51+
protected $privateKeyPath = null;
4952
protected $configured = false;
5053

5154
/**
@@ -64,6 +67,14 @@ public function configure($apiKey, $apiSecret, $apiUrl, $options = array())
6467
$this->apiKey = $apiKey;
6568
$this->apiSecret = $apiSecret;
6669

70+
if (array_key_exists('application_id', $options) || array_key_exists('private_key_path', $options)) {
71+
if (!is_null($options['application_id']) && !is_null($options['private_key_path'])) {
72+
$this->applicationId = $options['application_id'];
73+
$this->privateKeyPath = $options['private_key_path'];
74+
$apiUrl = 'https://video.api.vonage.com';
75+
}
76+
}
77+
6778
if (isset($this->options['client'])) {
6879
$this->client = $options['client'];
6980
} else {
@@ -124,13 +135,22 @@ public function isConfigured()
124135

125136
private function createAuthHeader()
126137
{
138+
if (!is_null($this->applicationId) && !is_null($this->privateKeyPath)) {
139+
$projectRoot = dirname(__DIR__, 3); // Adjust the number of dirname() calls if necessary to match your
140+
// project structure.
141+
$privateKeyFullPath = $projectRoot . DIRECTORY_SEPARATOR . $this->privateKeyPath;
142+
$tokenGenerator = new TokenGenerator($this->applicationId, file_get_contents($privateKeyFullPath));
143+
return $tokenGenerator->generate();
144+
}
145+
127146
$token = array(
128147
'ist' => 'project',
129148
'iss' => $this->apiKey,
130149
'iat' => time(), // this is in seconds
131150
'exp' => time() + (5 * 60),
132151
'jti' => uniqid('', true),
133152
);
153+
134154
return JWT::encode($token, $this->apiSecret, 'HS256');
135155
}
136156

src/OpenTok/Util/Validators.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,24 @@ public static function validateApiKey($apiKey)
3434
}
3535
}
3636

37+
public static function validateVonageJwtArguments(array $options)
38+
{
39+
if (!isset($data['application_id']) && !isset($data['private_key_path'])) {
40+
return;
41+
}
42+
43+
if (isset($data['application_id']) && isset($data['private_key_path'])) {
44+
if (is_string($data['application_id']) && is_string($data['private_key_path'])) {
45+
return;
46+
};
47+
}
48+
49+
// If one key is present but not the other, validation fails
50+
throw new InvalidArgumentException(
51+
'You are attempting to use the Vonage Video API. Both application_id and private key paths must be in options and both strings.'
52+
);
53+
}
54+
3755
public static function validateForceMuteAllOptions(array $options)
3856
{
3957
$validOptions = [

tests/OpenTokTest/OpenTokTest.php

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -758,9 +758,37 @@ public function testWillCreateLegacyT1DirectlyToBypassExpBug(): void
758758
$this->assertEquals('T1', substr($token, 0, 2));
759759
}
760760

761+
public function testWillHitVonageVideoWithVonageJwt(): void
762+
{
763+
// All of this manual DRY exists because the hardcoded setup helper methods
764+
// were not written to handle this sort of behaviour overriding.
765+
$mocks = [
766+
'code' => 200,
767+
'headers' => [
768+
'Content-Type' => 'application/json'
769+
],
770+
'path' => 'v2/project/APIKEY/archive/session'
771+
];
772+
773+
$customAgent = [
774+
'application_id' => 'abc123',
775+
'private_key_path' => './tests/OpenTokTest/test.key',
776+
];
777+
778+
$this->setupOTWithMocks([$mocks], $customAgent);
779+
780+
$sessionId = '2_MX44NTQ1MTF-flR1ZSBOb3YgMTIgMDk6NDA6NTkgUFNUIDIwMTN-MC43NjU0Nzh-';
781+
$archive = $this->opentok->startArchive($sessionId, ['maxBitrate' => 2000000]);
782+
783+
$this->assertCount(1, $this->historyContainer);
784+
785+
$request = $this->historyContainer[0]['request'];
786+
$this->assertEquals('POST', strtoupper($request->getMethod()));
787+
}
788+
761789
/**
762790
* Makes sure that a JWT is generated for the client-side token
763-
*
791+
*
764792
* Currently disabled due to the backend requiring an `exp` claim, which was
765793
* not required on T1s. Uncomment when the backend is fixed. - CRT
766794
*/
@@ -1319,7 +1347,7 @@ public function testGetsArchiveWithMaxBitrate(): void
13191347

13201348
$request = $this->historyContainer[0]['request'];
13211349
$this->assertEquals('GET', strtoupper($request->getMethod()));
1322-
$this->assertEquals('/v2/project/'.$this->API_KEY.'/archive/'.$archiveId, $request->getUri()->getPath());
1350+
$this->assertEquals('/v2/project/' . $this->API_KEY . '/archive/' . $archiveId, $request->getUri()->getPath());
13231351
$this->assertEquals('api.opentok.com', $request->getUri()->getHost());
13241352
$this->assertEquals('https', $request->getUri()->getScheme());
13251353

tests/OpenTokTest/test.key

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCy3YiiZ206+/7j
3+
oDzF9qGHhFuxEGuGL1ufGm0LvCiOgNJpV4KGatjdminomS0PwI6v9Gz3r4mYBxeR
4+
3xXV3xPpr3yEDu+ivQN8oMei4ttg++nuyk26gjAdEvz5uSQBV5lWvgjR6tlSPb/j
5+
ca4d5AymuWmT110qcQ+ui7eoOWAfQIWj5Tlqk6YyXUnoMlD4c2c9/hOJZR51VF1n
6+
diDONkHplqjzGfdHxDxCBXsIW1wi8h6PVHH54rDmYay1ojRVPJ7b2RBu8vgvWYoR
7+
du6cY8Bp/1skQUEvtOBhFN62vAZ12s91jFO+plzyA9oDfAXVguW0yRWj5GNJmtPZ
8+
YIcynpjvAgMBAAECggEAM1tzq3n5/Zk0jyRHvum5aKFi+HzH+t/nNVBPpjJxDLXF
9+
dLTJSBIu0bY9uUkeDKtT7QbIMPgokEvdAyfka6PhYlRecsadHQObmDHMEKOFrRu4
10+
CDXzSo2uBfMZSxTTV0VRRHxNKQT/QGN1kPdnsLJ1xXtwaqBIYnLTN2FrqvRKer4+
11+
molQK8v838q4tOVT0ZKjIFHX+zyebKqJDOsCO+jDnrKIw3VTID6iZ0DNwGp5xNJT
12+
HOLiT7CQM7Lg7fMdQp9xQxrGWJFw26cuvewmBuPdZRdqc8indgT5pq+VIZkLeTAB
13+
XMnf0W35abwIUlfMIvhVZOiaeZzMwzNuV/Qp9GPFAQKBgQDzVpWxefxmTyHCWXz4
14+
2m+wojoxEBgn6GRdvUbji7vyRRlmGZRNVybwqqxXyCq3RYdIwV55Ihk7O0mmO4g+
15+
ESuDchZaMxouzXzDKz8jyoG6Gxymd8QJetnA8ctFwUGnTrK3sCxnTAjphGSf1PlT
16+
vdev+f6T/QT0MT7qxUloDC9hAQKBgQC8LCF6OaFlZdi/kKPFcXbYIxFWRCdiun/A
17+
xAL3+UsMllF53aZcWnIsm9rv0sKhPfrTGCp0eLUyinZzjxzdGDeb5hqafWVArXfT
18+
xj4NC5uQVO2w0HGqB0BpZkBCtiyu25Pw0xPvXlcvwCBYcIDvJuf0hwiGBBKPk1b8
19+
LjlkbfoJ7wKBgQDZsU499gmtZYGoIvLAlnpxJNC2b9WMbkTL77bpfmrntJWiV6Pr
20+
BNrbV3TTG0nLp7H9jrB74dt8t++NfZjHHgk1kO0aSLlVwZOp7piP5mzkF7kr291P
21+
Nc505FubzeZ0TN1po3w19TnL3xs+OgPLvPymfBoaPrMd2qiU02Z2ZOBGAQKBgA9V
22+
GTU4VOpKLisNwgpogGKEGPmKfBsTTy2JyyQhb/gKl4Dyioej5wGzgVdhOPKidjmV
23+
EoCDBWCk35ny40swmfdd/HTyGrn2aHkdAhlWBMrx4Jwzn89W3+y2pC3LYkCtK5TH
24+
3iv25+vAH+KU6CyUYvoNtqgU1N5WBxRtP8frHiCJAoGAOtq0v8K2KKrEI6L/jHhJ
25+
eNZVUWdGQTZx33vvt5lIboxrNyajaBo25LpmmEAKOhgD61ivHJNrxVDkOMKNx2xt
26+
WnLZvQr7M62SdjWFmcFuY/xRbaX6IOW6C9qps3MdtJeFVw9P6z7udXfXHsCEbQvd
27+
YyR0bVDYLxbCAdYjs7PyCA8=
28+
-----END PRIVATE KEY-----

0 commit comments

Comments
 (0)