From c8cab2f17b6ae5dbc30316bae0cb984100677069 Mon Sep 17 00:00:00 2001 From: Michael Schlenker Date: Fri, 11 Nov 2022 22:43:14 +0100 Subject: [PATCH] Handle null or empty string values in UserInfo The spec allows null values or empty strings in UserInfo responses. Make the client accept those values but normalize and drop empty values when parsing the message. --- CHANGELOG.md | 3 +++ src/oic/oic/message.py | 12 +++++++++++- tests/test_oic_message.py | 22 ++++++++++++++++++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 029ee2cb..408c2023 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on the [KeepAChangeLog] project. ### Changed - [#827] Added support for python 3.11 +- [#830], [#831] Allow null and empty values in UserInfo responses, but filter them out. ### Fixed - [#826], [#829] Fixed RP-Initiated Logout To Accept id_token_hint @@ -21,6 +22,8 @@ The format is based on the [KeepAChangeLog] project. [#827]: https://github.com/OpenIDC/pyoidc/issues/827 [#826]: https://github.com/OpenIDC/pyoidc/issues/826 [#829]: https://github.com/OpenIDC/pyoidc/pull/829 +[#830]: https://github.com/OpenIDC/pyoidc/issues/830 +[#831]: https://github.com/OpenIDC/pyoidc/pull/831 ## 1.4.0 [2022-05-23] diff --git a/src/oic/oic/message.py b/src/oic/oic/message.py index ead44a9e..e4cb2de5 100644 --- a/src/oic/oic/message.py +++ b/src/oic/oic/message.py @@ -561,10 +561,20 @@ class OpenIDSchema(Message): "_claim_sources": OPTIONAL_MESSAGE, } + def from_dict(self, dictionary, **kwargs): + result = super().from_dict(dictionary, **kwargs) + # The spec allows empty fields in the UserInfo/IdToken response, but suggests + # the OP should omit those. So lets drop them here. + for key_ in [ + key_ for key_, val in self._dict.items() if val is None or val == "" + ]: + del self[key_] + return result + def verify(self, **kwargs): super().verify(**kwargs) - if "birthdate" in self and self["birthdate"]: + if "birthdate" in self: # Either YYYY-MM-DD or just YYYY or 0000-MM-DD try: time.strptime(self["birthdate"], "%Y-%m-%d") diff --git a/tests/test_oic_message.py b/tests/test_oic_message.py index f930b9d2..d09acdc8 100644 --- a/tests/test_oic_message.py +++ b/tests/test_oic_message.py @@ -59,10 +59,24 @@ def _eq(l1, l2): return set(l1) == set(l2) -def test_openidschema(): - inp = '{"middle_name":null, "updated_at":"20170328081544", "sub":"abc", "birthdate": null}' - ois = OpenIDSchema().from_json(inp) - assert ois.verify() is False +@pytest.mark.parametrize( + "json_param,claim", + [ + ( + '{"middle_name":null, "updated_at":"20170328081544", "sub":"abc"}', + "middle_name", + ), + ('{"birthdate":null, "updated_at":"20170328081544", "sub":"abc"}', "birthdate"), + ( + '{"family_name": "", "updated_at":"20170328081544", "sub":"abc"}', + "family_name", + ), + ], +) +def test_openidschema(json_param, claim): + ois = OpenIDSchema().from_json(json_param) + assert ois.verify() is True + assert claim not in ois @pytest.mark.parametrize(