Completed
Push — master ( a96eef...84c2f0 )
by Marcel
30s
created

Signer::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 5
ccs 5
cts 5
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
3
namespace UMA\Psr\Http\Message\HMAC;
4
5
use Psr\Http\Message\MessageInterface;
6
use Psr\Http\Message\RequestInterface;
7
use UMA\Psr\Http\Message\Serializer\MessageSerializer;
8
9
class Signer
10
{
11
    /**
12
     * @var string
13
     */
14
    private $secret;
15
16
    /**
17
     * @var Calculator
18
     */
19
    private $calculator;
20
21
    /**
22
     * @param string $secret
23
     */
24 72
    public function __construct($secret)
25 1
    {
26 72
        $this->secret = $secret;
27 72
        $this->calculator = new Calculator();
28 72
    }
29
30
    /**
31
     * @param MessageInterface $message
32
     *
33
     * @return MessageInterface The signed message.
34
     *
35
     * @throws \InvalidArgumentException When $message is an implementation of
36
     *                                   MessageInterface that cannot be
37
     *                                   serialized and thus neither signed.
38
     */
39 70
    public function sign(MessageInterface $message)
40
    {
41 70
        $serialization = MessageSerializer::serialize(
42 70
            $preSignedMessage = $this->withSignedHeadersHeader($message)
43 70
        );
44
45 70
        return $preSignedMessage->withHeader(
46 70
            Specification::AUTH_HEADER,
47 70
            Specification::AUTH_PREFIX.' '.$this->calculator->hmac($serialization, $this->secret)
48 70
        );
49
    }
50
51
    /**
52
     * @param MessageInterface $message
53
     *
54
     * @return MessageInterface
55
     */
56 70
    private function withSignedHeadersHeader(MessageInterface $message)
57
    {
58 70
        $headers = array_keys(array_change_key_case($message->getHeaders(), CASE_LOWER));
59 70
        array_push($headers, mb_strtolower(Specification::SIGN_HEADER));
60
61
        // Some of the tested RequestInterface implementations do not include
62
        // the Host header in $message->getHeaders(), so it is explicitly set when needed
63 70
        if ($message instanceof RequestInterface && !in_array('host', $headers)) {
64 12
            array_push($headers, 'host');
65 12
        }
66
67
        // There is no guarantee about the order of the headers returned by
68
        // $message->getHeaders(), so they are explicitly sorted in order
69
        // to produce the exact same string regardless of the underlying implementation
70 70
        sort($headers);
71
72 70
        return $message->withHeader(Specification::SIGN_HEADER, implode(',', $headers));
73
    }
74
}
75