friendship ended with social-app. php is my new best friend
1<?php 2/** 3 * Class Slack 4 * 5 * @created 26.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, InvalidAccessTokenException, OAuth2Provider, UserInfo}; 17use function sprintf; 18 19/** 20 * Slack v2 OAuth2 21 * 22 * @link https://api.slack.com/authentication/oauth-v2 23 * @link https://api.slack.com/authentication/sign-in-with-slack 24 * @link https://api.slack.com/authentication/token-types 25 */ 26class Slack extends OAuth2Provider implements CSRFToken, UserInfo{ 27 28 public const IDENTIFIER = 'SLACK'; 29 30 // bot token 31 public const SCOPE_BOT = 'bot'; 32 33 // user token 34 public const SCOPE_ADMIN = 'admin'; 35 public const SCOPE_CHAT_WRITE_BOT = 'chat:write:bot'; 36 public const SCOPE_CLIENT = 'client'; 37 public const SCOPE_DND_READ = 'dnd:read'; 38 public const SCOPE_DND_WRITE = 'dnd:write'; 39 public const SCOPE_FILES_READ = 'files:read'; 40 public const SCOPE_FILES_WRITE_USER = 'files:write:user'; 41 public const SCOPE_IDENTIFY = 'identify'; 42 public const SCOPE_IDENTITY_AVATAR = 'identity.avatar'; 43 public const SCOPE_IDENTITY_BASIC = 'identity.basic'; 44 public const SCOPE_IDENTITY_EMAIL = 'identity.email'; 45 public const SCOPE_IDENTITY_TEAM = 'identity.team'; 46 public const SCOPE_INCOMING_WEBHOOK = 'incoming-webhook'; 47 public const SCOPE_POST = 'post'; 48 public const SCOPE_READ = 'read'; 49 public const SCOPE_REMINDERS_READ = 'reminders:read'; 50 public const SCOPE_REMINDERS_WRITE = 'reminders:write'; 51 public const SCOPE_SEARCH_READ = 'search:read'; 52 public const SCOPE_STARS_READ = 'stars:read'; 53 public const SCOPE_STARS_WRITE = 'stars:write'; 54 55 // user & workspace tokens 56 public const SCOPE_CHANNELS_HISTORY = 'channels:history'; 57 public const SCOPE_CHANNELS_READ = 'channels:read'; 58 public const SCOPE_CHANNELS_WRITE = 'channels:write'; 59 public const SCOPE_CHAT_WRITE_USER = 'chat:write:user'; 60 public const SCOPE_COMMANDS = 'commands'; 61 public const SCOPE_EMOJI_READ = 'emoji:read'; 62 public const SCOPE_GROUPS_HISTORY = 'groups:history'; 63 public const SCOPE_GROUPS_READ = 'groups:read'; 64 public const SCOPE_GROUPS_WRITE = 'groups:write'; 65 public const SCOPE_IM_HISTORY = 'im:history'; 66 public const SCOPE_IM_READ = 'im:read'; 67 public const SCOPE_IM_WRITE = 'im:write'; 68 public const SCOPE_LINKS_READ = 'links:read'; 69 public const SCOPE_LINKS_WRITE = 'links:write'; 70 public const SCOPE_MPIM_HISTORY = 'mpim:history'; 71 public const SCOPE_MPIM_READ = 'mpim:read'; 72 public const SCOPE_MPIM_WRITE = 'mpim:write'; 73 public const SCOPE_PINS_READ = 'pins:read'; 74 public const SCOPE_PINS_WRITE = 'pins:write'; 75 public const SCOPE_REACTIONS_READ = 'reactions:read'; 76 public const SCOPE_REACTIONS_WRITE = 'reactions:write'; 77 public const SCOPE_TEAM_READ = 'team:read'; 78 public const SCOPE_USERGROUPS_READ = 'usergroups:read'; 79 public const SCOPE_USERGROUPS_WRITE = 'usergroups:write'; 80 public const SCOPE_USERS_PROFILE_READ = 'users.profile:read'; 81 public const SCOPE_USERS_PROFILE_WRITE = 'users.profile:write'; 82 public const SCOPE_USERS_READ = 'users:read'; 83 public const SCOPE_USERS_READ_EMAIL = 'users:read.email'; 84 public const SCOPE_USERS_WRITE = 'users:write'; 85 86 public const DEFAULT_SCOPES = [ 87 self::SCOPE_IDENTITY_AVATAR, 88 self::SCOPE_IDENTITY_BASIC, 89 self::SCOPE_IDENTITY_EMAIL, 90 self::SCOPE_IDENTITY_TEAM, 91 ]; 92 93 protected string $authorizationURL = 'https://slack.com/oauth/v2/authorize'; 94 protected string $accessTokenURL = 'https://slack.com/api/oauth.v2.access'; 95 protected string $apiURL = 'https://slack.com/api'; 96 protected string|null $userRevokeURL = 'https://slack.com/apps/manage'; 97 protected string|null $apiDocs = 'https://api.slack.com'; 98 protected string|null $applicationURL = 'https://api.slack.com/apps'; 99 100 /** 101 * HTTP/200 OK on errors? you're fired. 102 * 103 * @inheritDoc 104 * @codeCoverageIgnore 105 */ 106 public function me():AuthenticatedUser{ 107 $json = $this->getMeResponseData('/users.identity'); 108 109 if(!empty($json['ok'])){ 110 111 $userdata = [ 112 'data' => $json, 113 'avatar' => $json['user']['image_512'], 114 'displayName' => $json['user']['name'], 115 'email' => $json['user']['email'], 116 'id' => $json['user']['id'], 117 ]; 118 119 return new AuthenticatedUser($userdata); 120 } 121 122 if(isset($json['error'])){ 123 124 if($json['error'] === 'invalid_auth'){ 125 throw new InvalidAccessTokenException; 126 } 127 128 throw new ProviderException($json['error']); 129 } 130 131 throw new ProviderException(sprintf('user info error')); 132 } 133 134}