Completed
Push — master ( f9ded0...b13d5b )
by John
02:58 queued 01:00
created

GenericServer::handleRequest()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
ccs 10
cts 10
cp 1
cc 3
eloc 10
nc 3
nop 1
crap 3
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\ThrottleLimitExceededException;
10
use LunixREST\APIRequest\APIRequest;
11
use LunixREST\APIResponse\Exceptions\NotAcceptableResponseTypeException;
12
use LunixREST\APIResponse\APIResponse;
13
use LunixREST\APIResponse\ResponseFactory;
14
use LunixREST\Server\Exceptions\MethodNotFoundException;
15
use LunixREST\Throttle\Throttle;
16
17
class GenericServer implements Server
18
{
19
    /**
20
     * @var AccessControl
21
     */
22
    protected $accessControl;
23
    /**
24
     * @var Throttle
25
     */
26
    protected $throttle;
27
    /**
28
     * @var ResponseFactory
29
     */
30
    protected $responseFactory;
31
    /**
32
     * @var Router
33
     */
34
    private $router;
35
36
    /**
37
     * @param AccessControl $accessControl
38
     * @param Throttle $throttle
39
     * @param ResponseFactory $responseFactory
40
     * @param Router $router
41
     */
42 6
    public function __construct(
43
        AccessControl $accessControl,
44
        Throttle $throttle,
45
        ResponseFactory $responseFactory,
46
        Router $router
47
    ) {
48 6
        $this->accessControl = $accessControl;
49 6
        $this->throttle = $throttle;
50 6
        $this->responseFactory = $responseFactory;
51 6
        $this->router = $router;
52 6
    }
53
54
    /**
55
     * @param APIRequest $request
56
     * @return APIResponse
57
     * @throws InvalidAPIKeyException
58
     * @throws AccessDeniedException
59
     * @throws ThrottleLimitExceededException
60
     * @throws UnknownEndpointException
61
     * @throws MethodNotFoundException
62
     * @throws NotAcceptableResponseTypeException
63
     */
64 6
    public function handleRequest(APIRequest $request): APIResponse
65
    {
66 6
        $this->validateKey($request);
67
68 5
        if ($this->throttle->shouldThrottle($request)) {
69 1
            throw new ThrottleLimitExceededException('Request limit exceeded');
70
        }
71
72 4
        $this->validateAcceptableMIMETypes($request);
73
74 2
        if (!$this->accessControl->validateAccess($request)) {
75 1
            throw new AccessDeniedException("API key does not have the required permissions to access requested resource");
76
        }
77
78 1
        $this->throttle->logRequest($request);
79
80 1
        $responseData = $this->router->route($request);
81
82 1
        return $this->responseFactory->getResponse($responseData, $request->getAcceptableMIMETypes());
83
    }
84
85
    /**
86
     * @param APIRequest $request
87
     * @throws InvalidAPIKeyException
88
     */
89 6
    protected function validateKey(APIRequest $request)
90
    {
91 6
        if (!$this->accessControl->validateKey($request->getApiKey())) {
92 1
            throw new InvalidAPIKeyException('Invalid API key');
93
        }
94 5
    }
95
96
    /**
97
     * @param APIRequest $request
98
     * @throws NotAcceptableResponseTypeException
99
     */
100
    //TODO: Handle wildcards in request MIME types (*/*)
101 4
    protected function validateAcceptableMIMETypes(APIRequest $request)
102
    {
103 4
        $formats = $this->responseFactory->getSupportedMIMETypes();
104 4
        if (empty($formats) || (
105 4
                !empty($request->getAcceptableMIMETypes()) && empty(array_intersect($request->getAcceptableMIMETypes(),
106
                    $formats))
107
            )
108
        ) {
109 2
            throw new NotAcceptableResponseTypeException('None of the requests acceptable response types are valid');
110
        }
111 2
    }
112
}
113