GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (34)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

SnappyRouter/Handler/ControllerHandler.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Vectorface\SnappyRouter\Handler;
4
5
use \Exception;
6
use FastRoute\Dispatcher;
7
use Vectorface\SnappyRouter\Controller\AbstractController;
8
use Vectorface\SnappyRouter\Encoder\EncoderInterface;
9
use Vectorface\SnappyRouter\Encoder\NullEncoder;
10
use Vectorface\SnappyRouter\Encoder\TwigViewEncoder;
11
use Vectorface\SnappyRouter\Exception\ResourceNotFoundException;
12
use Vectorface\SnappyRouter\Request\HttpRequest;
13
use Vectorface\SnappyRouter\Response\AbstractResponse;
14
use Vectorface\SnappyRouter\Response\Response;
15
16
/**
17
 * Handles MVC requests mapping URIs like /controller/action/param1/param2/...
18
 * to its corresponding controller action.
19
 * @copyright Copyright (c) 2014, VectorFace, Inc.
20
 * @author Dan Bruce <[email protected]>
21
 */
22
class ControllerHandler extends PatternMatchHandler
23
{
24
    /** Options key for the base path */
25
    const KEY_BASE_PATH = 'basePath';
26
    /** Options key for the view config */
27
    const KEY_VIEWS = 'views';
28
    /** Options key for the view path config */
29
    const KEY_VIEWS_PATH = 'path';
30
31
    /** The current web request */
32
    protected $request;
33
    /** The current encoder */
34
    protected $encoder;
35
    /** The current route parameters */
36
    protected $routeParams;
37
38
    /** Constants indicating the type of route */
39
    const MATCHES_NOTHING = 0;
40
    const MATCHES_CONTROLLER = 1;
41
    const MATCHES_ACTION = 2;
42
    const MATCHES_CONTROLLER_AND_ACTION = 3;
43
    const MATCHES_PARAMS = 4;
44
    const MATCHES_CONTROLLER_ACTION_AND_PARAMS = 7;
45
46
    /** controller route pattern */
47
    const ROUTE_PATTERN_CONTROLLER = '{controller:[a-zA-Z]\w*}';
48
49
    /** action route pattern */
50
    const ROUTE_PATTERN_ACTION = '{action:[a-zA-Z]\w*}';
51
52
    /** URL parameters route pattern */
53
    const ROUTE_PATTERN_PARAMS = '{params:.+}';
54
55
    /**
56
     * Returns true if the handler determines it should handle this request and false otherwise.
57
     * @param string $path The URL path for the request.
58
     * @param array $query The query parameters.
59
     * @param array $post The post data.
60
     * @param string $verb The HTTP verb used in the request.
61
     * @return boolean Returns true if this handler will handle the request and false otherwise.
62
     */
63 29
    public function isAppropriate($path, $query, $post, $verb)
64
    {
65
        // remove the leading base path option if present
66 29
        $options = $this->getOptions();
67 29
        $path = $this->extractPathFromBasePath($path, $options);
68
69
        // extract the controller, action and route parameters if present
70
        // and fall back to defaults when not present
71 29
        $controller = 'index';
72 29
        $action = 'index';
73 29
        $this->routeParams = array();
74 29
        $routeInfo = $this->getRouteInfo($verb, $path);
75
        // ensure the path matches at least one of the routes
76 29
        if (Dispatcher::FOUND !== $routeInfo[0]) {
77 2
            return false;
78
        }
79
80 27
        if ($routeInfo[1] & self::MATCHES_CONTROLLER) {
81 27
            $controller = strtolower($routeInfo[2]['controller']);
82 27
            if ($routeInfo[1] & self::MATCHES_ACTION) {
83 14
                $action = strtolower($routeInfo[2]['action']);
84 14
                if ($routeInfo[1] & self::MATCHES_PARAMS) {
85 1
                    $this->routeParams = explode('/', $routeInfo[2]['params']);
86
                }
87
            }
88
        }
89
90
        // configure the default view encoder
91 27
        $this->configureViewEncoder($options, $controller, $action);
92
93
        // configure the request object
94 26
        $this->request = new HttpRequest(
95 26
            ucfirst($controller).'Controller',
96 26
            $action.'Action',
97 26
            $verb,
98 26
            'php://input'
99
        );
100
101 26
        $this->request->setQuery($query);
102 26
        $this->request->setPost($post);
103
104
        // return that we will handle this request
105 26
        return true;
106
    }
107
108
    /**
109
     * Performs the actual routing.
110
     * @return string Returns the result of the route.
111
     */
112 12
    public function performRoute()
113
    {
114 12
        $controller = null;
115 12
        $action = null;
116 12
        $this->determineControllerAndAction($controller, $action);
117 10
        $response = $this->invokeControllerAction($controller, $action);
118 8
        \Vectorface\SnappyRouter\http_response_code($response->getStatusCode());
119 8
        return $this->getEncoder()->encode($response);
120
    }
121
122
    /**
123
     * Returns a request object extracted from the request details (path, query, etc). The method
124
     * isAppropriate() must have returned true, otherwise this method should return null.
125
     * @return \Vectorface\SnappyRouter\Request\HttpRequest|null Returns a
126
     *         Request object or null if this handler is not appropriate.
127
     */
128 18
    public function getRequest()
129
    {
130 18
        return $this->request;
131
    }
132
133
    /**
134
     * Returns the active response encoder.
135
     * @return EncoderInterface Returns the response encoder.
136
     */
137 11
    public function getEncoder()
138
    {
139 11
        return $this->encoder;
140
    }
141
142
    /**
143
     * Sets the encoder to be used by this handler (overriding the default).
144
     * @param EncoderInterface $encoder The encoder to be used.
145
     * @return ControllerHandler Returns $this.
146
     */
147 2
    public function setEncoder(EncoderInterface $encoder)
148
    {
149 2
        $this->encoder = $encoder;
150 2
        return $this;
151
    }
152
153
    /**
154
     * Returns the new path with the base path extracted.
155
     * @param string $path The full path.
156
     * @param array $options The array of options.
157
     * @return string Returns the new path with the base path removed.
158
     */
159 29
    protected function extractPathFromBasePath($path, $options)
160
    {
161 29
        if (isset($options[self::KEY_BASE_PATH])) {
162 14
            $pos = strpos($path, $options[self::KEY_BASE_PATH]);
163 14 View Code Duplication
            if (false !== $pos) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
164 14
                $path = substr($path, $pos + strlen($options[self::KEY_BASE_PATH]));
165
            }
166
        }
167
        // ensure the path has a leading slash
168 29
        if (empty($path) || $path[0] !== '/') {
169 14
            $path = '/'.$path;
170
        }
171 29
        return $path;
172
    }
173
174
    /**
175
     * Determines the exact controller instance and action name to be invoked
176
     * by the request.
177
     * @param mixed $controller The controller passed by reference.
178
     * @param mixed $actionName The action name passed by reference.
179
     */
180 12
    private function determineControllerAndAction(&$controller, &$actionName)
181
    {
182 12
        $request = $this->getRequest();
183 12
        $this->invokePluginsHook(
184 12
            'beforeControllerSelected',
185 12
            array($this, $request)
186
        );
187
188 12
        $controllerDiKey = $request->getController();
189
        try {
190 12
            $controller = $this->getServiceProvider()->getServiceInstance($controllerDiKey);
191 1
        } catch (Exception $e) {
192 1
            throw new ResourceNotFoundException(sprintf(
193 1
                'No such controller found "%s".',
194 1
                $this->getRequest()->getController()
195
            ));
196
        }
197 11
        $actionName = $request->getAction();
198 11
        if (!method_exists($controller, $actionName)) {
199 1
            throw new ResourceNotFoundException(sprintf(
200 1
                '%s does not have method %s',
201 1
                $controllerDiKey,
202 1
                $actionName
203
            ));
204
        }
205 10
        $this->invokePluginsHook(
206 10
            'afterControllerSelected',
207 10
            array($this, $request, $controller, $actionName)
208
        );
209 10
        $controller->initialize($request, $this);
210 10
    }
211
212
    /**
213
     * Invokes the actual controller action and returns the response.
214
     * @param AbstractController $controller The controller to use.
215
     * @param string $action The action to invoke.
216
     * @return AbstractResponse Returns the response from the action.
217
     */
218 10
    protected function invokeControllerAction(AbstractController $controller, $action)
219
    {
220 10
        $this->invokePluginsHook(
221 10
            'beforeActionInvoked',
222 10
            array($this, $this->getRequest(), $controller, $action)
223
        );
224 10
        $response = $controller->$action($this->routeParams);
225 8
        if (null === $response) {
226
            // if the action returns null, we simply render the default view
227 2
            $response = array();
228 6
        } elseif (!is_string($response)) {
229
            // if they don't return a string, try to use whatever is returned
230
            // as variables to the view renderer
231 1
            $response = (array)$response;
232
        }
233
234
        // merge the response variables with the existing view context
235 8
        if (is_array($response)) {
236 3
            $response = array_merge($controller->getViewContext(), $response);
237
        }
238
239
        // whatever we have as a response needs to be encapsulated in an
240
        // AbstractResponse object
241 8
        if (!($response instanceof AbstractResponse)) {
242 8
            $response = new Response($response);
243
        }
244 8
        $this->invokePluginsHook(
245 8
            'afterActionInvoked',
246 8
            array($this, $this->getRequest(), $controller, $action, $response)
247
        );
248 8
        return $response;
249
    }
250
251
    /**
252
     * Configures the view encoder based on the current options.
253
     * @param array $options The current options.
254
     * @param string $controller The controller to use for the default view.
255
     * @param string $action The action to use for the default view.
256
     */
257 27
    private function configureViewEncoder($options, $controller, $action)
258
    {
259
        // configure the view encoder if they specify a view option
260 27
        if (isset($options[self::KEY_VIEWS])) {
261 8
            $this->encoder = new TwigViewEncoder(
262 8
                $options[self::KEY_VIEWS],
263 8
                sprintf('%s/%s.twig', $controller, $action)
264
            );
265
        } else {
266 19
            $this->encoder = new NullEncoder();
267
        }
268 26
    }
269
270
    /**
271
     * Returns the array of routes.
272
     * @return array The array of routes.
273
     */
274 19
    protected function getRoutes()
275
    {
276 19
        $c = self::ROUTE_PATTERN_CONTROLLER;
277 19
        $a = self::ROUTE_PATTERN_ACTION;
278 19
        $p = self::ROUTE_PATTERN_PARAMS;
279
        return array(
280 19
            "/" => self::MATCHES_NOTHING,
281 19
            "/$c" => self::MATCHES_CONTROLLER,
282 19
            "/$c/" => self::MATCHES_CONTROLLER,
283 19
            "/$c/$a" => self::MATCHES_CONTROLLER_AND_ACTION,
284 19
            "/$c/$a/" => self::MATCHES_CONTROLLER_AND_ACTION,
285 19
            "/$c/$a/$p" => self::MATCHES_CONTROLLER_ACTION_AND_PARAMS
286
        );
287
    }
288
}
289