Skip to content

Commit 9ffff88

Browse files
committed
fetch external md sources for SPs in a child resource
1 parent c516f7b commit 9ffff88

File tree

3 files changed

+53
-10
lines changed

3 files changed

+53
-10
lines changed

src/pyff/samlmd.py

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,12 +182,39 @@ def parse(self, resource: Resource, content: str) -> SAMLParserInfo:
182182
resource.expire_time = expire_time
183183
info.expiration_time = str(expire_time)
184184

185+
def _extra_md(_t, info, **kwargs):
186+
entityID = kwargs.get('entityID')
187+
if info['alias'] != entityID:
188+
return _t
189+
sp_entities = kwargs.get('sp_entities')
190+
location = kwargs.get('location')
191+
sp_entity = sp_entities.find("{%s}EntityDescriptor[@entityID='%s']" % (NS['md'], entityID))
192+
if sp_entity is not None:
193+
md_source = sp_entity.find("{%s}SPSSODescriptor/{%s}Extensions/{%s}TrustInfo/{%s}MetadataSource[@src='%s']" % (NS['md'], NS['md'], NS['ti'], NS['ti'], location))
194+
for e in iter_entities(_t):
195+
md_source.append(e)
196+
return etree.Element("{%s}EntitiesDescriptor" % NS['md'])
197+
185198
if t is not None:
186199
resource.t = t
187200
resource.type = "application/samlmetadata+xml"
188201

189202
for e in iter_entities(t):
190-
info.entities.append(e.get('entityID'))
203+
entityID = e.get('entityID')
204+
info.entities.append(entityID)
205+
206+
md_source = e.find("{%s}SPSSODescriptor/{%s}Extensions/{%s}TrustInfo/{%s}MetadataSource" % (NS['md'], NS['md'], NS['ti'], NS['ti']))
207+
if md_source is not None:
208+
location = md_source.attrib.get('src')
209+
if location is not None:
210+
child_opts = resource.opts.copy(update={'alias': entityID})
211+
r = resource.add_child(location, child_opts)
212+
kwargs = {
213+
'entityID': entityID,
214+
'sp_entities': t,
215+
'location': location,
216+
}
217+
r.add_via(Lambda(_extra_md, **kwargs))
191218

192219
if trust_info is not None:
193220
resource.trust_info = trust_info
@@ -932,13 +959,19 @@ def discojson_sp(e, global_trust_info=None, global_md_sources=None):
932959

933960
sp['entityID'] = e.get('entityID', None)
934961

935-
# grab metadata sources, download metadata, and translate to json
936-
# md_source_urls = [el.text for el in tinfo_el.findall('.//{%s}MetadataSource' % NS['ti'])]
937-
# if len(md_source_urls) > 0:
938-
# try:
939-
# sp['extra_md'] = fetch_mdjson(md_source_urls)
940-
# except Exception as e:
941-
# raise ValueError(f"Problem interpreting metadata at {md_source_urls}: {e}")
962+
md_sources = e.findall("{%s}SPSSODescriptor/{%s}Extensions/{%s}TrustInfo/{%s}MetadataSource" % (NS['md'], NS['md'], NS['ti'], NS['ti']))
963+
964+
sp['extra_md'] = []
965+
for md_source in md_sources:
966+
dname_external = {}
967+
for dname in md_source.iterfind('.//{%s}DisplayName' % NS['ti']):
968+
lang = dname.attrib['{%s}lang' % NS['xml']]
969+
dname_external[lang] = dname.text
970+
971+
for idp in md_source.findall("{%s}EntityDescriptor" % NS['md']):
972+
idp_json = discojson(idp)
973+
idp_json['trusted'] = dname_external
974+
sp['extra_md'].append(idp_json)
942975

943976
sp['profiles'] = {}
944977
# Grab trust profile emements, and translate to json

src/pyff/schema/saml-metadata-trustinfo-v1.0.xsd

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,14 @@
3232
</sequence>
3333
</complexType>
3434

35-
<element name="MetadataSource" type="anyURI"/>
35+
<element name="MetadataSource" type="ti:MetadataSourceType"/>
36+
<complexType name="MetadataSourceType">
37+
<sequence minOccurs="0">
38+
<element ref="ti:DisplayName" minOccurs="0" maxOccurs="unbounded"/>
39+
<element ref="md:EntityDescriptor" minOccurs="0" maxOccurs="unbounded"/>
40+
</sequence>
41+
<attribute name="src" type="anyURI"/>
42+
</complexType>
3643

3744
<element name="TrustProfileRef" type="anyURI"/>
3845

src/pyff/test/data/metadata/test-sp.xml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@
4646
<md:SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
4747
<md:Extensions>
4848
<ti:TrustInfo xmlns:ti="https://seamlessaccess.org/NS/trustinfo">
49-
<ti:MetadataSource>https://login.uleam.cedia.edu.ec/saml2/idp/metadata.php</ti:MetadataSource>
49+
<ti:MetadataSource src="https://login.uleam.cedia.edu.ec/saml2/idp/metadata.php">
50+
<ti:DisplayName xml:lang="en">Display name for extra md - en</ti:DisplayName>
51+
<ti:DisplayName xml:lang="sv">Display name for extra md - sv</ti:DisplayName>
52+
</ti:MetadataSource>
5053
<ti:TrustProfile name="customer" strict="true">
5154
<ti:DisplayName xml:lang="en">Customer Access</ti:DisplayName>
5255
<ti:DisplayName xml:lang="sv">Kundinloggning</ti:DisplayName>

0 commit comments

Comments
 (0)