PrivateRequestConfigurator::configurePostRequest()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 13
ccs 9
cts 9
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Codenixsv\KunaApi\Configurator;
6
7
use Codenixsv\ApiClient\configurator\RequestConfiguratorInterface;
8
use Psr\Http\Message\RequestInterface;
9
10
use function GuzzleHttp\Psr7\stream_for;
11
12
/**
13
 * Interface RequestConfiguratorInterface
14
 * @package Codenixsv\ApiClient
15
 */
16
class PrivateRequestConfigurator implements RequestConfiguratorInterface
17
{
18
    /** @var string  */
19
    private $publicKey;
20
    /** @var string  */
21
    private $secretKey;
22
23
    /**
24
     * PrivateRequestConfigurator constructor.
25
     * @param string $publicKey
26
     * @param string $secretKey
27
     */
28 8
    public function __construct(string $publicKey, string $secretKey)
29
    {
30 8
        $this->publicKey = $publicKey;
31 8
        $this->secretKey = $secretKey;
32 8
    }
33
34
    /**
35
     * @param RequestInterface $request
36
     * @return RequestInterface
37
     */
38 6
    public function configure(RequestInterface $request): RequestInterface
39
    {
40 6
        $method = $request->getMethod();
41
42 6
        if ($method === 'GET') {
43 4
            $request = $this->configureGetRequest($request);
44
        }
45
46 6
        if ($method === 'POST') {
47 2
            $request = $this->configurePostRequest($request);
48
        }
49
50 6
        return $request;
51
    }
52
53
    /**
54
     * @param RequestInterface $request
55
     * @return RequestInterface
56
     */
57 2
    private function configurePostRequest(RequestInterface $request): RequestInterface
58
    {
59 2
        parse_str((string) $request->getBody(), $params);
60 2
        $signedData = $this->getSignedData(
61 2
            $params,
62 2
            $request->getUri()->getPath(),
63 2
            'POST',
64 2
            $this->generateTonce()
65
        );
66
67 2
        $request = $request->withBody(stream_for(http_build_query($signedData)));
68
69 2
        return $request->withHeader('Content-Type', 'application/x-www-form-urlencoded');
70
    }
71
72
    /**
73
     * @param RequestInterface $request
74
     * @return RequestInterface
75
     */
76 4
    private function configureGetRequest(RequestInterface $request): RequestInterface
77
    {
78 4
        $uri = $request->getUri();
79 4
        parse_str($uri->getQuery(), $params);
80 4
        $signedData = $this->getSignedData(
81 4
            $params,
82 4
            $uri->getPath(),
83 4
            'GET',
84 4
            $this->generateTonce()
85
        );
86 4
        $signedUri = $uri->withQuery(http_build_query($signedData));
87
88 4
        return $request->withUri($signedUri);
89
    }
90
91
    /**
92
     * @param array $data
93
     * @param string $path
94
     * @param string $method
95
     * @param int $tonce
96
     * @return array
97
     */
98 7
    public function getSignedData(array $data, string $path, string $method, int $tonce): array
99
    {
100 7
        $params = array_merge($data, ['tonce' => $tonce, 'access_key' => $this->publicKey]);
101 7
        ksort($params, SORT_STRING);
102 7
        $signature = $this->generateSignature($method, $path, $params, $this->secretKey);
103 7
        $params['signature'] = $signature;
104
105 7
        return $params;
106
    }
107
108
    /**
109
     * @param string $method
110
     * @param string $path
111
     * @param array $query
112
     * @param string $secretKey
113
     * @return string
114
     */
115 7
    private function generateSignature(string $method, string $path, array $query, string $secretKey): string
116
    {
117 7
        $data = implode('|', [$method, $path, http_build_query($query)]);
118
119 7
        return hash_hmac('SHA256', $data, $secretKey);
120
    }
121
122
    /**
123
     * @return int
124
     */
125 6
    private function generateTonce(): int
126
    {
127 6
        return (int)(microtime(true) * 1000);
128
    }
129
}
130