GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Setup Failed
Push — master ( 9d889d...27a869 )
by Carlos
02:09
created

BaiduGateway::getName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
/*
4
 * This file is part of the overtrue/easy-sms.
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 Overtrue\EasySms\Gateways;
13
14
use Overtrue\EasySms\Contracts\MessageInterface;
15
use Overtrue\EasySms\Contracts\PhoneNumberInterface;
16
use Overtrue\EasySms\Exceptions\GatewayErrorException;
17
use Overtrue\EasySms\Support\Config;
18
use Overtrue\EasySms\Traits\HasHttpRequest;
19
20
/**
21
 * Class BaiduGateway.
22
 *
23
 * @see https://cloud.baidu.com/doc/SMS/API.html
24
 */
25
class BaiduGateway extends Gateway
26
{
27
    use HasHttpRequest;
28
29
    const ENDPOINT_HOST = 'sms.bj.baidubce.com';
30
31
    const ENDPOINT_URI = '/bce/v2/message';
32
33
    const BCE_AUTH_VERSION = 'bce-auth-v1';
34
35
    const DEFAULT_EXPIRATION_IN_SECONDS = 1800; //签名有效期默认1800秒
36
37
    const SUCCESS_CODE = 1000;
38
39
    /**
40
     * Send message.
41
     *
42
     * @param \Overtrue\EasySms\Contracts\PhoneNumberInterface $to
43 1
     * @param \Overtrue\EasySms\Contracts\MessageInterface     $message
44
     * @param \Overtrue\EasySms\Support\Config                 $config
45 1
     *
46
     * @return array
47
     *
48
     * @throws \Overtrue\EasySms\Exceptions\GatewayErrorException ;
49
     */
50
    public function send(PhoneNumberInterface $to, MessageInterface $message, Config $config)
51
    {
52
        $params = [
53
            'invokeId' => $config->get('invoke_id'),
54
            'phoneNumber' => $to->getNumber(),
55
            'templateCode' => $message->getTemplate($this),
56
            'contentVar' => $message->getData($this),
57
        ];
58
59 1
        $datetime = date('Y-m-d\TH:i:s\Z');
60
61
        $headers = [
62 1
            'host' => self::ENDPOINT_HOST,
63 1
            'content-type' => 'application/json',
64 1
            'x-bce-date' => $datetime,
65 1
            'x-bce-content-sha256' => hash('sha256', json_encode($params)),
66 1
        ];
67
        //获得需要签名的数据
68 1
        $signHeaders = $this->getHeadersToSign($headers, ['host', 'x-bce-content-sha256']);
69
70
        $headers['Authorization'] = $this->generateSign($signHeaders, $datetime, $config);
71 1
72 1
        $result = $this->request('post', self::buildEndpoint($config), ['headers' => $headers, 'json' => $params]);
73 1
74 1 View Code Duplication
        if (self::SUCCESS_CODE != $result['code']) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
75 1
            throw new GatewayErrorException($result['message'], $result['code'], $result);
76
        }
77 1
78
        return $result;
79 1
    }
80
81 1
    /**
82
     * Build endpoint url.
83 1
     *
84 1
     * @param \Overtrue\EasySms\Support\Config $config
85
     *
86
     * @return string
87 1
     */
88
    protected function buildEndpoint(Config $config)
89
    {
90
        return 'http://'.$config->get('domain', self::ENDPOINT_HOST).self::ENDPOINT_URI;
91
    }
92
93
    /**
94
     * Generate Authorization header.
95
     *
96
     * @param array                            $signHeaders
97 1
     * @param int                              $datetime
98
     * @param \Overtrue\EasySms\Support\Config $config
99 1
     *
100
     * @return string
101
     */
102
    protected function generateSign(array $signHeaders, $datetime, Config $config)
103
    {
104
        // 生成 authString
105
        $authString = self::BCE_AUTH_VERSION.'/'.$config->get('ak').'/'
106
            .$datetime.'/'.self::DEFAULT_EXPIRATION_IN_SECONDS;
107
108
        // 使用 sk 和 authString 生成 signKey
109
        $signingKey = hash_hmac('sha256', $authString, $config->get('sk'));
110
        // 生成标准化 URI
111 1
        // 根据 RFC 3986,除了:1.大小写英文字符 2.阿拉伯数字 3.点'.'、波浪线'~'、减号'-'以及下划线'_' 以外都要编码
112
        $canonicalURI = str_replace('%2F', '/', rawurlencode(self::ENDPOINT_URI));
113
114 1
        // 生成标准化 QueryString
115 1
        $canonicalQueryString = ''; // 此 api 不需要此项。返回空字符串
116
117
        // 整理 headersToSign,以 ';' 号连接
118 1
        $signedHeaders = empty($signHeaders) ? '' : strtolower(trim(implode(';', array_keys($signHeaders))));
119
120
        // 生成标准化 header
121 1
        $canonicalHeader = $this->getCanonicalHeaders($signHeaders);
122
123
        // 组成标准请求串
124 1
        $canonicalRequest = "POST\n{$canonicalURI}\n{$canonicalQueryString}\n{$canonicalHeader}";
125
126
        // 使用 signKey 和标准请求串完成签名
127 1
        $signature = hash_hmac('sha256', $canonicalRequest, $signingKey);
128
129
        // 组成最终签名串
130 1
        return "{$authString}/{$signedHeaders}/{$signature}";
131
    }
132
133 1
    /**
134
     * 生成标准化 http 请求头串.
135
     *
136 1
     * @param array $headers
137
     *
138
     * @return string
139 1
     */
140
    protected function getCanonicalHeaders(array $headers)
141
    {
142
        $headerStrings = [];
143
        foreach ($headers as $name => $value) {
144
            //trim后再encode,之后使用':'号连接起来
145
            $headerStrings[] = rawurlencode(strtolower(trim($name))).':'.rawurlencode(trim($value));
146
        }
147
148
        sort($headerStrings);
149 1
150
        return implode("\n", $headerStrings);
151 1
    }
152 1
153
    /**
154 1
     * 根据 指定的 keys 过滤应该参与签名的 header.
155 1
     *
156
     * @param array $headers
157 1
     * @param array $keys
158
     *
159 1
     * @return array
160
     */
161
    protected function getHeadersToSign(array $headers, array $keys)
162
    {
163
        return array_intersect_key($headers, array_flip($keys));
164
    }
165
}
166