Skip to content

Commit 51382a2

Browse files
author
Roland Hedberg
committed
Merge pull request #61 from koliber/loader_remote_xml_option
Created another way of loading remote_metadata. Allows you to specify a ...
2 parents 1db2988 + 3e89dce commit 51382a2

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ dist/
1313
example/sp/identities
1414
subject.db
1515
.idea
16+
.project
17+
.pydevproject
1618
.DS_store
1719
.gitignore
1820
debug_*

src/saml2/mdstore.py

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from saml2.time_util import valid
2222
from saml2.validate import NotValid
2323
from saml2.sigver import security_context
24+
from importlib import import_module
2425

2526
__author__ = 'rolandh'
2627

@@ -134,8 +135,8 @@ def do_entity_descriptor(self, entity_descr):
134135

135136
# have I seen this entity_id before ? If so if log: ignore it
136137
if entity_descr.entity_id in self.entity:
137-
print >> sys.stderr,\
138-
"Duplicated Entity descriptor (entity id: '%s')" %\
138+
print >> sys.stderr, \
139+
"Duplicated Entity descriptor (entity id: '%s')" % \
139140
entity_descr.entity_id
140141
return
141142

@@ -353,8 +354,11 @@ def __init__(self, onts, attrc, filename, cert=None):
353354
self.filename = filename
354355
self.cert = cert
355356

357+
def get_metadata_content(self):
358+
return open(self.filename).read()
359+
356360
def load(self):
357-
_txt = open(self.filename).read()
361+
_txt = self.get_metadata_content()
358362
if self.cert:
359363
node_name = "%s:%s" % (md.EntitiesDescriptor.c_namespace,
360364
md.EntitiesDescriptor.c_tag)
@@ -369,6 +373,49 @@ def load(self):
369373
return True
370374

371375

376+
class MetaDataLoader(MetaDataFile):
377+
"""
378+
Handles Metadata file loaded by a passed in function.
379+
The format of the file is the SAML Metadata format.
380+
"""
381+
def __init__(self, onts, attrc, loader_callable, cert=None):
382+
MetaData.__init__(self, onts, attrc)
383+
self.metadata_provider_callable = self.get_metadata_loader(loader_callable)
384+
self.cert = cert
385+
386+
def get_metadata_loader(self, func):
387+
if callable(func):
388+
return func
389+
390+
i = func.rfind('.')
391+
module, attr = func[:i], func[i + 1:]
392+
try:
393+
mod = import_module(module)
394+
except Exception, e:
395+
raise RuntimeError('Cannot find metadata provider function %s: "%s"' % (func, e))
396+
397+
try:
398+
metadata_loader = getattr(mod, attr)
399+
except AttributeError:
400+
raise RuntimeError(
401+
'Module "%s" does not define a "%s" metadata loader' %
402+
(module, attr)
403+
)
404+
405+
if not callable(metadata_loader):
406+
raise RuntimeError(
407+
'Metadata loader %s.%s must be callable' %
408+
(module, attr)
409+
)
410+
411+
return metadata_loader
412+
413+
414+
415+
def get_metadata_content(self):
416+
return self.metadata_provider_callable()
417+
418+
372419
class MetaDataExtern(MetaData):
373420
"""
374421
Class that handles metadata store somewhere on the net.
@@ -463,6 +510,9 @@ def load(self, typ, *args, **kwargs):
463510
elif typ == "mdfile":
464511
key = args[0]
465512
md = MetaDataMD(self.onts, self.attrc, args[0])
513+
elif typ == "loader":
514+
key = args[0]
515+
md = MetaDataLoader(self.onts, self.attrc, args[0])
466516
else:
467517
raise SAMLError("Unknown metadata type '%s'" % typ)
468518

0 commit comments

Comments
 (0)