friendship ended with social-app. php is my new best friend
1<?php 2/** 3 * Class GuildWars2 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\HTTP\Utils\{MessageUtil, QueryUtil}; 17use chillerlan\OAuth\Core\{AccessToken, AuthenticatedUser, OAuth2Provider, UserInfo}; 18use Psr\Http\Message\UriInterface; 19use function implode, preg_match, str_starts_with, substr; 20 21/** 22 * Guild Wars 2 23 * 24 * Note: GW2 does not support authentication (anymore) but the API still works like a regular OAUth API, so... 25 * 26 * @link https://api.guildwars2.com/v2 27 * @link https://wiki.guildwars2.com/wiki/API:Main 28 */ 29class GuildWars2 extends OAuth2Provider implements UserInfo{ 30 31 public const IDENTIFIER = 'GUILDWARS2'; 32 33 public const SCOPE_ACCOUNT = 'account'; 34 public const SCOPE_INVENTORIES = 'inventories'; 35 public const SCOPE_CHARACTERS = 'characters'; 36 public const SCOPE_TRADINGPOST = 'tradingpost'; 37 public const SCOPE_WALLET = 'wallet'; 38 public const SCOPE_UNLOCKS = 'unlocks'; 39 public const SCOPE_PVP = 'pvp'; 40 public const SCOPE_BUILDS = 'builds'; 41 public const SCOPE_PROGRESSION = 'progression'; 42 public const SCOPE_GUILDS = 'guilds'; 43 44 protected string $authorizationURL = 'https://api.guildwars2.com/v2/tokeninfo'; 45 protected string $apiURL = 'https://api.guildwars2.com'; 46 protected string|null $userRevokeURL = 'https://account.arena.net/applications'; 47 protected string|null $apiDocs = 'https://wiki.guildwars2.com/wiki/API:Main'; 48 protected string|null $applicationURL = 'https://account.arena.net/applications'; 49 50 /** 51 * @throws \chillerlan\OAuth\Providers\ProviderException 52 */ 53 public function storeGW2Token(string $access_token):AccessToken{ 54 55 if(!preg_match('/^[a-f\d\-]{72}$/i', $access_token)){ 56 throw new ProviderException('invalid token'); 57 } 58 59 // to verify the token we need to send a request without authentication 60 $request = $this->requestFactory 61 ->createRequest('GET', QueryUtil::merge($this->authorizationURL, ['access_token' => $access_token])) 62 ; 63 64 $tokeninfo = MessageUtil::decodeJSON($this->http->sendRequest($request)); 65 66 if(isset($tokeninfo->id) && str_starts_with($access_token, $tokeninfo->id)){ 67 $token = $this->createAccessToken(); 68 $token->accessToken = $access_token; 69 $token->accessTokenSecret = substr($access_token, 36, 36); // the actual token 70 $token->expires = AccessToken::NEVER_EXPIRES; 71 $token->extraParams = [ 72 'token_type' => 'Bearer', 73 'id' => $tokeninfo->id, 74 'name' => $tokeninfo->name, 75 'scope' => implode($this::SCOPES_DELIMITER, $tokeninfo->permissions), 76 ]; 77 78 $this->storage->storeAccessToken($token, $this->name); 79 80 return $token; 81 } 82 83 throw new ProviderException('unverified token'); // @codeCoverageIgnore 84 } 85 86 /** 87 * @throws \chillerlan\OAuth\Providers\ProviderException 88 */ 89 public function getAuthorizationURL(array|null $params = null, array|null $scopes = null):UriInterface{ 90 throw new ProviderException('GuildWars2 does not support authentication anymore.'); 91 } 92 93 /** 94 * @throws \chillerlan\OAuth\Providers\ProviderException 95 */ 96 public function getAccessToken(string $code, string|null $state = null):AccessToken{ 97 throw new ProviderException('GuildWars2 does not support authentication anymore.'); 98 } 99 100 /** @codeCoverageIgnore */ 101 public function me():AuthenticatedUser{ 102 $json = $this->getMeResponseData('/v2/tokeninfo'); 103 104 $userdata = [ 105 'data' => $json, 106 'handle' => $json['name'], 107 'id' => $json['id'], 108 ]; 109 110 return new AuthenticatedUser($userdata); 111 } 112 113}