Skip to content

Commit 909de18

Browse files
authored
Merge pull request #48 from Sammyjo20/feature/authenticators
Feature | Authenticators
2 parents cc895fe + 381f0ce commit 909de18

28 files changed

+746
-363
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Sammyjo20\Saloon\Exceptions;
4+
5+
class MissingAuthenticatorException extends SaloonException
6+
{
7+
}

src/Helpers/Keychain.php

Lines changed: 0 additions & 21 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Sammyjo20\Saloon\Http\Auth;
4+
5+
use Sammyjo20\Saloon\Http\SaloonRequest;
6+
use Sammyjo20\Saloon\Interfaces\AuthenticatorInterface;
7+
8+
class BasicAuthenticator implements AuthenticatorInterface
9+
{
10+
/**
11+
* @param string $username
12+
* @param string $password
13+
*/
14+
public function __construct(
15+
public string $username,
16+
public string $password,
17+
) {
18+
//
19+
}
20+
21+
/**
22+
* Apply the authentication to the request.
23+
*
24+
* @param SaloonRequest $request
25+
* @return void
26+
*/
27+
public function set(SaloonRequest $request): void
28+
{
29+
$request->addConfig('auth', [$this->username, $this->password]);
30+
}
31+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace Sammyjo20\Saloon\Http\Auth;
4+
5+
use Sammyjo20\Saloon\Http\SaloonRequest;
6+
use Sammyjo20\Saloon\Interfaces\AuthenticatorInterface;
7+
8+
class DigestAuthenticator implements AuthenticatorInterface
9+
{
10+
/**
11+
* @param string $username
12+
* @param string $password
13+
* @param string $digest
14+
*/
15+
public function __construct(
16+
public string $username,
17+
public string $password,
18+
public string $digest,
19+
) {
20+
//
21+
}
22+
23+
/**
24+
* Apply the authentication to the request.
25+
*
26+
* @param SaloonRequest $request
27+
* @return void
28+
*/
29+
public function set(SaloonRequest $request): void
30+
{
31+
$request->addConfig('auth', [$this->username, $this->password, $this->digest]);
32+
}
33+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Sammyjo20\Saloon\Http\Auth;
4+
5+
use Sammyjo20\Saloon\Http\SaloonRequest;
6+
use Sammyjo20\Saloon\Interfaces\AuthenticatorInterface;
7+
8+
class TokenAuthenticator implements AuthenticatorInterface
9+
{
10+
/**
11+
* @param string $token
12+
* @param string $prefix
13+
*/
14+
public function __construct(
15+
public string $token,
16+
public string $prefix = 'Bearer'
17+
) {
18+
//
19+
}
20+
21+
/**
22+
* Apply the authentication to the request.
23+
*
24+
* @param SaloonRequest $request
25+
* @return void
26+
*/
27+
public function set(SaloonRequest $request): void
28+
{
29+
$request->addHeader('Authorization', trim($this->prefix . ' ' . $this->token));
30+
}
31+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace Sammyjo20\Saloon\Interfaces;
4+
5+
use Sammyjo20\Saloon\Http\SaloonRequest;
6+
7+
interface AuthenticatorInterface
8+
{
9+
/**
10+
* Apply the authentication to the request.
11+
*
12+
* @param SaloonRequest $request
13+
* @return void
14+
*/
15+
public function set(SaloonRequest $request): void;
16+
}

src/Interfaces/KeychainInterface.php

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/Managers/RequestManager.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use GuzzleHttp\Exception\BadResponseException;
2020
use Sammyjo20\Saloon\Traits\CollectsQueryParams;
2121
use Sammyjo20\Saloon\Traits\CollectsInterceptors;
22+
use Sammyjo20\Saloon\Interfaces\AuthenticatorInterface;
2223
use Sammyjo20\Saloon\Exceptions\SaloonMultipleMockMethodsException;
2324
use Sammyjo20\Saloon\Exceptions\SaloonInvalidResponseClassException;
2425
use Sammyjo20\Saloon\Exceptions\SaloonNoMockResponsesProvidedException;
@@ -107,9 +108,9 @@ public function hydrate(): void
107108
$this->connector->boot($this->request);
108109
$this->request->boot($this->request);
109110

110-
// Now let's run our keychain boot method
111+
// Now let's run our authenticator if one is present.
111112

112-
$this->request->bootKeychain($this->request);
113+
$this->authenticateRequest();
113114

114115
// Merge in response interceptors now
115116

@@ -322,4 +323,20 @@ public function getRequest(): SaloonRequest
322323
{
323324
return $this->request;
324325
}
326+
327+
/**
328+
* Authenticate the request by running the authenticator if it is present.
329+
*
330+
* @return void
331+
*/
332+
private function authenticateRequest(): void
333+
{
334+
$authenticator = $this->request->getAuthenticator() ?? $this->connector->getAuthenticator();
335+
336+
if (! $authenticator instanceof AuthenticatorInterface) {
337+
return;
338+
}
339+
340+
$authenticator->set($this->request);
341+
}
325342
}

src/Traits/Auth/RequiresAuth.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Sammyjo20\Saloon\Traits\Auth;
4+
5+
use Sammyjo20\Saloon\Http\SaloonRequest;
6+
use Sammyjo20\Saloon\Interfaces\AuthenticatorInterface;
7+
use Sammyjo20\Saloon\Exceptions\MissingAuthenticatorException;
8+
9+
trait RequiresAuth
10+
{
11+
/**
12+
* Throw an exception if an authenticator is not on the request while it is booting.
13+
*
14+
* @param SaloonRequest $request
15+
* @return void
16+
* @throws MissingAuthenticatorException
17+
* @throws \Sammyjo20\Saloon\Exceptions\SaloonInvalidConnectorException
18+
*/
19+
public function bootRequiresAuth(SaloonRequest $request): void
20+
{
21+
$connector = $request->getAuthenticator() ?? $request->getConnector()->getAuthenticator();
22+
23+
if (! $connector instanceof AuthenticatorInterface) {
24+
throw new MissingAuthenticatorException($this->getRequiresAuthMessage($request));
25+
}
26+
}
27+
28+
/**
29+
* Default message.
30+
*
31+
* @param SaloonRequest $request
32+
* @return string
33+
*/
34+
protected function getRequiresAuthMessage(SaloonRequest $request): string
35+
{
36+
return sprintf('The "%s" request requires authentication. Please provide an authenticator using the `withAuth` method or return a default authenticator in your connector/request.', $request::class);
37+
}
38+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Sammyjo20\Saloon\Traits\Auth;
4+
5+
use Sammyjo20\Saloon\Http\SaloonRequest;
6+
use Sammyjo20\Saloon\Exceptions\MissingAuthenticatorException;
7+
8+
trait RequiresBasicAuth
9+
{
10+
use RequiresAuth;
11+
12+
/**
13+
* @throws MissingAuthenticatorException
14+
* @throws \Sammyjo20\Saloon\Exceptions\SaloonInvalidConnectorException
15+
*/
16+
public function bootRequiresBasicAuth(SaloonRequest $request): void
17+
{
18+
$this->bootRequiresAuth($request);
19+
}
20+
21+
/**
22+
* Default message.
23+
*
24+
* @param SaloonRequest $request
25+
* @return string
26+
*/
27+
protected function getRequiresAuthMessage(SaloonRequest $request): string
28+
{
29+
return sprintf('The "%s" request requires authentication. Please provide authentication using the `withBasicAuth` method or return a default authenticator in your connector/request.', $request::class);
30+
}
31+
}

0 commit comments

Comments
 (0)