@@ -169,4 +169,135 @@ public function trustMarkValidation(Request $request): Response
169169 RoutesEnum::AdminTestTrustMarkValidation->value ,
170170 );
171171 }
172+
173+
174+ /**
175+ * @throws \SimpleSAML\Error\ConfigurationError
176+ * @throws \SimpleSAML\Module\oidc\Server\Exceptions\OidcServerException
177+ * @throws \SimpleSAML\Module\oidc\Exceptions\OidcException
178+ */
179+ public function federationDiscovery (Request $ request ): Response
180+ {
181+ $ trustAnchorId = null ;
182+ $ isFormSubmitted = false ;
183+ $ entities = [];
184+ $ forceRefresh = false ;
185+ $ filterEntityTypes = [];
186+ $ filterTrustMarkTypes = '' ;
187+ $ filterQuery = '' ;
188+ $ sortBy = 'entity_id ' ;
189+ $ sortOrder = 'asc ' ;
190+ $ pageLimit = 50 ;
191+ $ pageFrom = null ;
192+ $ nextPageToken = null ;
193+ $ totalCount = 0 ;
194+
195+ if ($ request ->isMethod (Request::METHOD_POST )) {
196+ $ isFormSubmitted = true ;
197+
198+ !empty ($ trustAnchorId = $ request ->request ->getString ('trustAnchorId ' )) ||
199+ throw new OidcException ('Empty Trust Anchor ID. ' );
200+
201+ $ forceRefresh = $ request ->request ->getBoolean ('forceRefresh ' );
202+ /** @var string[] $filterEntityTypes */
203+ $ filterEntityTypes = $ request ->request ->all ('filterEntityTypes ' );
204+ $ filterTrustMarkTypes = $ request ->request ->getString ('filterTrustMarkTypes ' );
205+ $ filterQuery = $ request ->request ->getString ('filterQuery ' );
206+ $ sortBy = $ request ->request ->getString ('sortBy ' , 'entity_id ' );
207+ $ sortOrder = $ request ->request ->getString ('sortOrder ' , 'asc ' );
208+ /** @var 'asc'|'desc' $sortOrder */
209+ $ sortOrder = in_array ($ sortOrder , ['asc ' , 'desc ' ]) ? $ sortOrder : 'asc ' ;
210+ $ pageLimit = $ request ->request ->getInt ('pageLimit ' , 50 );
211+ $ pageFrom = $ request ->request ->get ('pageFrom ' );
212+ $ pageFrom = is_string ($ pageFrom ) ? $ pageFrom : null ;
213+
214+ try {
215+ $ entityCollection = $ this ->federationWithArrayLogger ->federationDiscovery ()->discover (
216+ trustAnchorId: $ trustAnchorId ,
217+ forceRefresh: $ forceRefresh ,
218+ );
219+
220+ // 1. Filtering
221+ $ criteria = array_filter ([
222+ 'entity_type ' => $ filterEntityTypes ,
223+ 'trust_mark_type ' => $ this ->helpers ->str ()->convertTextToArray ($ filterTrustMarkTypes ),
224+ 'query ' => $ filterQuery ,
225+ ]);
226+ if (!empty ($ criteria )) {
227+ $ entityCollection ->filter ($ criteria );
228+ }
229+
230+ $ totalCount = count ($ entityCollection ->getEntities ());
231+
232+ // 2. Sorting
233+ $ claimPaths = match ($ sortBy ) {
234+ 'display_name ' => [
235+ ['metadata ' , EntityTypesEnum::OpenIdProvider->value , 'display_name ' ],
236+ ['metadata ' , EntityTypesEnum::FederationEntity->value , 'display_name ' ],
237+ ['metadata ' , EntityTypesEnum::OpenIdRelyingParty->value , 'display_name ' ],
238+ ],
239+ 'organization_name ' => [
240+ ['metadata ' , EntityTypesEnum::OpenIdProvider->value , 'organization_name ' ],
241+ ['metadata ' , EntityTypesEnum::FederationEntity->value , 'organization_name ' ],
242+ ['metadata ' , EntityTypesEnum::OpenIdRelyingParty->value , 'organization_name ' ],
243+ ],
244+ default => [['sub ' ]],
245+ };
246+ $ entityCollection ->sort ($ claimPaths , $ sortOrder );
247+
248+ // 3. Pagination
249+ /** @var positive-int $pageLimit */
250+ $ entityCollection ->paginate ($ pageLimit , $ pageFrom );
251+
252+ $ nextPageToken = $ entityCollection ->getNextPageToken ();
253+
254+ foreach ($ entityCollection ->getEntities () as $ id => $ payload ) {
255+ $ entities [] = [
256+ 'id ' => $ id ,
257+ 'payload ' => $ payload ,
258+ ];
259+ }
260+ } catch (\Throwable $ exception ) {
261+ $ this ->arrayLogger ->error (sprintf (
262+ 'Error during entity discovery under Trust Anchor %s. Error was %s ' ,
263+ $ trustAnchorId ,
264+ $ exception ->getMessage (),
265+ ));
266+ }
267+ }
268+
269+ $ logMessages = $ this ->arrayLogger ->getEntries ();
270+
271+ try {
272+ $ trustAnchorIds = $ this ->moduleConfig ->getFederationTrustAnchorIds ();
273+ } catch (\Throwable $ exception ) {
274+ $ this ->arrayLogger ->error ('Module config error: ' . $ exception ->getMessage ());
275+ $ trustAnchorIds = [];
276+ }
277+
278+ $ entityTypeOptions = array_map (fn (EntityTypesEnum $ enum ) => $ enum ->value , EntityTypesEnum::cases ());
279+
280+ return $ this ->templateFactory ->build (
281+ 'oidc:tests/federation-discovery.twig ' ,
282+ compact (
283+ 'trustAnchorId ' ,
284+ 'logMessages ' ,
285+ 'isFormSubmitted ' ,
286+ 'entities ' ,
287+ 'trustAnchorIds ' ,
288+ 'forceRefresh ' ,
289+ 'filterEntityTypes ' ,
290+ 'filterTrustMarkTypes ' ,
291+ 'filterQuery ' ,
292+ 'sortBy ' ,
293+ 'sortOrder ' ,
294+ 'pageLimit ' ,
295+ 'pageFrom ' ,
296+ 'nextPageToken ' ,
297+ 'totalCount ' ,
298+ 'entityTypeOptions ' ,
299+ ),
300+ RoutesEnum::AdminTestFederationDiscovery->value ,
301+ );
302+ }
172303}
0 commit comments