From 8dd59fedeb227ace6fa26d7b266f027dee3fc773 Mon Sep 17 00:00:00 2001 From: Rastislav Krutak Date: Tue, 14 Mar 2023 16:14:12 +0100 Subject: [PATCH 1/3] Add logo to metadata collectors --- src/swamid_plugins/metainfo/collectors/oidc.py | 6 ++++++ src/swamid_plugins/metainfo/collectors/saml.py | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/swamid_plugins/metainfo/collectors/oidc.py b/src/swamid_plugins/metainfo/collectors/oidc.py index 145b242..490f865 100644 --- a/src/swamid_plugins/metainfo/collectors/oidc.py +++ b/src/swamid_plugins/metainfo/collectors/oidc.py @@ -1,6 +1,7 @@ def collect_entity_metadata(mdstore, entity_id): metadata = { "display_name": get_display_name(mdstore, entity_id), + "logo": get_logo(mdstore, entity_id), "privacy_statement": get_privacy_statement(mdstore, entity_id), "contacts": get_contacts(mdstore, entity_id), "entity_categories": get_entity_categories(mdstore, entity_id), @@ -18,6 +19,11 @@ def get_display_name(mdstore, entity_id): return display_name +def get_logo(mdstore, entity_id): + logo = mdstore.get("logo_uri") + return logo + + def get_privacy_statement(mdstore, entity_id): privacy_statement = mdstore.get("policy_uri") return privacy_statement diff --git a/src/swamid_plugins/metainfo/collectors/saml.py b/src/swamid_plugins/metainfo/collectors/saml.py index ded7ee6..f1ec87f 100644 --- a/src/swamid_plugins/metainfo/collectors/saml.py +++ b/src/swamid_plugins/metainfo/collectors/saml.py @@ -1,6 +1,7 @@ def collect_entity_metadata(mdstore, entity_id): metadata = { "display_name": get_display_name(mdstore, entity_id), + "logo": get_logo(mdstore, entity_id), "privacy_statement": get_privacy_statement(mdstore, entity_id), "contacts": get_contacts(mdstore, entity_id), "entity_categories": get_entity_categories(mdstore, entity_id), @@ -21,6 +22,11 @@ def get_display_name(mdstore, entity_id): return display_name +def get_logo(mdstore, entity_id): + logo = next(mdstore.mdui_uiinfo_logo(entity_id), None) + return logo + + def get_privacy_statement(mdstore, entity_id): privacy_statement = next( mdstore.mdui_uiinfo_privacy_statement_url(entity_id, langpref="en"), None From 460017352d599cb3ca86435916179587ba6d28a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pavel=20B=C5=99ou=C5=A1ek?= Date: Wed, 12 Apr 2023 22:16:10 +0200 Subject: [PATCH 2/3] fix: prevent KeyError when error_url is missing --- src/swamid_plugins/metainfo/collectors/saml.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/swamid_plugins/metainfo/collectors/saml.py b/src/swamid_plugins/metainfo/collectors/saml.py index f1ec87f..f2c60cf 100644 --- a/src/swamid_plugins/metainfo/collectors/saml.py +++ b/src/swamid_plugins/metainfo/collectors/saml.py @@ -63,6 +63,7 @@ def get_error_url(mdstore, entity_id): error_url = [ idpsso['error_url'] for idpsso in mdstore[entity_id].get('idpsso_descriptor', []) + if 'error_url' in idpsso ] return error_url From 85ef6c5269705f160d2a2c95cd6dad7a0dd4e5ba Mon Sep 17 00:00:00 2001 From: Rastislav Krutak <492918@mail.muni.cz> Date: Mon, 24 Apr 2023 14:13:09 +0200 Subject: [PATCH 3/3] feat: saml name and logo collected as arrays --- examples/metainfo.yaml | 6 +++ .../metainfo/collectors/oidc.py | 39 ++++++++++++------- .../metainfo/collectors/saml.py | 29 +++++++++----- src/swamid_plugins/metainfo/metainfo.py | 24 +++++++----- 4 files changed, 66 insertions(+), 32 deletions(-) create mode 100644 examples/metainfo.yaml diff --git a/examples/metainfo.yaml b/examples/metainfo.yaml new file mode 100644 index 0000000..5163695 --- /dev/null +++ b/examples/metainfo.yaml @@ -0,0 +1,6 @@ +module: swamid_plugins.metainfo.metainfo.MetaInfoIssuer +name: MetaInfoIssuer +config: + langs: + - en + - cz diff --git a/src/swamid_plugins/metainfo/collectors/oidc.py b/src/swamid_plugins/metainfo/collectors/oidc.py index 490f865..bfe670f 100644 --- a/src/swamid_plugins/metainfo/collectors/oidc.py +++ b/src/swamid_plugins/metainfo/collectors/oidc.py @@ -1,11 +1,13 @@ -def collect_entity_metadata(mdstore, entity_id): +def collect_entity_metadata(mdstore, entity_id, langs): metadata = { - "display_name": get_display_name(mdstore, entity_id), + "display_names": get_display_names_lang(mdstore, entity_id, langs), "logo": get_logo(mdstore, entity_id), "privacy_statement": get_privacy_statement(mdstore, entity_id), "contacts": get_contacts(mdstore, entity_id), "entity_categories": get_entity_categories(mdstore, entity_id), - "supported_entity_categories": get_supported_entity_categories(mdstore, entity_id), + "supported_entity_categories": get_supported_entity_categories( + mdstore, entity_id + ), "assurance_certifications": get_assurance_certifications(mdstore, entity_id), "registration_info": get_registration_info(mdstore, entity_id), "error_url": get_error_url(mdstore, entity_id), @@ -14,14 +16,25 @@ def collect_entity_metadata(mdstore, entity_id): return metadata -def get_display_name(mdstore, entity_id): - display_name = mdstore.get("client_name") - return display_name +def get_display_names_lang(mdstore, entity_id, langs=None): + if not langs: + langs = ["en"] + display_names = [] + for lang in langs: + if mdstore.get("client_name#" + lang, None): + display_names.append( + {"text": mdstore.get("client_name#" + lang), "lang": lang} + ) + return display_names def get_logo(mdstore, entity_id): + ret_logo = [] logo = mdstore.get("logo_uri") - return logo + width = mdstore.get("logo_width") + height = mdstore.get("logo_height") + ret_logo.append({"text": logo, "height": height, "width": width}) + return ret_logo def get_privacy_statement(mdstore, entity_id): @@ -39,7 +52,7 @@ def get_contacts(mdstore, entity_id): "mailto:{contact}".format(contact=email) for email in (mdstore.get("contacts") or []) ], - "given_name": "" + "given_name": "", }, { "contact_type": "technical", @@ -47,7 +60,7 @@ def get_contacts(mdstore, entity_id): "mailto:{contact}".format(contact=email) for email in (mdstore.get("technical_contacts") or []) ], - "given_name": "" + "given_name": "", }, { "contact_type": "security", @@ -55,7 +68,7 @@ def get_contacts(mdstore, entity_id): "mailto:{contact}".format(contact=email) for email in (mdstore.get("security_contacts") or []) ], - "given_name": "" + "given_name": "", }, ] if contact["email_address"] @@ -65,8 +78,8 @@ def get_contacts(mdstore, entity_id): def get_entity_categories(mdstore, entity_id): entity_categories_translation = { - 'research_and_scholarship': 'http://refeds.org/category/research-and-scholarship', - 'geant_coco': 'http://www.geant.net/uri/dataprotection-code-of-conduct/v1', + "research_and_scholarship": "http://refeds.org/category/research-and-scholarship", + "geant_coco": "http://www.geant.net/uri/dataprotection-code-of-conduct/v1", } entity_categories = [ category @@ -83,7 +96,7 @@ def get_supported_entity_categories(mdstore, entity_id): def get_assurance_certifications(mdstore, entity_id): assurance_certifications_translations = { - 'sirtfi': 'https://refeds.org/sirtfi', + "sirtfi": "https://refeds.org/sirtfi", } assurance_certifications = [ certification diff --git a/src/swamid_plugins/metainfo/collectors/saml.py b/src/swamid_plugins/metainfo/collectors/saml.py index f2c60cf..b3a0fdd 100644 --- a/src/swamid_plugins/metainfo/collectors/saml.py +++ b/src/swamid_plugins/metainfo/collectors/saml.py @@ -1,6 +1,6 @@ -def collect_entity_metadata(mdstore, entity_id): +def collect_entity_metadata(mdstore, entity_id, langs): metadata = { - "display_name": get_display_name(mdstore, entity_id), + "display_names": get_display_names_lang(mdstore, entity_id, langs), "logo": get_logo(mdstore, entity_id), "privacy_statement": get_privacy_statement(mdstore, entity_id), "contacts": get_contacts(mdstore, entity_id), @@ -14,17 +14,26 @@ def collect_entity_metadata(mdstore, entity_id): return metadata -def get_display_name(mdstore, entity_id): - display_name = ( - next(mdstore.mdui_uiinfo_display_name(entity_id, langpref="en"), None) - or mdstore.name(entity_id) - ) - return display_name +def get_display_names_lang(mdstore, entity_id, langs=None): + uiinfos = mdstore.mdui_uiinfo(entity_id) + cls = "urn:oasis:names:tc:SAML:metadata:ui&DisplayName" + elements = list(( + element + for uiinfo in uiinfos + for element_key, elements in uiinfo.items() + if element_key != "__class__" + for element in elements + if element.get("__class__") == cls + )) + list(map(lambda name: name.pop("__class__", None), elements)) + elements = list(filter(lambda x: x["lang"] in langs, elements)) + return elements def get_logo(mdstore, entity_id): - logo = next(mdstore.mdui_uiinfo_logo(entity_id), None) - return logo + logos = list(mdstore.mdui_uiinfo_logo(entity_id)) + list(map(lambda logo: logo.pop("__class__", None), logos)) + return logos def get_privacy_statement(mdstore, entity_id): diff --git a/src/swamid_plugins/metainfo/metainfo.py b/src/swamid_plugins/metainfo/metainfo.py index 495462f..945bd0d 100644 --- a/src/swamid_plugins/metainfo/metainfo.py +++ b/src/swamid_plugins/metainfo/metainfo.py @@ -8,7 +8,6 @@ import re - KEY_STATE = "MetaInfoService" KEY_ISSUER_METADATA = "metadata_store" KEY_SAML_REQUESTER_METADATA = "metadata_store" @@ -18,24 +17,26 @@ ) -def is_oidc_client(entity_id): +def is_oidc_client(entity_id, mdstore=None): + if mdstore: + return isinstance(mdstore, dict) result = entity_id.startswith("APP-") or bool(UUID4HEX.match(entity_id)) return result -def collect_entity_metadata(mdstore, metadata, entity_id): +def collect_entity_metadata(mdstore, metadata, entity_id, langs): entity_metadata = ( {} if not mdstore - else collect_oidc_entity_metadata(mdstore, entity_id) - if is_oidc_client(entity_id) - else collect_saml_entity_metadata(mdstore, entity_id) + else collect_oidc_entity_metadata(mdstore, entity_id, langs) + if is_oidc_client(entity_id, mdstore) + else collect_saml_entity_metadata(mdstore, entity_id, langs) ) return entity_metadata -def update_metadata_with_entity(mdstore, metadata, entity_id): - entity_metadata = collect_entity_metadata(mdstore, metadata, entity_id) +def update_metadata_with_entity(mdstore, metadata, entity_id, langs=None): + entity_metadata = collect_entity_metadata(mdstore, metadata, entity_id, langs) updated_metadata = ( {**metadata, entity_id: entity_metadata} if entity_metadata else metadata ) @@ -51,13 +52,14 @@ def process(self, context, internal_data): metadata = self.extract_metadata_state(context.state) entity_id = self.get_entity_id(internal_data) mdstore = self.get_metadata_store(context, entity_id) - + langs = getattr(self, "langs") has_been_processed = entity_id in metadata metadata_new = ( update_metadata_with_entity( mdstore=mdstore, metadata=metadata, entity_id=entity_id, + langs=langs, ) if not has_been_processed else metadata @@ -112,6 +114,10 @@ class MetaInfoIssuer(_MetaInfoService, ResponseMicroService): ``` """ + def __init__(self, config, *args, **kwargs): + super().__init__(*args, **kwargs) + self.langs = config.get("langs", None) + def extract_metadata_state(self, state): metadata = state.pop(KEY_STATE, {}).get("metadata", {}) return metadata