Skip to content

Commit 5360821

Browse files
Moved authentication logic to individual handlers (#283)
1 parent 6d85bd2 commit 5360821

12 files changed

+324
-78
lines changed

src/Client.php

Lines changed: 28 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@
3232
use Vonage\Client\Credentials\Basic;
3333
use Vonage\Client\Credentials\Container;
3434
use Vonage\Client\Credentials\CredentialsInterface;
35+
use Vonage\Client\Credentials\Handler\BasicHandler;
36+
use Vonage\Client\Credentials\Handler\KeypairHandler;
37+
use Vonage\Client\Credentials\Handler\SignatureBodyFormHandler;
38+
use Vonage\Client\Credentials\Handler\SignatureBodyHandler;
39+
use Vonage\Client\Credentials\Handler\SignatureQueryHandler;
40+
use Vonage\Client\Credentials\Handler\TokenBodyFormHandler;
41+
use Vonage\Client\Credentials\Handler\TokenBodyHandler;
42+
use Vonage\Client\Credentials\Handler\TokenQueryHandler;
3543
use Vonage\Client\Credentials\Keypair;
3644
use Vonage\Client\Credentials\OAuth;
3745
use Vonage\Client\Credentials\SignatureSecret;
@@ -297,97 +305,44 @@ public static function signRequest(RequestInterface $request, SignatureSecret $c
297305
{
298306
switch ($request->getHeaderLine('content-type')) {
299307
case 'application/json':
300-
$body = $request->getBody();
301-
$body->rewind();
302-
$content = $body->getContents();
303-
$params = json_decode($content, true);
304-
$params['api_key'] = $credentials['api_key'];
305-
$signature = new Signature($params, $credentials['signature_secret'], $credentials['signature_method']);
306-
$body->rewind();
307-
$body->write(json_encode($signature->getSignedParams()));
308+
$handler = new SignatureBodyHandler();
308309
break;
309310
case 'application/x-www-form-urlencoded':
310-
$body = $request->getBody();
311-
$body->rewind();
312-
$content = $body->getContents();
313-
$params = [];
314-
parse_str($content, $params);
315-
$params['api_key'] = $credentials['api_key'];
316-
$signature = new Signature($params, $credentials['signature_secret'], $credentials['signature_method']);
317-
$params = $signature->getSignedParams();
318-
$body->rewind();
319-
$body->write(http_build_query($params, '', '&'));
311+
$handler = new SignatureBodyFormHandler();
320312
break;
321313
default:
322-
$query = [];
323-
parse_str($request->getUri()->getQuery(), $query);
324-
$query['api_key'] = $credentials['api_key'];
325-
$signature = new Signature($query, $credentials['signature_secret'], $credentials['signature_method']);
326-
$request = $request->withUri(
327-
$request->getUri()->withQuery(http_build_query($signature->getSignedParams()))
328-
);
314+
$handler = new SignatureQueryHandler();
329315
break;
330316
}
331317

332-
return $request;
318+
return $handler($request, $credentials);
333319
}
334320

335321
public static function authRequest(RequestInterface $request, Basic $credentials): RequestInterface
336322
{
337323
switch ($request->getHeaderLine('content-type')) {
338324
case 'application/json':
339325
if (static::requiresBasicAuth($request)) {
340-
$c = $credentials->asArray();
341-
$cx = base64_encode($c['api_key'] . ':' . $c['api_secret']);
342-
343-
$request = $request->withHeader('Authorization', 'Basic ' . $cx);
326+
$handler = new BasicHandler();
344327
} elseif (static::requiresAuthInUrlNotBody($request)) {
345-
$query = [];
346-
parse_str($request->getUri()->getQuery(), $query);
347-
$query = array_merge($query, $credentials->asArray());
348-
349-
$request = $request->withUri($request->getUri()->withQuery(http_build_query($query)));
328+
$handler = new TokenQueryHandler();
350329
} else {
351-
$body = $request->getBody();
352-
$body->rewind();
353-
$content = $body->getContents();
354-
$params = json_decode($content, true);
355-
356-
if (!$params) {
357-
$params = [];
358-
}
359-
360-
$params = array_merge($params, $credentials->asArray());
361-
$body->rewind();
362-
$body->write(json_encode($params));
330+
$handler = new TokenBodyHandler();
363331
}
364332
break;
365333
case 'application/x-www-form-urlencoded':
366-
$body = $request->getBody();
367-
$body->rewind();
368-
$content = $body->getContents();
369-
$params = [];
370-
parse_str($content, $params);
371-
$params = array_merge($params, $credentials->asArray());
372-
$body->rewind();
373-
$body->write(http_build_query($params, '', '&'));
334+
$handler = new TokenBodyFormHandler();
374335
break;
375336
default:
376337
if (static::requiresBasicAuth($request)) {
377-
$c = $credentials->asArray();
378-
$cx = base64_encode($c['api_key'] . ':' . $c['api_secret']);
379-
380-
$request = $request->withHeader('Authorization', 'Basic ' . $cx);
338+
$handler = new BasicHandler();
381339
} else {
382-
$query = [];
383-
parse_str($request->getUri()->getQuery(), $query);
384-
$query = array_merge($query, $credentials->asArray());
385-
$request = $request->withUri($request->getUri()->withQuery(http_build_query($query)));
340+
$handler = new TokenQueryHandler();
386341
}
387342
break;
388343
}
389344

390-
return $request;
345+
return $handler($request, $credentials);
391346
}
392347

393348
/**
@@ -504,16 +459,14 @@ public function send(RequestInterface $request): ResponseInterface
504459
{
505460
if ($this->credentials instanceof Container) {
506461
if ($this->needsKeypairAuthentication($request)) {
507-
$token = $this->credentials->get(Keypair::class)->generateJwt();
508-
509-
$request = $request->withHeader('Authorization', 'Bearer ' . $token->toString());
462+
$handler = new KeypairHandler();
463+
$request = $handler($request, $this->getCredentials());
510464
} else {
511465
$request = self::authRequest($request, $this->credentials->get(Basic::class));
512466
}
513467
} elseif ($this->credentials instanceof Keypair) {
514-
$token = $this->credentials->generateJwt();
515-
516-
$request = $request->withHeader('Authorization', 'Bearer ' . $token->toString());
468+
$handler = new KeypairHandler();
469+
$request = $handler($request, $this->getCredentials());
517470
} elseif ($this->credentials instanceof SignatureSecret) {
518471
$request = self::signRequest($request, $this->credentials);
519472
} elseif ($this->credentials instanceof Basic) {
@@ -696,4 +649,9 @@ public function getLogger(): ?LoggerInterface
696649

697650
return $this->logger;
698651
}
652+
653+
public function getCredentials(): CredentialsInterface
654+
{
655+
return $this->credentials;
656+
}
699657
}

src/Client/APIResource.php

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,23 +11,28 @@
1111

1212
namespace Vonage\Client;
1313

14+
use function is_null;
15+
use function json_decode;
16+
use function json_encode;
17+
use function http_build_query;
1418
use Laminas\Diactoros\Request;
15-
use Psr\Http\Client\ClientExceptionInterface;
19+
use Vonage\Entity\Filter\EmptyFilter;
1620
use Psr\Http\Message\RequestInterface;
1721
use Psr\Http\Message\ResponseInterface;
18-
use Vonage\Entity\Filter\EmptyFilter;
19-
use Vonage\Entity\Filter\FilterInterface;
2022
use Vonage\Entity\IterableAPICollection;
21-
22-
use function http_build_query;
23-
use function is_null;
24-
use function json_decode;
25-
use function json_encode;
23+
use Vonage\Entity\Filter\FilterInterface;
24+
use Psr\Http\Client\ClientExceptionInterface;
25+
use Vonage\Client\Credentials\Handler\HandlerInterface;
2626

2727
class APIResource implements ClientAwareInterface
2828
{
2929
use ClientAwareTrait;
3030

31+
/**
32+
* @var HandlerInterface
33+
*/
34+
protected $authHandler;
35+
3136
/**
3237
* Base URL that we will hit. This can be overridden from the underlying
3338
* client or directly on this class.
@@ -80,6 +85,16 @@ class APIResource implements ClientAwareInterface
8085
*/
8186
protected $lastResponse;
8287

88+
/**
89+
* Adds authentication to a request
90+
* @todo Use this method when Vonage\Client no longer adds authentication
91+
*/
92+
public function addAuth(RequestInterface $request)
93+
{
94+
$creds = $this->getClient()->getCredentials();
95+
return $this->getAuthHandler()($request, $creds);
96+
}
97+
8398
/**
8499
* @throws ClientExceptionInterface
85100
* @throws Exception\Exception
@@ -97,6 +112,10 @@ public function create(array $body, string $uri = '', array $headers = []): ?arr
97112
$headers
98113
);
99114

115+
if ($this->getAuthHandler()) {
116+
$request = $this->addAuth($request);
117+
}
118+
100119
$request->getBody()->write(json_encode($body));
101120
$this->lastRequest = $request;
102121

@@ -142,6 +161,10 @@ public function delete(string $id, array $headers = []): ?array
142161
$headers
143162
);
144163

164+
if ($this->getAuthHandler()) {
165+
$request = $this->addAuth($request);
166+
}
167+
145168
$response = $this->getClient()->send($request);
146169
$status = (int)$response->getStatusCode();
147170

@@ -186,6 +209,10 @@ public function get($id, array $query = [], array $headers = [])
186209
$headers
187210
);
188211

212+
if ($this->getAuthHandler()) {
213+
$request = $this->addAuth($request);
214+
}
215+
189216
$response = $this->getClient()->send($request);
190217
$status = (int)$response->getStatusCode();
191218

@@ -202,6 +229,11 @@ public function get($id, array $query = [], array $headers = [])
202229
return json_decode($response->getBody()->getContents(), true);
203230
}
204231

232+
public function getAuthHandler(): ?HandlerInterface
233+
{
234+
return $this->authHandler;
235+
}
236+
205237
public function getBaseUrl(): ?string
206238
{
207239
if (!$this->baseUrl && $this->client) {
@@ -294,6 +326,13 @@ public function search(?FilterInterface $filter = null, string $uri = ''): Itera
294326
return $collection;
295327
}
296328

329+
public function setAuthHandler($handler): self
330+
{
331+
$this->authHandler = $handler;
332+
333+
return $this;
334+
}
335+
297336
public function setBaseUrl(string $url): self
298337
{
299338
$this->baseUrl = $url;
@@ -362,6 +401,10 @@ public function submit(array $formData = [], string $uri = '', array $headers =
362401
$headers
363402
);
364403

404+
if ($this->getAuthHandler()) {
405+
$request = $this->addAuth($request);
406+
}
407+
365408
$request->getBody()->write(http_build_query($formData));
366409
$response = $this->getClient()->send($request);
367410
$status = $response->getStatusCode();
@@ -396,6 +439,10 @@ public function update(string $id, array $body, array $headers = []): ?array
396439
$headers
397440
);
398441

442+
if ($this->getAuthHandler()) {
443+
$request = $this->addAuth($request);
444+
}
445+
399446
$request->getBody()->write(json_encode($body));
400447
$response = $this->getClient()->send($request);
401448

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace Vonage\Client\Credentials\Handler;
4+
5+
use Psr\Http\Message\RequestInterface;
6+
use Vonage\Client\Credentials\Container;
7+
use Vonage\Client\Credentials\CredentialsInterface;
8+
9+
abstract class AbstractHandler
10+
{
11+
abstract function __invoke(RequestInterface $request, CredentialsInterface $credentials);
12+
13+
protected function extract(string $class, CredentialsInterface $credentials): CredentialsInterface
14+
{
15+
if ($credentials instanceof $class) {
16+
return $credentials;
17+
}
18+
19+
if ($credentials instanceof Container) {
20+
$creds = $credentials->get($class);
21+
if (!is_null($creds)) {
22+
return $creds;
23+
}
24+
}
25+
26+
throw new \RuntimeException('Requested auth type not found');
27+
}
28+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Vonage\Client\Credentials\Handler;
4+
5+
use Psr\Http\Message\RequestInterface;
6+
use Vonage\Client\Credentials\Basic;
7+
use Vonage\Client\Credentials\CredentialsInterface;
8+
9+
class BasicHandler extends AbstractHandler
10+
{
11+
public function __invoke(RequestInterface $request, CredentialsInterface $credentials)
12+
{
13+
$credentials = $this->extract(Basic::class, $credentials);
14+
15+
$c = $credentials->asArray();
16+
$cx = base64_encode($c['api_key'] . ':' . $c['api_secret']);
17+
18+
$request = $request->withHeader('Authorization', 'Basic ' . $cx);
19+
20+
return $request;
21+
}
22+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
3+
namespace Vonage\Client\Credentials\Handler;
4+
5+
use Psr\Http\Message\RequestInterface;
6+
use Vonage\Client\Credentials\CredentialsInterface;
7+
8+
interface HandlerInterface
9+
{
10+
/**
11+
* Add authentication to a request
12+
*/
13+
function __invoke(RequestInterface $request, CredentialsInterface $credentials): RequestInterface;
14+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace Vonage\Client\Credentials\Handler;
4+
5+
use Psr\Http\Message\RequestInterface;
6+
use Vonage\Client\Credentials\CredentialsInterface;
7+
use Vonage\Client\Credentials\Keypair;
8+
9+
class KeypairHandler extends AbstractHandler
10+
{
11+
public function __invoke(RequestInterface $request, CredentialsInterface $credentials)
12+
{
13+
/** @var Keypair $credentials */
14+
$credentials = $this->extract(Keypair::class, $credentials);
15+
$token = $credentials->generateJwt();
16+
17+
return $request->withHeader('Authorization', 'Bearer ' . $token->toString());
18+
}
19+
}

0 commit comments

Comments
 (0)