Issues (37)

src/EndPoint/Token/TokenEndPoint.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Parroauth2\Client\EndPoint\Token;
4
5
use Http\Client\Exception;
6
use Parroauth2\Client\Client;
7
use Parroauth2\Client\ClientInterface;
8
use Parroauth2\Client\EndPoint\CallableEndPointInterface;
9
use Parroauth2\Client\EndPoint\EndPointInterface;
10
use Parroauth2\Client\EndPoint\EndPointParametersTrait;
11
use Parroauth2\Client\EndPoint\EndPointResponseListenerTrait;
12
use Parroauth2\Client\EndPoint\EndPointTransformerInterface;
13
use Parroauth2\Client\Exception\Parroauth2Exception;
14
15
/**
16
 * Endpoint for generates an access token
17
 *
18
 * @see https://tools.ietf.org/html/rfc6749#section-5.1
19
 *
20
 * @implements CallableEndPointInterface<TokenResponse>
21
 */
22
class TokenEndPoint implements CallableEndPointInterface
23
{
24
    use EndPointParametersTrait;
25
    /** @use EndPointResponseListenerTrait<TokenResponse> */
26
    use EndPointResponseListenerTrait;
27
28
    public const NAME = 'token';
29
30
    public const GRANT_TYPE_CODE = 'authorization_code';
31
    public const GRANT_TYPE_PASSWORD = 'password';
32
    public const GRANT_TYPE_REFRESH = 'refresh_token';
33
34
    /**
35
     * @var ClientInterface
36
     * @readonly
37
     */
38
    private $client;
39
40
    /**
41
     * @var callable(array):TokenResponse
42
     * @readonly
43
     */
44
    private $responseFactory;
45
46
47
    /**
48
     * TokenEndPoint constructor.
49
     *
50
     * @param ClientInterface $client
51
     * @param callable(array):TokenResponse $responseFactory
52
     */
53 143
    public function __construct(ClientInterface $client, callable $responseFactory = null)
54
    {
55 143
        $this->client = $client;
56
        $this->responseFactory = $responseFactory ?: function (array $response): TokenResponse {
57 8
            return new TokenResponse($response);
58 27
        };
59 143
    }
60
61
    /**
62
     * {@inheritdoc}
63
     *
64
     * @psalm-mutation-free
65
     */
66 143
    public function name(): string
67
    {
68 143
        return self::NAME;
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     */
74 11
    public function apply(EndPointTransformerInterface $transformer): TokenEndPoint
75
    {
76 11
        return $transformer->onToken($this);
77
    }
78
79
    /**
80
     * Configure a grant type authorization_code token request
81
     *
82
     * @param string $authorizationCode The received authorization code
83
     * @param string|null $redirectUri The redirect uri given to the authorization request
84
     *
85
     * @return static
86
     *
87
     * @see https://tools.ietf.org/html/rfc6749#section-4.1.3
88
     */
89 22
    public function code(string $authorizationCode, ?string $redirectUri = null): TokenEndPoint
90
    {
91 22
        $endpoint = clone $this;
92
93 22
        $endpoint->parameters['grant_type'] = self::GRANT_TYPE_CODE;
94 22
        $endpoint->parameters['code'] = $authorizationCode;
95 22
        $endpoint->parameters['client_id'] = $this->client->clientId();
96
97 22
        if ($redirectUri) {
98 5
            $endpoint->parameters['redirect_uri'] = $redirectUri;
99
        }
100
101 22
        return $endpoint;
102
    }
103
104
    /**
105
     * Configure a grant type password token request
106
     *
107
     * @param string $username The resource owner username
108
     * @param string $password The resource owner password
109
     * @param list<string>|null $scopes List of scopes to grant
0 ignored issues
show
The type Parroauth2\Client\EndPoint\Token\list was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
110
     *
111
     * @return static
112
     *
113
     * @see https://tools.ietf.org/html/rfc6749#section-4.3.2
114
     *
115
     * @psalm-mutation-free
116
     */
117 9
    public function password(string $username, string $password, ?array $scopes = null): TokenEndPoint
118
    {
119 9
        $endpoint = clone $this;
120
121 9
        $endpoint->parameters['grant_type'] = self::GRANT_TYPE_PASSWORD;
122 9
        $endpoint->parameters['username'] = $username;
123 9
        $endpoint->parameters['password'] = $password;
124
125 9
        if ($scopes) {
126 6
            $endpoint->parameters['scope'] = implode(' ', $scopes);
127
        }
128
129 9
        return $endpoint;
130
    }
131
132
    /**
133
     * Configure the refresh token request
134
     *
135
     * @param string $token The refresh token
136
     * @param list<string>|null $scopes List of scopes to grant
137
     *
138
     * @return static
139
     *
140
     * @see https://tools.ietf.org/html/rfc6749#section-6
141
     *
142
     * @psalm-mutation-free
143
     */
144 3
    public function refresh(string $token, ?array $scopes = null): TokenEndPoint
145
    {
146 3
        $endpoint = clone $this;
147
148 3
        $endpoint->parameters['grant_type'] = self::GRANT_TYPE_REFRESH;
149 3
        $endpoint->parameters['refresh_token'] = $token;
150
151 3
        if ($scopes) {
152 1
            $endpoint->parameters['scope'] = implode(' ', $scopes);
153
        }
154
155 3
        return $endpoint;
156
    }
157
158
    /**
159
     * {@inheritdoc}
160
     */
161 32
    public function call(): TokenResponse
162
    {
163 32
        $request = $this->client->endPoints()
164 32
            ->request('POST', $this)
165 32
            ->withHeader(
166 32
                'Authorization',
167 32
                'Basic ' . base64_encode($this->client->clientId() . ':' . $this->client->secret())
168
            )
169
        ;
170
171 32
        $body = (string) $this->client->provider()->sendRequest($request)->getBody();
172 32
        $response = ($this->responseFactory)(json_decode($body, true));
173
174 32
        $this->callResponseListeners($response);
175
176 31
        return $response;
177
    }
178
179
    /**
180
     * Change the token response factory
181
     * Factory prototype : function (array $body): TokenResponse
182
     *
183
     * @param callable(array):TokenResponse $factory
184
     *
185
     * @return static
186
     *
187
     * @psalm-mutation-free
188
     */
189 1
    public function responseFactory(callable $factory): TokenEndPoint
190
    {
191 1
        $endpoint = clone $this;
192 1
        $endpoint->responseFactory = $factory;
193
194 1
        return $endpoint;
195
    }
196
}
197