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 145b242..bfe670f 100644 --- a/src/swamid_plugins/metainfo/collectors/oidc.py +++ b/src/swamid_plugins/metainfo/collectors/oidc.py @@ -1,10 +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), @@ -13,9 +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") + 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): @@ -33,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", @@ -41,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", @@ -49,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"] @@ -59,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 @@ -77,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 ded7ee6..b3a0fdd 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): +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), @@ -13,12 +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): + 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): @@ -57,6 +72,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 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