Completed
Push — master ( 08683c...165a9d )
by John
01:44
created

Router::validateAccess()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 2
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 1
1
<?php
2
namespace LunixREST\Router;
3
4
use LunixREST\AccessControl\AccessControl;
5
use LunixREST\Endpoint\Endpoint;
6
use LunixREST\Endpoint\EndpointFactory;
7
use LunixREST\Endpoint\Exceptions\UnknownEndpointException;
8
use LunixREST\Exceptions\AccessDeniedException;
9
use LunixREST\Exceptions\InvalidAPIKeyException;
10
use LunixREST\Exceptions\ThrottleLimitExceededException;
11
use LunixREST\Request\Request;
12
use LunixREST\Response\Exceptions\UnknownResponseTypeException;
13
use LunixREST\Response\Response;
14
use LunixREST\Response\ResponseData;
15
use LunixREST\Response\ResponseFactory;
16
use LunixREST\Throttle\Throttle;
17
18
/**
19
 * Class Router
20
 * @package LunixREST\Router
21
 */
22
class Router {
23
    /**
24
     * @var AccessControl
25
     */
26
    protected $accessControl;
27
    /**
28
     * @var Throttle
29
     */
30
    protected $throttle;
31
    /**
32
     * @var ResponseFactory
33
     */
34
    protected $responseFactory;
35
    /**
36
     * @var EndpointFactory
37
     */
38
    private $endpointFactory;
39
40
    /**
41
     * @param AccessControl $accessControl
42
     * @param Throttle $throttle
43
     * @param ResponseFactory $responseFactory
44
     * @param EndpointFactory $endpointFactory
45
     */
46
    public function __construct(AccessControl $accessControl, Throttle $throttle, ResponseFactory $responseFactory, EndpointFactory $endpointFactory){
47
        $this->accessControl = $accessControl;
48
        $this->throttle = $throttle;
49
        $this->responseFactory = $responseFactory;
50
        $this->endpointFactory = $endpointFactory;
51
    }
52
53
    /**
54
     * @param Request $request
55
     * @return Response
56
     * @throws AccessDeniedException
57
     * @throws InvalidAPIKeyException
58
     * @throws ThrottleLimitExceededException
59
     * @throws UnknownEndpointException
60
     * @throws UnknownResponseTypeException
61
     */
62
    public function route(Request $request): Response{
63
        $this->validateKey($request);
64
65
        $this->validateExtension($request);
66
67
        $endpoint = $this->endpointFactory->getEndpoint($request->getEndpoint(), $request->getVersion());
68
69
        if($this->throttle->shouldThrottle($request)) {
70
            throw new ThrottleLimitExceededException('Request limit exceeded');
71
        }
72
73
        if(!$this->accessControl->validateAccess($request)) {
74
            throw new AccessDeniedException("API key does not have the required permissions to access requested resource");
75
        }
76
77
        $this->throttle->logRequest($request);
78
79
        $responseData = $this->executeEndpoint($endpoint, $request);
80
81
        return $this->responseFactory->getResponse($responseData, $request->getExtension());
82
    }
83
84
    /**
85
     * @param Request $request
86
     * @throws InvalidAPIKeyException
87
     */
88
    protected function validateKey(Request $request){
89
        if(!$this->accessControl->validateKey($request->getApiKey())){
90
            throw new InvalidAPIKeyException('Invalid API key');
91
        }
92
    }
93
94
    /**
95
     * @param Request $request
96
     * @throws UnknownResponseTypeException
97
     */
98
    protected function validateExtension(Request $request) {
99
        $formats = $this->responseFactory->getSupportedTypes();
100
        if(!$formats || !in_array($request->getExtension(), $formats)){
0 ignored issues
show
Bug Best Practice introduced by
The expression $formats of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
101
            throw new UnknownResponseTypeException('Unknown response format: ' . $request->getExtension());
102
        }
103
    }
104
105
    protected function executeEndpoint(Endpoint $endpoint, Request $request): ResponseData {
106
        return call_user_func([$endpoint, $request->getMethod()], [$request]);
107
    }
108
}
109