Completed
Pull Request — master (#159)
by
unknown
01:25
created

FeiShuProvider::getAuthUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the overtrue/socialite.
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\Socialite\Providers;
13
14
use Overtrue\Socialite\AccessToken;
15
use Overtrue\Socialite\AccessTokenInterface;
16
use Overtrue\Socialite\AuthorizeFailedException;
17
use Overtrue\Socialite\InvalidStateException;
18
use Overtrue\Socialite\ProviderInterface;
19
use Overtrue\Socialite\User;
20
21
/**
22
 * Class FeiShuProvider.
23
 *
24
 * @author [email protected]
25
 *
26
 * @see https://open.feishu.cn/
27
 */
28
class FeiShuProvider extends AbstractProvider implements ProviderInterface
29
{
30
    /**
31
     * 飞书接口域名.
32
     *
33
     * @var string
34
     */
35
    protected $baseUrl = 'https://open.feishu.cn';
36
37
    /**
38
     * 应用授权作用域.
39
     *
40
     * @var array
41
     */
42
    protected $scopes = ['user_info'];
43
44
    /**
45
     * 获取登录页面地址.
46
     *
47
     * {@inheritdoc}
48
     */
49
    protected function getAuthUrl($state)
50
    {
51
        return $this->buildAuthUrlFromBase($this->baseUrl.'/open-apis/authen/v1/index', $state);
52
    }
53
54
    /**
55
     * 获取授权码接口参数.
56
     *
57
     * @param string|null $state
58
     *
59
     * @return array
60
     */
61
    protected function getCodeFields($state = null)
62
    {
63
        $fields = [
64
            'redirect_uri' => $this->redirectUrl,
65
            'app_id' => $this->clientId,
66
        ];
67
68
        if ($this->usesState()) {
69
            $fields['state'] = $state;
70
        }
71
72
        return $fields;
73
    }
74
75
    /**
76
     * 获取 app_access_token 地址.
77
     *
78
     * {@inheritdoc}
79
     */
80
    protected function getTokenUrl()
81
    {
82
        return $this->baseUrl.'/open-apis/auth/v3/app_access_token/internal';
83
    }
84
85
    /**
86
     * 获取 app_access_token.
87
     *
88
     * @return \Overtrue\Socialite\AccessToken
89
     */
90 View Code Duplication
    public function getAccessToken($code = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
91
    {
92
        $response = $this->getHttpClient()->post($this->getTokenUrl(), [
93
            'headers' => ['Content-Type' => 'application/json'],
94
            'json' => $this->getTokenFields($code),
95
        ]);
96
97
        return $this->parseAccessToken($response->getBody()->getContents());
0 ignored issues
show
Documentation introduced by
$response->getBody()->getContents() is of type string, but the function expects a object<Psr\Http\Message\StreamInterface>|array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
98
    }
99
100
    /**
101
     * 获取 app_access_token 接口参数.
102
     *
103
     * @return array
104
     */
105
    protected function getTokenFields($code)
106
    {
107
        return [
108
            'app_id' => $this->clientId,
109
            'app_secret' => $this->clientSecret,
110
        ];
111
    }
112
113
    /**
114
     * 格式化 token.
115
     *
116
     * @param \Psr\Http\Message\StreamInterface|array $body
117
     *
118
     * @return \Overtrue\Socialite\AccessTokenInterface
119
     */
120 View Code Duplication
    protected function parseAccessToken($body)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
121
    {
122
        if (!is_array($body)) {
123
            $body = json_decode($body, true);
124
        }
125
126
        if (empty($body['app_access_token'])) {
127
            throw new AuthorizeFailedException('Authorize Failed: '.json_encode($body, JSON_UNESCAPED_UNICODE), $body);
128
        }
129
        $data['access_token'] = $body['app_access_token'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
130
131
        return new AccessToken($data);
132
    }
133
134
    /**
135
     * 获取用户信息.
136
     *
137
     * @return array|mixed
138
     */
139 View Code Duplication
    public function user(AccessTokenInterface $token = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
140
    {
141
        if (is_null($token) && $this->hasInvalidState()) {
142
            throw new InvalidStateException();
143
        }
144
145
        $token = $token ?: $this->getAccessToken();
146
147
        $user = $this->getUserByToken($token, $this->getCode());
0 ignored issues
show
Unused Code introduced by
The call to FeiShuProvider::getUserByToken() has too many arguments starting with $this->getCode().

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
148
        $user = $this->mapUserToObject($user)->merge(['original' => $user]);
149
150
        return $user->setToken($token)->setProviderName($this->getName());
151
    }
152
153
    /**
154
     * 通过 token 获取用户信息.
155
     *
156
     * @return array|mixed
157
     */
158
    protected function getUserByToken(AccessTokenInterface $token)
159
    {
160
        $userUrl = $this->baseUrl.'/open-apis/authen/v1/access_token';
161
162
        $response = $this->getHttpClient()->post(
163
            $userUrl,
164
            [
165
                'json' => [
166
                    'app_access_token' => $token->getToken(),
167
                    'code' => $this->getCode(),
168
                    'grant_type' => 'authorization_code',
169
                ],
170
            ]
171
        );
172
173
        $result = json_decode($response->getBody(), true);
174
175
        return $result['data'] ?? '';
176
    }
177
178
    /**
179
     * 格式化用户信息.
180
     *
181
     * @return User
182
     */
183
    protected function mapUserToObject(array $user)
184
    {
185
        return new User([
186
            'id' => $this->arrayItem($user, 'open_id'),
187
            'username' => $this->arrayItem($user, 'name'),
188
            'nickname' => $this->arrayItem($user, 'name'),
189
            'avatar' => $this->arrayItem($user, 'avatar_url'),
190
        ]);
191
    }
192
}
193