Completed
Push — master ( 11d5f2...dfaaf8 )
by
unknown
04:43
created

SignatureParameterHandler   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 8
lcom 1
cbo 4
dl 0
loc 90
c 0
b 0
f 0
ccs 25
cts 25
cp 1
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getQueryString() 0 8 1
A getPayload() 0 11 2
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\InvalidQueryParameterException;
6
use MediaMonks\SonataMediaBundle\Model\MediaInterface;
7
use Symfony\Component\HttpFoundation\Request;
8
9
class SignatureParameterHandler implements ParameterHandlerInterface
10
{
11
    const PARAMETER_ID = 'id';
12
    const PARAMETER_SIGNATURE = 's';
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 3
    public function __construct($key, $hashAlgorithm = 'sha256')
29
    {
30 3
        $this->key = $key;
31 3
        $this->hashAlgorithm = $hashAlgorithm;
32 3
    }
33
34
    /**
35
     * @param MediaInterface $media
36
     * @param array $parameters
37
     * @return string
38
     */
39 1
    public function getQueryString(MediaInterface $media, array $parameters)
40
    {
41 1
        $parameters[self::PARAMETER_SIGNATURE] = $this->calculateSignature(
42 1
            array_merge($parameters, [self::PARAMETER_ID => $media->getId()])
43 1
        );
44
45 1
        return http_build_query($parameters);
46
    }
47
48
    /**
49
     * @param MediaInterface $media
50
     * @param Request $request
51
     * @return array
52
     * @throws \Exception
53
     */
54 2
    public function getPayload(MediaInterface $media, Request $request)
55
    {
56 2
        $parameters = $request->query->all();
57 2
        if (!$this->isValid(array_merge($parameters, [self::PARAMETER_ID => $media->getId()]))) {
58 1
            throw new InvalidQueryParameterException('Signature Invalid');
59
        }
60
61 1
        unset($parameters[self::PARAMETER_SIGNATURE]);
62
63 1
        return $parameters;
64
    }
65
66
67
    /**
68
     * @param array $parameters
69
     * @return bool
70
     */
71 2
    private function isValid(array $parameters)
72
    {
73 2
        return hash_equals($this->calculateSignature($parameters), $parameters[self::PARAMETER_SIGNATURE]);
74
    }
75
76
    /**
77
     * @param array $parameters
78
     * @return string
79
     */
80 3
    private function calculateSignature(array $parameters)
81
    {
82 3
        return hash_hmac($this->hashAlgorithm, $this->key, json_encode($this->normalize($parameters)));
83
    }
84
85
    /**
86
     * @param array $parameters
87
     * @return array
88
     */
89 3
    private function normalize(array $parameters)
90
    {
91 3
        if (isset($parameters[self::PARAMETER_SIGNATURE])) {
92 2
            unset($parameters[self::PARAMETER_SIGNATURE]);
93 2
        }
94 3
        ksort($parameters);
95
96 3
        return $parameters;
97
    }
98
}
99