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