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) { |
|
0 ignored issues
–
show
|
|||
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); |
|
0 ignored issues
–
show
|
|||
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); |
|
0 ignored issues
–
show
|
|||
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); |
|
0 ignored issues
–
show
|
|||
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); |
|
0 ignored issues
–
show
|
|||
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); |
|
0 ignored issues
–
show
|
|||
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); |
|
0 ignored issues
–
show
|
|||
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.