first commit
This commit is contained in:
253
vendor/overtrue/socialite/src/Providers/OpenWeWork.php
vendored
Normal file
253
vendor/overtrue/socialite/src/Providers/OpenWeWork.php
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
<?php
|
||||
|
||||
namespace Overtrue\Socialite\Providers;
|
||||
|
||||
use GuzzleHttp\Exception\GuzzleException;
|
||||
use JetBrains\PhpStorm\Pure;
|
||||
use Overtrue\Socialite\Contracts;
|
||||
use Overtrue\Socialite\Exceptions;
|
||||
use Overtrue\Socialite\Exceptions\AuthorizeFailedException;
|
||||
use Overtrue\Socialite\User;
|
||||
|
||||
/**
|
||||
* @link https://open.work.weixin.qq.com/api/doc/90001/90143/91120
|
||||
*/
|
||||
class OpenWeWork extends Base
|
||||
{
|
||||
public const NAME = 'open-wework';
|
||||
|
||||
protected bool $detailed = false;
|
||||
|
||||
protected bool $asQrcode = false;
|
||||
|
||||
protected string $userType = 'member';
|
||||
|
||||
protected string $lang = 'zh';
|
||||
|
||||
protected ?string $suiteTicket = null;
|
||||
|
||||
protected ?int $agentId = null;
|
||||
|
||||
protected ?string $suiteAccessToken = null;
|
||||
|
||||
protected string $baseUrl = 'https://qyapi.weixin.qq.com';
|
||||
|
||||
public function __construct(array $config)
|
||||
{
|
||||
parent::__construct($config);
|
||||
|
||||
if ($this->getConfig()->has('base_url')) {
|
||||
$this->baseUrl = $this->getConfig()->get('base_url');
|
||||
}
|
||||
}
|
||||
|
||||
public function withAgentId(int $agentId): self
|
||||
{
|
||||
$this->agentId = $agentId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function detailed(): self
|
||||
{
|
||||
$this->detailed = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function asQrcode(): self
|
||||
{
|
||||
$this->asQrcode = true;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withUserType(string $userType): self
|
||||
{
|
||||
$this->userType = $userType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withLang(string $lang): self
|
||||
{
|
||||
$this->lang = $lang;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws GuzzleException
|
||||
* @throws AuthorizeFailedException
|
||||
*/
|
||||
public function userFromCode(string $code): Contracts\UserInterface
|
||||
{
|
||||
$user = $this->getUser($this->getSuiteAccessToken(), $code);
|
||||
|
||||
if ($this->detailed) {
|
||||
$user = \array_merge($user, $this->getUserByTicket($user['user_ticket']));
|
||||
}
|
||||
|
||||
return $this->mapUserToObject($user)->setProvider($this)->setRaw($user);
|
||||
}
|
||||
|
||||
public function withSuiteTicket(string $suiteTicket): self
|
||||
{
|
||||
$this->suiteTicket = $suiteTicket;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function withSuiteAccessToken(string $suiteAccessToken): self
|
||||
{
|
||||
$this->suiteAccessToken = $suiteAccessToken;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\InvalidArgumentException
|
||||
*/
|
||||
public function getAuthUrl(): string
|
||||
{
|
||||
$queries = \array_filter([
|
||||
'appid' => $this->getClientId(),
|
||||
Contracts\RFC6749_ABNF_REDIRECT_URI => $this->redirectUrl,
|
||||
Contracts\RFC6749_ABNF_RESPONSE_TYPE => Contracts\RFC6749_ABNF_CODE,
|
||||
Contracts\RFC6749_ABNF_SCOPE => $this->formatScopes($this->scopes, $this->scopeSeparator),
|
||||
Contracts\RFC6749_ABNF_STATE => $this->state,
|
||||
'agentid' => $this->agentId,
|
||||
]);
|
||||
|
||||
if ($this->asQrcode) {
|
||||
$queries = array_filter([
|
||||
'appid' => $queries['appid'] ?? $this->getClientId(),
|
||||
'redirect_uri' => $queries['redirect_uri'] ?? $this->redirectUrl,
|
||||
'usertype' => $this->userType,
|
||||
'lang' => $this->lang,
|
||||
'state' => $this->state,
|
||||
]);
|
||||
|
||||
return \sprintf('https://open.work.weixin.qq.com/wwopen/sso/3rd_qrConnect?%s', http_build_query($queries));
|
||||
}
|
||||
|
||||
return \sprintf('https://open.weixin.qq.com/connect/oauth2/authorize?%s#wechat_redirect', \http_build_query($queries));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\MethodDoesNotSupportException
|
||||
*/
|
||||
protected function getUserByToken(string $token): array
|
||||
{
|
||||
throw new Exceptions\MethodDoesNotSupportException('Open WeWork doesn\'t support access_token mode');
|
||||
}
|
||||
|
||||
protected function getSuiteAccessToken(): string
|
||||
{
|
||||
return $this->suiteAccessToken ?? $this->suiteAccessToken = $this->requestSuiteAccessToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\AuthorizeFailedException|GuzzleException
|
||||
*/
|
||||
protected function getUser(string $token, string $code): array
|
||||
{
|
||||
$responseInstance = $this->getHttpClient()->get(
|
||||
$this->baseUrl.'/cgi-bin/service/getuserinfo3rd',
|
||||
[
|
||||
'query' => \array_filter(
|
||||
[
|
||||
'suite_access_token' => $token,
|
||||
Contracts\RFC6749_ABNF_CODE => $code,
|
||||
]
|
||||
),
|
||||
]
|
||||
);
|
||||
|
||||
$response = $this->fromJsonBody($responseInstance);
|
||||
|
||||
if (($response['errcode'] ?? 1) > 0 || (empty($response['UserId']) && empty($response['openid']))) {
|
||||
throw new Exceptions\AuthorizeFailedException((string) $responseInstance->getBody(), $response);
|
||||
} elseif (empty($response['user_ticket'])) {
|
||||
$this->detailed = false;
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\AuthorizeFailedException
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
protected function getUserByTicket(string $userTicket): array
|
||||
{
|
||||
$responseInstance = $this->getHttpClient()->post(
|
||||
$this->baseUrl.'/cgi-bin/service/auth/getuserdetail3rd',
|
||||
[
|
||||
'query' => [
|
||||
'suite_access_token' => $this->getSuiteAccessToken(),
|
||||
],
|
||||
'json' => [
|
||||
'user_ticket' => $userTicket,
|
||||
],
|
||||
],
|
||||
);
|
||||
|
||||
$response = $this->fromJsonBody($responseInstance);
|
||||
|
||||
if (($response['errcode'] ?? 1) > 0 || empty($response['userid'])) {
|
||||
throw new Exceptions\AuthorizeFailedException((string) $responseInstance->getBody(), $response);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
#[Pure]
|
||||
protected function mapUserToObject(array $user): Contracts\UserInterface
|
||||
{
|
||||
return new User($this->detailed ? [
|
||||
Contracts\ABNF_ID => $user['userid'] ?? $user['UserId'] ?? null,
|
||||
Contracts\ABNF_NAME => $user[Contracts\ABNF_NAME] ?? null,
|
||||
Contracts\ABNF_AVATAR => $user[Contracts\ABNF_AVATAR] ?? null,
|
||||
'gender' => $user['gender'] ?? null,
|
||||
'corpid' => $user['corpid'] ?? $user['CorpId'] ?? null,
|
||||
'open_userid' => $user['open_userid'] ?? null,
|
||||
'qr_code' => $user['qr_code'] ?? null,
|
||||
] : [
|
||||
Contracts\ABNF_ID => $user['userid'] ?? $user['UserId'] ?? $user['OpenId'] ?? $user['openid'] ?? null,
|
||||
'corpid' => $user['CorpId'] ?? null,
|
||||
'open_userid' => $user['open_userid'] ?? null,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exceptions\AuthorizeFailedException
|
||||
* @throws GuzzleException
|
||||
*/
|
||||
protected function requestSuiteAccessToken(): string
|
||||
{
|
||||
$responseInstance = $this->getHttpClient()->post(
|
||||
$this->baseUrl.'/cgi-bin/service/get_suite_token',
|
||||
[
|
||||
'json' => [
|
||||
'suite_id' => $this->config->get('suite_id') ?? $this->config->get('client_id'),
|
||||
'suite_secret' => $this->config->get('suite_secret') ?? $this->config->get('client_secret'),
|
||||
'suite_ticket' => $this->suiteTicket,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$response = $this->fromJsonBody($responseInstance);
|
||||
|
||||
if (isset($response['errcode']) && $response['errcode'] > 0) {
|
||||
throw new Exceptions\AuthorizeFailedException((string) $responseInstance->getBody(), $response);
|
||||
}
|
||||
|
||||
return $response['suite_access_token'];
|
||||
}
|
||||
|
||||
protected function getTokenUrl(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user