Updated IdP example2
This commit is contained in:
parent
d1523b6d5e
commit
7f777c2c38
@ -41,7 +41,7 @@ CONFIG={
|
||||
# This database holds the map between a subjects local identifier and
|
||||
# the identifier returned to a SP
|
||||
#"xmlsec_binary": "/usr/local/bin/xmlsec1",
|
||||
"attribute_map_dir" : "./attributemaps",
|
||||
"attribute_map_dir" : "../attributemaps",
|
||||
"logger": {
|
||||
"rotating": {
|
||||
"filename": "idp.log",
|
||||
|
@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
import base64
|
||||
|
||||
import re
|
||||
import logging
|
||||
@ -9,23 +10,24 @@ from hashlib import sha1
|
||||
from urlparse import parse_qs
|
||||
from Cookie import SimpleCookie
|
||||
|
||||
from saml2 import server, BINDING_HTTP_ARTIFACT
|
||||
from saml2 import server
|
||||
from saml2 import BINDING_HTTP_ARTIFACT
|
||||
from saml2 import BINDING_URI
|
||||
from saml2 import BINDING_PAOS
|
||||
from saml2 import BINDING_SOAP
|
||||
from saml2 import BINDING_HTTP_REDIRECT
|
||||
from saml2 import BINDING_HTTP_POST
|
||||
from saml2 import time_util
|
||||
from saml2.httputil import Response
|
||||
from saml2.httputil import Response, NotFound
|
||||
from saml2.httputil import get_post
|
||||
from saml2.httputil import Redirect
|
||||
from saml2.httputil import Unauthorized
|
||||
from saml2.httputil import BadRequest
|
||||
from saml2.httputil import ServiceError
|
||||
from saml2.ident import Unknown
|
||||
from saml2.s_utils import rndstr
|
||||
from saml2.s_utils import rndstr, UnknownPrincipal, UnsupportedBinding
|
||||
from saml2.s_utils import PolicyError
|
||||
from saml2.saml import AUTHN_PASSWORD
|
||||
from saml2.saml import NAMEID_FORMAT_PERSISTENT
|
||||
from saml2.saml import NameID
|
||||
|
||||
logger = logging.getLogger("saml2.idp")
|
||||
|
||||
@ -113,14 +115,15 @@ def dict2list_of_tuples(d):
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def _operation(environ, start_response, user, _dict, func, binding):
|
||||
def _operation(environ, start_response, user, _dict, func, binding,
|
||||
**kwargs):
|
||||
logger.debug("_operation: %s" % _dict)
|
||||
if not _dict:
|
||||
resp = BadRequest('Error parsing request or no request')
|
||||
return resp(environ, start_response)
|
||||
else:
|
||||
return func(environ, start_response, user, _dict["SAMLRequest"],
|
||||
binding, _dict["RelayState"])
|
||||
binding, _dict["RelayState"], **kwargs)
|
||||
|
||||
def _artifact_oper(environ, start_response, user, _dict, func):
|
||||
if not _dict:
|
||||
@ -133,6 +136,13 @@ def _artifact_oper(environ, start_response, user, _dict, func):
|
||||
return func(environ, start_response, user, request,
|
||||
BINDING_HTTP_ARTIFACT, _dict["RelayState"])
|
||||
|
||||
def _response(environ, start_response, binding, http_args):
|
||||
if binding == BINDING_HTTP_ARTIFACT:
|
||||
resp = Redirect()
|
||||
else:
|
||||
resp = Response(http_args["data"], headers=http_args["headers"])
|
||||
return resp(environ, start_response)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
AUTHN = (AUTHN_PASSWORD, "http://lingon.catalogix.se/login")
|
||||
|
||||
@ -146,7 +156,8 @@ FORM_SPEC = """<form name="myform" method="post" action="%s">
|
||||
# === Single log in ====
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def _sso(environ, start_response, user, query, binding, relay_state=""):
|
||||
def _sso(environ, start_response, user, query, binding, relay_state="",
|
||||
response_bindings=None):
|
||||
logger.info("--- In SSO ---")
|
||||
logger.debug("user: %s" % user)
|
||||
|
||||
@ -161,7 +172,16 @@ def _sso(environ, start_response, user, query, binding, relay_state=""):
|
||||
logger.info("%s" % req_info)
|
||||
_authn_req = req_info.message
|
||||
|
||||
resp_args = IDP.response_args(_authn_req)
|
||||
try:
|
||||
resp_args = IDP.response_args(_authn_req)
|
||||
except UnknownPrincipal, excp:
|
||||
#IDP.create_error_response()
|
||||
resp = ServiceError("UnknownPrincipal: %s" % (excp,))
|
||||
return resp(environ, start_response)
|
||||
except UnsupportedBinding, excp:
|
||||
#IDP.create_error_response()
|
||||
resp = ServiceError("UnsupportedBinding: %s" % (excp,))
|
||||
return resp(environ, start_response)
|
||||
|
||||
identity = USERS[user]
|
||||
logger.info("Identity: %s" % (identity,))
|
||||
@ -178,12 +198,13 @@ def _sso(environ, start_response, user, query, binding, relay_state=""):
|
||||
|
||||
logger.info("AuthNResponse: %s" % authn_resp)
|
||||
binding, destination = IDP.pick_binding("assertion_consumer_service",
|
||||
bindings=response_bindings,
|
||||
entity_id=_authn_req.issuer.text)
|
||||
logger.debug("Binding: %s, destination: %s" % (binding, destination))
|
||||
http_args = IDP.apply_binding(binding, "%s" % authn_resp, destination,
|
||||
relay_state, response=True)
|
||||
|
||||
resp = Response(http_args["data"], headers=http_args["headers"])
|
||||
return resp(environ, start_response)
|
||||
return _response(environ, start_response, binding, http_args)
|
||||
|
||||
def sso(environ, start_response, user):
|
||||
""" This is the HTTP-redirect endpoint """
|
||||
@ -222,6 +243,36 @@ def sso_art(environ, start_response, user):
|
||||
del IDP.ticket[_dict["key"]]
|
||||
return _artifact_oper(environ, start_response, user, _request, _sso)
|
||||
|
||||
def sso_ecp(environ, start_response, user):
|
||||
# The ECP interface
|
||||
logger.info("--- ECP SSO ---")
|
||||
logger.debug("ENVIRON: %s" % environ)
|
||||
resp = None
|
||||
|
||||
try:
|
||||
authz_info = environ["HTTP_AUTHORIZATION"]
|
||||
if authz_info.startswith("Basic "):
|
||||
_info = base64.b64decode(authz_info[6:])
|
||||
logger.debug("Authz_info: %s" % _info)
|
||||
try:
|
||||
(user,passwd) = _info.split(":")
|
||||
if PASSWD[user] != passwd:
|
||||
resp = Unauthorized()
|
||||
except ValueError:
|
||||
resp = Unauthorized()
|
||||
else:
|
||||
resp = Unauthorized()
|
||||
except KeyError:
|
||||
resp = Unauthorized()
|
||||
|
||||
if resp:
|
||||
return resp(environ, start_response)
|
||||
|
||||
_dict = unpack_soap(environ)
|
||||
# Basic auth ?!
|
||||
return _operation(environ, start_response, user, _dict, _sso, BINDING_SOAP,
|
||||
response_bindings=[BINDING_PAOS])
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# === Authentication ====
|
||||
# -----------------------------------------------------------------------------
|
||||
@ -286,12 +337,10 @@ def do_authentication(environ, start_response, cookie=None):
|
||||
def verify_username_and_password(dic):
|
||||
global PASSWD
|
||||
# verify username and password
|
||||
for user, pwd in PASSWD:
|
||||
if user == dic["login"][0]:
|
||||
if pwd == dic["password"][0]:
|
||||
return True, user
|
||||
|
||||
return False, ""
|
||||
if PASSWD[dic["login"][0]] == dic["password"][0]:
|
||||
return True, dic["login"][0]
|
||||
else:
|
||||
return False, ""
|
||||
|
||||
|
||||
def do_verify(environ, start_response, _user):
|
||||
@ -331,6 +380,7 @@ def _slo(environ, start_response, _, request, binding, relay_state=""):
|
||||
try:
|
||||
req_info = IDP.parse_logout_request(request, binding)
|
||||
except Exception, exc:
|
||||
logger.error("Bad request: %s" % exc)
|
||||
resp = BadRequest("%s" % exc)
|
||||
return resp(environ, start_response)
|
||||
|
||||
@ -342,6 +392,7 @@ def _slo(environ, start_response, _, request, binding, relay_state=""):
|
||||
try:
|
||||
IDP.remove_authn_statements(msg.name_id)
|
||||
except KeyError,exc:
|
||||
logger.error("ServiceError: %s" % exc)
|
||||
resp = ServiceError("%s" % exc)
|
||||
return resp(environ, start_response)
|
||||
|
||||
@ -350,6 +401,7 @@ def _slo(environ, start_response, _, request, binding, relay_state=""):
|
||||
try:
|
||||
hinfo = IDP.apply_binding(binding, "%s" % resp, "", relay_state)
|
||||
except Exception, exc:
|
||||
logger.error("ServiceError: %s" % exc)
|
||||
resp = ServiceError("%s" % exc)
|
||||
return resp(environ, start_response)
|
||||
|
||||
@ -410,9 +462,9 @@ def not_found(environ, start_response):
|
||||
return ['Not Found']
|
||||
|
||||
|
||||
PASSWD = [("roland", "dianakra"),
|
||||
("babs", "howes"),
|
||||
("upper", "crust")]
|
||||
PASSWD = {"roland": "dianakra",
|
||||
"babs": "howes",
|
||||
"upper": "crust"}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
@ -433,21 +485,24 @@ def kaka2user(kaka):
|
||||
|
||||
def _mni(environ, start_response, user, query, binding, relay_state=""):
|
||||
logger.info("--- Manage Name ID Service ---")
|
||||
req = IDP.parse_manage_name_id_response(query, binding)
|
||||
req = IDP.parse_manage_name_id_request(query, binding)
|
||||
request = req.message
|
||||
|
||||
# Do the necessary stuff
|
||||
in_response_to = req.message.id
|
||||
name_id = NameID(format=NAMEID_FORMAT_PERSISTENT, text="foobar")
|
||||
name_id = IDP.ident.handle_manage_name_id_request(request.name_id,
|
||||
request.new_id,
|
||||
request.new_encrypted_id,
|
||||
request.terminate)
|
||||
|
||||
info = IDP.response_args(req)
|
||||
_resp = IDP.create_manage_name_id_response(name_id, **info)
|
||||
logger.debug("New NameID: %s" % name_id)
|
||||
|
||||
_resp = IDP.create_manage_name_id_response(request)
|
||||
|
||||
# It's using SOAP binding
|
||||
hinfo = IDP.apply_binding(binding, "%s" % _resp, "", relay_state,
|
||||
"SAMLResponse")
|
||||
response=True)
|
||||
|
||||
resp = Response(hinfo["data"],
|
||||
headers=dict2list_of_tuples(hinfo["headers"]))
|
||||
resp = Response(hinfo["data"], headers=hinfo["headers"])
|
||||
return resp(environ, start_response)
|
||||
|
||||
def mni(environ, start_response, user):
|
||||
@ -478,25 +533,29 @@ def mni_art(environ, start_response, user):
|
||||
# === Assertion ID request ===
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# Only SOAP binding
|
||||
# Only URI binding
|
||||
def assertion_id_request(environ, start_response, user=None):
|
||||
logger.info("--- Assertion ID Service ---")
|
||||
_dict = unpack_soap(environ)
|
||||
_binding = BINDING_SOAP
|
||||
_binding = BINDING_URI
|
||||
|
||||
if not _dict:
|
||||
_dict = unpack_artifact(environ)
|
||||
logger.debug("INPUT: %s" % _dict)
|
||||
# Presently only HTTP GET is supported
|
||||
if "ID" in _dict:
|
||||
aid = _dict["ID"]
|
||||
else:
|
||||
resp = BadRequest("Missing or faulty request")
|
||||
return resp(environ, start_response)
|
||||
|
||||
req_info = IDP.parse_assertion_id_request("%s" % _dict["SAMLRequest"],
|
||||
_binding)
|
||||
try:
|
||||
assertion = IDP.create_assertion_id_request_response(aid)
|
||||
except Unknown:
|
||||
resp = NotFound(aid)
|
||||
return resp(environ, start_response)
|
||||
|
||||
asids = [x.text for x in req_info.message.assertion_id_ref]
|
||||
|
||||
resp_args = IDP.response_args(req_info.message, _binding, "spsso")
|
||||
response = IDP.create_assertion_id_request_response(asids, **resp_args)
|
||||
hinfo = IDP.apply_binding(_binding, "%s" % response, "","",response=True)
|
||||
hinfo = IDP.apply_binding(_binding, "%s" % assertion, response=True)
|
||||
|
||||
logger.debug("HINFO: %s" % hinfo)
|
||||
resp = Response(hinfo["data"], headers=hinfo["headers"])
|
||||
return resp(environ, start_response)
|
||||
|
||||
@ -559,6 +618,45 @@ def authn_query_service(environ, start_response, user=None):
|
||||
return resp(environ, start_response)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# === Attribute query service ===
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# Only SOAP binding
|
||||
def attribute_query_service(environ, start_response, user=None):
|
||||
"""
|
||||
:param environ: Execution environment
|
||||
:param start_response: Function to start the response with
|
||||
"""
|
||||
logger.info("--- Attribute Query Service ---")
|
||||
_dict = unpack_soap(environ)
|
||||
_binding = BINDING_SOAP
|
||||
|
||||
if not _dict:
|
||||
resp = BadRequest("Missing or faulty request")
|
||||
return resp(environ, start_response)
|
||||
|
||||
_req = IDP.parse_attribute_query("%s" % _dict["SAMLRequest"], _binding)
|
||||
_query = _req.message
|
||||
|
||||
name_id = _query.subject.name_id
|
||||
uid = IDP.ident.find_local_id(name_id)
|
||||
logger.debug("Local uid: %s" % uid)
|
||||
identity = EXTRA[uid]
|
||||
|
||||
# Comes in over SOAP so only need to construct the response
|
||||
args = IDP.response_args(_query, [BINDING_SOAP])
|
||||
msg = IDP.create_attribute_response(identity, destination="",
|
||||
name_id=name_id, **args)
|
||||
|
||||
logger.debug("response: %s" % msg)
|
||||
hinfo = IDP.apply_binding(_binding, "%s" % msg, "","",response=True)
|
||||
|
||||
resp = Response(hinfo["data"], headers=hinfo["headers"])
|
||||
return resp(environ, start_response)
|
||||
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Name ID Mapping service
|
||||
# When an entity that shares an identifier for a principal with an identity
|
||||
@ -569,11 +667,12 @@ def authn_query_service(environ, start_response, user=None):
|
||||
|
||||
|
||||
def _nim(environ, start_response, user, query, binding, relay_state=""):
|
||||
req = IDP.parse_manage_name_id_response(query, binding)
|
||||
|
||||
req = IDP.parse_name_id_mapping_request(query, binding)
|
||||
request = req.message
|
||||
# Do the necessary stuff
|
||||
try:
|
||||
name_id = IDP.ident.handle_name_id_mapping_request()
|
||||
name_id = IDP.ident.handle_name_id_mapping_request(request.name_id,
|
||||
request.name_id_policy)
|
||||
except Unknown:
|
||||
resp = BadRequest("Unknown entity")
|
||||
return resp(environ, start_response)
|
||||
@ -581,56 +680,19 @@ def _nim(environ, start_response, user, query, binding, relay_state=""):
|
||||
resp = BadRequest("Unknown entity")
|
||||
return resp(environ, start_response)
|
||||
|
||||
info = IDP.response_args(req)
|
||||
_resp = IDP.create_manage_name_id_response(name_id, **info)
|
||||
info = IDP.response_args(request)
|
||||
_resp = IDP.create_name_id_mapping_response(name_id, **info)
|
||||
|
||||
# It's using SOAP binding
|
||||
# Only SOAP
|
||||
hinfo = IDP.apply_binding(binding, "%s" % _resp, "", "", response=True)
|
||||
|
||||
resp = Response(hinfo["data"],
|
||||
headers=dict2list_of_tuples(hinfo["headers"]))
|
||||
resp = Response(hinfo["data"], headers=hinfo["headers"])
|
||||
return resp(environ, start_response)
|
||||
|
||||
def nim(environ, start_response, user):
|
||||
""" Expects a HTTP-redirect logout request """
|
||||
|
||||
_dict = unpack_redirect(environ)
|
||||
|
||||
if not _dict:
|
||||
resp = Unauthorized('Unknown user')
|
||||
return resp(environ, start_response)
|
||||
else:
|
||||
return _mni(environ, start_response, user, _dict["SAMLRequest"],
|
||||
BINDING_HTTP_REDIRECT, _dict["RelayState"])
|
||||
|
||||
def nim_post(environ, start_response, user):
|
||||
""" Expects a HTTP-POST logout request """
|
||||
|
||||
_dict = unpack_post(environ)
|
||||
if not _dict:
|
||||
resp = Unauthorized('Unknown user')
|
||||
return resp(environ, start_response)
|
||||
else:
|
||||
return _mni(environ, start_response, user, _dict["SAMLRequest"],
|
||||
BINDING_HTTP_REDIRECT, _dict["RelayState"])
|
||||
|
||||
def nim_soap(environ, start_response, user):
|
||||
_dict = unpack_soap(environ)
|
||||
return _operation(environ, start_response, user, _dict, _nim, BINDING_SOAP)
|
||||
|
||||
_dict = unpack_post(environ)
|
||||
if not _dict:
|
||||
resp = Unauthorized('Unknown user')
|
||||
return resp(environ, start_response)
|
||||
else:
|
||||
return _mni(environ, start_response, user, _dict["SAMLRequest"],
|
||||
BINDING_HTTP_REDIRECT, _dict["RelayState"])
|
||||
|
||||
def nim_art(environ, start_response, user):
|
||||
# Could be by HTTP_REDIRECT or HTTP_POST
|
||||
|
||||
_dict = unpack_redirect(environ)
|
||||
if not _dict:
|
||||
_dict = unpack_post(environ)
|
||||
return _artifact_oper(environ, start_response, user, _dict, _mni)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------------
|
||||
@ -689,21 +751,17 @@ AUTHN_URLS = [
|
||||
(r'mni/soap$', mni_soap),
|
||||
(r'mni/soap/(.*)$', mni_soap),
|
||||
# nim
|
||||
(r'nim/post$', nim_post),
|
||||
(r'nim/post/(.*)$', nim_post),
|
||||
(r'nim/redirect$', nim),
|
||||
(r'nim/redirect/(.*)$', nim),
|
||||
(r'nim/art$', nim_art),
|
||||
(r'nim/art/(.*)$', nim_art),
|
||||
(r'nim/soap$', nim_soap),
|
||||
(r'nim/soap/(.*)$', nim_soap),
|
||||
(r'nim$', nim_soap),
|
||||
(r'nim/(.*)$', nim_soap),
|
||||
#
|
||||
(r'aqs$', authn_query_service)
|
||||
(r'aqs$', authn_query_service),
|
||||
(r'attr$', attribute_query_service)
|
||||
]
|
||||
|
||||
NON_AUTHN_URLS = [
|
||||
(r'login?(.*)$', do_authentication),
|
||||
(r'verify?(.*)$', do_verify),
|
||||
(r'sso/ecp$', sso_ecp),
|
||||
]
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
@ -776,6 +834,7 @@ LOOKUP = TemplateLookup(directories=[ROOT + 'templates', ROOT + 'htdocs'],
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
from idp_user import USERS
|
||||
from idp_user import EXTRA
|
||||
from wsgiref.simple_server import make_server
|
||||
|
||||
PORT = 8088
|
||||
|
@ -1,4 +1,6 @@
|
||||
from saml2 import BINDING_HTTP_REDIRECT
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
from saml2 import BINDING_HTTP_REDIRECT, BINDING_URI
|
||||
from saml2 import BINDING_HTTP_ARTIFACT
|
||||
from saml2 import BINDING_HTTP_POST
|
||||
from saml2 import BINDING_SOAP
|
||||
@ -27,8 +29,7 @@ CONFIG={
|
||||
"aa": {
|
||||
"endpoints" : {
|
||||
"attribute_service": [
|
||||
("%s/attr/post" % BASE, BINDING_HTTP_POST),
|
||||
("%s/attr/soap" % BASE, BINDING_SOAP)
|
||||
("%s/attr" % BASE, BINDING_SOAP)
|
||||
]
|
||||
},
|
||||
"name_id_format": [NAMEID_FORMAT_TRANSIENT,
|
||||
@ -47,7 +48,8 @@ CONFIG={
|
||||
"single_sign_on_service" : [
|
||||
("%s/sso/redirect" % BASE, BINDING_HTTP_REDIRECT),
|
||||
("%s/sso/post" % BASE, BINDING_HTTP_POST),
|
||||
("%s/sso/art" % BASE, BINDING_HTTP_ARTIFACT)
|
||||
("%s/sso/art" % BASE, BINDING_HTTP_ARTIFACT),
|
||||
("%s/sso/ecp" % BASE, BINDING_SOAP)
|
||||
],
|
||||
"single_logout_service": [
|
||||
("%s/slo/soap" % BASE, BINDING_SOAP),
|
||||
@ -58,7 +60,7 @@ CONFIG={
|
||||
("%s/ars" % BASE, BINDING_SOAP)
|
||||
],
|
||||
"assertion_id_request_service": [
|
||||
("%s/airs" % BASE, BINDING_SOAP)
|
||||
("%s/airs" % BASE, BINDING_URI)
|
||||
],
|
||||
"manage_name_id_service":[
|
||||
("%s/mni/soap" % BASE, BINDING_SOAP),
|
||||
@ -67,10 +69,7 @@ CONFIG={
|
||||
("%s/mni/art" % BASE, BINDING_HTTP_ARTIFACT)
|
||||
],
|
||||
"name_id_mapping_service":[
|
||||
("%s/nim/soap" % BASE, BINDING_SOAP),
|
||||
("%s/nim/post" % BASE, BINDING_HTTP_POST),
|
||||
("%s/nim/redirect" % BASE, BINDING_HTTP_REDIRECT),
|
||||
("%s/nim/art" % BASE, BINDING_HTTP_ARTIFACT)
|
||||
("%s/nim" % BASE, BINDING_SOAP),
|
||||
],
|
||||
},
|
||||
"policy": {
|
||||
|
@ -5,24 +5,22 @@ USERS = {
|
||||
"eduPersonAffiliation": "staff",
|
||||
"uid": "rohe0002"
|
||||
},
|
||||
"ozzie": {
|
||||
"surname": "Guillen",
|
||||
"babs": {
|
||||
"surname": "Babs",
|
||||
"givenName": "Ozzie",
|
||||
"eduPersonAffiliation": "affiliate"
|
||||
},
|
||||
"derek": {
|
||||
"upper": {
|
||||
"surname": "Jeter",
|
||||
"givenName": "Derek",
|
||||
"eduPersonAffiliation": "affiliate"
|
||||
},
|
||||
"ichiro": {
|
||||
"surname": "Suzuki",
|
||||
"givenName": "Ischiro",
|
||||
"eduPersonAffiliation": "affiliate"
|
||||
},
|
||||
"ryan": {
|
||||
"surname": "Howard",
|
||||
"givenName": "Ryan",
|
||||
"eduPersonAffiliation": "affiliate"
|
||||
}
|
||||
}
|
||||
|
||||
EXTRA = {
|
||||
"roland": {
|
||||
"eduPersonEntitlement" : "urn:mace:swamid.se:foo:bar",
|
||||
"schacGender": "male",
|
||||
"schacUserPresenceID": "skype:pepe.perez"
|
||||
}
|
||||
}
|
@ -1,20 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2006 Google Inc.
|
||||
# Copyright (C) 2009 Umeå University
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Contains base classes representing SAML elements.
|
||||
|
||||
@ -32,21 +17,6 @@
|
||||
provides methods and functions to convert SAML classes to and from strings.
|
||||
"""
|
||||
|
||||
# try:
|
||||
# # lxml: best performance for XML processing
|
||||
# import lxml.etree as ET
|
||||
# except ImportError:
|
||||
# try:
|
||||
# # Python 2.5+: batteries included
|
||||
# import xml.etree.cElementTree as ET
|
||||
# except ImportError:
|
||||
# try:
|
||||
# # Python <2.5: standalone ElementTree install
|
||||
# import elementtree.cElementTree as ET
|
||||
# except ImportError:
|
||||
# raise ImportError, "lxml or ElementTree are not installed, "\
|
||||
# +"see http://codespeak.net/lxml "\
|
||||
# +"or http://effbot.org/zone/element-index.htm"
|
||||
|
||||
import logging
|
||||
from saml2.validate import valid_instance
|
||||
|
Loading…
Reference in New Issue
Block a user