friendship ended with social-app. php is my new best friend
1<?php
2/**
3 * Class GitHub
4 *
5 * @created 22.10.2017
6 * @author Smiley <smiley@chillerlan.net>
7 * @copyright 2017 Smiley
8 * @license MIT
9 *
10 * @noinspection PhpUnused
11 */
12declare(strict_types=1);
13
14namespace chillerlan\OAuth\Providers;
15
16use chillerlan\OAuth\Core\{AuthenticatedUser, CSRFToken, OAuth2Provider, TokenRefresh, UserInfo};
17
18/**
19 * GitHub OAuth2
20 *
21 * @link https://docs.github.com/en/apps/oauth-apps/building-oauth-apps
22 * @link https://docs.github.com/rest
23 * @link https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/refreshing-user-access-tokens
24 */
25class GitHub extends OAuth2Provider implements CSRFToken, TokenRefresh, UserInfo{
26
27 public const IDENTIFIER = 'GITHUB';
28
29 // GitHub accepts both, comma and space, but the normalized scopes in the token response are only comma separated
30 public const SCOPES_DELIMITER = ',';
31
32 // @link https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps#available-scopes
33 public const SCOPE_CODESPACE = 'codespace';
34 public const SCOPE_GIST = 'gist';
35 public const SCOPE_GPG_KEY_ADMIN = 'admin:gpg_key';
36 public const SCOPE_GPG_KEY_READ = 'read:gpg_key';
37 public const SCOPE_GPG_KEY_WRITE = 'write:gpg_key';
38 public const SCOPE_NOTIFICATIONS = 'notifications';
39 public const SCOPE_ORG_ADMIN = 'admin:org';
40 public const SCOPE_ORG_HOOK_ADMIN = 'admin:org_hook';
41 public const SCOPE_ORG_READ = 'read:org';
42 public const SCOPE_ORG_WRITE = 'write:org';
43 public const SCOPE_PACKAGES_DELETE = 'delete:packages';
44 public const SCOPE_PACKAGES_READ = 'read:packages';
45 public const SCOPE_PACKAGES_WRITE = 'write:packages';
46 public const SCOPE_PROJECT = 'project';
47 public const SCOPE_PROJECT_READ = 'read:project';
48 public const SCOPE_PUBLIC_KEY_ADMIN = 'admin:public_key';
49 public const SCOPE_PUBLIC_KEY_READ = 'read:public_key';
50 public const SCOPE_PUBLIC_KEY_WRITE = 'write:public_key';
51 public const SCOPE_PUBLIC_REPO = 'public_repo';
52 public const SCOPE_REPO = 'repo';
53 public const SCOPE_REPO_DELETE = 'delete_repo';
54 public const SCOPE_REPO_DEPLOYMENT = 'repo_deployment';
55 public const SCOPE_REPO_HOOK_ADMIN = 'admin:repo_hook';
56 public const SCOPE_REPO_HOOK_READ = 'read:repo_hook';
57 public const SCOPE_REPO_HOOK_WRITE = 'write:repo_hook';
58 public const SCOPE_REPO_INVITE = 'repo:invite';
59 public const SCOPE_REPO_STATUS = 'repo:status';
60 public const SCOPE_SECURITY_EVENTS = 'security_events';
61 public const SCOPE_USER = 'user';
62 public const SCOPE_USER_EMAIL = 'user:email';
63 public const SCOPE_USER_FOLLOW = 'user:follow';
64 public const SCOPE_USER_READ = 'read:user';
65 public const SCOPE_WORKFLOW = 'workflow';
66
67 public const DEFAULT_SCOPES = [
68 self::SCOPE_USER,
69 self::SCOPE_PUBLIC_REPO,
70 self::SCOPE_GIST,
71 ];
72
73 public const HEADERS_AUTH = [
74 'Accept' => 'application/json',
75 ];
76
77 public const HEADERS_API = [
78 'Accept' => 'application/vnd.github+json',
79 'X-GitHub-Api-Version' => '2022-11-28',
80 ];
81
82 protected string $authorizationURL = 'https://github.com/login/oauth/authorize';
83 protected string $accessTokenURL = 'https://github.com/login/oauth/access_token';
84 protected string $apiURL = 'https://api.github.com';
85 protected string|null $userRevokeURL = 'https://github.com/settings/applications';
86 protected string|null $apiDocs = 'https://docs.github.com/rest';
87 protected string|null $applicationURL = 'https://github.com/settings/developers';
88
89 /** @codeCoverageIgnore */
90 public function me():AuthenticatedUser{
91 $json = $this->getMeResponseData('/user');
92
93 $userdata = [
94 'data' => $json,
95 'avatar' => $json['avatar_url'],
96 'handle' => $json['login'],
97 'displayName' => $json['name'],
98 'email' => $json['email'],
99 'id' => $json['id'],
100 'url' => $json['html_url'],
101 ];
102
103 return new AuthenticatedUser($userdata);
104 }
105
106}