friendship ended with social-app. php is my new best friend
1<?php
2/**
3 * Class MusicBrainz
4 *
5 * @created 31.07.2018
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\{
17 AccessToken, AuthenticatedUser, CSRFToken, OAuth2Provider, TokenInvalidate, TokenInvalidateTrait, TokenRefresh, UserInfo,
18};
19use Psr\Http\Message\{ResponseInterface, StreamInterface};
20use function in_array, strtoupper;
21
22/**
23 * MusicBrainz OAuth2
24 *
25 * @link https://musicbrainz.org/doc/Development
26 * @link https://musicbrainz.org/doc/Development/OAuth2
27 */
28class MusicBrainz extends OAuth2Provider implements CSRFToken, TokenInvalidate, TokenRefresh, UserInfo{
29 use TokenInvalidateTrait;
30
31 public const IDENTIFIER = 'MUSICBRAINZ';
32
33 public const SCOPE_PROFILE = 'profile';
34 public const SCOPE_EMAIL = 'email';
35 public const SCOPE_TAG = 'tag';
36 public const SCOPE_RATING = 'rating';
37 public const SCOPE_COLLECTION = 'collection';
38 public const SCOPE_SUBMIT_ISRC = 'submit_isrc';
39 public const SCOPE_SUBMIT_BARCODE = 'submit_barcode';
40
41 public const DEFAULT_SCOPES = [
42 self::SCOPE_PROFILE,
43 self::SCOPE_EMAIL,
44 self::SCOPE_TAG,
45 self::SCOPE_RATING,
46 self::SCOPE_COLLECTION,
47 ];
48
49 protected string $authorizationURL = 'https://musicbrainz.org/oauth2/authorize';
50 protected string $accessTokenURL = 'https://musicbrainz.org/oauth2/token';
51 protected string $revokeURL = 'https://musicbrainz.org/oauth2/revoke ';
52 protected string $apiURL = 'https://musicbrainz.org/ws/2';
53 protected string|null $userRevokeURL = 'https://musicbrainz.org/account/applications';
54 protected string|null $apiDocs = 'https://musicbrainz.org/doc/Development';
55 protected string|null $applicationURL = 'https://musicbrainz.org/account/applications';
56
57 protected function getRefreshAccessTokenRequestBodyParams(string $refreshToken):array{
58 return [
59 'client_id' => $this->options->key,
60 'client_secret' => $this->options->secret,
61 'grant_type' => 'refresh_token',
62 'refresh_token' => $refreshToken,
63 ];
64 }
65
66 /**
67 * @return array<string, scalar|bool|null>
68 */
69 protected function getInvalidateAccessTokenBodyParams(AccessToken $token, string $type):array{
70 return [
71 'client_id' => $this->options->key,
72 'client_secret' => $this->options->secret,
73 'token' => $token->accessToken,
74 'token_type_hint' => $type,
75 ];
76 }
77
78 public function request(
79 string $path,
80 array|null $params = null,
81 string|null $method = null,
82 StreamInterface|array|string|null $body = null,
83 array|null $headers = null,
84 string|null $protocolVersion = null,
85 ):ResponseInterface{
86 $params = ($params ?? []);
87 $method = strtoupper(($method ?? 'GET'));
88
89 if(!isset($params['fmt'])){
90 $params['fmt'] = 'json';
91 }
92
93 if(in_array($method, ['POST', 'PUT', 'DELETE'], true) && !isset($params['client'])){
94 $params['client'] = $this::USER_AGENT; // @codeCoverageIgnore
95 }
96
97 return parent::request($path, $params, $method, $body, $headers, $protocolVersion);
98 }
99
100 /** @codeCoverageIgnore */
101 public function me():AuthenticatedUser{
102 $json = $this->getMeResponseData('https://musicbrainz.org/oauth2/userinfo', ['fmt' => 'json']);
103
104 $userdata = [
105 'data' => $json,
106 'handle' => $json['sub'],
107 'email' => $json['email'],
108 'id' => $json['metabrainz_user_id'],
109 'url' => $json['profile'],
110 ];
111
112 return new AuthenticatedUser($userdata);
113 }
114
115}