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 (35)

Security Analysis    no request data  

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.

src/statemachine/Transition.php (2 issues)

Labels
Severity

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
namespace izzum\statemachine;
3
use izzum\command\NullCommand;
4
use izzum\rules\TrueRule;
5
use izzum\statemachine\Exception;
6
use izzum\statemachine\utils\Utils;
7
use izzum\statemachine\Context;
8
use izzum\rules\Rule;
9
use izzum\rules\AndRule;
10
use izzum\rules\izzum\rules;
11
use izzum\rules\IRule;
12
13
/**
14
 * Transition class
15
 * An abstraction for everything that is needed to make an allowed and succesful
16
 * transition between states.
17
 *
18
 * It has functionality to accept a Rule (guard logic) and a Command (transition
19
 * logic) as well as callables for the guard logic and transition logic .
20
 * callables are: closures, anonymous functions, user defined functions,
21
 * instance methods, static methods etc. see the php manual.
22
 *
23
 * The guards are used to check whether a transition can take place (Rule and callable)
24
 * The logic parts are used to execute the transition logic (Command and callable)
25
 *
26
 * Rules and commands should be able to be found/autoloaded by the application
27
 *
28
 * If transitions share the same states (both to and from) then they should
29
 * point to the same object reference (same states should share the exact same state
30
 * configuration).
31
 *
32
 * @link https://php.net/manual/en/language.types.callable.php
33
 * @link https://en.wikipedia.org/wiki/Command_pattern
34
 * @author Rolf Vreijdenberger
35
 *
36
 */
37
class Transition {
38
    const RULE_TRUE = '\izzum\rules\TrueRule';
39
    const RULE_FALSE = '\izzum\rules\FalseRule';
40
    const RULE_EMPTY = '';
41
    const COMMAND_NULL = '\izzum\command\NullCommand';
42
    const COMMAND_EMPTY = '';
43
    const CALLABLE_NULL = null;
44
    const CALLABLE_GUARD = 'transition guard';
45
    const CALLABLE_TRANSITION = 'transition logic';
46
47
    /**
48
     * the state this transition starts from
49
     *
50
     * @var State
51
     */
52
    protected $state_from;
53
54
    /**
55
     * the state this transition points to
56
     *
57
     * @var State
58
     */
59
    protected $state_to;
60
61
    /**
62
     * an event code that can trigger this transitions
63
     *
64
     * @var string
65
     */
66
    protected $event;
67
68
    /**
69
     * The fully qualified Rule class name of the
70
     * Rule to be applied to check if we can transition.
71
     * This can actually be a ',' seperated string of multiple rules.
72
     *
73
     * @var string
74
     */
75
    protected $rule;
76
77
    /**
78
     * the fully qualified Command class name of the Command to be
79
     * executed as part of the transition logic.
80
     * This can actually be a ',' seperated string of multiple commands.
81
     *
82
     * @var string
83
     */
84
    protected $command;
85
86
    /**
87
     * the callable to call as part of the transition logic
88
     * @var callable
89
     */
90
    protected $callable_transition;
91
92
    /**
93
     * the callable to call as part of the transition guard (should return a boolean)
94
     * @var callable
95
     */
96
    protected $callable_guard;
97
98
    /**
99
     * a description for the state
100
     *
101
     * @var string
102
     */
103
    protected $description;
104
105
    /**
106
     *
107
     * @param State $state_from
108
     * @param State $state_to
109
     * @param string $event
110
     *            optional: an event name by which this transition can be
111
     *            triggered
112
     * @param string $rule
113
     *            optional: one or more fully qualified Rule (sub)class name(s)
114
     *            to check to see if we are allowed to transition.
115
     *            This can actually be a ',' seperated string of multiple rules
116
     *            that will be applied as a chained 'and' rule.
117
     * @param string $command
118
     *            optional: one or more fully qualified Command (sub)class
119
     *            name(s) to execute for a transition.
120
     *            This can actually be a ',' seperated string of multiple
121
     *            commands that will be executed as a composite.
122
     * @param callable $callable_guard
123
     *            optional: a php callable to call. eg: "function(){echo 'closure called';};"
124
     * @param callable $callable_transition
125
     *            optional: a php callable to call. eg: "izzum\MyClass::myStaticMethod"
126
     */
127 67
    public function __construct(State $state_from, State $state_to, $event = null, $rule = self::RULE_EMPTY, $command = self::COMMAND_EMPTY, $callable_guard = self::CALLABLE_NULL, $callable_transition = self::CALLABLE_NULL)
128
    {
129 67
        $this->state_from = $state_from;
130 67
        $this->state_to = $state_to;
131 67
        $this->setRuleName($rule);
132 67
        $this->setCommandName($command);
133 67
        $this->setGuardCallable($callable_guard);
0 ignored issues
show
It seems like $callable_guard defined by parameter $callable_guard on line 127 can also be of type null; however, izzum\statemachine\Transition::setGuardCallable() does only seem to accept callable, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
134 67
        $this->setTransitionCallable($callable_transition);
0 ignored issues
show
It seems like $callable_transition defined by parameter $callable_transition on line 127 can also be of type null; however, izzum\statemachine\Trans...setTransitionCallable() does only seem to accept callable, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
135
        // setup bidirectional relationship with state this transition
136
        // originates from. only if it's not a regex or final state type
137 67
        if (!$state_from->isRegex() && !$state_from->isFinal()) {
138 67
            $state_from->addTransition($this);
139 67
        }
140
        // set and sanitize event name
141 67
        $this->setEvent($event);
142 67
    }
143
144
    /**
145
     * the callable to call as part of the transition logic
146
     * @param callable $callable
147
     */
148 67
    public function setTransitionCallable($callable) {
149 67
        $this->callable_transition = $callable;
150 67
        return $this;
151
    }
152
153
    /**
154
     * returns the callable for the transition logic.
155
     * @return callable or null
156
     */
157 38
    public function getTransitionCallable()
158
    {
159 38
        return $this->callable_transition;
160
    }
161
162
    /**
163
     * the callable to call as part of the transition guard
164
     * @param callable $callable
165
     */
166 67
    public function setGuardCallable($callable) {
167 67
        $this->callable_guard = $callable;
168 67
        return $this;
169
    }
170
171
    /**
172
     * returns the callable for the guard logic.
173
     * @return callable or null
174
     */
175 36
    public function getGuardCallable()
176
    {
177 36
        return $this->callable_guard;
178
    }
179
180
    /**
181
     * Can this transition be triggered by a certain event?
182
     * This also matches on the transition name.
183
     *
184
     * @param string $event
185
     * @return boolean
186
     */
187 12
    public function isTriggeredBy($event)
188
    {
189 12
        return ($this->event === $event || $this->getName() === $event) && $event !== null && $event !== '';
190
    }
191
192
    /**
193
     * is a transition possible? Check the guard Rule with the domain object
194
     * injected.
195
     *
196
     * @param Context $context
197
     * @return boolean
198
     */
199 23
    public function can(Context $context)
200
    {
201
        try {
202 23
            if(!$this->getRule($context)->applies()) {
203 5
                return false;
204
            }
205 20
            return $this->callCallable($this->getGuardCallable(), $context, self::CALLABLE_GUARD);
206 4
        } catch(\Exception $e) {
207
            //rule or callable failure
208 4
            $e = new Exception($this->toString() . ' '. $e->getMessage(), Exception::RULE_APPLY_FAILURE, $e);
209 4
            throw $e;
210
        }
211
    }
212
213
    /**
214
     * Process the transition for the statemachine and execute the associated
215
     * Command with the domain object injected.
216
     *
217
     * @param Context $context
218
     * @return void
219
     */
220 23
    public function process(Context $context)
221
    {
222
        // execute, we do not need to check if we 'can' since this is done
223
        // by the statemachine itself
224
        try {
225 23
            $this->getCommand($context)->execute();
226 22
            $this->callCallable($this->getTransitionCallable(), $context, self::CALLABLE_TRANSITION);
227 23
        } catch(\Exception $e) {
228
            // command or callable failure
229 2
            $e = new Exception($e->getMessage(), Exception::COMMAND_EXECUTION_FAILURE, $e);
230 2
            throw $e;
231
        }
232 21
    }
233
234
    /**
235
     * calls the $callable as part of the transition
236
     * @param callable $callable
237
     * @param Context $context
238
     * @throws Exception in case of an invalid callable
239
     */
240 24
    protected function callCallable($callable, Context $context, $type = 'n/a') {
241
        //in case it is a guard callable we need to return true/false
242 24
        if($callable != self::CALLABLE_NULL){
243 9
            Utils::checkCallable($callable, $type, "transition: " . $this, $context);
244 8
            return (boolean) call_user_func($callable, $context->getEntity());
245
        }
246 21
        return true;
247
    }
248
249
    /**
250
     * returns the associated Rule for this Transition,
251
     * configured with a 'reference' (stateful) object
252
     *
253
     * @param Context $context
254
     *            the associated Context for a our statemachine
255
     * @return IRule a Rule or chained AndRule if the rule input was a ','
256
     *         seperated string of rules.
257
     * @throws Exception
258
     */
259 30
    public function getRule(Context $context)
260
    {
261
        // if no rule is defined, just allow the transition by default
262 30
        if ($this->rule === '' || $this->rule === null) {
263 13
            return new TrueRule();
264
        }
265
266 22
        $entity = $context->getEntity();
267
268
        // a rule string can be made up of multiple rules seperated by a comma
269 22
        $all_rules = explode(',', $this->rule);
270 22
        $rule = new TrueRule();
271 22
        foreach ($all_rules as $single_rule) {
272
273
            // guard clause to check if rule exists
274 22
            if (!class_exists($single_rule)) {
275 1
                $e = new Exception(sprintf("failed rule creation, class does not exist: (%s) for Context (%s).", $this->rule, $context->toString()), Exception::RULE_CREATION_FAILURE);
276 1
                throw $e;
277
            }
278
279
            try {
280 21
                $and_rule = new $single_rule($entity);
281
                // create a chain of rules that need to be true
282 20
                $rule = new AndRule($rule, $and_rule);
283 21
            } catch(\Exception $e) {
284 1
                $e = new Exception(sprintf("failed rule creation, class objects to construction with entity: (%s) for Context (%s). message: %s", $this->rule, $context->toString(), $e->getMessage()), Exception::RULE_CREATION_FAILURE);
285 1
                throw $e;
286
            }
287 20
        }
288 20
        return $rule;
289
    }
290
291
292
    /**
293
     * returns the associated Command for this Transition.
294
     * the Command will be configured with the 'reference' of the stateful
295
     * object.
296
     * In case there have been multiple commands as input (',' seperated), this
297
     * method will return a Composite command.
298
     *
299
     * @param Context $context
300
     * @return izzum\command\ICommand
301
     * @throws Exception
302
     */
303 30
    public function getCommand(Context $context)
304
    {
305 30
        return Utils::getCommand($this->command, $context);
306
    }
307
308
    /**
309
     *
310
     * @return string
311
     */
312 8
    public function toString()
313
    {
314 8
        return get_class($this) . " '" . $this->getName() . "' [event]: '" . $this->event . "'" . " [rule]: '" . $this->rule . "' [command]: '" . $this->command . "'";
315
    }
316
317
    /**
318
     * get the state this transition points from
319
     *
320
     * @return State
321
     */
322 67
    public function getStateFrom()
323
    {
324 67
        return $this->state_from;
325
    }
326
327
    /**
328
     * get the state this transition points to
329
     *
330
     * @return State
331
     */
332 67
    public function getStateTo()
333
    {
334 67
        return $this->state_to;
335
    }
336
337
    /**
338
     * get the transition name.
339
     * the transition name is always unique for a statemachine
340
     * since it constists of <state_from>_to_<state_to>
341
     *
342
     * @return string
343
     */
344 67
    public function getName()
345
    {
346 67
        $name = Utils::getTransitionName($this->getStateFrom()->getName(), $this->getStateTo()->getName());
347 67
        return $name;
348
    }
349
350
    /**
351
     * return the command name(s).
352
     * one or more fully qualified command (sub)class name(s) to execute for a
353
     * transition.
354
     * This can actually be a ',' seperated string of multiple commands that
355
     * will be executed as a composite.
356
     *
357
     * @return string
358
     */
359 21
    public function getCommandName()
360
    {
361 21
        return $this->command;
362
    }
363
364 67
    public function setCommandName($command)
365
    {
366 67
        $this->command = trim($command);
367 67
        return $this;
368
    }
369
370 21
    public function getRuleName()
371
    {
372 21
        return $this->rule;
373
    }
374
375 67
    public function setRuleName($rule)
376
    {
377 67
        $this->rule = trim($rule);
378 67
        return $this;
379
    }
380
381
    /**
382
     * set the description of the transition (for uml generation for example)
383
     *
384
     * @param string $description
385
     */
386 23
    public function setDescription($description)
387
    {
388 23
        $this->description = $description;
389 23
        return $this;
390
    }
391
392
    /**
393
     * get the description for this transition (if any)
394
     *
395
     * @return string
396
     */
397 22
    public function getDescription()
398
    {
399 22
        return $this->description;
400
    }
401
402
    /**
403
     * set the event name by which this transition can be triggered.
404
     * In case the event name is null or an empty string, it defaults to the
405
     * transition name.
406
     *
407
     * @param string $event
408
     */
409 67
    public function setEvent($event)
410
    {
411 67
        if ($event === null || $event === '') {
412 46
            $event = $this->getName();
413 46
        }
414 67
        $this->event = $event;
415 67
        return $this;
416
    }
417
418
    /**
419
     * get the event name by which this transition can be triggered
420
     *
421
     * @return string
422
     */
423 22
    public function getEvent()
424
    {
425 22
        return $this->event;
426
    }
427
428
    /**
429
     * for transitions that contain regex states, we need to be able to copy an
430
     * existing (subclass of this) transition with all it's fields.
431
     * We need to instantiate it with a different from and to state since either
432
     * one of those states can be the regex states. All other fields need to be
433
     * copied.
434
     *
435
     * Override this method in a subclass to add other fields. By using 'new
436
     * static' we are already instantiating a possible subclass.
437
     *
438
     *
439
     * @param State $from
440
     * @param State $to
441
     * @return Transition
442
     */
443 19
    public function getCopy(State $from, State $to)
444
    {
445 19
        $copy = new static($from, $to, $this->getEvent(), $this->getRuleName(), $this->getCommandName(), $this->getGuardCallable(), $this->getTransitionCallable());
446 19
        $copy->setDescription($this->getDescription());
447 19
        return $copy;
448
    }
449
450
    /**
451
     *
452
     * @return string
453
     */
454 11
    public function __toString()
455
    {
456 11
        return $this->getName();
457
    }
458
}