Completed
Push — master ( e74e8a...e08e8c )
by John
01:52
created

Server::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

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