diff options
author | Frederick Muriuki Muriithi | 2024-07-19 12:24:04 -0500 |
---|---|---|
committer | Frederick Muriuki Muriithi | 2024-07-31 09:30:24 -0500 |
commit | 12453be99f2bf21842a9e488ecf72c06a06625f0 (patch) | |
tree | 039dc3b5b7ca80f73a98b8cee1a8f35b05cc609a /gn_auth/auth/authentication/oauth2/models/oauth2client.py | |
parent | 6b18e1f0b05222d84fd0b06a8e5c2780df6958d5 (diff) | |
download | gn-auth-12453be99f2bf21842a9e488ecf72c06a06625f0.tar.gz |
Fetch a client's JWKs from a URI
Diffstat (limited to 'gn_auth/auth/authentication/oauth2/models/oauth2client.py')
-rw-r--r-- | gn_auth/auth/authentication/oauth2/models/oauth2client.py | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/gn_auth/auth/authentication/oauth2/models/oauth2client.py b/gn_auth/auth/authentication/oauth2/models/oauth2client.py index d31faf6..1413722 100644 --- a/gn_auth/auth/authentication/oauth2/models/oauth2client.py +++ b/gn_auth/auth/authentication/oauth2/models/oauth2client.py @@ -1,13 +1,14 @@ """OAuth2 Client model.""" import json +import logging import datetime -from pathlib import Path - from uuid import UUID from dataclasses import dataclass from functools import cached_property from typing import Sequence, Optional +import requests +from requests.exceptions import JSONDecodeError from authlib.jose import KeySet, JsonWebKey from authlib.oauth2.rfc6749 import ClientMixin from pymonad.maybe import Just, Maybe, Nothing @@ -57,16 +58,30 @@ class OAuth2Client(ClientMixin): """ return self.client_metadata.get("client_type", "public") - @cached_property + def jwks(self) -> KeySet: """Return this client's KeySet.""" - def __parse_key__(keypath: Path) -> JsonWebKey: - with open(keypath) as _key:# pylint: disable=[unspecified-encoding] - return JsonWebKey.import_key(_key.read()) + jwksuri = self.client_metadata.get("public-jwks-uri") + if not bool(jwksuri): + logging.debug("No Public JWKs URI set for client!") + return KeySet([]) + try: + ## IMPORTANT: This can cause a deadlock if the client is working in + ## single-threaded mode, i.e. can only serve one request + ## at a time. + return KeySet([JsonWebKey.import_key(key) + for key in requests.get(jwksuri).json()["jwks"]]) + except requests.ConnectionError as _connerr: + logging.debug( + "Could not connect to provided URI: %s", jwksuri, exc_info=True) + except JSONDecodeError as _jsonerr: + logging.debug( + "Could not convert response to JSON", exc_info=True) + except Exception as _exc:# pylint: disable=[broad-except] + logging.debug( + "Error retrieving the JWKs for the client.", exc_info=True) + return KeySet([]) - return KeySet([ - __parse_key__(Path(pth)) - for pth in self.client_metadata.get("public_keys", [])]) def check_endpoint_auth_method(self, method: str, endpoint: str) -> bool: """ |