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

GenericServer   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 9
dl 0
loc 96
rs 10
c 0
b 0
f 0
ccs 26
cts 26
cp 1

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A handleRequest() 0 20 3
A validateKey() 0 6 2
A validateAcceptableMIMETypes() 0 11 4
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