RequestSigner   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 123
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 8
Bugs 0 Features 0
Metric Value
wmc 11
eloc 33
c 8
b 0
f 0
dl 0
loc 123
ccs 35
cts 35
cp 1
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A buildAuthorizationHeader() 0 8 1
A getContentHashedRequest() 0 14 2
A getTimestampedRequest() 0 12 3
A getAuthorizedRequest() 0 12 2
A signRequest() 0 7 1
A __construct() 0 5 2
1
<?php
2
3
namespace Acquia\Hmac;
4
5
use Acquia\Hmac\Digest\Digest;
6
use Acquia\Hmac\Digest\DigestInterface;
7
use Psr\Http\Message\RequestInterface;
8
9
/**
10
 * Signs requests according to the HTTP HMAC spec.
11
 */
12
class RequestSigner implements RequestSignerInterface
13
{
14
    /**
15
     * @var \Acquia\Hmac\KeyInterface
16
     *   The key to sign requests with.
17
     */
18
    protected $key;
19
20
    /**
21
     * @var string
22
     *   The API realm/provider.
23
     */
24
    protected $realm;
25
26
    /**
27
     * @var \Acquia\Hmac\Digest\DigestInterface
28
     *   The message digest to use when signing requests.
29
     */
30
    protected $digest;
31
32
    /**
33
     * Initializes the request signer with a key and realm.
34
     *
35
     * @param \Acquia\Hmac\KeyInterface $key
36
     *   The key to sign requests with.
37
     * @param string $realm
38
     *   The API realm/provider. Defaults to "Acquia".
39
     * @param \Acquia\Hmac\Digest\DigestInterface|null $digest
40
     *   The message digest to use when signing requests. Defaults to
41
     *   \Acquia\Hmac\Digest\Digest.
42
     */
43 17
    public function __construct(KeyInterface $key, $realm = 'Acquia', ?DigestInterface $digest = null)
44
    {
45 17
        $this->key = $key;
46 17
        $this->realm = $realm;
47 17
        $this->digest = $digest ?: new Digest();
48 17
    }
49
50
    /**
51
     * {@inheritDoc}
52
     */
53 13
    public function signRequest(RequestInterface $request, array $customHeaders = [])
54
    {
55 13
        $request = $this->getTimestampedRequest($request);
56 13
        $request = $this->getContentHashedRequest($request);
57 13
        $request = $this->getAuthorizedRequest($request, $customHeaders);
58
59 13
        return $request;
60
    }
61
62
    /**
63
     * {@inheritDoc}
64
     */
65 15
    public function getTimestampedRequest(RequestInterface $request, \DateTime $date = null)
66
    {
67 15
        if ($request->hasHeader('X-Authorization-Timestamp')) {
68 11
            return clone $request;
69
        }
70
71 4
        $date = $date ?: new \DateTime('now', new \DateTimeZone('UTC'));
72
73
        /** @var RequestInterface $request */
74 4
        $request = $request->withHeader('X-Authorization-Timestamp', (string) $date->getTimestamp());
75
76 4
        return $request;
77
    }
78
79
    /**
80
     * {@inheritDoc}
81
     */
82 15
    public function getContentHashedRequest(RequestInterface $request)
83
    {
84 15
        $body = (string) $request->getBody();
85
86 15
        if (!strlen($body)) {
87 12
            return clone $request;
88
        }
89
90 3
        $hashedBody = $this->digest->hash((string) $body);
91
92
        /** @var RequestInterface $request */
93 3
        $request =  $request->withHeader('X-Authorization-Content-SHA256', $hashedBody);
94
95 3
        return $request;
96
    }
97
98
    /**
99
     * {@inheritDoc}
100
     */
101 13
    public function getAuthorizedRequest(RequestInterface $request, array $customHeaders = [])
102
    {
103 13
        if ($request->hasHeader('Authorization')) {
104 1
            $authHeader = AuthorizationHeader::createFromRequest($request);
105
        } else {
106 13
            $authHeader = $this->buildAuthorizationHeader($request, $customHeaders);
107
        }
108
109
        /** @var RequestInterface $request */
110 13
        $request = $request->withHeader('Authorization', (string) $authHeader);
111
112 13
        return $request;
113
    }
114
115
    /**
116
     * Builds an AuthorizationHeader object.
117
     *
118
     * @param \Psr\Http\Message\RequestInterface $request
119
     *   The request being signed.
120
     * @param string[] $customHeaders
121
     *   A list of custom header names. The values of the headers will be
122
     *   extracted from the request.
123
     *
124
     * @return \Acquia\Hmac\AuthorizationHeader
125
     *   The compiled authorizatio header object.
126
     */
127 3
    protected function buildAuthorizationHeader(RequestInterface $request, array $customHeaders = [])
128
    {
129 3
        $authHeaderBuilder = new AuthorizationHeaderBuilder($request, $this->key, $this->digest);
130 3
        $authHeaderBuilder->setRealm($this->realm);
131 3
        $authHeaderBuilder->setId($this->key->getId());
132 3
        $authHeaderBuilder->setCustomHeaders($customHeaders);
133
134 3
        return $authHeaderBuilder->getAuthorizationHeader();
135
    }
136
}
137