Completed
Pull Request — master (#1556)
by wannanbigpig
04:10
created

BaseClient   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 215
Duplicated Lines 0 %

Test Coverage

Coverage 98.15%

Importance

Changes 0
Metric Value
eloc 63
dl 0
loc 215
ccs 53
cts 54
cp 0.9815
rs 10
c 0
b 0
f 0
wmc 16

9 Methods

Rating   Name   Duplication   Size   Complexity  
A requestRaw() 0 3 1
A logMiddleware() 0 5 1
A prepends() 0 3 1
A safeRequest() 0 8 1
A request() 0 31 5
A __construct() 0 7 1
A processParams() 0 12 3
A getSensitiveFieldsName() 0 13 1
A encryptSensitiveInformation() 0 10 2
1
<?php
2
/*
3
 * This file is part of the overtrue/wechat.
4
 *
5
 * (c) overtrue <[email protected]>
6
 *
7
 * This source file is subject to the MIT license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace EasyWeChat\MicroMerchant\Kernel;
12
13
use EasyWeChat\Kernel\Support;
14
use EasyWeChat\Kernel\Traits\HasHttpRequests;
15
use EasyWeChat\MicroMerchant\Application;
16
use EasyWeChat\MicroMerchant\Kernel\Exceptions\EncryptException;
17
use GuzzleHttp\MessageFormatter;
18
use GuzzleHttp\Middleware;
19
20
/**
21
 * Class BaseClient.
22
 *
23
 * @author overtrue <[email protected]>
24
 */
25
class BaseClient
26
{
27
    use HasHttpRequests {
0 ignored issues
show
Bug introduced by
The trait EasyWeChat\Kernel\Traits\HasHttpRequests requires the property $baseUri which is not provided by EasyWeChat\MicroMerchant\Kernel\BaseClient.
Loading history...
28
        request as performRequest;
29
    }
30
31
    /**
32
     * @var string
33
     */
34
    protected $microCertificates;
35
36
    /**
37
     * @var string
38
     */
39
    protected $certificates;
40
41
    /**
42
     * @var \EasyWeChat\MicroMerchant\Application
43
     */
44
    protected $app;
45
46
    /**
47
     * BaseClient constructor.
48
     *
49
     * @param  \EasyWeChat\MicroMerchant\Application  $app
50
     */
51 22
    public function __construct(Application $app)
52
    {
53 22
        $this->app = $app;
54
55 22
        $this->microCertificates = $this->app['config']->mch_id.'_micro_certificates';
56
57 22
        $this->setHttpClient($this->app['http_client']);
58 22
    }
59
60
    /**
61
     * Extra request params.
62
     *
63
     * @return array
64
     */
65 4
    protected function prepends()
66
    {
67 4
        return [];
68
    }
69
70
    /**
71
     * request.
72
     *
73
     * @param  string  $endpoint
74
     * @param  array   $params
75
     * @param  string  $method
76
     * @param  array   $options
77
     * @param  bool    $returnResponse
78
     *
79
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
80
     *
81
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
82
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
83
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
84
     */
85 4
    protected function request(string $endpoint, array $params = [], $method = 'post', array $options = [], $returnResponse = false)
86
    {
87
        $base = [
88 4
            'mch_id' => $this->app['config']['mch_id'],
89
        ];
90
91 4
        $params = array_filter(array_merge($base, $this->prepends(), $params));
92
93 4
        $secretKey = $this->app->getKey();
94 4
        if ('HMAC-SHA256' === ($params['sign_type'] ?? 'MD5')) {
95 1
            $encryptMethod = function ($str) use ($secretKey) {
96 1
                return hash_hmac('sha256', $str, $secretKey);
97 1
            };
98
        } else {
99 3
            $encryptMethod = 'md5';
100
        }
101 4
        $params['sign'] = Support\generate_sign($params, $secretKey, $encryptMethod);
0 ignored issues
show
Bug introduced by
The function generate_sign was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

101
        $params['sign'] = /** @scrutinizer ignore-call */ Support\generate_sign($params, $secretKey, $encryptMethod);
Loading history...
102
103 4
        $options = array_merge([
104 4
            'body' => Support\XML::build($params),
105
        ], $options);
106
107 4
        $this->pushMiddleware($this->logMiddleware(), 'log');
108
109 4
        $response = $this->performRequest($endpoint, $method, $options);
110 4
        $response = $returnResponse ? $response : $this->castResponseToType($response, $this->app->config->get('response_type'));
111
        // auto verify signature
112 4
        if (!$returnResponse && 'array' === ($this->app->config->get('response_type') ?? 'array')) {
113 1
            $this->app->verifySignature($response);
0 ignored issues
show
Bug introduced by
$response of type EasyWeChat\Kernel\Suppor...ssage\ResponseInterface is incompatible with the type array expected by parameter $data of EasyWeChat\MicroMerchant...tion::verifySignature(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

113
            $this->app->verifySignature(/** @scrutinizer ignore-type */ $response);
Loading history...
114
        }
115 4
        return $response;
116
    }
117
118
    /**
119
     * Log the request.
120
     *
121
     * @return \Closure
122
     */
123 4
    protected function logMiddleware()
124
    {
125 4
        $formatter = new MessageFormatter($this->app['config']['http.log_template'] ?? MessageFormatter::DEBUG);
126
127 4
        return Middleware::log($this->app['logger'], $formatter);
128
    }
129
130
    /**
131
     * Make a request and return raw response.
132
     *
133
     * @param          $endpoint
134
     * @param  array   $params
135
     * @param  string  $method
136
     * @param  array   $options
137
     *
138
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
139
     *
140
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
141
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
142
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
143
     */
144 4
    protected function requestRaw($endpoint, array $params = [], $method = 'post', array $options = [])
145
    {
146 4
        return $this->request($endpoint, $params, $method, $options, true);
147
    }
148
149
    /**
150
     * Request with SSL.
151
     *
152
     * @param          $endpoint
153
     * @param  array   $params
154
     * @param  string  $method
155
     * @param  array   $options
156
     *
157
     * @return array|\EasyWeChat\Kernel\Support\Collection|object|\Psr\Http\Message\ResponseInterface|string
158
     *
159
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
160
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
161
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
162
     */
163 1
    protected function safeRequest($endpoint, array $params, $method = 'post', array $options = [])
164
    {
165 1
        $options = array_merge([
166 1
            'cert' => $this->app['config']->get('cert_path'),
167 1
            'ssl_key' => $this->app['config']->get('key_path'),
168
        ], $options);
169
170 1
        return $this->request($endpoint, $params, $method, $options);
171
    }
172
173
    /**
174
     * processing parameters contain fields that require sensitive information encryption.
175
     *
176
     * @param  array  $params
177
     *
178
     * @return array
179
     *
180
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
181
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
182
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\EncryptException
183
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidExtensionException
184
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
185
     * @throws \Psr\SimpleCache\InvalidArgumentException
186
     */
187 1
    protected function processParams(array $params)
188
    {
189 1
        $cert = $this->app->getCertficates();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 15 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
190 1
        $this->certificates = $cert['certificates'];
191 1
        $params['cert_sn'] = $cert['serial_no'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 2 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
192 1
        $sensitive_fields = $this->getSensitiveFieldsName();
193 1
        foreach ($params as $k => $v) {
194 1
            if (in_array($k, $sensitive_fields, true)) {
195 1
                $params[$k] = $this->encryptSensitiveInformation($v);
196
            }
197
        }
198 1
        return $params;
199
    }
200
201
    /**
202
     * To id card, mobile phone number and other fields sensitive information encryption.
203
     *
204
     * @param  string  $string
205
     *
206
     * @return string
207
     *
208
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\EncryptException
209
     */
210 1
    protected function encryptSensitiveInformation(string $string)
211
    {
212 1
        $encrypted = '';
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 9 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
213 1
        $publicKeyResource = openssl_get_publickey($this->certificates);
214 1
        $f = openssl_public_encrypt($string, $encrypted, $publicKeyResource);
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 17 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
215 1
        openssl_free_key($publicKeyResource);
216 1
        if ($f) {
217 1
            return base64_encode($encrypted);
218
        }
219
        throw new EncryptException('Encryption of sensitive information failed');
220
    }
221
222
    /**
223
     * get sensitive fields name.
224
     *
225
     * @return array
226
     */
227 1
    protected function getSensitiveFieldsName()
228
    {
229
        return [
230 1
            'id_card_name',
231
            'id_card_number',
232
            'account_name',
233
            'account_number',
234
            'contact',
235
            'contact_phone',
236
            'contact_email',
237
            'legal_person',
238
            'mobile_phone',
239
            'email',
240
        ];
241
    }
242
}
243