SignedRequest   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 78
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 10
c 1
b 0
f 0
lcom 1
cbo 4
dl 0
loc 78
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A authenticateSignature() 0 12 3
A __construct() 0 8 1
A buildSignature() 0 21 2
A guardValidSignatureTime() 0 8 2
A setMethod() 0 12 2
1
<?php
2
3
namespace Rezzza\SecurityBundle\Security\Firewall;
4
5
class SignedRequest
6
{
7
    private $method;
8
9
    private $host;
10
11
    private $pathInfo;
12
13
    private $content;
14
15
    private $signatureTime;
16
17
    public function __construct($method, $host, $pathInfo, $content, $signatureTime = null)
18
    {
19
        $this->setMethod(strtoupper($method));
20
        $this->signatureTime = $signatureTime;
21
        $this->host = $host;
22
        $this->pathInfo = $pathInfo;
23
        $this->content = $content;
24
    }
25
26
    public function buildSignature(SignatureConfig $signatureConfig)
27
    {
28
        $payload = array(
29
            $this->method,
30
            $this->host,
31
            $this->pathInfo,
32
            $this->content
33
        );
34
35
        if ($signatureConfig->isReplayProtectionEnabled()) {
36
            $this->guardValidSignatureTime();
37
            // use unshift to keep BC on signature generation
38
            array_unshift($payload, $this->signatureTime);
39
        }
40
41
        return hash_hmac(
42
            $signatureConfig->getAlgorithm(),
43
            implode("\n", $payload),
44
            $signatureConfig->getSecret()
45
        );
46
    }
47
48
    public function authenticateSignature($signature, SignatureConfig $signatureConfig, ReplayProtection $replayProtection)
49
    {
50
        if ($signature !== $this->buildSignature($signatureConfig)) {
51
            throw new InvalidSignatureException;
52
        }
53
54
        if (!$replayProtection->accept($this->signatureTime, time())) {
55
            throw new ExpiredSignatureException('Signature has expired');
56
        }
57
58
        return true;
59
    }
60
61
    private function guardValidSignatureTime()
62
    {
63
        if (!is_numeric($this->signatureTime)) {
64
            throw new InvalidSignatureException(
65
                sprintf('Signed request accepts only numeric value for "signatureTime" attribute. "%s" given', $this->signatureTime)
66
            );
67
        }
68
    }
69
70
    private function setMethod($method)
71
    {
72
        $httpVerbs = array('POST', 'GET', 'PUT', 'PATCH', 'LINK');
73
74
        if (!in_array($method, $httpVerbs)) {
75
            throw new InvalidSignatureException(
76
                sprintf('Signed request accepts only valid http method for "method" attribute. "%s" given', $method)
77
            );
78
        }
79
80
        $this->method = $method;
81
    }
82
}
83