Signer::withSignedHeadersHeader()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 19
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 19
ccs 8
cts 8
cp 1
crap 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace UMA\Psr7Hmac;
6
7
use Psr\Http\Message\RequestInterface;
8
use UMA\Psr7Hmac\Internal\HashCalculator;
9
use UMA\Psr7Hmac\Internal\HeaderNameNormalizer;
10
use UMA\Psr7Hmac\Internal\RequestSerializer;
11
12
final class Signer
13
{
14
    /**
15
     * @var string
16
     */
17
    private $secret;
18
19 85
    public function __construct(string $secret)
20
    {
21 85
        $this->secret = $secret;
22 85
    }
23
24 85
    public function sign(RequestInterface $request): RequestInterface
25
    {
26 85
        $serialization = RequestSerializer::serialize(
27 85
            $preSignedMessage = $this->withSignedHeadersHeader($request)
28
        );
29
30 85
        return $preSignedMessage->withHeader(
31 85
            Specification::AUTH_HEADER,
32 85
            Specification::AUTH_PREFIX.HashCalculator::hmac($serialization, $this->secret)
33
        );
34
    }
35
36 85
    private function withSignedHeadersHeader(RequestInterface $request): RequestInterface
37
    {
38 85
        $headers = [HeaderNameNormalizer::normalize(Specification::SIGN_HEADER)];
39 85
        foreach ($request->getHeaders() as $name => $_) {
40 76
            $headers[] = HeaderNameNormalizer::normalize($name);
41
        }
42
43
        // Some of the tested RequestInterface implementations do not include
44
        // the Host header in $message->getHeaders(), so it is explicitly set when needed
45 85
        if (!\in_array('host', $headers, true)) {
46 22
            $headers[] = 'host';
47
        }
48
49
        // There is no guarantee about the order of the headers returned by
50
        // $message->getHeaders(), so they are explicitly sorted in order
51
        // to produce the exact same string regardless of the underlying implementation
52 85
        \sort($headers);
53
54 85
        return $request->withHeader(Specification::SIGN_HEADER, \implode(',', $headers));
55
    }
56
}
57