Passed
Pull Request — master (#458)
by Songda
02:12
created

SignPlugin::getContents()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
c 0
b 0
f 0
dl 0
loc 15
rs 9.9666
cc 3
nc 3
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yansongda\Pay\Plugin\Wechat;
6
7
use Closure;
8
use GuzzleHttp\Psr7\Utils;
9
use Yansongda\Pay\Contract\PluginInterface;
10
use Yansongda\Pay\Exception\InvalidConfigException;
11
use Yansongda\Pay\Exception\InvalidParamsException;
12
use Yansongda\Pay\Logger;
13
use Yansongda\Pay\Rocket;
14
use Yansongda\Supports\Collection;
15
use Yansongda\Supports\Str;
16
17
class SignPlugin implements PluginInterface
18
{
19
    /**
20
     * @throws \Yansongda\Pay\Exception\ContainerDependencyException
21
     * @throws \Yansongda\Pay\Exception\ContainerException
22
     * @throws \Yansongda\Pay\Exception\InvalidConfigException
23
     * @throws \Yansongda\Pay\Exception\InvalidParamsException
24
     * @throws \Yansongda\Pay\Exception\ServiceNotFoundException
25
     * @throws \Exception
26
     */
27
    public function assembly(Rocket $rocket, Closure $next): Rocket
28
    {
29
        Logger::info('[wechat][SignPlugin] 插件开始装载', ['rocket' => $rocket]);
30
31
        $timestamp = time();
32
        $random = Str::random(32);
33
        $body = $this->payloadToString($rocket->getPayload());
34
        $radar = $rocket->getRadar()->withAddedHeader('Authorization', get_wechat_authorization(
35
            $rocket->getParams(), $timestamp, $random, $this->getContents($rocket, $timestamp, $random))
36
        );
37
38
        if (!empty($body)) {
39
            $radar = $radar->withBody(Utils::streamFor($body));
40
        }
41
42
        $rocket->setRadar($radar);
43
44
        Logger::info('[wechat][SignPlugin] 插件装载完毕', ['rocket' => $rocket]);
45
46
        return $next($rocket);
47
    }
48
49
    /**
50
     * @throws \Yansongda\Pay\Exception\InvalidParamsException
51
     */
52
    protected function getContents(Rocket $rocket, int $timestamp, string $random): string
53
    {
54
        $request = $rocket->getRadar();
55
56
        if (is_null($request)) {
57
            throw new InvalidParamsException(InvalidParamsException::REQUEST_NULL_ERROR);
58
        }
59
60
        $uri = $request->getUri();
61
62
        return $request->getMethod()."\n".
63
            $uri->getPath().(empty($uri->getQuery()) ? '' : '?'.$uri->getQuery())."\n".
64
            $timestamp."\n".
65
            $random."\n".
66
            $this->payloadToString($rocket->getPayload())."\n";
67
    }
68
69
    /**
70
     * @throws \Yansongda\Pay\Exception\InvalidConfigException
71
     */
72
    protected function getMchPublicCertSerialNumber(?string $path): string
73
    {
74
        if (empty($path)) {
75
            throw new InvalidConfigException(InvalidConfigException::WECHAT_CONFIG_ERROR, 'Missing Wechat Config -- [mch_public_cert_path]');
76
        }
77
78
        $cert = file_get_contents($path);
79
        $ssl = openssl_x509_parse($cert);
80
81
        if (empty($ssl['serialNumberHex'])) {
82
            throw new InvalidConfigException(InvalidConfigException::WECHAT_CONFIG_ERROR, 'Parse [mch_public_cert_path] Serial Number Error');
83
        }
84
85
        return $ssl['serialNumberHex'];
86
    }
87
88
    protected function payloadToString(?Collection $payload): string
89
    {
90
        return (is_null($payload) || 0 === $payload->count()) ? '' : $payload->toJson();
91
    }
92
}
93