Completed
Pull Request — master (#1556)
by wannanbigpig
14:01
created

Client::getCertficates()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
ccs 0
cts 5
cp 0
crap 12
1
<?php
2
3
/*
4
 * This file is part of the overtrue/wechat.
5
 *
6
 * (c) overtrue <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace EasyWeChat\MicroMerchant\Certficates;
13
14
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
15
use EasyWeChat\MicroMerchant\Kernel\BaseClient;
16
use EasyWeChat\Kernel\Traits\InteractsWithCache;
17
use EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidExtensionException;
18
19
/**
20
 * Class Client
21
 *
22
 * @author   liuml  <[email protected]>
23
 * @DateTime 2019-05-30  14:19
24
 */
25
class Client extends BaseClient
26
{
27
    use InteractsWithCache;
28
29
    /**
30
     * get certficates
31
     *
32
     * @return mixed
33
     *
34
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
35
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
36
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidExtensionException
37
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
38
     * @throws \Psr\SimpleCache\InvalidArgumentException
39
     */
40
    public function getCertficates()
41
    {
42
        $certificates = $this->getCache()->get($this->microCertificates);
43
        if ($certificates && strtotime($certificates['expire_time']) > time()) {
44
            return $certificates;
45
        }
46
        return $this->refreshCertificate();
47
    }
48
49
    /**
50
     * download certficates
51
     *
52
     * @return mixed
53
     *
54
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
55
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
56
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidExtensionException
57
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
58
     * @throws \Psr\SimpleCache\InvalidArgumentException
59
     */
60
    private function downloadCertficates()
61
    {
62
        $params = [
63
            'sign_type' => 'HMAC-SHA256',
64
            'nonce_str' => uniqid('micro'),
65
        ];
66
        return $this->analytical($this->request('risk/getcertficates', $params));
67
    }
68
69
    /**
70
     * analytical certificate
71
     *
72
     * @param $data
73
     *
74
     * @return mixed
75
     *
76
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
77
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidExtensionException
78
     * @throws \Psr\SimpleCache\InvalidArgumentException
79
     */
80
    protected function analytical($data)
81
    {
82
        if ($data['return_code'] != 'SUCCESS') {
83
            throw new InvalidArgumentException(
84
                sprintf(
85
                    'Failed to download certificate. return_code_msg: "%s" .',
86
                    $data['return_code'].'('.$data['return_msg'].')'
87
                )
88
            );
89
        }
90
        if ($data['result_code'] != 'SUCCESS') {
91
            throw new InvalidArgumentException(
92
                sprintf(
93
                    'Failed to download certificate. result_err_code_des: "%s" .',
94
                    $data['result_code'].'('.$data['err_code'].'['.$data['err_code_des'].'])'
95
                )
96
            );
97
        }
98
        $certificates = \GuzzleHttp\json_decode($data['certificates'], JSON_UNESCAPED_UNICODE)['data'][0];
0 ignored issues
show
Bug introduced by
EasyWeChat\MicroMerchant...\JSON_UNESCAPED_UNICODE of type integer is incompatible with the type boolean expected by parameter $assoc of GuzzleHttp\json_decode(). ( Ignorable by Annotation )

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

98
        $certificates = \GuzzleHttp\json_decode($data['certificates'], /** @scrutinizer ignore-type */ JSON_UNESCAPED_UNICODE)['data'][0];
Loading history...
99
        $ciphertext   = $this->decryptCiphertext($certificates['encrypt_certificate']);
100
        unset($certificates['encrypt_certificate']);
101
        $certificates['certificates'] = $ciphertext;
102
        $this->getCache()->set($this->microCertificates, $certificates);
103
        return $certificates;
104
    }
105
106
    /**
107
     * decrypt ciphertext
108
     *
109
     * @param $encryptCertificate
110
     *
111
     * @return string
112
     *
113
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidExtensionException
114
     */
115
    protected function decryptCiphertext($encryptCertificate)
116
    {
117
        if (extension_loaded('sodium') === false) {
118
            throw new InvalidExtensionException('sodium extension is not installed,Reference link https://blog.csdn.net/u010324331/article/details/82153067');
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 140 characters; contains 158 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
119
        }
120
121
        if (sodium_crypto_aead_aes256gcm_is_available() === false) {
122
            throw new InvalidExtensionException('aes256gcm is not currently supported');
123
        }
124
125
        // sodium_crypto_aead_aes256gcm_decrypt function needs to open libsodium extension.
126
        // https://blog.csdn.net/u010324331/article/details/82153067
127
        return sodium_crypto_aead_aes256gcm_decrypt(
128
            base64_decode($encryptCertificate['ciphertext']),
129
            $encryptCertificate['associated_data'],
130
            $encryptCertificate['nonce'],
131
            $this->app['config']->apiv3_key
132
        );
133
    }
134
135
    /**
136
     * refresh certificate
137
     *
138
     * @return mixed
139
     *
140
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
141
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
142
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidExtensionException
143
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
144
     * @throws \Psr\SimpleCache\InvalidArgumentException
145
     */
146
    public function refreshCertificate()
147
    {
148
        return $this->downloadCertficates();
149
    }
150
}
151