Completed
Pull Request — master (#1556)
by wannanbigpig
05:05 queued 57s
created

Application::verifySignature()   A

Complexity

Conditions 6
Paths 9

Size

Total Lines 24
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 14
nc 9
nop 1
dl 0
loc 24
rs 9.2222
c 0
b 0
f 0
ccs 12
cts 12
cp 1
crap 6
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;
13
14
use EasyWeChat\BasicService;
15
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
16
use EasyWeChat\Kernel\ServiceContainer;
17
use EasyWeChat\Kernel\Support;
18
use EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException;
19
20
/**
21
 * Class Application.
22
 *
23
 * @author liuml <[email protected]>
24
 *
25
 * @property \EasyWeChat\MicroMerchant\Certficates\Client    $certficates
26
 * @property \EasyWeChat\MicroMerchant\Material\Client       $material
27
 * @property \EasyWeChat\MicroMerchant\MerchantConfig\Client $merchantConfig
28
 * @property \EasyWeChat\MicroMerchant\Withdraw\Client       $withdraw
29
 *
30
 * @method mixed applyForEnter(array $params)
31
 * @method mixed getStatus(string $applymentId, string $businessCode = '')
32
 * @method mixed upgrade(array $params)
33
 * @method mixed getUpgradeStatus(string $subMchId = '')
34
 */
35
class Application extends ServiceContainer
36
{
37
    /**
38
     * @var array
39
     */
40
    protected $providers = [
41
        // Base services
42
        BasicService\Media\ServiceProvider::class,
43
        Base\ServiceProvider::class,
44
        Certficates\ServiceProvider::class,
45
        MerchantConfig\ServiceProvider::class,
46
        Material\ServiceProvider::class,
47
        Withdraw\ServiceProvider::class,
48
    ];
49
50
    /**
51
     * @var array
52
     */
53
    protected $defaultConfig = [
54
        'http' => [
55
            'base_uri' => 'https://api.mch.weixin.qq.com/',
56
        ],
57
        'log' => [
58
            'default' => 'dev', // 默认使用的 channel,生产环境可以改为下面的 prod
59
            'channels' => [
60
                // 测试环境
61
                'dev' => [
62
                    'driver' => 'single',
63
                    'path' => '/tmp/easywechat.log',
64
                    'level' => 'debug',
65
                ],
66
                // 生产环境
67
                'prod' => [
68
                    'driver' => 'daily',
69
                    'path' => '/tmp/easywechat.log',
70
                    'level' => 'info',
71
                ],
72
            ],
73
        ],
74
    ];
75
76
    /**
77
     * @return string
78
     *
79
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
80
     */
81 6
    public function getKey()
82
    {
83 6
        $key = $this['config']->key;
84
85 6
        if (empty($key)) {
86
            throw new InvalidArgumentException('config key connot be empty.');
87
        }
88
89 6
        if (32 !== strlen($key)) {
90 1
            throw new InvalidArgumentException(sprintf("'%s' should be 32 chars length.", $key));
91
        }
92
93 6
        return $key;
94
    }
95
96
    /**
97
     * get certficates.
98
     *
99
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
100
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
101
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidExtensionException
102
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
103
     * @throws \Psr\SimpleCache\InvalidArgumentException
104
     */
105 1
    public function getCertficates()
106
    {
107 1
        return $this->certficates->get();
108
    }
109
110
    /**
111
     * set sub-mch-id and appid.
112
     *
113
     * @param string $subMchId Identification Number of Small and Micro Businessmen Reported by Service Providers
114
     * @param string $appid    Public Account ID of Service Provider
115
     *
116
     * @return $this
117
     */
118 1
    public function setSubMchId(string $subMchId, string $appid = '')
119
    {
120 1
        $this['config']->set('sub_mch_id', $subMchId);
121 1
        $this['config']->set('appid', $appid);
122
123 1
        return $this;
124
    }
125
126
    /**
127
     * Returning true indicates that the verification is successful,
128
     * returning false indicates that the signature field does not exist or is empty,
129
     * and if the signature verification is wrong, the InvalidSignException will be thrown directly.
130
     *
131
     * @param array $data
132
     *
133
     * @return bool
134
     *
135
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
136
     * @throws \EasyWeChat\MicroMerchant\Kernel\Exceptions\InvalidSignException
137
     */
138 5
    public function verifySignature(array $data)
139
    {
140 5
        if (!isset($data['sign']) || empty($data['sign'])) {
141 5
            return false;
142
        }
143
144 1
        $sign = $data['sign'];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 27 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...
145 1
        strlen($sign) > 32 && $signType = 'HMAC-SHA256';
146 1
        unset($data['sign']);
147 1
        $secretKey = $this->getKey();
148
149 1
        if ('HMAC-SHA256' === ($signType ?? 'MD5')) {
150
            $encryptMethod = function ($str) use ($secretKey) {
151
                return hash_hmac('sha256', $str, $secretKey);
152
            };
153
        } else {
154 1
            $encryptMethod = 'md5';
155
        }
156
157 1
        if (Support\generate_sign($data, $secretKey, $encryptMethod) === $sign) {
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

157
        if (/** @scrutinizer ignore-call */ Support\generate_sign($data, $secretKey, $encryptMethod) === $sign) {
Loading history...
158 1
            return true;
159
        }
160
161 1
        throw new InvalidSignException('return value signature verification error');
162
    }
163
164
    /**
165
     * @param string $name
166
     * @param array  $arguments
167
     *
168
     * @return mixed
169
     */
170
    public function __call($name, $arguments)
171
    {
172
        return call_user_func_array([$this['base'], $name], $arguments);
173
    }
174
}
175