88use SimpleSAML \OpenID \Codebooks \ClaimsEnum ;
99use SimpleSAML \OpenID \Codebooks \ContentTypesEnum ;
1010use SimpleSAML \OpenID \Codebooks \EntityTypesEnum ;
11- use SimpleSAML \OpenID \Codebooks \HttpHeadersEnum ;
12- use SimpleSAML \OpenID \Codebooks \HttpMethodsEnum ;
1311use SimpleSAML \OpenID \Codebooks \WellKnownEnum ;
14- use SimpleSAML \OpenID \Decorators \CacheDecorator ;
1512use SimpleSAML \OpenID \Decorators \DateIntervalDecorator ;
16- use SimpleSAML \OpenID \Decorators \HttpClientDecorator ;
1713use SimpleSAML \OpenID \Exceptions \FetchException ;
1814use SimpleSAML \OpenID \Exceptions \JwsException ;
1915use SimpleSAML \OpenID \Federation \Factories \EntityStatementFactory ;
2016use SimpleSAML \OpenID \Helpers ;
17+ use SimpleSAML \OpenID \Jws \JwsFetcher ;
2118use SimpleSAML \OpenID \Utils \ArtifactFetcher ;
22- use Throwable ;
2319
24- class EntityStatementFetcher
20+ class EntityStatementFetcher extends JwsFetcher
2521{
2622 public function __construct (
27- protected readonly ArtifactFetcher $ artifactFetcher ,
28- protected readonly EntityStatementFactory $ entityStatementFactory ,
29- protected readonly DateIntervalDecorator $ maxCacheDuration ,
30- protected readonly Helpers $ helpers ,
31- protected readonly ?LoggerInterface $ logger = null ,
23+ private readonly EntityStatementFactory $ parsedJwsFactory ,
24+ ArtifactFetcher $ artifactFetcher ,
25+ DateIntervalDecorator $ maxCacheDuration ,
26+ Helpers $ helpers ,
27+ ?LoggerInterface $ logger = null ,
3228 ) {
29+ parent ::__construct ($ parsedJwsFactory , $ artifactFetcher , $ maxCacheDuration , $ helpers , $ logger );
30+ }
31+
32+ protected function buildJwsInstance (string $ token ): EntityStatement
33+ {
34+ return $ this ->parsedJwsFactory ->fromToken ($ token );
35+ }
36+
37+ protected function getExpectedContentTypeHttpHeader (): string
38+ {
39+ return ContentTypesEnum::ApplicationEntityStatementJwt->value ;
3340 }
3441
3542 /**
@@ -104,27 +111,27 @@ public function fromCacheOrNetwork(string $uri): EntityStatement
104111 * @param string $uri
105112 * @return \SimpleSAML\OpenID\Federation\EntityStatement|null
106113 * @throws \SimpleSAML\OpenID\Exceptions\JwsException
114+ * @throws \SimpleSAML\OpenID\Exceptions\FetchException
107115 */
108116 public function fromCache (string $ uri ): ?EntityStatement
109117 {
110- $ this ->logger ?->debug(
111- 'Trying to get entity statement token from cache. ' ,
112- compact ('uri ' ),
113- );
118+ $ entityStatement = parent ::fromCache ($ uri );
114119
115- $ jws = $ this ->artifactFetcher ->fromCacheAsString ($ uri );
116-
117- if (!is_string ($ jws )) {
118- $ this ->logger ?->debug('Entity statement token not found in cache. ' , compact ('uri ' ));
120+ if (is_null ($ entityStatement )) {
119121 return null ;
120122 }
121123
122- $ this ->logger ?->debug(
123- 'Entity statement token found in cache, trying to build instance. ' ,
124- compact ('uri ' ),
124+ if (is_a ($ entityStatement , EntityStatement::class)) {
125+ return $ entityStatement ;
126+ }
127+
128+ $ message = 'Unexpected entity statement instance encountered for cache fetch. ' ;
129+ $ this ->logger ?->error(
130+ $ message ,
131+ compact ('uri ' , 'entityStatement ' ),
125132 );
126133
127- return $ this -> prepareEntityStatement ( $ jws );
134+ throw new FetchException ( $ message );
128135 }
129136
130137 /**
@@ -135,57 +142,18 @@ public function fromCache(string $uri): ?EntityStatement
135142 */
136143 public function fromNetwork (string $ uri ): EntityStatement
137144 {
138- $ response = $ this ->artifactFetcher ->fromNetwork ($ uri );
139-
140- if ($ response ->getStatusCode () !== 200 ) {
141- $ message = sprintf (
142- 'Unexpected HTTP response for entity statement fetch, status code: %s, reason: %s. URI %s ' ,
143- $ response ->getStatusCode (),
144- $ response ->getReasonPhrase (),
145- $ uri ,
146- );
147- $ this ->logger ?->error($ message );
148- throw new FetchException ($ message );
149- }
145+ $ entityStatement = parent ::fromNetwork ($ uri );
150146
151- /** @psalm-suppress InvalidLiteralArgument */
152- if (
153- !str_contains (
154- $ response ->getHeaderLine (HttpHeadersEnum::ContentType->value ),
155- ContentTypesEnum::ApplicationEntityStatementJwt->value ,
156- )
157- ) {
158- $ message = sprintf (
159- 'Unexpected content type in response for entity statement fetch: %s, expected: %s. URI %s ' ,
160- $ response ->getHeaderLine (HttpHeadersEnum::ContentType->value ),
161- ContentTypesEnum::ApplicationEntityStatementJwt->value ,
162- $ uri ,
163- );
164- $ this ->logger ?->error($ message );
165- throw new FetchException ($ message );
147+ if (is_a ($ entityStatement , EntityStatement::class)) {
148+ return $ entityStatement ;
166149 }
167150
168- $ token = $ response ->getBody ()->getContents ();
169- $ this ->logger ?->debug('Successful HTTP response for entity statement fetch. ' , compact ('uri ' , 'token ' ));
170- $ this ->logger ?->debug('Proceeding to EntityStatement instance building. ' );
171-
172- $ entityStatement = $ this ->entityStatementFactory ->fromToken ($ token );
173- $ this ->logger ?->debug('Entity Statement instance built, saving its token to cache. ' , compact ('uri ' , 'token ' ));
174-
175- $ cacheTtl = $ this ->maxCacheDuration ->lowestInSecondsComparedToExpirationTime (
176- $ entityStatement ->getExpirationTime (),
151+ $ message = 'Unexpected entity statement instance encountered for network fetch. ' ;
152+ $ this ->logger ?->error(
153+ $ message ,
154+ compact ('uri ' , 'entityStatement ' ),
177155 );
178- $ this ->artifactFetcher ->cacheIt ($ token , $ cacheTtl , $ uri );
179156
180- $ this ->logger ?->debug('Returning built Entity Statement instance. ' , compact ('uri ' , 'token ' ));
181- return $ entityStatement ;
182- }
183-
184- /**
185- * @throws \SimpleSAML\OpenID\Exceptions\JwsException
186- */
187- protected function prepareEntityStatement (string $ jws ): EntityStatement
188- {
189- return $ this ->entityStatementFactory ->fromToken ($ jws );
157+ throw new FetchException ($ message );
190158 }
191159}
0 commit comments