diff --git a/src/pyff/builtins.py b/src/pyff/builtins.py index 8bdd3a2d..4fee0ab8 100644 --- a/src/pyff/builtins.py +++ b/src/pyff/builtins.py @@ -844,14 +844,14 @@ def select(req: Plumbing.Request, *opts): def _strings(elt): lst = [] for attr in [ - '{%s}DisplayName' % NS['mdui'], + './/{%s}UIInfo/{%s}DisplayName' % (NS['mdui'], NS['mdui']), '{%s}ServiceName' % NS['md'], '{%s}OrganizationDisplayName' % NS['md'], '{%s}OrganizationName' % NS['md'], - '{%s}Keywords' % NS['mdui'], + './/{%s}UIInfo/{%s}Keywords' % (NS['mdui'], NS['mdui']), '{%s}Scope' % NS['shibmd'], ]: - lst.extend([s.text for s in elt.iter(attr)]) + lst.extend([s.text for s in elt.iterfind(attr)]) lst.append(elt.get('entityID')) return [item for item in lst if item is not None] diff --git a/src/pyff/samlmd.py b/src/pyff/samlmd.py index c6f445b3..7923a5ba 100644 --- a/src/pyff/samlmd.py +++ b/src/pyff/samlmd.py @@ -698,12 +698,12 @@ def gen_icon(e): def entity_icon_url(e, langs=None): - for ico in filter_lang(e.iter("{%s}Logo" % NS['mdui']), langs=langs): + for ico in filter_lang(e.iterfind(".//{%s}UIInfo/{%s}Logo" % (NS['mdui'], NS['mdui'])), langs=langs): return dict(url=ico.text, width=ico.get('width'), height=ico.get('height')) def privacy_statement_url(entity, langs): - for url in filter_lang(entity.iter("{%s}PrivacyStatementURL" % NS['mdui']), langs=langs): + for url in filter_lang(entity.iterfind(".//{%s}UIInfo/{%s}PrivacyStatementURL" % (NS['mdui'], NS['mdui'])), langs=langs): return url.text @@ -732,12 +732,12 @@ def entity_extended_display_i18n(entity, default_lang=None): ) name_dict.update(lang_dict(entity.iter("{%s}ServiceName" % NS['md']), lambda e: e.text, default_lang=default_lang)) name_dict.update( - lang_dict(entity.iter("{%s}DisplayName" % NS['mdui']), lambda e: e.text, default_lang=default_lang) + lang_dict(entity.iterfind(".//{%s}UIInfo/{%s}DisplayName" % (NS['mdui'], NS['mdui'])), lambda e: e.text, default_lang=default_lang) ) desc_dict = lang_dict(entity.iter("{%s}OrganizationURL" % NS['md']), lambda e: e.text, default_lang=default_lang) desc_dict.update( - lang_dict(entity.iter("{%s}Description" % NS['mdui']), lambda e: e.text, default_lang=default_lang) + lang_dict(entity.iterfind(".//{%s}UIInfo/{%s}Description" % (NS['mdui'], NS['mdui'])), lambda e: e.text, default_lang=default_lang) ) return name_dict, desc_dict @@ -825,7 +825,7 @@ def entity_extended_display(entity, langs=None): display = serviceName.text break - for displayName in filter_lang(entity.iter("{%s}DisplayName" % NS['mdui']), langs=langs): + for displayName in filter_lang(entity.iterfind(".//{%s}UIInfo/{%s}DisplayName" % (NS['mdui'], NS['mdui'])), langs=langs): info = display display = displayName.text break @@ -834,7 +834,7 @@ def entity_extended_display(entity, langs=None): info = organizationUrl.text break - for description in filter_lang(entity.iter("{%s}Description" % NS['mdui']), langs=langs): + for description in filter_lang(entity.iterfind(".//{%s}UIInfo/{%s}Description" % (NS['mdui'], NS['mdui'])), langs=langs): info = description.text break @@ -850,7 +850,7 @@ def entity_display_name(entity: Element, langs=None) -> str: :param entity: An EntityDescriptor element :param langs: The list of languages to search in priority order """ - for displayName in filter_lang(entity.iter("{%s}DisplayName" % NS['mdui']), langs=langs): + for displayName in filter_lang(entity.iterfind(".//{%s}UIInfo/{%s}DisplayName" % (NS['mdui'], NS['mdui'])), langs=langs): return displayName.text.strip() for serviceName in filter_lang(entity.iter("{%s}ServiceName" % NS['md']), langs=langs): @@ -946,7 +946,7 @@ def discojson(e, sources=None, langs=None, fallback_to_favicon=False, icon_store icon_info['url'] = ico d['entity_icon_url'] = icon_info - keywords = filter_lang(e.iter("{%s}Keywords" % NS['mdui']), langs=langs) + keywords = filter_lang(e.iterfind(".//{%s}UIInfo/{%s}Keywords" % (NS['mdui'], NS['mdui'])), langs=langs) if keywords is not None: lst = [elt.text for elt in keywords] if len(lst) > 0: @@ -1214,7 +1214,7 @@ def entity_simple_info(e, langs=None): d['service_name'] = entity_service_name(e, langs) d['service_descr'] = entity_service_description(e, langs) d['entity_attributes'] = entity_attribute_dict(e) - keywords = filter_lang(e.iter("{%s}Keywords" % NS['mdui']), langs=langs) + keywords = filter_lang(e.iterfind(".//{%s}UIInfo/{%s}Keywords" % (NS['mdui'], NS['mdui'])), langs=langs) if keywords is not None: lst = [elt.text for elt in keywords] if len(lst) > 0: @@ -1224,7 +1224,7 @@ def entity_simple_info(e, langs=None): def entity_info(e, langs=None): d = entity_simple_summary(e) - keywords = filter_lang(e.iter("{%s}Keywords" % NS['mdui']), langs=langs) + keywords = filter_lang(e.iterfind(".//{%s}UIInfo/{%s}Keywords" % (NS['mdui'], NS['mdui'])), langs=langs) if keywords is not None: lst = [elt.text for elt in keywords] if len(lst) > 0: diff --git a/src/pyff/store.py b/src/pyff/store.py index c4c31b33..f0f197a1 100644 --- a/src/pyff/store.py +++ b/src/pyff/store.py @@ -413,14 +413,14 @@ def search(self, query=None, path=None, entity_filter=None, related=None): def _strings(elt): lst = [] for attr in [ - '{%s}DisplayName' % NS['mdui'], + './/{%s}UIInfo/{%s}DisplayName' % (NS['mdui'], NS['mdui']), '{%s}ServiceName' % NS['md'], '{%s}OrganizationDisplayName' % NS['md'], '{%s}OrganizationName' % NS['md'], - '{%s}Keywords' % NS['mdui'], + './/{%s}UIInfo/{%s}Keywords' % (NS['mdui'], NS['mdui']), '{%s}Scope' % NS['shibmd'], ]: - lst.extend([s.text for s in elt.iter(attr)]) + lst.extend([s.text for s in elt.iterfind(attr)]) lst.append(elt.get('entityID')) return [item for item in lst if item is not None] diff --git a/src/pyff/test/data/metadata/test-scoped-display-name.xml b/src/pyff/test/data/metadata/test-scoped-display-name.xml new file mode 100644 index 00000000..c3aa6a68 --- /dev/null +++ b/src/pyff/test/data/metadata/test-scoped-display-name.xml @@ -0,0 +1,60 @@ + + + + + example.com + 81098135.example.com + + Scoped Example Universitet + Scoped Example University + + + Example universitet + Example University + Identity Provider för Example universitet + Identity Provider for Example University + http://www.example.com/ + http://www.example.com/english/ + https://www.example.com/static/images/umu_logo.jpg + https://www.example.com/static/images/logo.jpg + https://www.example.com/static/images/logo_eng.jpg + exempel + example + + + example.com + example.net + 10.0.0.0/8 + + + + + urn:oasis:names:tc:SAML:2.0:nameid-format:transient + + + + ExempelU + ExampleU + Exempel Universitetet + The Example University + http://www.example.com + http://www.example.com/english + + + Example University + Example helpdesk + helpdesk@example.com + + + Example University + Example helpdesk + helpdesk@example.com + + + Example University + Servicedesk Example universitet + support@example.com + + diff --git a/src/pyff/test/test_pipeline.py b/src/pyff/test/test_pipeline.py index d4c687f4..44e95094 100644 --- a/src/pyff/test/test_pipeline.py +++ b/src/pyff/test/test_pipeline.py @@ -795,3 +795,36 @@ def test_discojson_sp_trustinfo_in_attr(self): pass finally: shutil.rmtree(tmpdir) + + def test_discojson_scoped_display_name(self): + with patch.multiple("sys", exit=self.sys_exit): + tmpdir = tempfile.mkdtemp() + os.rmdir(tmpdir) # lets make sure 'store' can recreate it + try: + self.exec_pipeline(""" +- load: + - file://%s/metadata/test-scoped-display-name.xml +- select +- discojson +- publish: + output: %s/disco.json + raw: true + update_store: false +""" % (self.datadir, tmpdir)) + fn = "%s/disco.json" % tmpdir + assert os.path.exists(fn) + with open(fn, 'r') as f: + idps_json = json.load(f) + + idp_json = idps_json[0] + assert idp_json['title'] == 'Example University' + assert idp_json['title_langs']['sv'] == 'Example universitet' + assert idp_json['title_langs']['en'] == 'Example University' + assert idp_json['descr'] == 'Identity Provider for Example University' + assert idp_json['descr_langs']['sv'] == 'Identity Provider för Example universitet' + assert idp_json['descr_langs']['en'] == 'Identity Provider for Example University' + assert idp_json['keywords'] == 'example' + except IOError: + pass + finally: + shutil.rmtree(tmpdir)