Completed
Push — master ( 162ac8...74252e )
by
unknown
19:44
created

SignatureParameterHandler   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 97
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 92.59%

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 2
dl 0
loc 97
ccs 25
cts 27
cp 0.9259
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getRouteParameters() 0 7 1
A isValid() 0 4 1
A calculateSignature() 0 4 1
A normalize() 0 9 2
A getPayload() 0 16 3
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 5
    public function __construct($key, $hashAlgorithm = 'sha256')
28
    {
29 5
        $this->key = $key;
30 5
        $this->hashAlgorithm = $hashAlgorithm;
31 5
    }
32
33
    /**
34
     * @param MediaInterface $media
35
     * @param ParameterBag $parameterBag
36
     * @return array
37
     */
38 1
    public function getRouteParameters(MediaInterface $media, ParameterBag $parameterBag)
39
    {
40 1
        $parameters = $parameterBag->toArray($media);
41 1
        $parameters[self::PARAMETER_SIGNATURE] = $this->calculateSignature($parameters);
42
43 1
        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 4
    private function calculateSignature(array $parameters)
87
    {
88 4
        return hash_hmac($this->hashAlgorithm, $this->key, json_encode($this->normalize($parameters)));
89
    }
90
91
    /**
92
     * @param array $parameters
93
     * @return array
94
     */
95 4
    private function normalize(array $parameters)
96
    {
97 4
        if (isset($parameters[self::PARAMETER_BUST_CACHE])) {
98
            unset($parameters[self::PARAMETER_BUST_CACHE]);
99
        }
100 4
        ksort($parameters);
101
102 4
        return array_map('strval', $parameters);
103
    }
104
}
105