diff --git a/example/idp/idp.py b/example/idp/idp.py
deleted file mode 100755
index 6dbcd3b..0000000
--- a/example/idp/idp.py
+++ /dev/null
@@ -1,304 +0,0 @@
-#!/usr/bin/env python
-
-import re
-import logging
-
-#from cgi import parse_qs
-from urlparse import parse_qs
-from saml2.httputil import Unauthorized, NotFound, BadRequest
-from saml2.httputil import ServiceError
-from saml2.httputil import Response
-from saml2.pack import http_form_post_message
-from saml2.saml import AUTHN_PASSWORD
-from saml2 import server
-from saml2 import BINDING_HTTP_REDIRECT, BINDING_HTTP_POST
-from saml2 import time_util
-from Cookie import SimpleCookie
-
-logger = logging.getLogger("saml2.IDP")
-
-AUTHN = (AUTHN_PASSWORD, "http://www.example.com/login")
-
-def _expiration(timeout, format=None):
- if timeout == "now":
- return time_util.instant(format)
- else:
- # validity time should match lifetime of assertions
- return time_util.in_a_while(minutes=timeout, format=format)
-
-# -----------------------------------------------------------------------------
-def dict_to_table(ava, lev=0, width=1):
- txt = ['
\n' % width]
- for prop, valarr in ava.items():
- txt.append("\n")
- if isinstance(valarr, basestring):
- txt.append("%s | \n" % str(prop))
- try:
- txt.append("%s | \n" % valarr.encode("utf8"))
- except AttributeError:
- txt.append("%s | \n" % valarr)
- elif isinstance(valarr, list):
- index = 0
- num = len(valarr)
- for val in valarr:
- if not index:
- txt.append("%s\n" % (len(valarr), prop))
- else:
- txt.append(" |
\n")
- if isinstance(val, dict):
- txt.append("\n")
- txt.extend(dict_to_table(val, lev+1, width-1))
- txt.append(" | \n")
- else:
- try:
- txt.append("%s | \n" % val.encode("utf8"))
- except AttributeError:
- txt.append("%s | \n" % val)
- if num > 1:
- txt.append("
\n")
- num -= 1
- index += 1
- elif isinstance(valarr, dict):
- txt.append("%s | \n" % prop)
- txt.append("\n")
- txt.extend(dict_to_table(valarr, lev+1, width-1))
- txt.append(" | \n")
- txt.append("\n")
- txt.append('
\n')
- return txt
-
-REPOZE_ID_EQUIVALENT = "uid"
-FORM_SPEC = """"""
-
-
-def sso(environ, start_response, user):
- """ Supposed to return a self issuing Form POST """
- #edict = dict_to_table(environ)
- #if logger: logger.info("Environ keys: %s" % environ.keys())
- logger.info("--- In SSO ---")
- query = None
- if "QUERY_STRING" in environ:
- if logger:
- logger.info("Query string: %s" % environ["QUERY_STRING"])
- query = parse_qs(environ["QUERY_STRING"])
- elif "s2repoze.qinfo" in environ:
- query = environ["s2repoze.qinfo"]
-
- if not query:
- resp = Unauthorized('Unknown user')
- return resp(environ, start_response)
-
- # base 64 encoded request
- # Assume default binding, that is HTTP-redirect
- req = IDP.parse_authn_request(query["SAMLRequest"][0])
-
- if req is None:
- resp = ServiceError("Failed to parse the SAML request")
- return resp(environ, start_response)
-
- logger.info("parsed OK")
- logger.info("%s" % req)
-
- identity = dict(environ["repoze.who.identity"]["user"])
- logger.info("Identity: %s" % (identity,))
- userid = environ["repoze.who.identity"]['repoze.who.userid']
- if REPOZE_ID_EQUIVALENT:
- identity[REPOZE_ID_EQUIVALENT] = userid
-
- # What's the binding ? ProtocolBinding
- if req.message.protocol_binding == BINDING_HTTP_REDIRECT:
- _binding = BINDING_HTTP_POST
- else:
- _binding = req.message.protocol_binding
-
- try:
- resp_args = IDP.response_args(req.message, [_binding])
- except Exception:
- raise
-
- if req.message.assertion_consumer_service_url:
- if req.message.assertion_consumer_service_url != resp_args["destination"]:
- # serious error on someones behalf
- logger.error("%s != %s" % (req.message.assertion_consumer_service_url,
- resp_args["destination"]))
- resp = BadRequest("ConsumerURL and return destination mismatch")
- raise resp(environ, start_response)
-
- try:
- authn_resp = IDP.create_authn_response(identity, userid=userid,
- authn=AUTHN, **resp_args)
- except Exception, excp:
- logger.error("Exception: %s" % (excp,))
- raise
-
- logger.info("AuthNResponse: %s" % authn_resp)
-
- http_args = http_form_post_message(authn_resp, resp_args["destination"],
- relay_state=query["RelayState"][0],
- typ="SAMLResponse")
-
- resp = Response(http_args["data"], headers=http_args["headers"])
- return resp(environ, start_response)
-
-def whoami(environ, start_response, user):
- identity = environ["repoze.who.identity"].copy()
- for prop in ["login", "password"]:
- try:
- del identity[prop]
- except KeyError:
- continue
- response = Response(dict_to_table(identity))
- return response(environ, start_response)
-
-def not_found(environ, start_response):
- """Called if no URL matches."""
- resp = NotFound('Not Found')
- return resp(environ, start_response)
-
-def not_authn(environ, start_response):
- if "QUERY_STRING" in environ:
- query = parse_qs(environ["QUERY_STRING"])
- logger.info("query: %s" % query)
- resp = Unauthorized('Unknown user')
- return resp(environ, start_response)
-
-def slo(environ, start_response, user):
- """ Expects a HTTP-redirect logout request """
-
- query = None
- if "QUERY_STRING" in environ:
- logger.info("Query string: %s" % environ["QUERY_STRING"])
- query = parse_qs(environ["QUERY_STRING"])
-
- if not query:
- resp = Unauthorized('Unknown user')
- return resp(environ, start_response)
-
- try:
- req_info = IDP.parse_logout_request(query["SAMLRequest"][0],
- BINDING_HTTP_REDIRECT)
- logger.info("LOGOUT request parsed OK")
- logger.info("REQ_INFO: %s" % req_info.message)
- except KeyError, exc:
- logger.info("logout request error: %s" % (exc,))
- resp = BadRequest('Request parse error')
- return resp(environ, start_response)
-
- # look for the subject
- subject = req_info.subject_id()
- subject = subject.text.strip()
- logger.info("Logout subject: %s" % (subject,))
-
- status = None
-
- # Either HTTP-Post or HTTP-redirect is possible, prefer HTTP-Post.
- # Order matters
- bindings = [BINDING_HTTP_POST, BINDING_HTTP_REDIRECT]
- try:
- response = IDP.create_logout_response(req_info.message,
- bindings)
- binding, destination = IDP.pick_binding("single_logout_service",
- bindings, "spsso", response)
-
- http_args = IDP.apply_binding(binding, "%s" % response, destination,
- query["RelayState"], response=True)
-
- except Exception, exc:
- resp = BadRequest('%s' % exc)
- return resp(environ, start_response)
-
- delco = delete_cookie(environ, "pysaml2idp")
- if delco:
- http_args["headers"].append(delco)
-
- if binding == BINDING_HTTP_POST:
- resp = Response(http_args["data"], headers=http_args["headers"])
- else:
- resp = NotFound(http_args["data"], headers=http_args["headers"])
- return resp(environ, start_response)
-
-def delete_cookie(environ, name):
- kaka = environ.get("HTTP_COOKIE", '')
- if kaka:
- cookie_obj = SimpleCookie(kaka)
- morsel = cookie_obj.get(name, None)
- cookie = SimpleCookie()
- cookie[name] = morsel
- cookie[name]["expires"] = \
- _expiration("now", "%a, %d-%b-%Y %H:%M:%S CET")
- return tuple(cookie.output().split(": ", 1))
- return None
-
-# ----------------------------------------------------------------------------
-
-# map urls to functions
-URLS = [
- (r'whoami$', whoami),
- (r'whoami/(.*)$', whoami),
- (r'sso$', sso),
- (r'sso/(.*)$', sso),
- (r'logout$', slo),
- (r'logout/(.*)$', slo),
-]
-
-# ----------------------------------------------------------------------------
-
-def application(environ, start_response):
- """
- The main WSGI application. Dispatch the current request to
- the functions from above and store the regular expression
- captures in the WSGI environment as `myapp.url_args` so that
- the functions from above can access the url placeholders.
-
- If nothing matches call the `not_found` function.
-
- :param environ: The HTTP application environment
- :param start_response: The application to run when the handling of the
- request is done
- :return: The response as a list of lines
- """
- user = environ.get("REMOTE_USER", "")
- kaka = environ.get("HTTP_COOKIE", '')
- if not user:
- user = environ.get("repoze.who.identity", "")
-
- path = environ.get('PATH_INFO', '').lstrip('/')
- logger.info(" PATH: %s" % path)
- logger.info("Cookie: %s" % (kaka,))
- for regex, callback in URLS:
- if user:
- match = re.search(regex, path)
- if match is not None:
- try:
- environ['myapp.url_args'] = match.groups()[0]
- except IndexError:
- environ['myapp.url_args'] = path
- logger.info("callback: %s" % (callback,))
- return callback(environ, start_response, user)
- else:
- logger.info("-- No USER --")
- return not_authn(environ, start_response)
- return not_found(environ, start_response)
-
-# ----------------------------------------------------------------------------
-
-from repoze.who.config import make_middleware_with_config
-
-APP_WITH_AUTH = make_middleware_with_config(application, {"here":"."},
- './who.ini', log_file="repoze_who.log")
-
-# ----------------------------------------------------------------------------
-
-if __name__ == '__main__':
- import sys
- from wsgiref.simple_server import make_server
-
- PORT = 8088
-
- IDP = server.Server(sys.argv[1])
- SRV = make_server('localhost', PORT, APP_WITH_AUTH)
- print "IdP listening on port: %s" % PORT
- SRV.serve_forever()
\ No newline at end of file
diff --git a/example/idp/idp_conf.py.example b/example/idp/idp_conf.py.example
deleted file mode 100644
index 250c1ca..0000000
--- a/example/idp/idp_conf.py.example
+++ /dev/null
@@ -1,53 +0,0 @@
-from saml2 import BINDING_HTTP_REDIRECT
-from saml2.saml import NAME_FORMAT_URI
-
-BASE = "http://localhost:8088/"
-
-CONFIG={
- "entityid" : "urn:mace:umu.se:saml:roland:idp",
- "description": "My IDP",
- "service": {
- "idp": {
- "name" : "Rolands IdP",
- "endpoints" : {
- "single_sign_on_service" : [BASE+"sso"],
- "single_logout_service" : [(BASE+"logout",
- BINDING_HTTP_REDIRECT)],
- },
- "policy": {
- "default": {
- "lifetime": {"minutes":15},
- "attribute_restrictions": None, # means all I have
- "name_form": NAME_FORMAT_URI
- },
- "urn:mace:umu.se:saml:roland:sp": {
- "lifetime": {"minutes": 5},
- }
- },
- "subject_data": "./idp.subject.db",
- }
- },
- "debug" : 1,
- "key_file" : "pki/mykey.pem",
- "cert_file" : "pki/mycert.pem",
- "metadata" : {
- "local": ["../sp/sp.xml"],
- },
- "organization": {
- "display_name": "Rolands Identiteter",
- "name": "Rolands Identiteter",
- "url": "http://www.example.com",
- },
- # 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",
- "logger": {
- "rotating": {
- "filename": "idp.log",
- "maxBytes": 100000,
- "backupCount": 5,
- },
- "loglevel": "debug",
- }
-}
diff --git a/example/idp/idp_user.ini b/example/idp/idp_user.ini
deleted file mode 100644
index f8cb558..0000000
--- a/example/idp/idp_user.ini
+++ /dev/null
@@ -1,25 +0,0 @@
-[roland]
-surname=Hedberg
-givenName=Roland
-eduPersonAffiliation=staff
-uid=rohe0002
-
-[ozzie]
-surname=Guillen
-givenName=Ozzie
-eduPersonAffiliation=affiliate
-
-[derek]
-surname=Jeter
-givenName=Derek
-eduPersonAffiliation=affiliate
-
-[ichiro]
-surname=Suzuki
-givenName=Ischiro
-eduPersonAffiliation=affiliate
-
-[ryan]
-surname=Howard
-givenName=Ryan
-eduPersonAffiliation=affiliate
diff --git a/example/idp/passwd b/example/idp/passwd
deleted file mode 100644
index d652eaf..0000000
--- a/example/idp/passwd
+++ /dev/null
@@ -1,5 +0,0 @@
-roland:Jek7qtYXouxmM
-ozzie:wT390u9XwBFaU
-derek:efNb53YcncbRI
-ryan:YlIhvZ6Rdt6fA
-ischiro:wgMhJvmkQgMGs
diff --git a/example/idp/pki/mycert.pem b/example/idp/pki/mycert.pem
deleted file mode 100644
index d4a0873..0000000
--- a/example/idp/pki/mycert.pem
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC8jCCAlugAwIBAgIJAJHg2V5J31I8MA0GCSqGSIb3DQEBBQUAMFoxCzAJBgNV
-BAYTAlNFMQ0wCwYDVQQHEwRVbWVhMRgwFgYDVQQKEw9VbWVhIFVuaXZlcnNpdHkx
-EDAOBgNVBAsTB0lUIFVuaXQxEDAOBgNVBAMTB1Rlc3QgU1AwHhcNMDkxMDI2MTMz
-MTE1WhcNMTAxMDI2MTMzMTE1WjBaMQswCQYDVQQGEwJTRTENMAsGA1UEBxMEVW1l
-YTEYMBYGA1UEChMPVW1lYSBVbml2ZXJzaXR5MRAwDgYDVQQLEwdJVCBVbml0MRAw
-DgYDVQQDEwdUZXN0IFNQMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkJWP7
-bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr6/ROgW96ZeQ57fzVy2MC
-FiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43qCfLx+clUlOvtnsoMiiR
-mo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQABo4G/MIG8MB0GA1UdDgQW
-BBQ7RgbMJFDGRBu9o3tDQDuSoBy7JjCBjAYDVR0jBIGEMIGBgBQ7RgbMJFDGRBu9
-o3tDQDuSoBy7JqFepFwwWjELMAkGA1UEBhMCU0UxDTALBgNVBAcTBFVtZWExGDAW
-BgNVBAoTD1VtZWEgVW5pdmVyc2l0eTEQMA4GA1UECxMHSVQgVW5pdDEQMA4GA1UE
-AxMHVGVzdCBTUIIJAJHg2V5J31I8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF
-BQADgYEAMuRwwXRnsiyWzmRikpwinnhTmbooKm5TINPE7A7gSQ710RxioQePPhZO
-zkM27NnHTrCe2rBVg0EGz7QTd1JIwLPvgoj4VTi/fSha/tXrYUaqc9AqU1kWI4WN
-+vffBGQ09mo+6CffuFTZYeOhzP/2stAPwCTU4kxEoiy0KpZMANI=
------END CERTIFICATE-----
diff --git a/example/idp/pki/mykey.pem b/example/idp/pki/mykey.pem
deleted file mode 100644
index d9ec5f8..0000000
--- a/example/idp/pki/mykey.pem
+++ /dev/null
@@ -1,15 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQDkJWP7bwOxtH+E15VTaulNzVQ/0cSbM5G7abqeqSNSs0l0veHr
-6/ROgW96ZeQ57fzVy2MCFiQRw2fzBs0n7leEmDJyVVtBTavYlhAVXDNa3stgvh43
-qCfLx+clUlOvtnsoMiiRmo7qf0BoPKTj7c0uLKpDpEbAHQT4OF1HRYVxMwIDAQAB
-AoGAbx9rKH91DCw/ZEPhHsVXJ6cYHxGcMoAWvnMMC9WUN+bNo4gNL205DLfsxXA1
-jqXFXZj3+38vSFumGPA6IvXrN+Wyp3+Lz3QGc4K5OdHeBtYlxa6EsrxPgvuxYDUB
-vx3xdWPMjy06G/ML+pR9XHnRaPNubXQX3UxGBuLjwNXVmyECQQD2/D84tYoCGWoq
-5FhUBxFUy2nnOLKYC/GGxBTX62iLfMQ3fbQcdg2pJsB5rrniyZf7UL+9FOsAO9k1
-8DO7G12DAkEA7Hkdg1KEw4ZfjnnjEa+KqpyLTLRQ91uTVW6kzR+4zY719iUJ/PXE
-PxJqm1ot7mJd1LW+bWtjLpxs7jYH19V+kQJBAIEpn2JnxdmdMuFlcy/WVmDy09pg
-0z0imdexeXkFmjHAONkQOv3bWv+HzYaVMo8AgCOksfEPHGqN4eUMTfFeuUMCQF+5
-E1JSd/2yCkJhYqKJHae8oMLXByNqRXTCyiFioutK4JPYIHfugJdLfC4QziD+Xp85
-RrGCU+7NUWcIJhqfiJECQAIgUAzfzhdj5AyICaFPaOQ+N8FVMLcTyqeTXP0sIlFk
-JStVibemTRCbxdXXM7OVipz1oW3PBVEO3t/VyjiaGGg=
------END RSA PRIVATE KEY-----
diff --git a/example/idp/who.ini b/example/idp/who.ini
deleted file mode 100644
index 75817f9..0000000
--- a/example/idp/who.ini
+++ /dev/null
@@ -1,57 +0,0 @@
-[plugin:form]
-# identificaion and challenge
-use = s2repoze.plugins.formswithhidden:make_plugin
-login_form_qs = __do_login
-rememberer_name = auth_tkt
-#form = %(here)s/login_form.html
-
-[plugin:auth_tkt]
-# identification
-use = repoze.who.plugins.auth_tkt:make_plugin
-secret = cassiopeja
-cookie_name = pysaml2idp
-secure = False
-include_ip = True
-timeout=3600
-reissue_time = 3000
-
-[plugin:basicauth]
-# identification and challenge
-use = repoze.who.plugins.basicauth:make_plugin
-realm = 'sample'
-
-[plugin:htpasswd]
-# authentication
-use = repoze.who.plugins.htpasswd:make_plugin
-filename = %(here)s/passwd
-check_fn = repoze.who.plugins.htpasswd:crypt_check
-
-[plugin:ini]
-use = s2repoze.plugins.ini:make_plugin
-ini_file = %(here)s/idp_user.ini
-
-[general]
-request_classifier = repoze.who.classifiers:default_request_classifier
-challenge_decider = repoze.who.classifiers:default_challenge_decider
-remote_user_key = REMOTE_USER
-
-[identifiers]
-# plugin_name;classifier_name:.. or just plugin_name (good for any)
-plugins =
- form;browser
- auth_tkt
- basicauth
-
-[authenticators]
-# plugin_name;classifier_name.. or just plugin_name (good for any)
-plugins =
- htpasswd
-
-[challengers]
-# plugin_name;classifier_name:.. or just plugin_name (good for any)
-plugins =
- form;browser
- basicauth
-
-[mdproviders]
-plugins = ini
diff --git a/tests/sp_1_conf.py b/tests/sp_1_conf.py
index e39be48..90bf075 100644
--- a/tests/sp_1_conf.py
+++ b/tests/sp_1_conf.py
@@ -2,47 +2,49 @@ from pathutils import full_path
CONFIG = {
- "entityid" : "urn:mace:example.com:saml:roland:sp",
- "name" : "urn:mace:example.com:saml:roland:sp",
+ "entityid": "urn:mace:example.com:saml:roland:sp",
+ "name": "urn:mace:example.com:saml:roland:sp",
"description": "My own SP",
"service": {
"sp": {
- "endpoints":{
- "assertion_consumer_service": ["http://lingon.catalogix.se:8087/"],
+ "endpoints": {
+ "assertion_consumer_service": [
+ "http://lingon.catalogix.se:8087/"],
},
"required_attributes": ["surName", "givenName", "mail"],
"optional_attributes": ["title"],
"idp": ["urn:mace:example.com:saml:roland:idp"],
}
},
- "debug" : 1,
- "key_file" : full_path("test.key"),
- "cert_file" : full_path("test.pem"),
- "xmlsec_binary" : None,
+ "debug": 1,
+ "key_file": full_path("test.key"),
+ "cert_file": full_path("test.pem"),
+ "xmlsec_binary": None,
"metadata": {
"local": [full_path("idp.xml"), full_path("vo_metadata.xml")],
},
- "virtual_organization" : {
- "urn:mace:example.com:it:tek":{
- "nameid_format" : "urn:oid:1.3.6.1.4.1.1466.115.121.1.15-NameID",
+ "virtual_organization": {
+ "urn:mace:example.com:it:tek": {
+ "nameid_format": "urn:oid:1.3.6.1.4.1.1466.115.121.1.15-NameID",
"common_identifier": "umuselin",
}
},
"subject_data": full_path("subject_data.db"),
"accepted_time_diff": 60,
- "attribute_map_dir" : full_path("attributemaps"),
+ "attribute_map_dir": full_path("attributemaps"),
"organization": {
"name": ("AB Exempel", "se"),
"display_name": ("AB Exempel", "se"),
"url": "http://www.example.org",
},
"contact_person": [{
- "given_name": "Roland",
- "sur_name": "Hedberg",
- "telephone_number": "+46 70 100 0000",
- "email_address": ["tech@eample.com", "tech@example.org"],
- "contact_type": "technical"
- },
+ "given_name": "Roland",
+ "sur_name": "Hedberg",
+ "telephone_number": "+46 70 100 0000",
+ "email_address": ["tech@eample.com",
+ "tech@example.org"],
+ "contact_type": "technical"
+ },
],
"secret": "0123456789",
}