1
1
from __future__ import print_function
2
+
3
+ import hashlib
2
4
import logging
3
5
import os
4
6
import sys
5
7
import json
6
- import six
7
8
9
+ import requests
10
+ import six
8
11
from hashlib import sha1
9
12
from os .path import isfile , join
10
13
from saml2 .httpbase import HTTPBase
11
14
from saml2 .extension .idpdisc import BINDING_DISCO
12
15
from saml2 .extension .idpdisc import DiscoveryResponse
13
16
from saml2 .md import EntitiesDescriptor
14
-
15
17
from saml2 .mdie import to_dict
16
-
17
18
from saml2 import md
18
19
from saml2 import samlp
19
20
from saml2 import SAMLError
@@ -67,6 +68,20 @@ class ToOld(Exception):
67
68
68
69
# ---------------------------------------------------
69
70
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
+
70
85
71
86
def destinations (srvs ):
72
87
return [s ["location" ] for s in srvs ]
@@ -564,8 +579,8 @@ def parse_and_check_signature(self, txt):
564
579
return True
565
580
566
581
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 )
569
584
570
585
if self .security .verify_signature (
571
586
txt , node_name = node_name , cert_file = self .cert ):
@@ -705,41 +720,41 @@ class MetaDataMDX(InMemoryMetaData):
705
720
""" Uses the md protocol to fetch entity information
706
721
"""
707
722
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 ):
710
729
"""
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
712
733
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.
720
736
"""
721
- super (MetaDataMDX , self ).__init__ (onts , attrc , ** kwargs )
737
+ super (MetaDataMDX , self ).__init__ (None , None )
722
738
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
727
745
728
746
def load (self ):
747
+ # Do nothing
729
748
pass
730
749
731
750
def __getitem__ (self , item ):
732
751
try :
733
752
return self .entity [item ]
734
753
except KeyError :
735
754
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 })
738
757
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
-
743
758
_txt = response .text .encode ("utf-8" )
744
759
745
760
if self .parse_and_check_signature (_txt ):
@@ -748,6 +763,12 @@ def __getitem__(self, item):
748
763
logger .info ("Response status: %s" , response .status_code )
749
764
raise KeyError
750
765
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
+
751
772
752
773
class MetadataStore (MetaData ):
753
774
def __init__ (self , onts , attrc , config , ca_certs = None ,
0 commit comments