GenericServer::validateAcceptableMIMETypes()   B
last analyzed

Complexity

Conditions 5
Paths 6

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 9
cts 9
cp 1
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 8
nc 6
nop 1
crap 5
1
<?php
2
namespace LunixREST\Server;
3
4
use LunixREST\Server\AccessControl\AccessControl;
5
use LunixREST\Server\Exceptions\UnableToHandleRequestException;
6
use LunixREST\Server\ResponseFactory\Exceptions\UnableToCreateAPIResponseException;
7
use LunixREST\Server\APIRequest\APIRequest;
8
use LunixREST\Server\APIResponse\APIResponse;
9
use LunixREST\Server\Exceptions\AccessDeniedException;
10
use LunixREST\Server\Exceptions\InvalidAPIKeyException;
11
use LunixREST\Server\Exceptions\ThrottleLimitExceededException;
12
use LunixREST\Server\ResponseFactory\Exceptions\NotAcceptableResponseTypeException;
13
use LunixREST\Server\ResponseFactory\ResponseFactory;
14
use LunixREST\Server\Router\Exceptions\UnableToRouteRequestException;
15
use LunixREST\Server\Router\Router;
16
use LunixREST\Server\Throttle\Throttle;
17
18
/**
19
 * A Server implementation that derives it's behaviour from an AccessControl, a Throttle, a ResponseFactory, and a Router.
20
 * Class GenericServer
21
 * @package LunixREST\Server
22
 */
23
class GenericServer implements Server
24
{
25
    /**
26
     * @var AccessControl
27
     */
28
    protected $accessControl;
29
    /**
30
     * @var Throttle
31
     */
32
    protected $throttle;
33
    /**
34
     * @var ResponseFactory
35
     */
36
    protected $responseFactory;
37
    /**
38
     * @var Router
39
     */
40
    private $router;
41
42
    /**
43
     * @param AccessControl $accessControl
44
     * @param Throttle $throttle
45
     * @param ResponseFactory $responseFactory
46
     * @param Router $router
47
     */
48 16
    public function __construct(
49
        AccessControl $accessControl,
50
        Throttle $throttle,
51
        ResponseFactory $responseFactory,
52
        Router $router
53
    ) {
54 16
        $this->accessControl = $accessControl;
55 16
        $this->throttle = $throttle;
56 16
        $this->responseFactory = $responseFactory;
57 16
        $this->router = $router;
58 16
    }
59
60
    /**
61
     * @param APIRequest $request
62
     * @return APIResponse
63
     * @throws UnableToHandleRequestException
64
     * @throws InvalidAPIKeyException
65
     * @throws ThrottleLimitExceededException
66
     * @throws NotAcceptableResponseTypeException
67
     * @throws AccessDeniedException
68
     * @throws UnableToRouteRequestException
69
     * @throws UnableToCreateAPIResponseException
70
     */
71 16
    public function handleRequest(APIRequest $request): APIResponse
72
    {
73 16
        $this->validateKey($request);
74
75 14
        if ($this->throttle->shouldThrottle($request)) {
76 2
            throw new ThrottleLimitExceededException('Request limit exceeded');
77
        }
78
79 12
        $this->validateAcceptableMIMETypes($request);
80
81 8
        if (!$this->accessControl->validateAccess($request)) {
82 6
            throw new AccessDeniedException("API key does not have the required permissions to access requested resource");
83
        }
84
85 2
        $this->throttle->logRequest($request);
86
87 2
        $responseData = $this->router->route($request);
88
89 2
        return $this->responseFactory->getResponse($responseData, $request->getAcceptableMIMETypes());
90
    }
91
92
    /**
93
     * @param APIRequest $request
94
     * @throws InvalidAPIKeyException
95
     */
96 16
    protected function validateKey(APIRequest $request)
97
    {
98 16
        if (!$this->accessControl->validateKey($request->getApiKey())) {
99 2
            throw new InvalidAPIKeyException('Invalid API key');
100
        }
101 14
    }
102
103
    /**
104
     * @param APIRequest $request
105
     * @throws NotAcceptableResponseTypeException
106
     */
107 12
    protected function validateAcceptableMIMETypes(APIRequest $request)
108
    {
109 12
        $supportedFormats = $this->responseFactory->getSupportedMIMETypes();
110 12
        $requestedFormats = $request->getAcceptableMIMETypes();
111
112
        //Cases that our response factory is capable of responding to
113 12
        $requestedFormatSupported = empty($requestedFormats) ||
114 10
            in_array('*/*', $requestedFormats) ||
115 12
            !empty(array_intersect($requestedFormats, $supportedFormats));
116
117 12
        if (empty($supportedFormats) || !$requestedFormatSupported) {
118 4
            throw new NotAcceptableResponseTypeException('None of the requested acceptable response types are supported');
119
        }
120 8
    }
121
}
122