Signer   A
last analyzed

Complexity

Total Complexity 5

Size/Duplication

Total Lines 43
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 15
c 1
b 0
f 0
dl 0
loc 43
ccs 17
cts 17
cp 1
rs 10
wmc 5

3 Methods

Rating   Name   Duplication   Size   Complexity  
A sign() 0 9 1
A __construct() 0 3 1
A withSignedHeadersHeader() 0 19 3
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