1
|
|
|
<?php |
2
|
|
|
namespace LunixREST\Router; |
3
|
|
|
|
4
|
|
|
use LunixREST\AccessControl\AccessControl; |
5
|
|
|
use LunixREST\Endpoint\Endpoint; |
6
|
|
|
use LunixREST\Endpoint\EndpointFactory; |
7
|
|
|
use LunixREST\Endpoint\Exceptions\UnknownEndpointException; |
8
|
|
|
use LunixREST\Exceptions\AccessDeniedException; |
9
|
|
|
use LunixREST\Exceptions\InvalidAPIKeyException; |
10
|
|
|
use LunixREST\Exceptions\ThrottleLimitExceededException; |
11
|
|
|
use LunixREST\Request\Request; |
12
|
|
|
use LunixREST\Response\Exceptions\UnknownResponseTypeException; |
13
|
|
|
use LunixREST\Response\Response; |
14
|
|
|
use LunixREST\Response\ResponseData; |
15
|
|
|
use LunixREST\Response\ResponseFactory; |
16
|
|
|
use LunixREST\Throttle\Throttle; |
17
|
|
|
|
18
|
|
|
/** |
19
|
|
|
* Class Router |
20
|
|
|
* @package LunixREST\Router |
21
|
|
|
*/ |
22
|
|
|
class Router { |
23
|
|
|
/** |
24
|
|
|
* @var AccessControl |
25
|
|
|
*/ |
26
|
|
|
protected $accessControl; |
27
|
|
|
/** |
28
|
|
|
* @var Throttle |
29
|
|
|
*/ |
30
|
|
|
protected $throttle; |
31
|
|
|
/** |
32
|
|
|
* @var ResponseFactory |
33
|
|
|
*/ |
34
|
|
|
protected $responseFactory; |
35
|
|
|
/** |
36
|
|
|
* @var EndpointFactory |
37
|
|
|
*/ |
38
|
|
|
private $endpointFactory; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @param AccessControl $accessControl |
42
|
|
|
* @param Throttle $throttle |
43
|
|
|
* @param ResponseFactory $responseFactory |
44
|
|
|
* @param EndpointFactory $endpointFactory |
45
|
|
|
*/ |
46
|
|
|
public function __construct(AccessControl $accessControl, Throttle $throttle, ResponseFactory $responseFactory, EndpointFactory $endpointFactory){ |
47
|
|
|
$this->accessControl = $accessControl; |
48
|
|
|
$this->throttle = $throttle; |
49
|
|
|
$this->responseFactory = $responseFactory; |
50
|
|
|
$this->endpointFactory = $endpointFactory; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* @param Request $request |
55
|
|
|
* @return Response |
56
|
|
|
* @throws AccessDeniedException |
57
|
|
|
* @throws InvalidAPIKeyException |
58
|
|
|
* @throws ThrottleLimitExceededException |
59
|
|
|
* @throws UnknownEndpointException |
60
|
|
|
* @throws UnknownResponseTypeException |
61
|
|
|
*/ |
62
|
|
|
public function route(Request $request): Response{ |
63
|
|
|
$this->validateKey($request); |
64
|
|
|
|
65
|
|
|
$this->validateExtension($request); |
66
|
|
|
|
67
|
|
|
$endpoint = $this->endpointFactory->getEndpoint($request->getEndpoint(), $request->getVersion()); |
68
|
|
|
|
69
|
|
|
if($this->throttle->shouldThrottle($request)) { |
70
|
|
|
throw new ThrottleLimitExceededException('Request limit exceeded'); |
71
|
|
|
} |
72
|
|
|
|
73
|
|
|
if(!$this->accessControl->validateAccess($request)) { |
74
|
|
|
throw new AccessDeniedException("API key does not have the required permissions to access requested resource"); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
$this->throttle->logRequest($request); |
78
|
|
|
|
79
|
|
|
$responseData = $this->executeEndpoint($endpoint, $request); |
80
|
|
|
|
81
|
|
|
return $this->responseFactory->getResponse($responseData, $request->getExtension()); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* @param Request $request |
86
|
|
|
* @throws InvalidAPIKeyException |
87
|
|
|
*/ |
88
|
|
|
protected function validateKey(Request $request){ |
89
|
|
|
if(!$this->accessControl->validateKey($request->getApiKey())){ |
90
|
|
|
throw new InvalidAPIKeyException('Invalid API key'); |
91
|
|
|
} |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @param Request $request |
96
|
|
|
* @throws UnknownResponseTypeException |
97
|
|
|
*/ |
98
|
|
|
protected function validateExtension(Request $request) { |
99
|
|
|
$formats = $this->responseFactory->getSupportedTypes(); |
100
|
|
|
if(!$formats || !in_array($request->getExtension(), $formats)){ |
|
|
|
|
101
|
|
|
throw new UnknownResponseTypeException('Unknown response format: ' . $request->getExtension()); |
102
|
|
|
} |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
protected function executeEndpoint(Endpoint $endpoint, Request $request): ResponseData { |
106
|
|
|
return call_user_func([$endpoint, $request->getMethod()], [$request]); |
107
|
|
|
} |
108
|
|
|
} |
109
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.