1919use SimpleSAML \OpenID \Factories \DateIntervalDecoratorFactory ;
2020use SimpleSAML \OpenID \Factories \HttpClientDecoratorFactory ;
2121use SimpleSAML \OpenID \Factories \JwsSerializerManagerDecoratorFactory ;
22+ use SimpleSAML \OpenID \Federation \CacheEntityCollectionStore ;
23+ use SimpleSAML \OpenID \Federation \EntityCollectionBuilder ;
24+ use SimpleSAML \OpenID \Federation \EntityCollectionFetcher ;
25+ use SimpleSAML \OpenID \Federation \EntityCollectionFilter ;
26+ use SimpleSAML \OpenID \Federation \EntityCollectionPaginator ;
27+ use SimpleSAML \OpenID \Federation \EntityCollectionSorter ;
28+ use SimpleSAML \OpenID \Federation \EntityCollectionStoreInterface ;
2229use SimpleSAML \OpenID \Federation \EntityStatementFetcher ;
2330use SimpleSAML \OpenID \Federation \Factories \EntityStatementFactory ;
2431use SimpleSAML \OpenID \Federation \Factories \RequestObjectFactory ;
2734use SimpleSAML \OpenID \Federation \Factories \TrustMarkDelegationFactory ;
2835use SimpleSAML \OpenID \Federation \Factories \TrustMarkFactory ;
2936use SimpleSAML \OpenID \Federation \Factories \TrustMarkStatusResponseFactory ;
37+ use SimpleSAML \OpenID \Federation \FederationDiscovery ;
38+ use SimpleSAML \OpenID \Federation \InMemoryEntityCollectionStore ;
3039use SimpleSAML \OpenID \Federation \MetadataPolicyApplicator ;
3140use SimpleSAML \OpenID \Federation \MetadataPolicyResolver ;
41+ use SimpleSAML \OpenID \Federation \SubordinateListingFetcher ;
3242use SimpleSAML \OpenID \Federation \TrustChainResolver ;
3343use SimpleSAML \OpenID \Federation \TrustMarkFetcher ;
3444use SimpleSAML \OpenID \Federation \TrustMarkStatusResponseFetcher ;
3545use SimpleSAML \OpenID \Federation \TrustMarkValidator ;
46+ use SimpleSAML \OpenID \Helpers ;
3647use SimpleSAML \OpenID \Jwks \Factories \JwksDecoratorFactory ;
3748use SimpleSAML \OpenID \Jws \Factories \JwsDecoratorBuilderFactory ;
3849use SimpleSAML \OpenID \Jws \Factories \JwsVerifierDecoratorFactory ;
@@ -50,6 +61,8 @@ class Federation
5061
5162 protected int $ maxTrustChainDepth ;
5263
64+ protected int $ maxDiscoveryDepth ;
65+
5366 protected ?CacheDecorator $ cacheDecorator ;
5467
5568 protected HttpClientDecorator $ httpClientDecorator ;
@@ -60,6 +73,20 @@ class Federation
6073
6174 protected ?JwsVerifierDecorator $ jwsVerifierDecorator = null ;
6275
76+ protected ?SubordinateListingFetcher $ subordinateListingFetcher = null ;
77+
78+ protected ?FederationDiscovery $ federationDiscovery = null ;
79+
80+ protected ?EntityCollectionFetcher $ entityCollectionFetcher = null ;
81+
82+ protected ?EntityCollectionFilter $ entityCollectionFilter = null ;
83+
84+ protected ?EntityCollectionSorter $ entityCollectionSorter = null ;
85+
86+ protected ?EntityCollectionPaginator $ entityCollectionPaginator = null ;
87+
88+ protected ?EntityCollectionBuilder $ entityCollectionBuilder = null ;
89+
6390 protected ?EntityStatementFetcher $ entityStatementFetcher = null ;
6491
6592 protected ?MetadataPolicyResolver $ metadataPolicyResolver = null ;
@@ -126,11 +153,13 @@ public function __construct(
126153 ?Client $ client = null ,
127154 // phpcs:ignore
128155 protected readonly TrustMarkStatusEndpointUsagePolicyEnum $ defaultTrustMarkStatusEndpointUsagePolicyEnum = TrustMarkStatusEndpointUsagePolicyEnum::NotUsed,
156+ int $ maxDiscoveryDepth = 10 ,
129157 ) {
130158 $ this ->maxCacheDurationDecorator = $ this ->dateIntervalDecoratorFactory ()->build ($ maxCacheDuration );
131159 $ this ->timestampValidationLeewayDecorator = $ this ->dateIntervalDecoratorFactory ()
132160 ->build ($ timestampValidationLeeway );
133161 $ this ->maxTrustChainDepth = min (20 , max (1 , $ maxTrustChainDepth ));
162+ $ this ->maxDiscoveryDepth = max (1 , $ maxDiscoveryDepth );
134163 $ this ->cacheDecorator = is_null ($ cache ) ? null : $ this ->cacheDecoratorFactory ()->build ($ cache );
135164 $ this ->httpClientDecorator = $ this ->httpClientDecoratorFactory ()->build ($ client );
136165 }
@@ -321,6 +350,80 @@ public function trustMarkFetcher(): TrustMarkFetcher
321350 }
322351
323352
353+ public function subordinateListingFetcher (): SubordinateListingFetcher
354+ {
355+ return $ this ->subordinateListingFetcher ??= new SubordinateListingFetcher (
356+ $ this ->artifactFetcher (),
357+ $ this ->helpers (),
358+ $ this ->logger ,
359+ );
360+ }
361+
362+
363+ public function federationDiscovery (?EntityCollectionStoreInterface $ store = null ): FederationDiscovery
364+ {
365+ if (!$ this ->federationDiscovery instanceof \SimpleSAML \OpenID \Federation \FederationDiscovery) {
366+ $ effectiveStore = $ store ?? ($ this ->cacheDecorator () instanceof \SimpleSAML \OpenID \Decorators \CacheDecorator
367+ ? new CacheEntityCollectionStore ($ this ->cacheDecorator ())
368+ : new InMemoryEntityCollectionStore ());
369+
370+ $ this ->federationDiscovery = new FederationDiscovery (
371+ $ this ->entityStatementFetcher (),
372+ $ this ->subordinateListingFetcher (),
373+ $ effectiveStore ,
374+ $ this ->maxCacheDurationDecorator (),
375+ $ this ->logger ,
376+ $ this ->maxDiscoveryDepth ,
377+ );
378+ }
379+
380+ return $ this ->federationDiscovery ;
381+ }
382+
383+
384+ public function entityCollectionFetcher (): EntityCollectionFetcher
385+ {
386+ return $ this ->entityCollectionFetcher ??= new EntityCollectionFetcher (
387+ $ this ->artifactFetcher (),
388+ $ this ->helpers (),
389+ $ this ->logger ,
390+ );
391+ }
392+
393+
394+ public function entityCollectionFilter (): EntityCollectionFilter
395+ {
396+ return $ this ->entityCollectionFilter ??= new EntityCollectionFilter ($ this ->helpers ());
397+ }
398+
399+
400+ public function entityCollectionSorter (): EntityCollectionSorter
401+ {
402+ return $ this ->entityCollectionSorter ??= new EntityCollectionSorter ($ this ->helpers ());
403+ }
404+
405+
406+ public function entityCollectionPaginator (): EntityCollectionPaginator
407+ {
408+ return $ this ->entityCollectionPaginator ??= new EntityCollectionPaginator ();
409+ }
410+
411+
412+ /**
413+ * @param \SimpleSAML\OpenID\Federation\EntityCollectionStoreInterface|null $store Forwarded to
414+ * federationDiscovery()
415+ */
416+ public function entityCollectionBuilder (?EntityCollectionStoreInterface $ store = null ): EntityCollectionBuilder
417+ {
418+ return $ this ->entityCollectionBuilder ??= new EntityCollectionBuilder (
419+ $ this ->federationDiscovery ($ store ),
420+ $ this ->entityCollectionFilter (),
421+ $ this ->entityCollectionSorter (),
422+ $ this ->entityCollectionPaginator (),
423+ );
424+ }
425+
426+
324427 public function helpers (): Helpers
325428 {
326429 return $ this ->helpers ??= new Helpers ();
0 commit comments