1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Parroauth2\Client\EndPoint; |
4
|
|
|
|
5
|
|
|
use InvalidArgumentException; |
6
|
|
|
use Parroauth2\Client\EndPoint\Authorization\AuthorizationEndPoint; |
7
|
|
|
use Parroauth2\Client\EndPoint\Introspection\IntrospectionEndPoint; |
8
|
|
|
use Parroauth2\Client\EndPoint\Token\RevocationEndPoint; |
9
|
|
|
use Parroauth2\Client\EndPoint\Token\TokenEndPoint; |
10
|
|
|
use Parroauth2\Client\Exception\UnsupportedServerOperation; |
11
|
|
|
use Parroauth2\Client\OpenID\EndPoint\EndSessionEndPoint; |
12
|
|
|
use Parroauth2\Client\OpenID\EndPoint\Userinfo\UserinfoEndPoint; |
13
|
|
|
use Parroauth2\Client\Provider\Provider; |
14
|
|
|
use Parroauth2\Client\Provider\ProviderInterface; |
15
|
|
|
use Psr\Http\Message\RequestInterface; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Store endpoints |
19
|
|
|
*/ |
20
|
|
|
class EndPoints |
21
|
|
|
{ |
22
|
|
|
/** |
23
|
|
|
* @var ProviderInterface |
24
|
|
|
* @readonly |
25
|
|
|
*/ |
26
|
|
|
private $provider; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* List of registered endpoints, indexed by name |
30
|
|
|
* |
31
|
|
|
* @var EndPointInterface[] |
32
|
|
|
*/ |
33
|
|
|
private $endpoints = []; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var EndPointTransformerInterface[] |
37
|
|
|
*/ |
38
|
|
|
private $extensions = []; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* EndPointsSet constructor. |
42
|
|
|
* |
43
|
|
|
* @param ProviderInterface $provider |
44
|
|
|
*/ |
45
|
150 |
|
public function __construct(ProviderInterface $provider) |
46
|
|
|
{ |
47
|
150 |
|
$this->provider = $provider; |
48
|
150 |
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Get an endpoint, and apply extensions |
52
|
|
|
* |
53
|
|
|
* @param string $name The endpoint name |
54
|
|
|
* |
55
|
|
|
* @return EndPointInterface |
56
|
|
|
* |
57
|
|
|
* @throws InvalidArgumentException When the client do not implements the endpoint |
58
|
|
|
*/ |
59
|
63 |
|
public function get(string $name): EndPointInterface |
60
|
|
|
{ |
61
|
63 |
|
if (!isset($this->endpoints[$name])) { |
62
|
1 |
|
throw new InvalidArgumentException('The endpoint "' . $name . '" is not implemented'); |
63
|
|
|
} |
64
|
|
|
|
65
|
62 |
|
$endpoint = $this->endpoints[$name]; |
66
|
|
|
|
67
|
62 |
|
foreach ($this->extensions as $extension) { |
68
|
19 |
|
$endpoint = $endpoint->apply($extension); |
69
|
|
|
} |
70
|
|
|
|
71
|
61 |
|
return $endpoint; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* Generates the URI for an endpoint |
76
|
|
|
* |
77
|
|
|
* @param EndPointInterface $endpoint |
78
|
|
|
* |
79
|
|
|
* @return string |
80
|
|
|
* |
81
|
|
|
* @throws UnsupportedServerOperation When the server is not configured for supports the endpoint |
82
|
|
|
* |
83
|
|
|
* @see Provider::uri() For generate lower level URI |
84
|
|
|
*/ |
85
|
51 |
|
public function uri(EndPointInterface $endpoint): string |
86
|
|
|
{ |
87
|
51 |
|
return $this->provider->uri($endpoint->name(), $endpoint->parameters()); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Create a request for the endpoint |
92
|
|
|
* The endpoint name is used for generates the URI |
93
|
|
|
* The parameters are set as query parameters for GET request, or as body with other methods |
94
|
|
|
* |
95
|
|
|
* @param string $method The HTTP method |
96
|
|
|
* @param EndPointInterface $endpoint The endpoint |
97
|
|
|
* |
98
|
|
|
* @return RequestInterface |
99
|
|
|
* |
100
|
|
|
* @throws UnsupportedServerOperation When the server is not configured for supports the endpoint |
101
|
|
|
* |
102
|
|
|
* @see Provider::request() For create lower level request |
103
|
|
|
*/ |
104
|
48 |
|
public function request(string $method, EndPointInterface $endpoint): RequestInterface |
105
|
|
|
{ |
106
|
48 |
|
$isGet = $method === 'GET'; |
107
|
48 |
|
$parameters = $endpoint->parameters(); |
108
|
|
|
|
109
|
48 |
|
$request = $this->provider->request( |
110
|
48 |
|
$method, |
111
|
48 |
|
$endpoint->name(), |
112
|
48 |
|
$isGet ? $parameters : [], |
113
|
48 |
|
$isGet ? null : $parameters |
114
|
|
|
); |
115
|
|
|
|
116
|
48 |
|
if (!$isGet && $parameters) { |
|
|
|
|
117
|
39 |
|
$request = $request->withHeader('Content-Type', 'application/x-www-form-urlencoded'); |
118
|
|
|
} |
119
|
|
|
|
120
|
48 |
|
return $request; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* Add an endpoint to the set |
125
|
|
|
* |
126
|
|
|
* @param EndPointInterface $endPoint |
127
|
|
|
*/ |
128
|
145 |
|
public function add(EndPointInterface $endPoint): void |
129
|
|
|
{ |
130
|
145 |
|
$this->endpoints[$endPoint->name()] = $endPoint; |
131
|
145 |
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Register a new extension |
135
|
|
|
* |
136
|
|
|
* @param EndPointTransformerInterface $extension |
137
|
|
|
*/ |
138
|
33 |
|
public function register(EndPointTransformerInterface $extension): void |
139
|
|
|
{ |
140
|
33 |
|
$this->extensions[] = $extension; |
141
|
33 |
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Get the authorization endpoint |
145
|
|
|
* |
146
|
|
|
* @throws UnsupportedServerOperation When the server is not configured for supports the endpoint |
147
|
|
|
* @throws InvalidArgumentException When the client do not implements the endpoint |
148
|
|
|
*/ |
149
|
41 |
|
public function authorization(): AuthorizationEndPoint |
150
|
|
|
{ |
151
|
|
|
/** @var AuthorizationEndPoint */ |
152
|
41 |
|
return $this->get(AuthorizationEndPoint::NAME); |
|
|
|
|
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
/** |
156
|
|
|
* Get the token endpoint |
157
|
|
|
* |
158
|
|
|
* @throws UnsupportedServerOperation When the server is not configured for supports the endpoint |
159
|
|
|
* @throws InvalidArgumentException When the client do not implements the endpoint |
160
|
|
|
*/ |
161
|
25 |
|
public function token(): TokenEndPoint |
162
|
|
|
{ |
163
|
|
|
/** @var TokenEndPoint */ |
164
|
25 |
|
return $this->get(TokenEndPoint::NAME); |
|
|
|
|
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Get the revocation endpoint |
169
|
|
|
* |
170
|
|
|
* @throws UnsupportedServerOperation When the server is not configured for supports the endpoint |
171
|
|
|
* @throws InvalidArgumentException When the client do not implements the endpoint |
172
|
|
|
*/ |
173
|
5 |
|
public function revocation(): RevocationEndPoint |
174
|
|
|
{ |
175
|
|
|
/** @var RevocationEndPoint */ |
176
|
5 |
|
return $this->get(RevocationEndPoint::NAME); |
|
|
|
|
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Get the introspection endpoint |
181
|
|
|
* |
182
|
|
|
* @throws UnsupportedServerOperation When the server is not configured for supports the endpoint |
183
|
|
|
* @throws InvalidArgumentException When the client do not implements the endpoint |
184
|
|
|
*/ |
185
|
7 |
|
public function introspection(): IntrospectionEndPoint |
186
|
|
|
{ |
187
|
|
|
/** @var IntrospectionEndPoint */ |
188
|
7 |
|
return $this->get(IntrospectionEndPoint::NAME); |
|
|
|
|
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Get the userinfo endpoint |
193
|
|
|
* |
194
|
|
|
* @throws UnsupportedServerOperation When the server is not configured for supports the endpoint |
195
|
|
|
* @throws InvalidArgumentException When the client do not implements the endpoint |
196
|
|
|
*/ |
197
|
5 |
|
public function userinfo(): UserinfoEndPoint |
198
|
|
|
{ |
199
|
|
|
/** @var UserinfoEndPoint */ |
200
|
5 |
|
return $this->get(UserinfoEndPoint::NAME); |
|
|
|
|
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* Get the endSession endpoint |
205
|
|
|
* |
206
|
|
|
* @throws UnsupportedServerOperation When the server is not configured for supports the endpoint |
207
|
|
|
* @throws InvalidArgumentException When the client do not implements the endpoint |
208
|
|
|
*/ |
209
|
4 |
|
public function endSession(): EndSessionEndPoint |
210
|
|
|
{ |
211
|
|
|
/** @var EndSessionEndPoint */ |
212
|
4 |
|
return $this->get(EndSessionEndPoint::NAME); |
|
|
|
|
213
|
|
|
} |
214
|
|
|
} |
215
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.