From 837045ef47e0bb1f44d075da8b97efef5d43b3d2 Mon Sep 17 00:00:00 2001 From: Ivan Kanakarakis Date: Tue, 31 May 2022 12:26:14 +0300 Subject: [PATCH 01/14] Fix typo in method name Signed-off-by: Ivan Kanakarakis --- src/pyop/authz_state.py | 2 +- src/pyop/provider.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pyop/authz_state.py b/src/pyop/authz_state.py index 9270f20..574ffa1 100644 --- a/src/pyop/authz_state.py +++ b/src/pyop/authz_state.py @@ -363,7 +363,7 @@ def get_user_info_for_code(self, authorization_code): return self.authorization_codes[authorization_code].get(self.KEY_USER_INFO) - def get_extra_io_token_claims_for_code(self, authorization_code): + def get_extra_id_token_claims_for_code(self, authorization_code): # type: (str) -> dict if authorization_code not in self.authorization_codes: raise InvalidAuthorizationCode('{} unknown'.format(authorization_code)) diff --git a/src/pyop/provider.py b/src/pyop/provider.py index c2a337d..92461b1 100644 --- a/src/pyop/provider.py +++ b/src/pyop/provider.py @@ -453,7 +453,7 @@ def _do_code_exchange(self, request, # type: Dict[str, str] else: extra_id_token_claims = extra_id_token_claims(user_id, authentication_request['client_id']) if self.stateless: - extra_id_token_claims_in_code = self.authz_state.get_extra_io_token_claims_for_code(token_request['code']) + extra_id_token_claims_in_code = self.authz_state.get_extra_id_token_claims_for_code(token_request['code']) extra_id_token_claims.update(extra_id_token_claims_in_code) requested_claims = self._get_requested_claims_in(authentication_request, 'id_token') if self.stateless: From 58a7c15e5ee921dbce7166d21a2688ea7d461a5d Mon Sep 17 00:00:00 2001 From: Vlad Mencl Date: Wed, 9 Nov 2022 00:02:08 +1300 Subject: [PATCH 02/14] fix: ValueError should be raised, not returned Fix an issue where invalid config might lead to an ValueError object being used as a databasse object, leading to application errors later. Rather fail fast by properly raising the exception. --- src/pyop/storage.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pyop/storage.py b/src/pyop/storage.py index bdc12bf..6ed58c9 100644 --- a/src/pyop/storage.py +++ b/src/pyop/storage.py @@ -93,7 +93,7 @@ def from_uri(cls, db_uri, collection, db_name=None, ttl=None, **kwargs): alg=alg ) - return ValueError(f"Invalid DB URI: {db_uri}") + raise ValueError(f"Invalid DB URI: {db_uri}") @classmethod def type(cls, db_uri): @@ -105,7 +105,7 @@ def type(cls, db_uri): elif url.scheme == "stateless": return "stateless" - return ValueError(f"Invalid DB URI: {db_uri}") + raise ValueError(f"Invalid DB URI: {db_uri}") @property def ttl(self): From b4c32ecdceef648ca360dca34715ffc34eab3ffa Mon Sep 17 00:00:00 2001 From: Vlad Mencl Date: Wed, 9 Nov 2022 22:21:16 +1300 Subject: [PATCH 03/14] fix: auth_state: update db when marking code as used Store the updated `authz_info` info back into the database after marking the code as used. Otherwise, the change would be discarded when using a DB (would hold only with in-memory dict) --- src/pyop/authz_state.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pyop/authz_state.py b/src/pyop/authz_state.py index 574ffa1..35085cf 100644 --- a/src/pyop/authz_state.py +++ b/src/pyop/authz_state.py @@ -200,6 +200,7 @@ def exchange_code_for_token(self, authorization_code): raise InvalidAuthorizationCode('{} has expired'.format(authorization_code)) authz_info['used'] = True + self.authorization_codes[authorization_code] = authz_info access_token = self._create_access_token(authz_info['sub'], authz_info[self.KEY_AUTHORIZATION_REQUEST], authz_info['granted_scope'], From e2f7d88b166631a1461884a33b42afb5beb08f9a Mon Sep 17 00:00:00 2001 From: Vlad Mencl Date: Tue, 15 Nov 2022 12:22:08 +0100 Subject: [PATCH 04/14] fix: userinfo: avoid indexing by None user_id in stateless mode (#46) In stateless mode, `user_id` passed to `get_claims_for` is always `None`. When no claims are available and userinfo is thus also `None`, `user_id` is used as index to self._db, but that triggers a `KeyError: None`. As `create_access_token` populates `user_info` field in `authz_info` only of `user_info` is pythonically `True`, `user_info` passed here ends up being `None`, not empty dict `{}`. As the `Userinfo` class does not have access to `Provider.stateless`, the easiest fix is to make the db lookup conditional on user_id being pythonically True - which corresponds with not being in stateltess mode. --- src/pyop/userinfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pyop/userinfo.py b/src/pyop/userinfo.py index ec92c2b..b01e563 100644 --- a/src/pyop/userinfo.py +++ b/src/pyop/userinfo.py @@ -31,6 +31,6 @@ def get_claims_for(self, user_id, requested_claims, userinfo=None): """ if not userinfo: - userinfo = self._db[user_id] + userinfo = self._db[user_id] if user_id else {} claims = {claim: userinfo[claim] for claim in requested_claims if claim in userinfo} return claims From c7b9ff666121a93933d132e8948b9b856e8059b5 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Tue, 15 Nov 2022 11:22:37 +0000 Subject: [PATCH 05/14] fix: example/requirements.txt to reduce vulnerabilities The following vulnerabilities are fixed by pinning transitive dependencies: - https://snyk.io/vuln/SNYK-PYTHON-SETUPTOOLS-3113904 --- example/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/example/requirements.txt b/example/requirements.txt index 5f3ff80..3e9476b 100644 --- a/example/requirements.txt +++ b/example/requirements.txt @@ -2,3 +2,4 @@ pyop Flask gunicorn oic>=1.2.1 +setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability From 8cbd697d63f427cbc70a9454abd639d1fb949735 Mon Sep 17 00:00:00 2001 From: Sven Haardiek Date: Fri, 30 Jun 2023 15:08:55 +0200 Subject: [PATCH 06/14] Add configurable subject_identifier_uri to clients According to the [OIDC Documentation](https://openid.net/specs/openid-connect-core-1_0.html#PairwiseAlg), the client must configure a `subject_identifier_uri`, if multiple `redirect_uri` are configured. This patch adds the possibility to do this as described in #49. Signed-off-by: Sven Haardiek --- src/pyop/provider.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pyop/provider.py b/src/pyop/provider.py index 92461b1..38a22d6 100644 --- a/src/pyop/provider.py +++ b/src/pyop/provider.py @@ -240,7 +240,8 @@ def _create_subject_identifier(self, user_id, client_id, redirect_uri): """ supported_subject_types = self.configuration_information['subject_types_supported'][0] subject_type = self.clients[client_id].get('subject_type', supported_subject_types) - sector_identifier = urlparse(redirect_uri).netloc + sector_identifier_uri = self.clients[client_id].get('sector_identifier_uri', redirect_uri) + sector_identifier = urlparse(sector_identifier_uri).netloc return self.authz_state.get_subject_identifier(subject_type, user_id, sector_identifier) def _get_requested_claims_in(self, authentication_request, response_method): From 8bc8d0a68a8587725bae2b5954ba9e03b743ebdb Mon Sep 17 00:00:00 2001 From: "Economou, Matthew (NIH/NIAID) [C]" Date: Thu, 7 Sep 2023 12:07:19 -0400 Subject: [PATCH 07/14] Start migration to PyMongo 4 Pin pyop to the latest version of PyMongo 3.x until it has completely migrated to PyMongo 4. Most of the key new methods and options from PyMongo 4.0 are backported in PyMongo 3.12, making migration much easier. Closes IdentityPython/pyop#51 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 7961abc..3e61dde 100644 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ 'pycryptodomex', ], extras_require={ - 'mongo': 'pymongo', + 'mongo': 'pymongo >= 3.12, < 4.0', 'redis': 'redis', }, ) From a6cbe4092124e420671a4b0f650a48f5c91d87a7 Mon Sep 17 00:00:00 2001 From: Ivan Kanakarakis Date: Wed, 11 Oct 2023 11:34:21 +0200 Subject: [PATCH 08/14] Bump version to 3.4.1 - Fix support of PyMongo 4 - Add configurable subject_identifier_uri to clients - fix: example/requirements.txt to reduce vulnerabilities - fix: userinfo: avoid indexing by None user_id in stateless mode Signed-off-by: Ivan Kanakarakis --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3e61dde..13fd9ff 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='pyop', - version='3.4.0', + version='3.4.1', packages=find_packages('src'), package_dir={'': 'src'}, url='https://github.com/IdentityPython/pyop', From 1c98f84a894cf5a61862a347867d1a732ddde212 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Thu, 26 Oct 2023 19:08:50 +0000 Subject: [PATCH 09/14] fix: example/requirements.txt to reduce vulnerabilities The following vulnerabilities are fixed by pinning transitive dependencies: - https://snyk.io/vuln/SNYK-PYTHON-WERKZEUG-6035177 --- example/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/example/requirements.txt b/example/requirements.txt index 3e9476b..13e2335 100644 --- a/example/requirements.txt +++ b/example/requirements.txt @@ -3,3 +3,4 @@ Flask gunicorn oic>=1.2.1 setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability +werkzeug>=3.0.1 # not directly required, pinned by Snyk to avoid a vulnerability From 38d5fbdd74296478189d7dae6a3357310a57d1e3 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Tue, 21 May 2024 11:31:45 +0000 Subject: [PATCH 10/14] fix: example/requirements.txt to reduce vulnerabilities The following vulnerabilities are fixed by pinning transitive dependencies: - https://snyk.io/vuln/SNYK-PYTHON-REQUESTS-6928867 --- example/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/example/requirements.txt b/example/requirements.txt index 13e2335..5adaf10 100644 --- a/example/requirements.txt +++ b/example/requirements.txt @@ -4,3 +4,4 @@ gunicorn oic>=1.2.1 setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability werkzeug>=3.0.1 # not directly required, pinned by Snyk to avoid a vulnerability +requests>=2.32.0 # not directly required, pinned by Snyk to avoid a vulnerability From 5d222afc2a7d1161928e149167c328968969d724 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Tue, 1 Oct 2024 12:35:17 +0000 Subject: [PATCH 11/14] fix: example/requirements.txt to reduce vulnerabilities The following vulnerabilities are fixed by pinning transitive dependencies: - https://snyk.io/vuln/SNYK-PYTHON-REQUESTS-6928867 - https://snyk.io/vuln/SNYK-PYTHON-URLLIB3-7267250 --- example/requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/example/requirements.txt b/example/requirements.txt index 5adaf10..ea138f7 100644 --- a/example/requirements.txt +++ b/example/requirements.txt @@ -4,4 +4,5 @@ gunicorn oic>=1.2.1 setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability werkzeug>=3.0.1 # not directly required, pinned by Snyk to avoid a vulnerability -requests>=2.32.0 # not directly required, pinned by Snyk to avoid a vulnerability +requests>=2.32.2 # not directly required, pinned by Snyk to avoid a vulnerability +urllib3>=2.2.2 # not directly required, pinned by Snyk to avoid a vulnerability From edb739743da2e662ed51189c535b43af4bbe6e76 Mon Sep 17 00:00:00 2001 From: snyk-bot Date: Tue, 16 Jul 2024 02:25:56 +0000 Subject: [PATCH 12/14] fix: example/requirements.txt to reduce vulnerabilities The following vulnerabilities are fixed by pinning transitive dependencies: - https://snyk.io/vuln/SNYK-PYTHON-SETUPTOOLS-7448482 --- example/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/requirements.txt b/example/requirements.txt index ea138f7..1732184 100644 --- a/example/requirements.txt +++ b/example/requirements.txt @@ -2,7 +2,7 @@ pyop Flask gunicorn oic>=1.2.1 -setuptools>=65.5.1 # not directly required, pinned by Snyk to avoid a vulnerability +setuptools>=70.0.0 # not directly required, pinned by Snyk to avoid a vulnerability werkzeug>=3.0.1 # not directly required, pinned by Snyk to avoid a vulnerability requests>=2.32.2 # not directly required, pinned by Snyk to avoid a vulnerability urllib3>=2.2.2 # not directly required, pinned by Snyk to avoid a vulnerability From de52a30c54db853bf6e587184eab49fe26433750 Mon Sep 17 00:00:00 2001 From: Ali Haider Date: Mon, 27 May 2024 06:34:40 +0500 Subject: [PATCH 13/14] For the stateless flow, retrieve the extra_id_token_claims from the auth_code in the request --- src/pyop/provider.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/pyop/provider.py b/src/pyop/provider.py index 38a22d6..67f9c2d 100644 --- a/src/pyop/provider.py +++ b/src/pyop/provider.py @@ -446,16 +446,13 @@ def _do_code_exchange(self, request, # type: Dict[str, str] if refresh_token is not None: response['refresh_token'] = refresh_token - if extra_id_token_claims is None: - extra_id_token_claims = {} - elif callable(extra_id_token_claims): - if self.stateless: - extra_id_token_claims = extra_id_token_claims(sub, authentication_request['client_id']) - else: - extra_id_token_claims = extra_id_token_claims(user_id, authentication_request['client_id']) + extra_id_token_claims = {} if self.stateless: extra_id_token_claims_in_code = self.authz_state.get_extra_id_token_claims_for_code(token_request['code']) extra_id_token_claims.update(extra_id_token_claims_in_code) + elif callable(extra_id_token_claims): + extra_id_token_claims = extra_id_token_claims(user_id, authentication_request['client_id']) + requested_claims = self._get_requested_claims_in(authentication_request, 'id_token') if self.stateless: user_info = self.authz_state.get_user_info_for_code(token_request['code']) From fab87f9f6193079171fdad0c223c810fe9532dd2 Mon Sep 17 00:00:00 2001 From: Ivan Kanakarakis Date: Wed, 6 Nov 2024 13:16:15 +0200 Subject: [PATCH 14/14] Bump version to v3.4.2 For the stateless flow, retrieve the extra_id_token_claims from the auth_code in the request Signed-off-by: Ivan Kanakarakis --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 13fd9ff..0fc26b7 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='pyop', - version='3.4.1', + version='3.4.2', packages=find_packages('src'), package_dir={'': 'src'}, url='https://github.com/IdentityPython/pyop',