1 | <?php |
||||
2 | |||||
3 | namespace BenTools\MercurePHP\Security; |
||||
4 | |||||
5 | use BenTools\MercurePHP\Configuration\Configuration; |
||||
6 | use Lcobucci\JWT\Parser; |
||||
7 | use Lcobucci\JWT\Signer; |
||||
8 | use Lcobucci\JWT\Signer\Key; |
||||
9 | use Lcobucci\JWT\Token; |
||||
10 | use Psr\Http\Message\ServerRequestInterface; |
||||
11 | use RuntimeException; |
||||
12 | |||||
13 | use function BenTools\MercurePHP\get_signer; |
||||
14 | |||||
15 | final class Authenticator |
||||
16 | { |
||||
17 | private Parser $parser; |
||||
18 | private Key $key; |
||||
19 | private Signer $signer; |
||||
20 | 53 | ||||
21 | public function __construct(Parser $parser, Key $key, Signer $signer) |
||||
22 | 53 | { |
|||
23 | 53 | $this->parser = $parser; |
|||
24 | 53 | $this->key = $key; |
|||
25 | 53 | $this->signer = $signer; |
|||
26 | } |
||||
27 | 50 | ||||
28 | public function authenticate(ServerRequestInterface $request): ?Token |
||||
29 | 50 | { |
|||
30 | $token = self::extractToken($request, $this->parser, $this->key, $this->signer); |
||||
31 | 50 | ||||
32 | 7 | if (null === $token) { |
|||
33 | return null; |
||||
34 | } |
||||
35 | 43 | ||||
36 | 2 | if (!$token->verify($this->signer, $this->key)) { |
|||
37 | throw new RuntimeException('Invalid token signature.'); |
||||
38 | } |
||||
39 | 41 | ||||
40 | 2 | if ($token->isExpired()) { |
|||
41 | throw new RuntimeException('Your token has expired.'); |
||||
42 | } |
||||
43 | 39 | ||||
44 | return $token; |
||||
45 | } |
||||
46 | 50 | ||||
47 | private static function extractRawToken(ServerRequestInterface $request): ?string |
||||
48 | 50 | { |
|||
49 | 41 | if ($request->hasHeader('Authorization')) { |
|||
50 | 41 | $payload = \trim($request->getHeaderLine('Authorization')); |
|||
51 | 41 | if (0 === \strpos($payload, 'Bearer ')) { |
|||
52 | return \substr($payload, 7); |
||||
53 | } |
||||
54 | } |
||||
55 | 9 | ||||
56 | 9 | $cookies = $request->getCookieParams(); |
|||
57 | return $cookies['mercureAuthorization'] ?? null; |
||||
58 | } |
||||
59 | 50 | ||||
60 | private static function extractToken(ServerRequestInterface $request, Parser $parser, Key $key, Signer $signer): ?Token |
||||
0 ignored issues
–
show
The parameter
$key is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||
61 | 50 | { |
|||
62 | 50 | $payload = self::extractRawToken($request); |
|||
63 | 7 | if (null === $payload) { |
|||
64 | return null; |
||||
65 | } |
||||
66 | |||||
67 | 43 | try { |
|||
68 | return $parser->parse($payload); |
||||
69 | } catch (RuntimeException $e) { |
||||
70 | throw new RuntimeException("Cannot decode token."); |
||||
71 | } |
||||
72 | } |
||||
73 | 19 | ||||
74 | public static function createPublisherAuthenticator(array $config): Authenticator |
||||
75 | { |
||||
76 | 19 | $publisherKey = $config[Configuration::PUBLISHER_JWT_KEY] ?? $config[Configuration::JWT_KEY]; |
|||
77 | 19 | $publisherAlgorithm = $config[Configuration::PUBLISHER_JWT_ALGORITHM] ?? $config[Configuration::JWT_ALGORITHM]; |
|||
78 | |||||
79 | return new self( |
||||
80 | 19 | new Parser(), |
|||
81 | new Key($publisherKey), |
||||
82 | get_signer($publisherAlgorithm) |
||||
83 | ); |
||||
84 | 19 | } |
|||
85 | |||||
86 | public static function createSubscriberAuthenticator(array $config): Authenticator |
||||
87 | 10 | { |
|||
88 | $subscriberKey = $config[Configuration::SUBSCRIBER_JWT_KEY] ?? $config[Configuration::JWT_KEY]; |
||||
89 | 10 | $subscriberAlgorithm = $config[Configuration::SUBSCRIBER_JWT_ALGORITHM] ?? $config[Configuration::JWT_ALGORITHM]; |
|||
90 | 10 | ||||
91 | return new self( |
||||
92 | 10 | new Parser(), |
|||
93 | 10 | new Key($subscriberKey), |
|||
94 | 10 | get_signer($subscriberAlgorithm) |
|||
95 | 10 | ); |
|||
96 | } |
||||
97 | } |
||||
98 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.