Issues (120)

src/Authorization/AuthRequest.php (4 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Facile\OpenIDClient\Authorization;
6
7
use function array_diff;
8
use function array_diff_key;
9
use function array_flip;
10
use function array_keys;
11
use function array_merge;
12
use function count;
13
use Facile\OpenIDClient\Exception\InvalidArgumentException;
14
use function implode;
15
16
/**
17
 * @psalm-type AuthRequestParams = array{client_id: string, redirect_uri: string, scope: string, response_type: string, response_mode: string, state?: string, nonce?: string, display?: string, prompt?: string, max_age?: int, ui_locales?: string, id_token_hint?: string, login_hint?: string, acr_values?: string, request?: string, code_challenge?: string, code_challenge_method?: string}
18
 */
19
final class AuthRequest implements AuthRequestInterface
20
{
21
    /**
22
     * @var array<string, mixed>
23
     * @psalm-var AuthRequestParams
24
     */
25
    private $params;
26
27
    /** @var string[] */
28
    private static $requiredKeys = [
29
        'client_id',
30
        'redirect_uri',
31
    ];
32
33
    /**
34
     * @param string $clientId
35
     * @param string $redirectUri
36
     * @param array<string, mixed> $params
37
     */
38 21
    public function __construct(
39
        string $clientId,
40
        string $redirectUri,
41
        array $params = []
42
    ) {
43
        $defaults = [
44 21
            'scope' => 'openid',
45
            'response_type' => 'code',
46
            'response_mode' => 'query',
47
        ];
48
        /** @var AuthRequestParams $merged */
49 21
        $merged = array_merge($defaults, $params);
50
51 21
        $merged['client_id'] = $clientId;
52 21
        $merged['redirect_uri'] = $redirectUri;
53
54 21
        $this->params = $merged;
0 ignored issues
show
Documentation Bug introduced by
It seems like $merged of type Facile\OpenIDClient\Auth...ation\AuthRequestParams is incompatible with the declared type array<string,mixed> of property $params.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
55 21
    }
56
57
    /**
58
     * @param array<string, mixed> $params
59
     *
60
     * @return static
61
     *
62
     * @psalm-param array{client_id: string, redirect_uri: string} $params
63
     */
64 3
    public static function fromParams(array $params): self
65
    {
66 3
        $missingKeys = array_diff(self::$requiredKeys, array_keys($params));
67 3
        if (0 !== count($missingKeys)) {
68
            throw new InvalidArgumentException(implode(', ', $missingKeys) . ' keys not provided');
69
        }
70
71 3
        return new static(
72 3
            $params['client_id'],
73 3
            $params['redirect_uri'],
74
            $params
75
        );
76
    }
77
78
    /**
79
     * OpenID Connect requests MUST contain the openid scope value.
80
     *
81
     * @return string
82
     */
83 2
    public function getScope(): string
84
    {
85 2
        return $this->params['scope'];
86
    }
87
88
    /**
89
     * OAuth 2.0 Response Type value that determines the authorization processing flow to be used,
90
     * including what parameters are returned from the endpoints used. When using the Authorization Code Flow,
91
     * this value is code.
92
     *
93
     * @return string
94
     */
95 1
    public function getResponseType(): string
96
    {
97 1
        return $this->params['response_type'];
98
    }
99
100
    /**
101
     * OAuth 2.0 Client Identifier valid at the Authorization Server.
102
     *
103
     * @return string
104
     */
105 2
    public function getClientId(): string
106
    {
107 2
        return $this->params['client_id'];
108
    }
109
110
    /**
111
     * Redirection URI to which the response will be sent.
112
     *
113
     * @return string
114
     */
115 2
    public function getRedirectUri(): string
116
    {
117 2
        return $this->params['redirect_uri'];
118
    }
119
120
    /**
121
     * Opaque value used to maintain state between the request and the callback.
122
     *
123
     * @return null|string
124
     */
125 1
    public function getState(): ?string
126
    {
127 1
        return $this->params['state'] ?? null;
128
    }
129
130
    /**
131
     * Informs the Authorization Server of the mechanism to be used for returning parameters from
132
     * the Authorization Endpoint.
133
     *
134
     * @return string|null
135
     */
136 1
    public function getResponseMode(): ?string
137
    {
138 1
        return $this->params['response_mode'] ?? null;
139
    }
140
141
    /**
142
     * String value used to associate a Client session with an ID Token, and to mitigate replay attacks.
143
     *
144
     * @return null|string
145
     */
146 1
    public function getNonce(): ?string
147
    {
148 1
        return $this->params['nonce'] ?? null;
149
    }
150
151
    /**
152
     * ASCII string value that specifies how the Authorization Server displays the authentication and consent
153
     * user interface pages to the End-User.
154
     *
155
     * The defined values are:
156
     * - page
157
     * - popup
158
     * - touch
159
     * - wrap
160
     *
161
     * @return string|null
162
     */
163 1
    public function getDisplay(): ?string
164
    {
165 1
        return $this->params['display'] ?? null;
166
    }
167
168
    /**
169
     * Case sensitive list of ASCII string values that specifies whether the Authorization Server prompts
170
     * the End-User for reauthentication and consent.
171
     *
172
     * The defined values are:
173
     * - none
174
     * - login
175
     * - consent
176
     * - select_account
177
     *
178
     * @return null|string
179
     */
180 1
    public function getPrompt(): ?string
181
    {
182 1
        return $this->params['prompt'] ?? null;
183
    }
184
185
    /**
186
     * Maximum Authentication Age. Specifies the allowable elapsed time in seconds since the last time the End-User
187
     * was actively authenticated by the OP.
188
     *
189
     * @return int|null
190
     */
191 1
    public function getMaxAge(): ?int
192
    {
193 1
        return $this->params['max_age'] ?? null;
194
    }
195
196
    /**
197
     * End-User's preferred languages and scripts for the user interface, represented as a space-separated list
198
     * of BCP47 [RFC5646] language tag values, ordered by preference.
199
     *
200
     * @return null|string
201
     */
202 1
    public function getUiLocales(): ?string
203
    {
204 1
        return $this->params['ui_locales'] ?? null;
205
    }
206
207
    /**
208
     * ID Token previously issued by the Authorization Server being passed as a hint about the End-User's current or
209
     * past authenticated session with the Client.
210
     *
211
     * @return string|null
212
     */
213 1
    public function getIdTokenHint(): ?string
214
    {
215 1
        return $this->params['id_token_hint'] ?? null;
216
    }
217
218
    /**
219
     * Hint to the Authorization Server about the login identifier the End-User might use to log in (if necessary).
220
     *
221
     * @return string|null
222
     */
223 1
    public function getLoginHint(): ?string
224
    {
225 1
        return $this->params['login_hint'] ?? null;
226
    }
227
228
    /**
229
     * Requested Authentication Context Class Reference values.
230
     *
231
     * @return null|string
232
     */
233 1
    public function getAcrValues(): ?string
234
    {
235 1
        return $this->params['acr_values'] ?? null;
236
    }
237
238 2
    public function getRequest(): ?string
239
    {
240 2
        return $this->params['request'] ?? null;
241
    }
242
243 1
    public function getCodeChallenge(): ?string
244
    {
245 1
        return $this->params['code_challenge'] ?? null;
246
    }
247
248 1
    public function getCodeChallengeMethod(): ?string
249
    {
250 1
        return $this->params['code_challenge_method'] ?? null;
251
    }
252
253
    /**
254
     * Add other params and return a new instance.
255
     *
256
     * @param array<string, mixed> $params
257
     *
258
     * @return AuthRequestInterface
259
     */
260 1
    public function withParams(array $params): AuthRequestInterface
261
    {
262 1
        $instance = clone $this;
263
        /** @var AuthRequestParams $params */
264 1
        $params = array_merge($instance->params, $params);
0 ignored issues
show
$params of type Facile\OpenIDClient\Auth...ation\AuthRequestParams is incompatible with the type array expected by parameter $arrays of array_merge(). ( Ignorable by Annotation )

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

264
        $params = array_merge($instance->params, /** @scrutinizer ignore-type */ $params);
Loading history...
265
266 1
        $instance->params = $params;
0 ignored issues
show
Documentation Bug introduced by
It seems like $params of type Facile\OpenIDClient\Auth...ation\AuthRequestParams is incompatible with the declared type array<string,mixed> of property $params.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
267
268 1
        if (0 === count(array_diff_key($instance->params, array_flip(self::$requiredKeys)))) {
0 ignored issues
show
$instance->params of type Facile\OpenIDClient\Auth...ation\AuthRequestParams is incompatible with the type array expected by parameter $array1 of array_diff_key(). ( Ignorable by Annotation )

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

268
        if (0 === count(array_diff_key(/** @scrutinizer ignore-type */ $instance->params, array_flip(self::$requiredKeys)))) {
Loading history...
269
            throw new InvalidArgumentException(implode(', ', self::$requiredKeys) . ' should be provided');
270
        }
271
272 1
        return $instance;
273
    }
274
275
    /**
276
     * Create params ready to use.
277
     *
278
     * @return array<string, mixed>
279
     */
280 2
    public function createParams(): array
281
    {
282 2
        return $this->params;
283
    }
284
285
    /**
286
     * @return array<string, mixed>
287
     */
288 1
    public function jsonSerialize(): array
289
    {
290 1
        return $this->createParams();
291
    }
292
}
293