Skip to content

Commit 2ce425c

Browse files
author
Roland Hedberg
committed
Fixed a problem in parsing metadata extensions.
1 parent 0218b0b commit 2ce425c

File tree

6 files changed

+167
-83
lines changed

6 files changed

+167
-83
lines changed

src/saml2/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ def extension_elements_to_elements(extension_elements, schemas):
979979
if isinstance(schemas, list):
980980
pass
981981
elif isinstance(schemas, dict):
982-
schemas = schemas.values()
982+
schemas = list(schemas.values())
983983
else:
984984
return res
985985

src/saml2/mdstore.py

Lines changed: 47 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
from __future__ import print_function
2+
3+
import hashlib
24
import logging
35
import os
46
import sys
57
import json
6-
import six
78

9+
import requests
10+
import six
811
from hashlib import sha1
912
from os.path import isfile, join
1013
from saml2.httpbase import HTTPBase
1114
from saml2.extension.idpdisc import BINDING_DISCO
1215
from saml2.extension.idpdisc import DiscoveryResponse
1316
from saml2.md import EntitiesDescriptor
14-
1517
from saml2.mdie import to_dict
16-
1718
from saml2 import md
1819
from saml2 import samlp
1920
from saml2 import SAMLError
@@ -67,6 +68,20 @@ class ToOld(Exception):
6768

6869
# ---------------------------------------------------
6970

71+
def load_extensions():
72+
from saml2 import extension
73+
import pkgutil
74+
75+
package = extension
76+
prefix = package.__name__ + "."
77+
ext_map = {}
78+
for importer, modname, ispkg in pkgutil.iter_modules(package.__path__,
79+
prefix):
80+
module = __import__(modname, fromlist="dummy")
81+
ext_map[module.NAMESPACE] = module
82+
83+
return ext_map
84+
7085

7186
def destinations(srvs):
7287
return [s["location"] for s in srvs]
@@ -564,8 +579,8 @@ def parse_and_check_signature(self, txt):
564579
return True
565580

566581
node_name = self.node_name \
567-
or "%s:%s" % (md.EntitiesDescriptor.c_namespace,
568-
md.EntitiesDescriptor.c_tag)
582+
or "%s:%s" % (md.EntitiesDescriptor.c_namespace,
583+
md.EntitiesDescriptor.c_tag)
569584

570585
if self.security.verify_signature(
571586
txt, node_name=node_name, cert_file=self.cert):
@@ -705,41 +720,41 @@ class MetaDataMDX(InMemoryMetaData):
705720
""" Uses the md protocol to fetch entity information
706721
"""
707722

708-
def __init__(self, entity_transform, onts, attrc, url, security, cert,
709-
http, **kwargs):
723+
@staticmethod
724+
def sha1_entity_transform(entity_id):
725+
return "{{sha1}}{}".format(
726+
hashlib.sha1(entity_id.encode("utf-8")).hexdigest())
727+
728+
def __init__(self, url, entity_transform=None):
710729
"""
711-
:params entity_transform: function transforming (e.g. base64 or sha1
730+
:params url: mdx service url
731+
:params entity_transform: function transforming (e.g. base64,
732+
sha1 hash or URL quote
712733
hash) the entity id. It is applied to the entity id before it is
713-
concatenated with the request URL sent to the MDX server.
714-
:params onts:
715-
:params attrc:
716-
:params url:
717-
:params security: SecurityContext()
718-
:params cert:
719-
:params http:
734+
concatenated with the request URL sent to the MDX server. Defaults to
735+
sha1 transformation.
720736
"""
721-
super(MetaDataMDX, self).__init__(onts, attrc, **kwargs)
737+
super(MetaDataMDX, self).__init__(None, None)
722738
self.url = url
723-
self.security = security
724-
self.cert = cert
725-
self.http = http
726-
self.entity_transform = entity_transform
739+
740+
if entity_transform:
741+
self.entity_transform = entity_transform
742+
else:
743+
744+
self.entity_transform = MetaDataMDX.sha1_entity_transform
727745

728746
def load(self):
747+
# Do nothing
729748
pass
730749

731750
def __getitem__(self, item):
732751
try:
733752
return self.entity[item]
734753
except KeyError:
735754
mdx_url = "%s/entities/%s" % (self.url, self.entity_transform(item))
736-
response = self.http.send(
737-
mdx_url, headers={'Accept': SAML_METADATA_CONTENT_TYPE})
755+
response = requests.get(mdx_url, headers={
756+
'Accept': SAML_METADATA_CONTENT_TYPE})
738757
if response.status_code == 200:
739-
node_name = self.node_name \
740-
or "%s:%s" % (md.EntitiesDescriptor.c_namespace,
741-
md.EntitiesDescriptor.c_tag)
742-
743758
_txt = response.text.encode("utf-8")
744759

745760
if self.parse_and_check_signature(_txt):
@@ -748,6 +763,12 @@ def __getitem__(self, item):
748763
logger.info("Response status: %s", response.status_code)
749764
raise KeyError
750765

766+
def single_sign_on_service(self, entity_id, binding=None, typ="idpsso"):
767+
if binding is None:
768+
binding = BINDING_HTTP_REDIRECT
769+
return self.service(entity_id, "idpsso_descriptor",
770+
"single_sign_on_service", binding)
771+
751772

752773
class MetadataStore(MetaData):
753774
def __init__(self, onts, attrc, config, ca_certs=None,

0 commit comments

Comments
 (0)