Completed
Push — master ( 4d17b1...c45d49 )
by Romain
01:38
created

Spotify::getBaseAuthorizationUrl()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
c 0
b 0
f 0
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Kerox\OAuth2\Client\Provider;
6
7
use Kerox\OAuth2\Client\Provider\Exception\SpotifyIdentityProviderException;
8
use League\OAuth2\Client\Provider\AbstractProvider;
9
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
10
use League\OAuth2\Client\Provider\ResourceOwnerInterface;
11
use League\OAuth2\Client\Token\AccessToken;
12
use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
13
use Psr\Http\Message\ResponseInterface;
14
15
class Spotify extends AbstractProvider
16
{
17
    use BearerAuthorizationTrait;
18
19
    public const BASE_SPOTIFY_URL = 'https://accounts.spotify.com/';
20
    public const RESPONSE_TYPE = 'code';
21
22
    // Available scopes.
23
    public const SCOPE_APP_REMOTE_CONTROL = 'app-remote-control';
24
    public const SCOPE_PLAYLIST_MODIFY_PRIVATE = 'playlist-modify-private';
25
    public const SCOPE_PLAYLIST_MODIFY_PUBLIC = 'playlist-modify-public';
26
    public const SCOPE_PLAYLIST_READ_COLLABORATIVE = 'playlist-read-collaborative';
27
    public const SCOPE_PLAYLIST_READ_PRIVATE = 'playlist-read-private';
28
    public const SCOPE_STREAMING = 'streaming';
29
    public const SCOPE_USER_READ_PRIVATE = 'user-read-private';
30
    public const SCOPE_USER_READ_BIRTHDATE = 'user-read-birthdate';
31
    public const SCOPE_USER_READ_EMAIL = 'user-read-email';
32
    public const SCOPE_USER_TOP_READ = 'user-top-read';
33
    public const SCOPE_USER_READ_RECENTLY_PLAYED = 'user-read-recently-played';
34
    public const SCOPE_USER_LIBRARY_MODIFY = 'user-library-modify';
35
    public const SCOPE_USER_LIBRARY_READ = 'user-library-read';
36
    public const SCOPE_USER_READ_CURRENTLY_PLAYING = 'user-read-currently-playing';
37
    public const SCOPE_USER_READ_PLAYBACK_STATE = 'user-read-playback-state';
38
    public const SCOPE_USER_MODIFY_PLAYBACK_STATE = 'user-modify-playback-state';
39
    public const SCOPE_USER_FOLLOW_MODIFY = 'user-follow-modify';
40
    public const SCOPE_USER_FOLLOW_READ = 'user-follow-read';
41
42
    /**
43
     * Spotify constructor.
44
     *
45
     * @param array $options
46
     * @param array $collaborators
47
     */
48 8
    public function __construct(array $options = [], array $collaborators = [])
49
    {
50 8
        if (!isset($options['responseType']) || $options['responseType'] !== self::RESPONSE_TYPE) {
51 1
            $options['responseType'] = self::RESPONSE_TYPE;
52
        }
53
54 8
        parent::__construct($options, $collaborators);
55 8
    }
56
57
    /**
58
     * Returns the base URL for authorizing a client.
59
     *
60
     * Eg. https://oauth.service.com/authorize
61
     *
62
     * @return string
63
     */
64 2
    public function getBaseAuthorizationUrl(): string
65
    {
66 2
        return self::BASE_SPOTIFY_URL . 'authorize';
67
    }
68
69
    /**
70
     * Returns the base URL for requesting an access token.
71
     *
72
     * Eg. https://oauth.service.com/token
73
     *
74
     * @param array $params
75
     *
76
     * @return string
77
     */
78 2
    public function getBaseAccessTokenUrl(array $params): string
79
    {
80 2
        return self::BASE_SPOTIFY_URL . 'api/token';
81
    }
82
83
    /**
84
     * Returns the URL for requesting the resource owner's details.
85
     *
86
     * @param AccessToken $token
87
     *
88
     * @return string
89
     */
90 1
    public function getResourceOwnerDetailsUrl(AccessToken $token): string
91
    {
92 1
        return 'https://api.spotify.com/v1/me';
93
    }
94
95
    /**
96
     * Returns the default scopes used by this provider.
97
     *
98
     * This should only be the scopes that are required to request the details
99
     * of the resource owner, rather than all the available scopes.
100
     *
101
     * @return array
102
     */
103 2
    protected function getDefaultScopes(): array
104
    {
105 2
        return [];
106
    }
107
108
    /**
109
     * Checks a provider response for errors.
110
     *
111
     *
112
     * @param ResponseInterface $response
113
     * @param array|string      $data     Parsed response data
114
     *
115
     * @throws IdentityProviderException
116
     */
117 3
    protected function checkResponse(ResponseInterface $response, $data): void
118
    {
119 3
        if ($response->getStatusCode() >= 400) {
120 2
            $error = $data['error_description'] ?? $data['error'] ?? $response->getReasonPhrase();
121 2
            $statusCode = $response->getStatusCode();
122
123 2
            if (\is_array($data['error'])) {
124 1
                $error = $data['error']['message'];
125 1
                $statusCode = $data['error']['status'];
126
            }
127
128 2
            throw new SpotifyIdentityProviderException($error, $statusCode, $response);
0 ignored issues
show
Bug introduced by
$response of type Psr\Http\Message\ResponseInterface is incompatible with the type array|string expected by parameter $response of Kerox\OAuth2\Client\Prov...xception::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

128
            throw new SpotifyIdentityProviderException($error, $statusCode, /** @scrutinizer ignore-type */ $response);
Loading history...
129
        }
130 1
    }
131
132
    /**
133
     * Generates a resource owner object from a successful resource owner
134
     * details request.
135
     *
136
     * @param array       $response
137
     * @param AccessToken $token
138
     *
139
     * @return ResourceOwnerInterface
140
     */
141 1
    protected function createResourceOwner(array $response, AccessToken $token): ResourceOwnerInterface
142
    {
143 1
        return new SpotifyResourceOwner($response);
144
    }
145
}
146