Moved s2repoze, xmkdsig and xmlenc under saml2.
Fixed bug in mdstore.MetadataStore in handling external metadata using the new config format.
This commit is contained in:
11
setup.py
11
setup.py
@@ -51,7 +51,7 @@ if sys.version_info < (2, 7):
|
||||
|
||||
setup(
|
||||
name='pysaml2',
|
||||
version='2.4.0',
|
||||
version='2.5.0',
|
||||
description='Python implementation of SAML Version 2',
|
||||
# long_description = read("README"),
|
||||
author='Roland Hedberg',
|
||||
@@ -59,14 +59,15 @@ setup(
|
||||
license='Apache 2.0',
|
||||
url='https://github.com/rohe/pysaml2',
|
||||
|
||||
packages=['saml2', 'xmldsig', 'xmlenc', 's2repoze', 's2repoze.plugins',
|
||||
"saml2/profile", "saml2/schema", "saml2/extension",
|
||||
"saml2/attributemaps", "saml2/authn_context",
|
||||
packages=['saml2', 'saml2/xmldsig', 'saml2/xmlenc', 'saml2/s2repoze',
|
||||
'saml2/s2repoze.plugins', "saml2/profile", "saml2/schema",
|
||||
"saml2/extension", "saml2/attributemaps", "saml2/authn_context",
|
||||
"saml2/entity_category", "saml2/userinfo"],
|
||||
|
||||
package_dir={'': 'src'},
|
||||
package_data={'': ['xml/*.xml']},
|
||||
classifiers=["Development Status :: 4 - Beta",
|
||||
classifiers=[
|
||||
"Development Status :: 4 - Beta",
|
||||
"License :: OSI Approved :: Apache Software License",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Programming Language :: Python :: 2.6",
|
||||
|
@@ -8,15 +8,17 @@ import sys
|
||||
|
||||
import logging
|
||||
import imp
|
||||
import xmldsig
|
||||
import xmlenc
|
||||
from saml2 import xmldsig
|
||||
from saml2 import xmlenc
|
||||
|
||||
from saml2.client import Saml2Client
|
||||
from saml2.config import SPConfig
|
||||
from saml2.mdstore import MetadataStore, ToOld
|
||||
from saml2.mdstore import MetadataStore
|
||||
from saml2.mdstore import MetaData
|
||||
from saml2.mdstore import ToOld
|
||||
|
||||
from saml2test import CheckError, FatalError
|
||||
from saml2test import CheckError
|
||||
from saml2test import FatalError
|
||||
from saml2test import exception_trace
|
||||
from saml2test import ContextFilter
|
||||
|
||||
|
@@ -31,8 +31,8 @@ from saml2.extension import idpdisc
|
||||
from saml2.extension import dri
|
||||
from saml2.extension import mdattr
|
||||
from saml2.extension import ui
|
||||
import xmldsig
|
||||
import xmlenc
|
||||
from saml2 import xmldsig
|
||||
from saml2 import xmlenc
|
||||
|
||||
|
||||
ONTS = {
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
import saml2
|
||||
from saml2 import SamlBase
|
||||
from xmldsig import X509Data
|
||||
from saml2.xmldsig import X509Data
|
||||
|
||||
NAMESPACE = 'urn:net:eustix:names:tc:PEFIM:0.0:assertion'
|
||||
|
||||
|
@@ -6,8 +6,7 @@
|
||||
|
||||
import saml2
|
||||
from saml2 import SamlBase
|
||||
|
||||
import xmldsig as ds
|
||||
from saml2 import xmldsig as ds
|
||||
|
||||
NAMESPACE = 'urn:mace:shibboleth:metadata:1.0'
|
||||
|
||||
|
@@ -5,11 +5,10 @@
|
||||
#
|
||||
|
||||
import saml2
|
||||
from saml2 import SamlBase
|
||||
|
||||
import xmldsig as ds
|
||||
import xmlenc as xenc
|
||||
from saml2 import saml
|
||||
from saml2 import SamlBase
|
||||
from saml2 import xmldsig as ds
|
||||
from saml2 import xmlenc as xenc
|
||||
|
||||
NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:metadata'
|
||||
|
||||
|
@@ -113,8 +113,8 @@ def repack_cert(cert):
|
||||
|
||||
|
||||
class MetaData(object):
|
||||
def __init__(self, onts, attrc, metadata='', node_name=None, check_validity=True,
|
||||
security=None, **kwargs):
|
||||
def __init__(self, onts, attrc, metadata='', node_name=None,
|
||||
check_validity=True, security=None, **kwargs):
|
||||
self.onts = onts
|
||||
self.attrc = attrc
|
||||
self.metadata = metadata
|
||||
@@ -616,7 +616,8 @@ class MetaDataExtern(InMemoryMetaData):
|
||||
Accessible but HTTP GET.
|
||||
"""
|
||||
|
||||
def __init__(self, onts, attrc, url=None, security=None, cert=None, http=None, **kwargs):
|
||||
def __init__(self, onts, attrc, url=None, security=None, cert=None,
|
||||
http=None, **kwargs):
|
||||
"""
|
||||
:params onts:
|
||||
:params attrc:
|
||||
@@ -827,8 +828,12 @@ class MetadataStore(object):
|
||||
|
||||
# Separately handle MDExtern
|
||||
if MDloader == MetaDataExtern:
|
||||
item['http'] = self.http
|
||||
item['security'] = self.security
|
||||
kwargs = {
|
||||
'http': self.http,
|
||||
'security': self.security
|
||||
}
|
||||
else:
|
||||
kwargs = {}
|
||||
|
||||
for key in item['metadata']:
|
||||
# Separately handle MetaDataFile and directory
|
||||
@@ -840,7 +845,11 @@ class MetadataStore(object):
|
||||
_md.load()
|
||||
self.metadata[_fil] = _md
|
||||
return
|
||||
_md = MDloader(self.onts, self.attrc, *key)
|
||||
|
||||
if len(key) == 2:
|
||||
kwargs["cert"] = key[1]
|
||||
|
||||
_md = MDloader(self.onts, self.attrc, key[0], **kwargs)
|
||||
_md.load()
|
||||
self.metadata[key[0]] = _md
|
||||
|
||||
|
@@ -19,7 +19,7 @@ from saml2 import BINDING_SOAP
|
||||
from saml2 import samlp
|
||||
from saml2 import class_name
|
||||
|
||||
import xmldsig as ds
|
||||
from saml2 import xmldsig as ds
|
||||
|
||||
from saml2.sigver import pre_signature_part
|
||||
|
||||
|
@@ -19,8 +19,8 @@ from saml2.extension import idpdisc
|
||||
from saml2.extension import dri
|
||||
from saml2.extension import mdattr
|
||||
from saml2.extension import ui
|
||||
import xmldsig
|
||||
import xmlenc
|
||||
from saml2 import xmldsig
|
||||
from saml2 import xmlenc
|
||||
|
||||
|
||||
ONTS = {
|
||||
|
@@ -26,8 +26,8 @@ from saml2.samlp import STATUS_UNKNOWN_PRINCIPAL
|
||||
from saml2.samlp import STATUS_UNSUPPORTED_BINDING
|
||||
from saml2.samlp import STATUS_RESPONDER
|
||||
|
||||
import xmldsig as ds
|
||||
import xmlenc as xenc
|
||||
from saml2 import xmldsig as ds
|
||||
from saml2 import xmlenc as xenc
|
||||
|
||||
from saml2 import samlp
|
||||
from saml2 import class_name
|
||||
|
@@ -14,7 +14,7 @@ import traceback
|
||||
import saml2
|
||||
from urlparse import parse_qs, urlparse
|
||||
from saml2.md import Extensions
|
||||
import xmldsig as ds
|
||||
from saml2 import xmldsig as ds
|
||||
|
||||
from StringIO import StringIO
|
||||
|
@@ -11,8 +11,8 @@ from saml2.validate import valid_domain_name
|
||||
import saml2
|
||||
from saml2 import SamlBase
|
||||
|
||||
import xmldsig as ds
|
||||
import xmlenc as xenc
|
||||
from saml2 import xmldsig as ds
|
||||
from saml2 import xmlenc as xenc
|
||||
|
||||
NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:assertion'
|
||||
|
||||
|
@@ -5,10 +5,9 @@
|
||||
#
|
||||
|
||||
import saml2
|
||||
from saml2 import SamlBase
|
||||
|
||||
import xmldsig as ds
|
||||
from saml2 import saml
|
||||
from saml2 import SamlBase
|
||||
from saml2 import xmldsig as ds
|
||||
|
||||
NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:protocol'
|
||||
|
||||
|
@@ -11,8 +11,8 @@ from saml2.extension import idpdisc
|
||||
from saml2.extension import dri
|
||||
from saml2.extension import mdattr
|
||||
from saml2.extension import ui
|
||||
import xmldsig
|
||||
import xmlenc
|
||||
from saml2 import xmldsig
|
||||
from saml2 import xmlenc
|
||||
|
||||
|
||||
ONTS = {
|
||||
|
@@ -7,25 +7,31 @@ Based on the use of xmlsec1 binaries and not the python xmlsec module.
|
||||
"""
|
||||
|
||||
import base64
|
||||
from binascii import hexlify
|
||||
import hashlib
|
||||
import logging
|
||||
import random
|
||||
import os
|
||||
import ssl
|
||||
from time import mktime
|
||||
import urllib
|
||||
|
||||
from time import mktime
|
||||
from binascii import hexlify
|
||||
|
||||
from Crypto.PublicKey.RSA import importKey
|
||||
from Crypto.Signature import PKCS1_v1_5
|
||||
from Crypto.Util.asn1 import DerSequence
|
||||
from Crypto.PublicKey import RSA
|
||||
from saml2.cert import OpenSSLWrapper
|
||||
from saml2.extension import pefim
|
||||
from saml2.saml import EncryptedAssertion
|
||||
from Crypto.Hash import SHA
|
||||
from Crypto.Hash import SHA224
|
||||
from Crypto.Hash import SHA256
|
||||
from Crypto.Hash import SHA384
|
||||
from Crypto.Hash import SHA512
|
||||
|
||||
import xmldsig as ds
|
||||
from tempfile import NamedTemporaryFile
|
||||
from subprocess import Popen
|
||||
from subprocess import PIPE
|
||||
|
||||
from saml2 import samlp, SamlBase
|
||||
from saml2 import samlp
|
||||
from saml2 import SamlBase
|
||||
from saml2 import SAMLError
|
||||
from saml2 import extension_elements_to_elements
|
||||
from saml2 import class_name
|
||||
@@ -33,32 +39,29 @@ from saml2 import saml
|
||||
from saml2 import ExtensionElement
|
||||
from saml2 import VERSION
|
||||
|
||||
from saml2.s_utils import sid, rndstr
|
||||
from saml2.cert import OpenSSLWrapper
|
||||
from saml2.extension import pefim
|
||||
from saml2.saml import EncryptedAssertion
|
||||
|
||||
import saml2.xmldsig as ds
|
||||
|
||||
from saml2.s_utils import sid
|
||||
from saml2.s_utils import Unsupported
|
||||
|
||||
from saml2.time_util import instant
|
||||
from saml2.time_util import utc_now
|
||||
from saml2.time_util import str_to_time
|
||||
|
||||
from tempfile import NamedTemporaryFile
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
from xmldsig import SIG_RSA_SHA1
|
||||
from xmldsig import SIG_RSA_SHA224
|
||||
from xmldsig import SIG_RSA_SHA256
|
||||
from xmldsig import SIG_RSA_SHA384
|
||||
from xmldsig import SIG_RSA_SHA512
|
||||
from xmlenc import EncryptionMethod
|
||||
from xmlenc import EncryptedKey
|
||||
from xmlenc import CipherData
|
||||
from xmlenc import CipherValue
|
||||
from xmlenc import EncryptedData
|
||||
|
||||
from Crypto.Hash import SHA
|
||||
from Crypto.Hash import SHA224
|
||||
from Crypto.Hash import SHA256
|
||||
from Crypto.Hash import SHA384
|
||||
from Crypto.Hash import SHA512
|
||||
from saml2.xmldsig import SIG_RSA_SHA1
|
||||
from saml2.xmldsig import SIG_RSA_SHA224
|
||||
from saml2.xmldsig import SIG_RSA_SHA256
|
||||
from saml2.xmldsig import SIG_RSA_SHA384
|
||||
from saml2.xmldsig import SIG_RSA_SHA512
|
||||
from saml2.xmlenc import EncryptionMethod
|
||||
from saml2.xmlenc import EncryptedKey
|
||||
from saml2.xmlenc import CipherData
|
||||
from saml2.xmlenc import CipherValue
|
||||
from saml2.xmlenc import EncryptedData
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@@ -6,8 +6,7 @@
|
||||
|
||||
import saml2
|
||||
from saml2 import SamlBase
|
||||
|
||||
import xmldsig as ds
|
||||
from saml2 import xmldsig as ds
|
||||
|
||||
NAMESPACE = 'http://www.w3.org/2001/04/xmlenc#'
|
||||
|
@@ -22,10 +22,7 @@ from saml2test.interaction import Action
|
||||
from saml2test.interaction import Interaction
|
||||
from saml2test.interaction import InteractionNeeded
|
||||
|
||||
import xmldsig as ds
|
||||
|
||||
from sp_test.tests import ErrorResponse
|
||||
from sp_test.check import VerifyEchopageContents
|
||||
|
||||
__author__ = 'rolandh'
|
||||
|
||||
|
@@ -11,7 +11,7 @@ try:
|
||||
except ImportError:
|
||||
from elementtree import ElementTree
|
||||
import ds_data
|
||||
import xmldsig as ds
|
||||
import saml2.xmldsig as ds
|
||||
|
||||
class TestObject:
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import saml2
|
||||
import xmlenc as xenc
|
||||
import xmldsig
|
||||
import saml2.xmlenc as xenc
|
||||
from saml2 import xmldsig
|
||||
|
||||
data1 = """<?xml version='1.0' encoding='UTF-8'?>
|
||||
<ns0:EncryptedData MimeType="text/xml" xmlns:ns0="http://www.w3.org/2001/04/xmlenc#">
|
||||
|
@@ -12,9 +12,10 @@ except ImportError:
|
||||
from elementtree import ElementTree
|
||||
|
||||
import saml2
|
||||
import saml2_data, ds_data
|
||||
import saml2_data
|
||||
import ds_data
|
||||
|
||||
import xmldsig as ds
|
||||
from saml2 import xmldsig as ds
|
||||
|
||||
from saml2 import saml
|
||||
|
||||
|
@@ -6,18 +6,17 @@
|
||||
|
||||
__author__ = 'roland.hedberg@adm.umu.se (Roland Hedberg)'
|
||||
|
||||
import unittest
|
||||
try:
|
||||
from xml.etree import ElementTree
|
||||
except ImportError:
|
||||
from elementtree import ElementTree
|
||||
import saml2
|
||||
|
||||
import saml2_data, ds_data, samlp_data
|
||||
import samlp_data
|
||||
|
||||
from saml2 import saml
|
||||
from saml2 import samlp
|
||||
import xmldsig as ds
|
||||
from saml2 import xmldsig as ds
|
||||
|
||||
|
||||
# class TestRequestAbstractType:
|
||||
|
@@ -13,8 +13,7 @@ except ImportError:
|
||||
from elementtree import ElementTree
|
||||
|
||||
import saml2
|
||||
import xmldsig as ds
|
||||
|
||||
from saml2 import xmldsig as ds
|
||||
from saml2 import saml
|
||||
from saml2 import samlp
|
||||
from saml2 import md
|
||||
|
@@ -61,16 +61,16 @@ METADATACONF = {
|
||||
"class": "saml2.mdstore.MetaDataFile",
|
||||
"metadata": [(full_path("extended.xml"), )],
|
||||
}],
|
||||
"7": [{
|
||||
"class": "saml2.mdstore.MetaDataFile",
|
||||
"metadata": [(full_path("metadata_sp_1.xml"), ),
|
||||
(full_path("InCommon-metadata.xml"), )], },
|
||||
{
|
||||
"class": "saml2.mdstore.MetaDataExtern",
|
||||
"metadata": [
|
||||
("https://kalmar2.org/simplesaml/module.php/aggregator/?id=kalmarcentral2&set=saml2",
|
||||
full_path("kalmar2.pem")), ],
|
||||
}],
|
||||
# "7": [{
|
||||
# "class": "saml2.mdstore.MetaDataFile",
|
||||
# "metadata": [(full_path("metadata_sp_1.xml"), ),
|
||||
# (full_path("InCommon-metadata.xml"), )], },
|
||||
# {
|
||||
# "class": "saml2.mdstore.MetaDataExtern",
|
||||
# "metadata": [
|
||||
# ("https://kalmar2.org/simplesaml/module.php/aggregator/?id=kalmarcentral2&set=saml2",
|
||||
# full_path("kalmar2.pem")), ],
|
||||
# }],
|
||||
"4": [{
|
||||
"class": "saml2.mdstore.MetaDataFile",
|
||||
"metadata": [(full_path("metadata_example.xml"), )],
|
||||
@@ -86,7 +86,14 @@ METADATACONF = {
|
||||
"9": [{
|
||||
"class": "saml2.mdstore.MetaDataFile",
|
||||
"metadata": [(full_path("metadata"), )]
|
||||
}]
|
||||
}],
|
||||
"10": [{
|
||||
"class": "saml2.mdstore.MetaDataExtern",
|
||||
"metadata": [
|
||||
("http://md.incommon.org/InCommon/InCommon-metadata-export.xml",
|
||||
full_path("inc-md-cert.pem"))]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -277,5 +284,16 @@ def test_load_local_dir():
|
||||
assert len(mds) == 3 # Three sources
|
||||
assert len(mds.keys()) == 4 # number of idps
|
||||
|
||||
|
||||
def test_load_extern_incommon():
|
||||
sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
|
||||
mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config,
|
||||
disable_ssl_certificate_validation=True)
|
||||
|
||||
mds.imp(METADATACONF["10"])
|
||||
print mds
|
||||
assert mds
|
||||
assert len(mds.keys())
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_load_local_dir()
|
||||
test_load_extern_incommon()
|
||||
|
@@ -58,13 +58,13 @@ METADATACONF = {
|
||||
"3": {
|
||||
"local": [full_path("extended.xml")]
|
||||
},
|
||||
"7": {
|
||||
"local": [full_path("metadata_sp_1.xml"),
|
||||
full_path("InCommon-metadata.xml")],
|
||||
"remote": [
|
||||
{"url": "https://kalmar2.org/simplesaml/module.php/aggregator/?id=kalmarcentral2&set=saml2",
|
||||
"cert": full_path("kalmar2.pem")}]
|
||||
},
|
||||
# "7": {
|
||||
# "local": [full_path("metadata_sp_1.xml"),
|
||||
# full_path("InCommon-metadata.xml")],
|
||||
# "remote": [
|
||||
# {"url": "https://kalmar2.org/simplesaml/module.php/aggregator/?id=kalmarcentral2&set=saml2",
|
||||
# "cert": full_path("kalmar2.pem")}]
|
||||
# },
|
||||
"4": {
|
||||
"local": [full_path("metadata_example.xml")]
|
||||
},
|
||||
@@ -76,6 +76,11 @@ METADATACONF = {
|
||||
},
|
||||
"9": {
|
||||
"local": [full_path("metadata")]
|
||||
},
|
||||
"10": {
|
||||
"remote": [
|
||||
{"url": "http://md.incommon.org/InCommon/InCommon-metadata-export.xml",
|
||||
"cert": full_path("inc-md-cert.pem")}]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -266,5 +271,16 @@ def test_load_local_dir():
|
||||
assert len(mds) == 3 # Three sources
|
||||
assert len(mds.keys()) == 4 # number of idps
|
||||
|
||||
|
||||
def test_load_external():
|
||||
sec_config.xmlsec_binary = sigver.get_xmlsec_binary(["/opt/local/bin"])
|
||||
mds = MetadataStore(ONTS.values(), ATTRCONV, sec_config,
|
||||
disable_ssl_certificate_validation=True)
|
||||
|
||||
mds.imp(METADATACONF["10"])
|
||||
print mds
|
||||
assert len(mds) == 1 # One source
|
||||
assert len(mds.keys()) > 1 # number of idps
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_mdx_certs()
|
||||
test_load_external()
|
||||
|
@@ -16,7 +16,7 @@ from pathutils import full_path
|
||||
|
||||
FALSE_ASSERT_SIGNED = full_path("saml_false_signed.xml")
|
||||
|
||||
TIMESLACK = 20000000 # Roughly +- 12 month
|
||||
TIMESLACK = 40000000 # Roughly +- 24 month
|
||||
|
||||
|
||||
def _eq(l1, l2):
|
||||
|
@@ -12,8 +12,8 @@ from saml2.extension import mdrpi
|
||||
from saml2.extension import mdui
|
||||
from saml2.extension import shibmd
|
||||
from saml2.extension import ui
|
||||
import xmldsig
|
||||
import xmlenc
|
||||
from saml2 import xmldsig
|
||||
from saml2 import xmlenc
|
||||
|
||||
import argparse
|
||||
|
||||
|
@@ -9,8 +9,8 @@ from saml2.extension import dri
|
||||
from saml2.extension import mdattr
|
||||
from saml2.extension import ui
|
||||
from saml2.extension import shibmd
|
||||
import xmldsig
|
||||
import xmlenc
|
||||
from saml2 import xmldsig
|
||||
from saml2 import xmlenc
|
||||
|
||||
from saml2.mdstore import MetaDataFile, MetaDataExtern
|
||||
|
||||
|
@@ -6,8 +6,8 @@ from saml2.mdstore import MetaDataMD, MetaDataFile
|
||||
|
||||
__author__ = 'rolandh'
|
||||
|
||||
import xmldsig
|
||||
import xmlenc
|
||||
from saml2 import xmldsig
|
||||
from saml2 import xmlenc
|
||||
from saml2 import md
|
||||
from saml2 import saml
|
||||
from saml2.extension import dri
|
||||
@@ -40,7 +40,7 @@ print time.time() - start
|
||||
start = time.time()
|
||||
for i in range(1, 10):
|
||||
mdf = MetaDataFile(ONTS.values(), ac_factory("../tests/attributemaps"),
|
||||
"../tests/swamid-2.0.xml")
|
||||
"../tests/swamid-2.0.xml")
|
||||
mdf.load()
|
||||
_ = mdf.keys()
|
||||
|
||||
|
@@ -12,8 +12,8 @@ from saml2.extension import mdrpi
|
||||
from saml2.extension import mdui
|
||||
from saml2.extension import shibmd
|
||||
from saml2.extension import ui
|
||||
import xmldsig
|
||||
import xmlenc
|
||||
from saml2 import xmldsig
|
||||
from saml2 import xmlenc
|
||||
|
||||
import argparse
|
||||
|
||||
|
@@ -1,10 +1,14 @@
|
||||
#!/usr/bin/env python
|
||||
from saml2.sigver import _get_xmlsec_cryptobackend, SecurityContext
|
||||
from saml2.httpbase import HTTPBase
|
||||
|
||||
import argparse
|
||||
|
||||
from saml2 import saml
|
||||
from saml2 import md
|
||||
from saml2 import xmldsig
|
||||
from saml2 import xmlenc
|
||||
|
||||
from saml2.attribute_converter import ac_factory
|
||||
from saml2.httpbase import HTTPBase
|
||||
from saml2.extension import dri
|
||||
from saml2.extension import idpdisc
|
||||
from saml2.extension import mdattr
|
||||
@@ -12,12 +16,12 @@ from saml2.extension import mdrpi
|
||||
from saml2.extension import mdui
|
||||
from saml2.extension import shibmd
|
||||
from saml2.extension import ui
|
||||
import xmldsig
|
||||
import xmlenc
|
||||
|
||||
import argparse
|
||||
from saml2.sigver import _get_xmlsec_cryptobackend
|
||||
from saml2.sigver import SecurityContext
|
||||
|
||||
from saml2.mdstore import MetaDataFile, MetaDataExtern
|
||||
from saml2.mdstore import MetaDataFile
|
||||
from saml2.mdstore import MetaDataExtern
|
||||
|
||||
__author__ = 'rolandh'
|
||||
|
||||
|
Reference in New Issue
Block a user