1
|
|
|
<?php |
2
|
|
|
namespace LunixREST\Server; |
3
|
|
|
|
4
|
|
|
use LunixREST\AccessControl\AccessControl; |
5
|
|
|
use LunixREST\Endpoint\EndpointFactory; |
6
|
|
|
use LunixREST\Endpoint\Exceptions\UnknownEndpointException; |
7
|
|
|
use LunixREST\Exceptions\AccessDeniedException; |
8
|
|
|
use LunixREST\Exceptions\InvalidAPIKeyException; |
9
|
|
|
use LunixREST\Exceptions\MethodNotFoundException; |
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\ResponseFactory; |
15
|
|
|
use LunixREST\Throttle\Throttle; |
16
|
|
|
|
17
|
|
|
class Server { |
18
|
|
|
/** |
19
|
|
|
* @var AccessControl |
20
|
|
|
*/ |
21
|
|
|
protected $accessControl; |
22
|
|
|
/** |
23
|
|
|
* @var Throttle |
24
|
|
|
*/ |
25
|
|
|
protected $throttle; |
26
|
|
|
/** |
27
|
|
|
* @var ResponseFactory |
28
|
|
|
*/ |
29
|
|
|
protected $responseFactory; |
30
|
|
|
/** |
31
|
|
|
* @var Router |
32
|
|
|
*/ |
33
|
|
|
private $router; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @param AccessControl $accessControl |
37
|
|
|
* @param Throttle $throttle |
38
|
|
|
* @param ResponseFactory $responseFactory |
39
|
|
|
* @param EndpointFactory $endpointFactory |
40
|
|
|
*/ |
41
|
|
|
public function __construct(AccessControl $accessControl, Throttle $throttle, ResponseFactory $responseFactory, EndpointFactory $endpointFactory){ |
42
|
|
|
$this->accessControl = $accessControl; |
43
|
|
|
$this->throttle = $throttle; |
44
|
|
|
$this->responseFactory = $responseFactory; |
45
|
|
|
$this->router = new Router($endpointFactory); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @param Request $request |
50
|
|
|
* @return Response |
51
|
|
|
* @throws AccessDeniedException |
52
|
|
|
* @throws ThrottleLimitExceededException |
53
|
|
|
* @throws UnknownEndpointException |
54
|
|
|
* @throws MethodNotFoundException |
55
|
|
|
*/ |
56
|
|
|
public function handleRequest(Request $request): Response { |
57
|
|
|
$this->validateKey($request); |
58
|
|
|
|
59
|
|
|
$this->validateExtension($request); |
60
|
|
|
|
61
|
|
|
if($this->throttle->shouldThrottle($request)) { |
62
|
|
|
throw new ThrottleLimitExceededException('Request limit exceeded'); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
if(!$this->accessControl->validateAccess($request)) { |
66
|
|
|
throw new AccessDeniedException("API key does not have the required permissions to access requested resource"); |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
$this->throttle->logRequest($request); |
70
|
|
|
|
71
|
|
|
$responseData = $this->router->route($request); |
72
|
|
|
|
73
|
|
|
return $this->responseFactory->getResponse($responseData, $request->getExtension()); |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* @param Request $request |
78
|
|
|
* @throws InvalidAPIKeyException |
79
|
|
|
*/ |
80
|
|
|
protected function validateKey(Request $request){ |
81
|
|
|
if(!$this->accessControl->validateKey($request->getApiKey())){ |
82
|
|
|
throw new InvalidAPIKeyException('Invalid API key'); |
83
|
|
|
} |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* @param Request $request |
88
|
|
|
* @throws UnknownResponseTypeException |
89
|
|
|
*/ |
90
|
|
|
protected function validateExtension(Request $request) { |
91
|
|
|
$formats = $this->responseFactory->getSupportedTypes(); |
92
|
|
|
if(!$formats || !in_array($request->getExtension(), $formats)){ |
|
|
|
|
93
|
|
|
throw new UnknownResponseTypeException('Unknown response format: ' . $request->getExtension()); |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
} |
97
|
|
|
|
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.