Completed
Push — master ( a303a7...df04fd )
by
unknown
03:08
created

SignatureParameterHandler::getRouteParameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 1
1
<?php
2
3
namespace MediaMonks\SonataMediaBundle\Handler;
4
5
use MediaMonks\SonataMediaBundle\Exception\SignatureInvalidException;
6
use MediaMonks\SonataMediaBundle\Model\MediaInterface;
7
use Symfony\Component\HttpFoundation\Request;
8
9
class SignatureParameterHandler implements ParameterHandlerInterface
10
{
11
    const PARAMETER_SIGNATURE = 's';
12
    const PARAMETER_BUST_CACHE = 'bc';
13
14
    /**
15
     * @var string
16
     */
17
    private $key;
18
19
    /**
20
     * @var string
21
     */
22
    private $hashAlgorithm;
23
24
    /**
25
     * @param $key
26
     * @param string $hashAlgorithm
27
     */
28 4
    public function __construct($key, $hashAlgorithm = 'sha256')
29
    {
30 4
        $this->key = $key;
31 4
        $this->hashAlgorithm = $hashAlgorithm;
32 4
    }
33
34
    /**
35
     * @param ParameterBag $parameterBag
36
     * @return array
37
     */
38
    public function getRouteParameters(ParameterBag $parameterBag)
39 2
    {
40
        $parameters = $parameterBag->toArray();
41 2
        $parameters[self::PARAMETER_SIGNATURE] = $this->calculateSignature($parameters);
42 2
43 2
        return $parameters;
44
    }
45 2
46
    /**
47
     * @param $id
48
     * @param $width
49
     * @param $height
50
     * @param array $extra
51
     * @return ParameterBag
52
     * @throws SignatureInvalidException
53
     */
54 3
    public function getPayload($id, $width, $height, array $extra)
55
    {
56 3
        if (!isset($extra[self::PARAMETER_SIGNATURE])) {
57 3
            throw new SignatureInvalidException();
58 1
        }
59
60
        $signature = $extra[self::PARAMETER_SIGNATURE];
61 2
        unset($extra[self::PARAMETER_SIGNATURE]);
62
63 2
        $parameters = new ParameterBag($id, $width, $height, $extra);
64
        if (!$this->isValid($parameters, $signature)) {
65
            throw new SignatureInvalidException();
66
        }
67
68
        return $parameters;
69
    }
70
71 3
    /**
72
     * @param ParameterBag $parameters
73 3
     * @param $expectedSignature
74
     * @return bool
75
     */
76
    private function isValid(ParameterBag $parameters, $expectedSignature)
77
    {
78
        return hash_equals($this->calculateSignature($parameters->toArray()), $expectedSignature);
79
    }
80 4
81
    /**
82 4
     * @param array $parameters
83
     * @return string
84
     */
85
    private function calculateSignature(array $parameters)
86
    {
87
        return hash_hmac($this->hashAlgorithm, $this->key, json_encode($this->normalize($parameters)));
88
    }
89 4
90
    /**
91 4
     * @param array $parameters
92 3
     * @return array
93 3
     */
94 4
    private function normalize(array $parameters)
95
    {
96
        if (isset($parameters[self::PARAMETER_BUST_CACHE])) {
97 4
            unset($parameters[self::PARAMETER_BUST_CACHE]);
98
        }
99 4
        ksort($parameters);
100
101
        return array_map('strval', $parameters);
102
    }
103
}
104