diff options
author | H. Shay <hillerys@element.io> | 2023-08-16 09:23:11 -0700 |
---|---|---|
committer | H. Shay <hillerys@element.io> | 2023-08-16 09:23:11 -0700 |
commit | 400c90d0a702d553175494f47ec9fe91b12cbea9 (patch) | |
tree | 991bceea32cb76d9469df663ea2ce341152f083f | |
parent | newsfragment (diff) | |
download | synapse-400c90d0a702d553175494f47ec9fe91b12cbea9.tar.xz |
requested changes
-rw-r--r-- | synapse/api/auth/msc3861_delegated.py | 106 | ||||
-rw-r--r-- | tests/handlers/test_oauth_delegation.py | 6 |
2 files changed, 57 insertions, 55 deletions
diff --git a/synapse/api/auth/msc3861_delegated.py b/synapse/api/auth/msc3861_delegated.py index e85931c6ff..3a516093f5 100644 --- a/synapse/api/auth/msc3861_delegated.py +++ b/synapse/api/auth/msc3861_delegated.py @@ -156,70 +156,72 @@ class MSC3861DelegatedAuth(BaseAuth): # check the cache before doing a request introspection_token = self._token_cache.get(token, None) - expired = False if introspection_token: # check the expiration field of the token (if it exists) exp = introspection_token.get("exp", None) if exp: - time_now = self._clock.time_msec() + time_now = self._clock.time() expired = time_now > exp + if not expired: + return introspection_token + else: + return introspection_token + + metadata = await self._issuer_metadata.get() + introspection_endpoint = metadata.get("introspection_endpoint") + raw_headers: Dict[str, str] = { + "Content-Type": "application/x-www-form-urlencoded", + "User-Agent": str(self._http_client.user_agent, "utf-8"), + "Accept": "application/json", + } + + args = {"token": token, "token_type_hint": "access_token"} + body = urlencode(args, True) + + # Fill the body/headers with credentials + uri, raw_headers, body = self._client_auth.prepare( + method="POST", + uri=introspection_endpoint, + headers=raw_headers, + body=body, + ) + headers = Headers({k: [v] for (k, v) in raw_headers.items()}) + + # Do the actual request + # We're not using the SimpleHttpClient util methods as we don't want to + # check the HTTP status code, and we do the body encoding ourselves. + response = await self._http_client.request( + method="POST", + uri=uri, + data=body.encode("utf-8"), + headers=headers, + ) - if not introspection_token or expired: - metadata = await self._issuer_metadata.get() - introspection_endpoint = metadata.get("introspection_endpoint") - raw_headers: Dict[str, str] = { - "Content-Type": "application/x-www-form-urlencoded", - "User-Agent": str(self._http_client.user_agent, "utf-8"), - "Accept": "application/json", - } - - args = {"token": token, "token_type_hint": "access_token"} - body = urlencode(args, True) - - # Fill the body/headers with credentials - uri, raw_headers, body = self._client_auth.prepare( - method="POST", - uri=introspection_endpoint, - headers=raw_headers, - body=body, - ) - headers = Headers({k: [v] for (k, v) in raw_headers.items()}) - - # Do the actual request - # We're not using the SimpleHttpClient util methods as we don't want to - # check the HTTP status code, and we do the body encoding ourselves. - response = await self._http_client.request( - method="POST", - uri=uri, - data=body.encode("utf-8"), - headers=headers, - ) - - resp_body = await make_deferred_yieldable(readBody(response)) + resp_body = await make_deferred_yieldable(readBody(response)) - if response.code < 200 or response.code >= 300: - raise HttpResponseException( - response.code, - response.phrase.decode("ascii", errors="replace"), - resp_body, - ) + if response.code < 200 or response.code >= 300: + raise HttpResponseException( + response.code, + response.phrase.decode("ascii", errors="replace"), + resp_body, + ) - resp = json_decoder.decode(resp_body.decode("utf-8")) + resp = json_decoder.decode(resp_body.decode("utf-8")) - if not isinstance(resp, dict): - raise ValueError( - "The introspection endpoint returned an invalid JSON response." - ) + if not isinstance(resp, dict): + raise ValueError( + "The introspection endpoint returned an invalid JSON response." + ) - expiration = resp.get("exp", None) - if expiration: - if self._clock.time_msec() > expiration: - raise InvalidClientTokenError("Token is expired.") + expiration = resp.get("exp", None) + if expiration: + if self._clock.time() > expiration: + raise InvalidClientTokenError("Token is expired.") - introspection_token = IntrospectionToken(**resp) + introspection_token = IntrospectionToken(**resp) - # add token to cache - self._token_cache[token] = introspection_token + # add token to cache + self._token_cache[token] = introspection_token return introspection_token diff --git a/tests/handlers/test_oauth_delegation.py b/tests/handlers/test_oauth_delegation.py index c86af57d22..82c26e303f 100644 --- a/tests/handlers/test_oauth_delegation.py +++ b/tests/handlers/test_oauth_delegation.py @@ -500,7 +500,7 @@ class MSC3861OAuthDelegation(HomeserverTestCase): ) ) - # first call should cache response - check cache + # first call should cache response # Mpyp ignores below are due to mypy not understanding the dynamic substitution of msc3861 auth code # for regular auth code via the config self.get_success( @@ -531,7 +531,7 @@ class MSC3861OAuthDelegation(HomeserverTestCase): "active": "true", "scope": "guest", "jti": "stale", - "exp": self.clock.time_msec() + 100, + "exp": self.clock.time() + 100, }, ) ) @@ -543,7 +543,7 @@ class MSC3861OAuthDelegation(HomeserverTestCase): self.assertEqual(self.http_client.request.call_count, 1) # advance the reactor past the token expiry but less than the cache expiry - self.reactor.advance(30) + self.reactor.advance(120) self.assertEqual(self.auth._token_cache.get("stale"), introspection_token) # type: ignore[attr-defined] # check that the next call causes another http request (which will fail because the token is technically expired |