GuzzleRequest::buildSignature()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
rs 9.4285
ccs 7
cts 7
cp 1
cc 1
eloc 7
nc 1
nop 3
crap 1
1
<?php
2
/*
3
 * Copyright 2016 Jan Eichhorn <[email protected]>
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
namespace ApaiIO\Request;
19
20
use ApaiIO\ApaiIO;
21
use ApaiIO\Configuration\ConfigurationInterface;
22
use ApaiIO\Operations\OperationInterface;
23
use GuzzleHttp\ClientInterface;
24
use GuzzleHttp\Psr7\Uri;
25
26
/**
27
 * Basic implementation of the rest request
28
 *
29
 * @see    http://docs.aws.amazon.com/AWSECommerceService/2011-08-01/DG/AnatomyOfaRESTRequest.html
30
 * @author Jan Eichhorn <[email protected]>
31
 */
32
class GuzzleRequest implements RequestInterface
33
{
34
    /**
35
     * The requestscheme
36
     *
37
     * @var string
38
     */
39
    private $requestTemplate = "//webservices.amazon.%s/onca/xml?%s";
40
41
    /**
42
     * The scheme for the uri. E.g. http or https.
43
     *
44
     * @var string
45
     */
46
    private $scheme = 'http';
47
48
    /**
49
     * @var ClientInterface
50
     */
51
    private $client;
52
53
    /**
54
     * Initialize instance
55
     *
56
     * @param ClientInterface $client
57
     */
58 4
    public function __construct(ClientInterface $client)
59
    {
60 4
        $this->client = $client;
61 4
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 2
    public function perform(OperationInterface $operation, ConfigurationInterface $configuration)
67
    {
68 2
        $preparedRequestParams = $this->prepareRequestParams($operation, $configuration);
69 2
        $queryString = $this->buildQueryString($preparedRequestParams, $configuration);
70
71 2
        $uri = new Uri(sprintf($this->requestTemplate, $configuration->getCountry(), $queryString));
72 2
        $request = new \GuzzleHttp\Psr7\Request('GET', $uri->withScheme($this->scheme), [
73 2
            'User-Agent' => 'ApaiIO [' . ApaiIO::VERSION . ']'
74
        ]);
75 2
        $result = $this->client->send($request);
76
77 2
        return $result->getBody()->getContents();
78
    }
79
80
    /**
81
     * Sets the scheme.
82
     *
83
     * @param string $scheme
84
     */
85 2
    public function setScheme($scheme)
86
    {
87 2
        if (!in_array($scheme = strtolower($scheme), ['http', 'https'])) {
88 1
            throw new \InvalidArgumentException('The scheme can only be http or https.');
89
        }
90
91 1
        $this->scheme = $scheme;
92 1
    }
93
94
    /**
95
     * Prepares the parameters for the request
96
     *
97
     * @param OperationInterface     $operation
98
     * @param ConfigurationInterface $configuration
99
     *
100
     * @return array
101
     */
102 2
    protected function prepareRequestParams(OperationInterface $operation, ConfigurationInterface $configuration)
103
    {
104
        $baseRequestParams = [
105 2
            'Service'        => 'AWSECommerceService',
106 2
            'AWSAccessKeyId' => $configuration->getAccessKey(),
107 2
            'AssociateTag'   => $configuration->getAssociateTag(),
108 2
            'Operation'      => $operation->getName(),
109 2
            'Version'        => '2013-08-01',
110 2
            'Timestamp'      => Util::getTimeStamp()
111
        ];
112
113 2
        $operationParams = $operation->getOperationParameter();
114
115 2
        foreach ($operationParams as $key => $value) {
116 2
            if (true === is_array($value)) {
117 2
                $operationParams[$key] = implode(',', $value);
118
            }
119
        }
120
121 2
        $fullParameterList = array_merge($baseRequestParams, $operationParams);
122 2
        ksort($fullParameterList);
123
124 2
        return $fullParameterList;
125
    }
126
127
    /**
128
     * Builds the final querystring including the signature
129
     *
130
     * @param array                  $params
131
     * @param ConfigurationInterface $configuration
132
     *
133
     * @return string
134
     */
135 2
    protected function buildQueryString(array $params, ConfigurationInterface $configuration)
136
    {
137 2
        $parameterList = [];
138 2
        foreach ($params as $key => $value) {
139 2
            $parameterList[] = sprintf('%s=%s', $key, rawurlencode($value));
140
        }
141
142 2
        $parameterList[] = 'Signature=' . rawurlencode(
143 2
            $this->buildSignature($parameterList, $configuration->getCountry(), $configuration->getSecretKey())
144
        );
145
146 2
        return implode("&", $parameterList);
147
    }
148
149
    /**
150
     * Calculates the signature for the request
151
     *
152
     * @param array  $params
153
     * @param string $country
154
     * @param string $secret
155
     *
156
     * @return string
157
     */
158 2
    protected function buildSignature(array $params, $country, $secret)
159
    {
160 2
        return Util::buildSignature(
161 2
            sprintf(
162 2
                "GET\nwebservices.amazon.%s\n/onca/xml\n%s",
163 2
                $country,
164 2
                implode('&', $params)
165
            ),
166 2
            $secret
167
        );
168
    }
169
}
170