Completed
Push — master ( 8db26a...d97d4a )
by John
01:50
created

Server::validateAcceptableMIMETypes()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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