AcceptParsedBodyToken::__invoke()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 3
nop 3
1
<?php
2
3
namespace Schnittstabil\Psr7\Csrf\Middlewares;
4
5
use Psr\Http\Message\ServerRequestInterface;
6
use Psr\Http\Message\ResponseInterface;
7
use function Schnittstabil\Get\getValue;
8
use Schnittstabil\Psr7\Csrf\RequestAttributesTrait;
9
10
/**
11
 * Middleware for accepting CSRF tokens sent by request bodies, e.g. POST.
12
 */
13
class AcceptParsedBodyToken
14
{
15
    use RequestAttributesTrait;
16
17
    /**
18
     * Used to validate tokens.
19
     *
20
     * @var callable
21
     */
22
    protected $tokenValidator;
23
24
    /**
25
     * Used to _get_ the token.
26
     *
27
     * @var string|int|mixed[] a `Schnittstabil\Get\getValue` path
28
     */
29
    protected $path;
30
31
    /**
32
     * Create new AcceptParsedBodyToken middleware.
33
     *
34
     * @see https://github.com/schnittstabil/get Documentation of `Schnittstabil\Get\getValue`
35
     *
36
     * @param callable           $tokenValidator Used to validate tokens
37
     * @param string|int|mixed[] $path           a `Schnittstabil\Get\getValue` path
38
     */
39
    public function __construct(callable $tokenValidator, $path = 'X-XSRF-TOKEN')
40
    {
41
        $this->tokenValidator = $tokenValidator;
42
        $this->path = $path;
43
    }
44
45
    /**
46
     * Invoke middleware.
47
     *
48
     * @param ServerRequestInterface $request  request object
49
     * @param ResponseInterface      $response response object
50
     * @param callable               $next     next middleware
51
     *
52
     * @return ResponseInterface response object
53
     */
54
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
55
    {
56
        $token = getValue($this->path, $request->getParsedBody(), null);
57
58
        if ($token === null) {
59
            return $next($request, $response);
60
        }
61
62
        $tokenViolations = call_user_func($this->tokenValidator, $token);
63
64
        if (count($tokenViolations) === 0) {
65
            return $next($request->withAttribute(self::$isValidAttribute, true), $response);
66
        }
67
68
        $violations = $request->getAttribute(self::$violationsAttribute, []);
69
        $violations = array_merge($violations, $tokenViolations);
70
71
        return $next($request->withAttribute(self::$violationsAttribute, $violations), $response);
72
    }
73
}
74