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

FeiShuProvider::getTokenUrl()   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 0
1
<?php
2
3
namespace Overtrue\Socialite\Providers;
4
5
use Overtrue\Socialite\User;
6
use Overtrue\Socialite\AccessToken;
7
use Overtrue\Socialite\ProviderInterface;
8
use Overtrue\Socialite\AccessTokenInterface;
9
use Overtrue\Socialite\InvalidStateException;
10
use Overtrue\Socialite\AuthorizeFailedException;
11
12
/**
13
 * Class FeiShuProvider.
14
 *
15
 * @author [email protected]
16
 *
17
 * @see https://open.feishu.cn/
18
 */
19
class FeiShuProvider extends AbstractProvider implements ProviderInterface
20
{
21
    /**
22
     * 飞书接口域名.
23
     *
24
     * @var string
25
     */
26
    protected $baseUrl = 'https://open.feishu.cn';
27
28
    /**
29
     * 应用授权作用域.
30
     *
31
     * @var array
32
     */
33
    protected $scopes = ['user_info'];
34
35
    /**
36
     * 获取登录页面地址.
37
     *
38
     * {@inheritdoc}
39
     */
40
    protected function getAuthUrl($state)
41
    {
42
        return $this->buildAuthUrlFromBase($this->baseUrl.'/open-apis/authen/v1/index', $state);
43
    }
44
45
    /**
46
     * 获取授权码接口参数.
47
     *
48
     * @param string|null $state
49
     *
50
     * @return array
51
     */
52
    protected function getCodeFields($state = null)
53
    {
54
        $fields = [
55
            'redirect_uri' => $this->redirectUrl,
56
            'app_id' => $this->clientId,
57
        ];
58
59
        if ($this->usesState()) {
60
            $fields['state'] = $state;
61
        }
62
63
        return $fields;
64
    }
65
66
    /**
67
     * 获取 app_access_token 地址.
68
     *
69
     * {@inheritdoc}
70
     */
71
    protected function getTokenUrl()
72
    {
73
        return $this->baseUrl.'/open-apis/auth/v3/app_access_token/internal';
74
    }
75
76
    /**
77
     * 获取 app_access_token.
78
     *
79
     * @return \Overtrue\Socialite\AccessToken
80
     */
81 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...
82
    {
83
        $response = $this->getHttpClient()->post($this->getTokenUrl(), [
84
            'headers' => ['Content-Type' => 'application/json'],
85
            'json' => $this->getTokenFields($code),
86
        ]);
87
88
        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...
89
    }
90
91
    /**
92
     * 获取 app_access_token 接口参数.
93
     *
94
     * @return array
95
     */
96
    protected function getTokenFields($code)
97
    {
98
        return [
99
            'app_id' => $this->clientId,
100
            'app_secret' => $this->clientSecret,
101
        ];
102
    }
103
104
    /**
105
     * 格式化 token.
106
     *
107
     * @param \Psr\Http\Message\StreamInterface|array $body
108
     *
109
     * @return \Overtrue\Socialite\AccessTokenInterface
110
     */
111 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...
112
    {
113
        if (!is_array($body)) {
114
            $body = json_decode($body, true);
115
        }
116
117
        if (empty($body['app_access_token'])) {
118
            throw new AuthorizeFailedException('Authorize Failed: '.json_encode($body, JSON_UNESCAPED_UNICODE), $body);
119
        }
120
        $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...
121
122
        return new AccessToken($data);
123
    }
124
125
    /**
126
     * 获取用户信息.
127
     *
128
     * @return array|mixed
129
     */
130 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...
131
    {
132
        if (is_null($token) && $this->hasInvalidState()) {
133
            throw new InvalidStateException();
134
        }
135
136
        $token = $token ?: $this->getAccessToken();
137
138
        $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...
139
        $user = $this->mapUserToObject($user)->merge(['original' => $user]);
140
141
        return $user->setToken($token)->setProviderName($this->getName());
142
    }
143
144
    /**
145
     * 通过 token 获取用户信息.
146
     *
147
     * @return array|mixed
148
     */
149
    protected function getUserByToken(AccessTokenInterface $token)
150
    {
151
        $userUrl = $this->baseUrl.'/open-apis/authen/v1/access_token';
152
153
        $response = $this->getHttpClient()->post(
154
            $userUrl,
155
            [
156
                'json' => [
157
                    'app_access_token' => $token->getToken(),
158
                    'code' => $this->getCode(),
159
                    'grant_type' => 'authorization_code',
160
                ],
161
            ]
162
        );
163
164
        $result = json_decode($response->getBody(), true);
165
166
        return $result['data'] ?? '';
167
    }
168
169
    /**
170
     * 格式化用户信息.
171
     *
172
     * @return User
173
     */
174
    protected function mapUserToObject(array $user)
175
    {
176
        return new User([
177
            'id' => $this->arrayItem($user, 'open_id'),
178
            'username' => $this->arrayItem($user, 'name'),
179
            'nickname' => $this->arrayItem($user, 'name'),
180
            'avatar' => $this->arrayItem($user, 'avatar_url'),
181
        ]);
182
    }
183
}
184