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}