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

SignatureParameterHandler   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 95
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 92.86%

Importance

Changes 0
Metric Value
wmc 9
lcom 1
cbo 2
dl 0
loc 95
ccs 26
cts 28
cp 0.9286
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 getPayload() 0 16 3
A isValid() 0 4 1
A calculateSignature() 0 4 1
A normalize() 0 9 2
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