Commit | Line | Data |
---|---|---|
320f4a6d | 1 | <?php |
a9229942 | 2 | |
320f4a6d | 3 | namespace wcf\action; |
a9229942 | 4 | |
8b2a995f | 5 | use GuzzleHttp\Psr7\Request; |
85176ea5 | 6 | use Psr\Http\Client\ClientExceptionInterface; |
f41cd47c | 7 | use Psr\Http\Message\ResponseInterface; |
320f4a6d | 8 | use wcf\data\user\User; |
320f4a6d | 9 | use wcf\system\request\LinkHandler; |
8b2a995f | 10 | use wcf\system\user\authentication\oauth\User as OauthUser; |
320f4a6d MW |
11 | use wcf\util\JSON; |
12 | use wcf\util\StringUtil; | |
13 | ||
14 | /** | |
8b2a995f | 15 | * Performs authentication against GitHub.com |
a9229942 TD |
16 | * |
17 | * @author Tim Duesterhus | |
18 | * @copyright 2001-2021 WoltLab GmbH | |
19 | * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php> | |
320f4a6d | 20 | */ |
34de730b | 21 | final class GithubAuthAction extends AbstractOauth2AuthAction |
a9229942 | 22 | { |
34de730b | 23 | #[\Override] |
a9229942 TD |
24 | protected function getTokenEndpoint(): string |
25 | { | |
26 | return 'https://github.com/login/oauth/access_token'; | |
27 | } | |
28 | ||
34de730b C |
29 | #[\Override] |
30 | public function isEnabled(): bool | |
31 | { | |
32 | return !empty(GITHUB_PUBLIC_KEY) && !empty(GITHUB_PRIVATE_KEY); | |
33 | } | |
34 | ||
35 | #[\Override] | |
a9229942 TD |
36 | protected function getClientId(): string |
37 | { | |
38 | return StringUtil::trim(GITHUB_PUBLIC_KEY); | |
39 | } | |
40 | ||
34de730b | 41 | #[\Override] |
a9229942 TD |
42 | protected function getClientSecret(): string |
43 | { | |
44 | return StringUtil::trim(GITHUB_PRIVATE_KEY); | |
45 | } | |
46 | ||
34de730b | 47 | #[\Override] |
a9229942 TD |
48 | protected function getScope(): string |
49 | { | |
50 | return 'user:email'; | |
51 | } | |
52 | ||
34de730b | 53 | #[\Override] |
a9229942 TD |
54 | protected function getAuthorizeUrl(): string |
55 | { | |
56 | return 'https://github.com/login/oauth/authorize'; | |
57 | } | |
58 | ||
34de730b | 59 | #[\Override] |
a9229942 TD |
60 | protected function getCallbackUrl(): string |
61 | { | |
62 | return LinkHandler::getInstance()->getControllerLink(self::class); | |
63 | } | |
64 | ||
34de730b | 65 | #[\Override] |
a9229942 TD |
66 | protected function supportsState(): bool |
67 | { | |
68 | return true; | |
69 | } | |
70 | ||
34de730b | 71 | #[\Override] |
a9229942 TD |
72 | protected function getUser(array $accessToken): OauthUser |
73 | { | |
74 | $request = new Request('GET', 'https://api.github.com/user', [ | |
75 | 'accept' => 'application/json', | |
76 | 'authorization' => \sprintf('Bearer %s', $accessToken['access_token']), | |
77 | ]); | |
78 | $response = $this->getHttpClient()->send($request); | |
79 | $parsed = JSON::decode((string)$response->getBody()); | |
80 | ||
81 | $parsed['__id'] = $parsed['id']; | |
82 | $parsed['__username'] = $parsed['login']; | |
83 | $parsed['accessToken'] = $accessToken; | |
84 | ||
85 | return new OauthUser($parsed); | |
86 | } | |
87 | ||
34de730b C |
88 | #[\Override] |
89 | protected function getInternalUser(OauthUser $oauthUser): User | |
a9229942 | 90 | { |
34de730b C |
91 | return User::getUserByAuthData('github:' . $oauthUser->getId()); |
92 | } | |
a9229942 | 93 | |
34de730b C |
94 | #[\Override] |
95 | protected function getProviderName(): string | |
96 | { | |
97 | return 'github'; | |
98 | } | |
a9229942 | 99 | |
34de730b | 100 | #[\Override] |
359c5313 | 101 | protected function redirectToRegistration(OauthUser $oauthUser): ResponseInterface |
34de730b C |
102 | { |
103 | try { | |
104 | $request = new Request('GET', 'https://api.github.com/user/emails', [ | |
105 | 'accept' => 'application/json', | |
106 | 'authorization' => \sprintf('Bearer %s', $oauthUser["accessToken"]["access_token"]), | |
107 | ]); | |
108 | $response = $this->getHttpClient()->send($request); | |
109 | $emails = JSON::decode((string)$response->getBody()); | |
110 | ||
111 | // search primary email | |
112 | $email = $emails[0]['email']; | |
113 | foreach ($emails as $tmp) { | |
114 | if ($tmp['primary']) { | |
115 | $email = $tmp['email']; | |
116 | break; | |
117 | } | |
a9229942 | 118 | } |
34de730b C |
119 | $oauthUser["__email"] = $email; |
120 | } catch (ClientExceptionInterface $e) { | |
a9229942 | 121 | } |
34de730b | 122 | |
359c5313 | 123 | return parent::redirectToRegistration($oauthUser); |
a9229942 | 124 | } |
320f4a6d | 125 | } |