summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhoerbe <rainer@hoerbe.at>2014-09-22 09:47:58 +0200
committerrhoerbe <rainer@hoerbe.at>2014-09-22 09:47:58 +0200
commit816dcc76107cc23fb115ff449ac4afea45bb3a0d (patch)
treea18ba8124e96747660b2078d4d893f24731abec8
parent2f4f2d6324a540123a114cadf7408acc7f67e684 (diff)
parent33db77a9ed5c00526e74dd5f9b4facf5be4a491e (diff)
downloadpysaml2-816dcc76107cc23fb115ff449ac4afea45bb3a0d.tar.gz
Merge https://github.com/rohe/pysaml2
Conflicts: src/saml2/attributemaps/saml_uri.py
-rw-r--r--LICENSE.txt2
-rw-r--r--doc/conf.py2
-rwxr-xr-xexample/idp2/idp.py3
-rw-r--r--example/idp2/templates/root.mako2
-rw-r--r--example/idp2_repoze/templates/root.mako2
-rw-r--r--example/sp-wsgi/sp.xml125
-rwxr-xr-xsetup.py23
-rw-r--r--src/s2repoze/__init__.py1
-rw-r--r--src/s2repoze/plugins/__init__.py2
-rw-r--r--src/s2repoze/plugins/sp.py13
-rw-r--r--src/saml2/assertion.py14
-rw-r--r--src/saml2/attribute_converter.py13
-rw-r--r--src/saml2/attribute_resolver.py13
-rw-r--r--src/saml2/attributemaps/saml_uri.py10
-rw-r--r--src/saml2/client.py52
-rw-r--r--src/saml2/client_base.py23
-rw-r--r--src/saml2/config.py11
-rw-r--r--src/saml2/ecp.py13
-rw-r--r--src/saml2/ecp_client.py13
-rw-r--r--src/saml2/httpbase.py2
-rw-r--r--src/saml2/ident.py13
-rw-r--r--src/saml2/mdstore.py89
-rw-r--r--src/saml2/metadata.py15
-rw-r--r--src/saml2/pack.py13
-rw-r--r--src/saml2/request.py2
-rw-r--r--src/saml2/response.py13
-rw-r--r--src/saml2/s_utils.py4
-rw-r--r--src/saml2/server.py15
-rw-r--r--src/saml2/sigver.py65
-rw-r--r--src/saml2/soap.py13
-rw-r--r--src/saml2/time_util.py15
-rw-r--r--tests/ds_data.py13
-rw-r--r--tests/fakeIDP.py10
-rw-r--r--tests/idp_example.xml230
-rw-r--r--tests/md_data.py13
-rw-r--r--tests/saml2_data.py13
-rw-r--r--tests/samlp_data.py13
-rw-r--r--tests/server_conf_syslog.py40
-rw-r--r--tests/sp_slo_redirect_conf.py41
-rw-r--r--tests/test_00_xmldsig.py13
-rw-r--r--tests/test_02_saml.py13
-rw-r--r--tests/test_04_samlp.py13
-rw-r--r--tests/test_05_md.py13
-rw-r--r--tests/test_12_s_utils.py445
-rw-r--r--tests/test_51_client.py4
-rw-r--r--tests/test_67_manage_name_id.py2
46 files changed, 734 insertions, 738 deletions
diff --git a/LICENSE.txt b/LICENSE.txt
index 4192d2ce..70a5155d 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright 2013 Roland Hedberg. All rights reserved.
+Copyright 2014 Roland Hedberg. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
diff --git a/doc/conf.py b/doc/conf.py
index a1340d26..1f7f2b52 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -39,7 +39,7 @@ master_doc = 'index'
# General information about the project.
project = u'pysaml2'
-copyright = u'2010-2011, Roland Hedberg'
+copyright = u'2014, Roland Hedberg'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
diff --git a/example/idp2/idp.py b/example/idp2/idp.py
index edae5333..922ba139 100755
--- a/example/idp2/idp.py
+++ b/example/idp2/idp.py
@@ -51,6 +51,7 @@ from mako.lookup import TemplateLookup
logger = logging.getLogger("saml2.idp")
logger.setLevel(logging.WARNING)
+
class Cache(object):
def __init__(self):
self.user2uid = {}
@@ -879,6 +880,7 @@ def metadata(environ, start_response):
logger.error("An error occured while creating metadata:" + ex.message)
return not_found(environ, start_response)
+
def staticfile(environ, start_response):
try:
path = args.path
@@ -893,6 +895,7 @@ def staticfile(environ, start_response):
logger.error("An error occured while creating metadata:" + ex.message)
return not_found(environ, start_response)
+
def application(environ, start_response):
"""
The main WSGI application. Dispatch the current request to
diff --git a/example/idp2/templates/root.mako b/example/idp2/templates/root.mako
index c27e954a..f6b70cee 100644
--- a/example/idp2/templates/root.mako
+++ b/example/idp2/templates/root.mako
@@ -16,7 +16,7 @@
<%def name="post()" filter="trim">
<div>
<div class="footer">
- <p>&#169; Copyright 2011 Ume&#229; Universitet &nbsp;</p>
+ <p>&#169; Copyright 2014 Ume&#229; Universitet &nbsp;</p>
</div>
</div>
</%def>
diff --git a/example/idp2_repoze/templates/root.mako b/example/idp2_repoze/templates/root.mako
index c27e954a..f6b70cee 100644
--- a/example/idp2_repoze/templates/root.mako
+++ b/example/idp2_repoze/templates/root.mako
@@ -16,7 +16,7 @@
<%def name="post()" filter="trim">
<div>
<div class="footer">
- <p>&#169; Copyright 2011 Ume&#229; Universitet &nbsp;</p>
+ <p>&#169; Copyright 2014 Ume&#229; Universitet &nbsp;</p>
</div>
</div>
</%def>
diff --git a/example/sp-wsgi/sp.xml b/example/sp-wsgi/sp.xml
index db3c6df9..6c28d9c0 100644
--- a/example/sp-wsgi/sp.xml
+++ b/example/sp-wsgi/sp.xml
@@ -1,93 +1,34 @@
<?xml version='1.0' encoding='UTF-8'?>
-<ns0:EntityDescriptor xmlns:ns0="urn:oasis:names:tc:SAML:2.0:metadata"
- xmlns:ns1="urn:oasis:names:tc:SAML:metadata:attribute"
- xmlns:ns2="urn:oasis:names:tc:SAML:2.0:assertion"
- xmlns:ns4="http://www.w3.org/2000/09/xmldsig#"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- entityID="http://localhost:8087/sp.xml">
- <ns0:Extensions>
- <ns1:EntityAttributes>
- <ns2:Attribute Name="http://macedir.org/entity-category">
- <ns2:AttributeValue xsi:type="xs:string">
- http://www.geant.net/uri/dataprotection-code-of-conduct/v1
- </ns2:AttributeValue>
- </ns2:Attribute>
- </ns1:EntityAttributes>
- </ns0:Extensions>
- <ns0:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true"
- protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
- <ns0:KeyDescriptor use="encryption">
- <ns4:KeyInfo>
- <ns4:X509Data>
- <ns4:X509Certificate>
- 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=
- </ns4:X509Certificate>
- </ns4:X509Data>
- </ns4:KeyInfo>
- </ns0:KeyDescriptor>
- <ns0:KeyDescriptor use="signing">
- <ns4:KeyInfo>
- <ns4:X509Data>
- <ns4:X509Certificate>
- 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=
- </ns4:X509Certificate>
- </ns4:X509Data>
- </ns4:KeyInfo>
- </ns0:KeyDescriptor>
- <ns0:AssertionConsumerService
- Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
- Location="http://localhost:8087/acs/redirect" index="1"/>
- <ns0:AssertionConsumerService
- Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
- Location="http://localhost:8087/acs/post" index="2"/>
- <ns0:AttributeConsumingService index="1">
- <ns0:ServiceName xml:lang="en">My SP service</ns0:ServiceName>
- <ns0:ServiceDescription xml:lang="en">Example SP
- </ns0:ServiceDescription>
- <ns0:RequestedAttribute FriendlyName="sn" Name="urn:oid:2.5.4.4"
- NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
- isRequired="true"/>
- <ns0:RequestedAttribute FriendlyName="givenname"
- Name="urn:oid:2.5.4.42"
- NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
- isRequired="true"/>
- <ns0:RequestedAttribute FriendlyName="edupersonaffiliation"
- Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1"
- NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
- isRequired="true"/>
- <ns0:RequestedAttribute FriendlyName="title" Name="urn:oid:2.5.4.12"
- NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
- isRequired="false"/>
- </ns0:AttributeConsumingService>
- </ns0:SPSSODescriptor>
-</ns0:EntityDescriptor>
+<ns0:EntityDescriptor xmlns:ns0="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn:oasis:names:tc:SAML:metadata:attribute" xmlns:ns2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:ns4="http://www.w3.org/2000/09/xmldsig#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" entityID="http://localhost:8087/sp.xml"><ns0:Extensions><ns1:EntityAttributes><ns2:Attribute Name="http://macedir.org/entity-category"><ns2:AttributeValue xsi:type="xs:string">http://www.geant.net/uri/dataprotection-code-of-conduct/v1</ns2:AttributeValue></ns2:Attribute></ns1:EntityAttributes></ns0:Extensions><ns0:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><ns0:KeyDescriptor use="encryption"><ns4:KeyInfo><ns4:X509Data><ns4:X509Certificate>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=
+</ns4:X509Certificate></ns4:X509Data></ns4:KeyInfo></ns0:KeyDescriptor><ns0:KeyDescriptor use="signing"><ns4:KeyInfo><ns4:X509Data><ns4:X509Certificate>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=
+</ns4:X509Certificate></ns4:X509Data></ns4:KeyInfo></ns0:KeyDescriptor><ns0:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:8087/acs/redirect" index="1" /><ns0:AttributeConsumingService index="1"><ns0:ServiceName xml:lang="en">My SP service</ns0:ServiceName><ns0:ServiceDescription xml:lang="en">Example SP</ns0:ServiceDescription><ns0:RequestedAttribute FriendlyName="sn" Name="urn:oid:2.5.4.4" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" /><ns0:RequestedAttribute FriendlyName="givenname" Name="urn:oid:2.5.4.42" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" /><ns0:RequestedAttribute FriendlyName="edupersonaffiliation" Name="urn:oid:1.3.6.1.4.1.5923.1.1.1.1" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" /><ns0:RequestedAttribute FriendlyName="title" Name="urn:oid:2.5.4.12" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="false" /></ns0:AttributeConsumingService></ns0:SPSSODescriptor></ns0:EntityDescriptor>
diff --git a/setup.py b/setup.py
index 137354a5..59b21af7 100755
--- a/setup.py
+++ b/setup.py
@@ -1,27 +1,10 @@
#!/usr/bin/env python
-#
-# Copyright (C) 2007 SIOS Technology, Inc.
-# Copyright (C) 2011 Umea Universitet, Sweden
-#
-# 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.
-#
-#
+
import sys
from setuptools import setup
from setuptools.command.test import test as TestCommand
-
class PyTest(TestCommand):
def finalize_options(self):
@@ -84,7 +67,9 @@ setup(
package_data={'': ['xml/*.xml']},
classifiers=["Development Status :: 4 - Beta",
"License :: OSI Approved :: Apache Software License",
- "Topic :: Software Development :: Libraries :: Python Modules"],
+ "Topic :: Software Development :: Libraries :: Python Modules",
+ "Programming Language :: Python :: 2.6",
+ "Programming Language :: Python :: 2.7"],
scripts=["tools/parse_xsd2.py", "tools/make_metadata.py",
"tools/mdexport.py", "tools/merge_metadata.py"],
diff --git a/src/s2repoze/__init__.py b/src/s2repoze/__init__.py
index 94e6145b..e3620e55 100644
--- a/src/s2repoze/__init__.py
+++ b/src/s2repoze/__init__.py
@@ -1,3 +1,2 @@
# -*- coding: utf-8 -*-
# Created by Roland Hedberg
-# Copyright (c) 2009 Umeå Universitet. All rights reserved.
diff --git a/src/s2repoze/plugins/__init__.py b/src/s2repoze/plugins/__init__.py
index a53880b5..40a96afc 100644
--- a/src/s2repoze/plugins/__init__.py
+++ b/src/s2repoze/plugins/__init__.py
@@ -1,3 +1 @@
# -*- coding: utf-8 -*-
-# Created by Roland Hedberg
-# Copyright (c) 2009 Umeå Universitet. All rights reserved.
diff --git a/src/s2repoze/plugins/sp.py b/src/s2repoze/plugins/sp.py
index 5bd7897c..60a34e54 100644
--- a/src/s2repoze/plugins/sp.py
+++ b/src/s2repoze/plugins/sp.py
@@ -1,17 +1,4 @@
-# Copyright (C) 2009 Umea 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.
-
"""
A plugin that allows you to use SAML2 SSO as authentication
and SAML2 attribute aggregations as metadata collector in your
diff --git a/src/saml2/assertion.py b/src/saml2/assertion.py
index 7a361aed..e7410672 100644
--- a/src/saml2/assertion.py
+++ b/src/saml2/assertion.py
@@ -1,19 +1,5 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-#
-# Copyright (C) 2010-2011 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.
import importlib
import logging
diff --git a/src/saml2/attribute_converter.py b/src/saml2/attribute_converter.py
index 49d00bf0..bc39ca54 100644
--- a/src/saml2/attribute_converter.py
+++ b/src/saml2/attribute_converter.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) s2010-2011 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.
import os
import sys
diff --git a/src/saml2/attribute_resolver.py b/src/saml2/attribute_resolver.py
index dab809ce..e02fd8a6 100644
--- a/src/saml2/attribute_resolver.py
+++ b/src/saml2/attribute_resolver.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2009-2011 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 classes and functions that a SAML2.0 Service Provider (SP) may use
diff --git a/src/saml2/attributemaps/saml_uri.py b/src/saml2/attributemaps/saml_uri.py
index 840b6619..fd5d51c7 100644
--- a/src/saml2/attributemaps/saml_uri.py
+++ b/src/saml2/attributemaps/saml_uri.py
@@ -1,16 +1,16 @@
EDUCOURSE_OID = 'urn:oid:1.3.6.1.4.1.5923.1.6.1.'
EDUPERSON_OID = 'urn:oid:1.3.6.1.4.1.5923.1.1.1.'
+LDAPGVAT_OID = 'urn:oid:1.2.40.0.10.2.1.1.' # ldap.gv.at definitions as specified in http://www.ref.gv.at/AG-IZ-PVP2-Version-2-1-0-2.2754.0.html
+UCL_DIR_PILOT = 'urn:oid:0.9.2342.19200300.100.1.'
+X500ATTR_OID = 'urn:oid:2.5.4.'
+LDAPGVAT_UCL_DIR_PILOT = UCL_DIR_PILOT
+LDAPGVAT_X500ATTR_OID = X500ATTR_OID
NETSCAPE_LDAP = 'urn:oid:2.16.840.1.113730.3.1.'
NOREDUPERSON_OID = 'urn:oid:1.3.6.1.4.1.2428.90.1.'
PKCS_9 = 'urn:oid:1.2.840.113549.1.9.1.'
SCHAC = 'urn:oid:1.3.6.1.4.1.25178.1.2.'
SIS = 'urn:oid:1.2.752.194.10.2.'
-UCL_DIR_PILOT = 'urn:oid:0.9.2342.19200300.100.1.'
UMICH = 'urn:oid:1.3.6.1.4.1.250.1.57.'
-X500ATTR_OID = 'urn:oid:2.5.4.'
-LDAPGVAT_OID = 'urn:oid:1.2.40.0.10.2.1.1.' # ldap.gv.at definitions as specified in http://www.ref.gv.at/AG-IZ-PVP2-Version-2-1-0-2.2754.0.html
-LDAPGVAT_UCL_DIR_PILOT = UCL_DIR_PILOT
-LDAPGVAT_X500ATTR_OID = X500ATTR_OID
MAP = {
diff --git a/src/saml2/client.py b/src/saml2/client.py
index 3a7848ba..27afc2af 100644
--- a/src/saml2/client.py
+++ b/src/saml2/client.py
@@ -1,19 +1,6 @@
-#!/usr/bin/env python
+# !/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2009-2011 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 classes and functions that a SAML2.0 Service Provider (SP) may use
to conclude its tasks.
@@ -26,7 +13,7 @@ from saml2 import BINDING_HTTP_REDIRECT
from saml2 import BINDING_HTTP_POST
from saml2 import BINDING_SOAP
-from saml2.ident import decode
+from saml2.ident import decode, code
from saml2.httpbase import HTTPError
from saml2.s_utils import sid
from saml2.s_utils import status_message_factory
@@ -48,6 +35,7 @@ except ImportError:
from cgi import parse_qs
import logging
+
logger = logging.getLogger(__name__)
@@ -80,9 +68,10 @@ class Saml2Client(Base):
destination = self._sso_location(entityid, binding)
reqid, req = self.create_authn_request(destination, vorg, scoping,
- response_binding, nameid_format,
- consent=consent, extensions=extensions,
- sign=sign, **kwargs)
+ response_binding, nameid_format,
+ consent=consent,
+ extensions=extensions, sign=sign,
+ **kwargs)
_req_str = "%s" % req
logger.info("AuthNReq: %s" % _req_str)
@@ -117,7 +106,7 @@ class Saml2Client(Base):
# find out which IdPs/AAs I should notify
entity_ids = self.users.issuers_of_info(name_id)
return self.do_logout(name_id, entity_ids, reason, expire, sign)
-
+
def do_logout(self, name_id, entity_ids, reason, expire, sign=None,
expected_binding=None):
"""
@@ -137,7 +126,7 @@ class Saml2Client(Base):
# Do the local logout anyway
self.local_logout(name_id)
return 0, "504 Gateway Timeout", [], []
-
+
not_done = entity_ids[:]
responses = {}
@@ -164,7 +153,7 @@ class Saml2Client(Base):
req_id, request = self.create_logout_request(
destination, entity_id, name_id=name_id, reason=reason,
expire=expire)
-
+
#to_sign = []
if binding.startswith("http://"):
sign = True
@@ -196,12 +185,12 @@ class Saml2Client(Base):
else:
self.state[req_id] = {"entity_id": entity_id,
- "operation": "SLO",
- "entity_ids": entity_ids,
- "name_id": name_id,
- "reason": reason,
- "not_on_of_after": expire,
- "sign": sign}
+ "operation": "SLO",
+ "entity_ids": entity_ids,
+ "name_id": code(name_id),
+ "reason": reason,
+ "not_on_of_after": expire,
+ "sign": sign}
responses[entity_id] = (binding, http_info)
not_done.remove(entity_id)
@@ -212,7 +201,7 @@ class Saml2Client(Base):
if not_done:
# upstream should try later
raise LogoutError("%s" % (entity_ids,))
-
+
return responses
def local_logout(self, name_id):
@@ -230,7 +219,7 @@ class Saml2Client(Base):
"""
identity = self.users.get_identity(name_id)[0]
return bool(identity)
-
+
def handle_logout_response(self, response):
""" handles a Logout response
@@ -246,11 +235,12 @@ class Saml2Client(Base):
logger.info("issuer: %s" % issuer)
del self.state[response.in_response_to]
if status["entity_ids"] == [issuer]: # done
- self.local_logout(status["name_id"])
+ self.local_logout(decode(status["name_id"]))
return 0, "200 Ok", [("Content-type", "text/html")], []
else:
status["entity_ids"].remove(issuer)
- return self.do_logout(status["name_id"], status["entity_ids"],
+ return self.do_logout(decode(status["name_id"]),
+ status["entity_ids"],
status["reason"], status["not_on_or_after"],
status["sign"])
diff --git a/src/saml2/client_base.py b/src/saml2/client_base.py
index f4676d23..d5283d6f 100644
--- a/src/saml2/client_base.py
+++ b/src/saml2/client_base.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2009-2011 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 classes and functions that a SAML2.0 Service Provider (SP) may use
to conclude its tasks.
@@ -191,7 +178,8 @@ class Base(Entity):
return ava
#noinspection PyUnusedLocal
- def is_session_valid(self, _session_id):
+ @staticmethod
+ def is_session_valid(_session_id):
""" Place holder. Supposed to check if the session is still valid.
"""
return True
@@ -399,7 +387,7 @@ class Base(Entity):
return self._message(AuthzDecisionQuery, destination, message_id,
consent, extensions, sign, action=action,
evidence=evidence, resource=resource,
- subject=subject)
+ subject=subject, **kwargs)
def create_authz_decision_query_using_assertion(self, destination,
assertion, action=None,
@@ -436,7 +424,8 @@ class Base(Entity):
resource, subject, message_id=message_id, consent=consent,
extensions=extensions, sign=sign)
- def create_assertion_id_request(self, assertion_id_refs, **kwargs):
+ @staticmethod
+ def create_assertion_id_request(assertion_id_refs, **kwargs):
"""
:param assertion_id_refs:
@@ -534,7 +523,7 @@ class Base(Entity):
"entity_id": self.config.entityid,
"attribute_converters": self.config.attribute_converters,
"allow_unknown_attributes":
- self.config.allow_unknown_attributes,
+ self.config.allow_unknown_attributes,
}
try:
resp = self._parse_response(xmlstr, AuthnResponse,
diff --git a/src/saml2/config.py b/src/saml2/config.py
index 11ef7857..e704fa39 100644
--- a/src/saml2/config.py
+++ b/src/saml2/config.py
@@ -71,7 +71,8 @@ COMMON_ARGS = [
"tmp_cert_file",
"tmp_key_file",
"validate_certificate",
- "extensions"
+ "extensions",
+ "allow_unknown_attributes"
]
SP_ARGS = [
@@ -90,7 +91,6 @@ SP_ARGS = [
"allow_unsolicited",
"ecp",
"name_id_format",
- "allow_unknown_attributes"
]
AA_IDP_ARGS = [
@@ -216,6 +216,7 @@ class Config(object):
self.crypto_backend = 'xmlsec1'
self.scope = ""
self.allow_unknown_attributes = False
+ self.allow_unsolicited = False
self.extension_schema = {}
self.cert_handler_extra_class = None
self.verify_encrypt_cert = None
@@ -400,9 +401,9 @@ class Config(object):
def endpoint(self, service, binding=None, context=None):
""" Goes through the list of endpoint specifications for the
- given type of service and returnes the first endpoint that matches
- the given binding. If no binding is given any endpoint for that
- service will be returned.
+ given type of service and returns a list of endpoint that matches
+ the given binding. If no binding is given all endpoints available for
+ that service will be returned.
:param service: The service the endpoint should support
:param binding: The expected binding
diff --git a/src/saml2/ecp.py b/src/saml2/ecp.py
index 4a1a0c19..e99e174a 100644
--- a/src/saml2/ecp.py
+++ b/src/saml2/ecp.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2010-2011 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 classes used in the SAML ECP profile
diff --git a/src/saml2/ecp_client.py b/src/saml2/ecp_client.py
index beb638a5..b9f4573c 100644
--- a/src/saml2/ecp_client.py
+++ b/src/saml2/ecp_client.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2010-2011 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 a class that can do SAML ECP Authentication for other python
diff --git a/src/saml2/httpbase.py b/src/saml2/httpbase.py
index 56d4a7e5..eeb0a566 100644
--- a/src/saml2/httpbase.py
+++ b/src/saml2/httpbase.py
@@ -177,7 +177,7 @@ class HTTPBase(object):
std_attr[attr] = morsel[attr]
elif attr == "max-age":
if morsel["max-age"]:
- std_attr["expires"] = _since_epoch(morsel["max-age"])
+ std_attr["expires"] = time.time() + int(morsel["max-age"])
for att, item in PAIRS.items():
if std_attr[att]:
diff --git a/src/saml2/ident.py b/src/saml2/ident.py
index 0e51cc83..162f3fac 100644
--- a/src/saml2/ident.py
+++ b/src/saml2/ident.py
@@ -26,6 +26,15 @@ class Unknown(SAMLError):
def code(item):
+ """
+ Turn a NameID class instance into a quoted string of comma separated
+ attribute,value pairs. The attribute name is replaced with a digits.
+ Depends on knowledge on the specific order of the attributes for that
+ class that is used.
+
+ :param item: The class instance
+ :return: A quoted string
+ """
_res = []
i = 0
for attr in ATTR:
@@ -37,6 +46,10 @@ def code(item):
def decode(txt):
+ """Turns a coded string by code() into a NameID class instance.
+
+ :param txt: The coded string
+ """
_nid = NameID()
for part in txt.split(","):
if part.find("=") != -1:
diff --git a/src/saml2/mdstore.py b/src/saml2/mdstore.py
index fe450e7d..f7ce467e 100644
--- a/src/saml2/mdstore.py
+++ b/src/saml2/mdstore.py
@@ -16,7 +16,7 @@ from saml2 import SAMLError
from saml2 import BINDING_HTTP_REDIRECT
from saml2 import BINDING_HTTP_POST
from saml2 import BINDING_SOAP
-from saml2.s_utils import UnsupportedBinding, UnknownPrincipal
+from saml2.s_utils import UnsupportedBinding, UnknownSystemEntity
from saml2.sigver import split_len
from saml2.validate import valid_instance
from saml2.time_util import valid
@@ -67,9 +67,12 @@ def destinations(srvs):
return [s["location"] for s in srvs]
-def attribute_requirement(entity):
+def attribute_requirement(entity, index=None):
res = {"required": [], "optional": []}
for acs in entity["attribute_consuming_service"]:
+ if index is not None and acs["index"] != index:
+ continue
+
for attr in acs["requested_attribute"]:
if "is_required" in attr and attr["is_required"] == "true":
res["required"].append(attr)
@@ -127,12 +130,21 @@ class MetaData(object):
def values(self):
return self.entity.values()
+ def __len__(self):
+ return len(self.entity)
+
def __contains__(self, item):
- return item in self.entity
+ return item in self.entity.keys()
def __getitem__(self, item):
return self.entity[item]
+ def __setitem__(self, key, value):
+ self.entity[key] = value
+
+ def __delitem__(self, key):
+ del self.entity[key]
+
def do_entity_descriptor(self, entity_descr):
if self.check_validity:
try:
@@ -221,7 +233,7 @@ class MetaData(object):
"""
logger.debug("service(%s, %s, %s, %s)" % (entity_id, typ, service,
- binding))
+ binding))
try:
srvs = []
for t in self[entity_id][typ]:
@@ -297,12 +309,14 @@ class MetaData(object):
return self.service(entity_id, typ, service)
- def attribute_requirement(self, entity_id, index=0):
+ def attribute_requirement(self, entity_id, index=None):
""" Returns what attributes the SP requires and which are optional
if any such demands are registered in the Metadata.
:param entity_id: The entity id of the SP
:param index: which of the attribute consumer services its all about
+ if index=None then return all attributes expected by all
+ attribute_consuming_services.
:return: 2-tuple, list of required and list of optional attributes
"""
@@ -310,7 +324,7 @@ class MetaData(object):
try:
for sp in self[entity_id]["spsso_descriptor"]:
- _res = attribute_requirement(sp)
+ _res = attribute_requirement(sp, index)
res["required"].extend(_res["required"])
res["optional"].extend(_res["optional"])
except KeyError:
@@ -513,6 +527,7 @@ class MetaDataMD(MetaData):
class MetadataStore(object):
def __init__(self, onts, attrc, config, ca_certs=None,
+ check_validity=True,
disable_ssl_certificate_validation=False):
"""
:params onts:
@@ -523,11 +538,16 @@ class MetadataStore(object):
"""
self.onts = onts
self.attrc = attrc
- self.http = HTTPBase(verify=disable_ssl_certificate_validation,
- ca_bundle=ca_certs)
+
+ if disable_ssl_certificate_validation:
+ self.http = HTTPBase(verify=False, ca_bundle=ca_certs)
+ else:
+ self.http = HTTPBase(verify=True, ca_bundle=ca_certs)
+
self.security = security_context(config)
self.ii = 0
self.metadata = {}
+ self.check_validity = check_validity
def load(self, typ, *args, **kwargs):
if typ == "local":
@@ -539,10 +559,16 @@ class MetadataStore(object):
_md = MetaData(self.onts, self.attrc, args[0], **kwargs)
elif typ == "remote":
key = kwargs["url"]
+ _args = {}
+ for _key in ["node_name", "check_validity"]:
+ try:
+ _args[_key] = kwargs[_key]
+ except KeyError:
+ pass
+
_md = MetaDataExtern(self.onts, self.attrc,
kwargs["url"], self.security,
- kwargs["cert"], self.http,
- node_name=kwargs.get('node_name'))
+ kwargs["cert"], self.http, **_args)
elif typ == "mdfile":
key = args[0]
_md = MetaDataMD(self.onts, self.attrc, args[0])
@@ -559,12 +585,14 @@ class MetadataStore(object):
for key, vals in spec.items():
for val in vals:
if isinstance(val, dict):
+ if not self.check_validity:
+ val["check_validity"] = False
self.load(key, **val)
else:
self.load(key, val)
def service(self, entity_id, typ, service, binding=None):
- known_principal = False
+ known_entity = False
for key, _md in self.metadata.items():
srvs = _md.service(entity_id, typ, service, binding)
if srvs:
@@ -572,17 +600,17 @@ class MetadataStore(object):
elif srvs is None:
pass
else:
- known_principal = True
+ known_entity = True
- if known_principal:
+ if known_entity:
logger.error("Unsupported binding: %s (%s)" % (binding, entity_id))
raise UnsupportedBinding(binding)
else:
- logger.error("Unknown principal: %s" % entity_id)
- raise UnknownPrincipal(entity_id)
+ logger.error("Unknown system entity: %s" % entity_id)
+ raise UnknownSystemEntity(entity_id)
def ext_service(self, entity_id, typ, service, binding=None):
- known_principal = False
+ known_entity = False
for key, _md in self.metadata.items():
srvs = _md.ext_service(entity_id, typ, service, binding)
if srvs:
@@ -590,12 +618,12 @@ class MetadataStore(object):
elif srvs is None:
pass
else:
- known_principal = True
+ known_entity = True
- if known_principal:
+ if known_entity:
raise UnsupportedBinding(binding)
else:
- raise UnknownPrincipal(entity_id)
+ raise UnknownSystemEntity(entity_id)
def single_sign_on_service(self, entity_id, binding=None, typ="idpsso"):
# IDP
@@ -633,7 +661,7 @@ class MetadataStore(object):
if binding is None:
binding = BINDING_SOAP
return self.service(entity_id, "pdp_descriptor",
- "authz_service", binding)
+ "authz_service", binding)
def assertion_id_request_service(self, entity_id, binding=None, typ=None):
# AuthnAuthority + IDP + PDP + AttributeAuthority
@@ -642,7 +670,7 @@ class MetadataStore(object):
if binding is None:
binding = BINDING_SOAP
return self.service(entity_id, "%s_descriptor" % typ,
- "assertion_id_request_service", binding)
+ "assertion_id_request_service", binding)
def single_logout_service(self, entity_id, binding=None, typ=None):
# IDP + SP
@@ -651,35 +679,35 @@ class MetadataStore(object):
if binding is None:
binding = BINDING_HTTP_REDIRECT
return self.service(entity_id, "%s_descriptor" % typ,
- "single_logout_service", binding)
+ "single_logout_service", binding)
def manage_name_id_service(self, entity_id, binding=None, typ=None):
# IDP + SP
if binding is None:
binding = BINDING_HTTP_REDIRECT
return self.service(entity_id, "%s_descriptor" % typ,
- "manage_name_id_service", binding)
+ "manage_name_id_service", binding)
def artifact_resolution_service(self, entity_id, binding=None, typ=None):
# IDP + SP
if binding is None:
binding = BINDING_HTTP_REDIRECT
return self.service(entity_id, "%s_descriptor" % typ,
- "artifact_resolution_service", binding)
+ "artifact_resolution_service", binding)
def assertion_consumer_service(self, entity_id, binding=None, _="spsso"):
# SP
if binding is None:
binding = BINDING_HTTP_POST
return self.service(entity_id, "spsso_descriptor",
- "assertion_consumer_service", binding)
+ "assertion_consumer_service", binding)
def attribute_consuming_service(self, entity_id, binding=None, _="spsso"):
# SP
if binding is None:
binding = BINDING_HTTP_REDIRECT
return self.service(entity_id, "spsso_descriptor",
- "attribute_consuming_service", binding)
+ "attribute_consuming_service", binding)
def discovery_response(self, entity_id, binding=None, _="spsso"):
if binding is None:
@@ -863,7 +891,11 @@ class MetadataStore(object):
for _md in self.metadata.values():
for ent_id, ent_desc in _md.items():
if descriptor in ent_desc:
- res.append(ent_id)
+ if ent_id in res:
+ #print "duplicated entity_id: %s" % res
+ pass
+ else:
+ res.append(ent_id)
return res
def service_providers(self):
@@ -887,7 +919,8 @@ class MetadataStore(object):
res = EntitiesDescriptor()
for _md in self.metadata.values():
try:
- res.entity_descriptor.extend(_md.entities_descr.entity_descriptor)
+ res.entity_descriptor.extend(
+ _md.entities_descr.entity_descriptor)
except AttributeError:
res.entity_descriptor.append(_md.entity_descr)
diff --git a/src/saml2/metadata.py b/src/saml2/metadata.py
index 3491bef5..8d81f371 100644
--- a/src/saml2/metadata.py
+++ b/src/saml2/metadata.py
@@ -423,9 +423,18 @@ def do_endpoints(conf, endpoints):
args = {"location": args[0], "binding": args[1],
"index": args[2]}
- if indexed and "index" not in args:
- args["index"] = "%d" % i
- i += 1
+ if indexed:
+ if "index" not in args:
+ args["index"] = "%d" % i
+ i += 1
+ else:
+ try:
+ int(args["index"])
+ except ValueError:
+ raise
+ else:
+ args["index"] = str(args["index"])
+
servs.append(factory(eclass, **args))
service[endpoint] = servs
except KeyError:
diff --git a/src/saml2/pack.py b/src/saml2/pack.py
index 53c31ccd..a7b86857 100644
--- a/src/saml2/pack.py
+++ b/src/saml2/pack.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2010-2011 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 classes and functions that are necessary to implement
different bindings.
diff --git a/src/saml2/request.py b/src/saml2/request.py
index e8348084..f840db1d 100644
--- a/src/saml2/request.py
+++ b/src/saml2/request.py
@@ -75,7 +75,7 @@ class Request(object):
def _verify(self):
assert self.message.version == "2.0"
- if self.message.destination and \
+ if self.message.destination and self.receiver_addrs and \
self.message.destination not in self.receiver_addrs:
logger.error("%s not in %s" % (self.message.destination,
self.receiver_addrs))
diff --git a/src/saml2/response.py b/src/saml2/response.py
index f6a8d187..b7c8fa99 100644
--- a/src/saml2/response.py
+++ b/src/saml2/response.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2010-2011 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.
import calendar
import logging
diff --git a/src/saml2/s_utils.py b/src/saml2/s_utils.py
index 57fe0886..0a2aa5c2 100644
--- a/src/saml2/s_utils.py
+++ b/src/saml2/s_utils.py
@@ -47,6 +47,10 @@ class UnknownPrincipal(SamlException):
pass
+class UnknownSystemEntity(SamlException):
+ pass
+
+
class Unsupported(SamlException):
pass
diff --git a/src/saml2/server.py b/src/saml2/server.py
index 954b1ec3..f7512add 100644
--- a/src/saml2/server.py
+++ b/src/saml2/server.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2009-2011 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 classes and functions that a SAML2.0 Identity provider (IdP)
or attribute authority (AA) may use to conclude its tasks.
@@ -187,6 +174,8 @@ class Server(Entity):
:param sp_entity_id: The entity id of the SP
:param index: which of the attribute consumer services its all about
+ if index == None then all attribute consumer services are clumped
+ together.
:return: 2-tuple, list of required and list of optional attributes
"""
return self.metadata.attribute_requirement(sp_entity_id, index)
diff --git a/src/saml2/sigver.py b/src/saml2/sigver.py
index cbbbcbee..c32136ad 100644
--- a/src/saml2/sigver.py
+++ b/src/saml2/sigver.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2009-2011 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.
""" Functions connected to signing and verifying.
Based on the use of xmlsec1 binaries and not the python xmlsec module.
@@ -123,6 +110,11 @@ class CertificateError(SigverError):
pass
+def read_file(*args, **kwargs):
+ with open(*args, **kwargs) as handler:
+ return handler.read()
+
+
def rm_xmltag(statement):
try:
_t = statement.startswith(XMLTAG)
@@ -557,7 +549,7 @@ def pem_format(key):
def import_rsa_key_from_file(filename):
- return RSA.importKey(open(filename, 'r').read())
+ return RSA.importKey(read_file(filename, 'r'))
def parse_xmlsec_output(output):
@@ -644,14 +636,11 @@ def verify_redirect_signature(saml_msg, cert):
args = saml_msg.copy()
del args["Signature"] # everything but the signature
string = "&".join(
- [urllib.urlencode({k: args[k][0]}) for k in _order])
+ [urllib.urlencode({k: args[k][0]}) for k in _order if k in args])
_key = extract_rsa_key_from_x509_cert(pem_format(cert))
_sign = base64.b64decode(saml_msg["Signature"][0])
- try:
- signer.verify(string, _sign, _key)
- return True
- except BadSignature:
- return False
+
+ return bool(signer.verify(string, _sign, _key))
LOG_LINE = 60 * "=" + "\n%s\n" + 60 * "-" + "\n%s" + 60 * "="
@@ -669,11 +658,13 @@ def read_cert_from_file(cert_file, cert_type):
:param cert_type: The certificate type
:return: A base64 encoded certificate as a string or the empty string
"""
+
+
if not cert_file:
return ""
if cert_type == "pem":
- line = open(cert_file).read().split("\n")
+ line = read_file(cert_file).split("\n")
if line[0] == "-----BEGIN CERTIFICATE-----":
line = line[1:]
elif line[0] == "-----BEGIN PUBLIC KEY-----":
@@ -693,7 +684,7 @@ def read_cert_from_file(cert_file, cert_type):
return "".join(line)
if cert_type in ["der", "cer", "crt"]:
- data = open(cert_file).read()
+ data = read_file(cert_file)
return base64.b64encode(str(data))
@@ -1013,9 +1004,15 @@ def security_context(conf, debug=None):
return None
if debug is None:
- debug = conf.debug
+ try:
+ debug = conf.debug
+ except AttributeError:
+ pass
- metadata = conf.metadata
+ try:
+ metadata = conf.metadata
+ except AttributeError:
+ metadata = None
_only_md = conf.only_use_keys_in_metadata
if _only_md is None:
@@ -1063,13 +1060,19 @@ def encrypt_cert_from_item(item):
certs = cert_from_instance(item)
if len(certs) > 0:
_encrypt_cert = certs[0]
- if _encrypt_cert is not None:
- if _encrypt_cert.find("-----BEGIN CERTIFICATE-----\n") == -1:
- _encrypt_cert = "-----BEGIN CERTIFICATE-----\n" + _encrypt_cert
- if _encrypt_cert.find("-----END CERTIFICATE-----\n") == -1:
- _encrypt_cert = _encrypt_cert + "-----END CERTIFICATE-----\n"
except Exception:
- return None
+ pass
+
+ if _encrypt_cert is None:
+ certs = cert_from_instance(item)
+ if len(certs) > 0:
+ _encrypt_cert = certs[0]
+
+ if _encrypt_cert is not None:
+ if _encrypt_cert.find("-----BEGIN CERTIFICATE-----\n") == -1:
+ _encrypt_cert = "-----BEGIN CERTIFICATE-----\n" + _encrypt_cert
+ if _encrypt_cert.find("\n-----END CERTIFICATE-----") == -1:
+ _encrypt_cert = _encrypt_cert + "\n-----END CERTIFICATE-----"
return _encrypt_cert
@@ -1835,4 +1838,4 @@ if __name__ == '__main__':
args = parser.parse_args()
if args.listsigalgs:
- print '\n'.join([key for key, value in SIGNER_ALGS.items()]) \ No newline at end of file
+ print '\n'.join([key for key, value in SIGNER_ALGS.items()])
diff --git a/src/saml2/soap.py b/src/saml2/soap.py
index 75329895..e42e8f9e 100644
--- a/src/saml2/soap.py
+++ b/src/saml2/soap.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2009-2011 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.
"""
Suppport for the client part of the SAML2.0 SOAP binding.
diff --git a/src/saml2/time_util.py b/src/saml2/time_util.py
index 34df69e7..40d7d062 100644
--- a/src/saml2/time_util.py
+++ b/src/saml2/time_util.py
@@ -1,20 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2009-2011 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.
-"""
+"""
Implements some usefull functions when dealing with validity of
different types of information.
"""
diff --git a/tests/ds_data.py b/tests/ds_data.py
index 71743852..243d955e 100644
--- a/tests/ds_data.py
+++ b/tests/ds_data.py
@@ -1,18 +1,5 @@
#!/usr/bin/env python
#
-# Copyright (C) 2007 SIOS Technology, Inc.
-#
-# 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.
"""Test data for ds"""
diff --git a/tests/fakeIDP.py b/tests/fakeIDP.py
index 3fd25a73..1df910e2 100644
--- a/tests/fakeIDP.py
+++ b/tests/fakeIDP.py
@@ -47,6 +47,7 @@ class DummyResponse(object):
self.status_code = code
self.text = data
self.headers = headers or []
+ self.content = data
class FakeIDP(Server):
@@ -142,12 +143,9 @@ class FakeIDP(Server):
#userid = "Pavill"
name_id = aquery.subject.name_id
- attr_resp = self.create_attribute_response(extra, aquery.id,
- None,
- sp_entity_id=aquery.issuer
- .text,
- name_id=name_id,
- attributes=aquery.attribute)
+ attr_resp = self.create_attribute_response(
+ extra, aquery.id, None, sp_entity_id=aquery.issuer.text,
+ name_id=name_id, attributes=aquery.attribute)
if binding == BINDING_SOAP:
# SOAP packing
diff --git a/tests/idp_example.xml b/tests/idp_example.xml
new file mode 100644
index 00000000..6c7efca9
--- /dev/null
+++ b/tests/idp_example.xml
@@ -0,0 +1,230 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<ns0:EntityDescriptor xmlns:ns0="urn:oasis:names:tc:SAML:2.0:metadata"
+ xmlns:ns1="http://www.w3.org/2000/09/xmldsig#"
+ entityID="http://localhost:8088/idp.xml"
+ validUntil="2014-04-12T06:06:13Z">
+ <ns0:IDPSSODescriptor WantAuthnRequestsOnlyWithValidCert="false"
+ WantAuthnRequestsSigned="false"
+ protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <ns0:KeyDescriptor use="encryption">
+ <ns1:KeyInfo>
+ <ns1:X509Data>
+ <ns1:X509Certificate>
+ 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=
+ </ns1:X509Certificate>
+ </ns1:X509Data>
+ </ns1:KeyInfo>
+ </ns0:KeyDescriptor>
+ <ns0:KeyDescriptor use="signing">
+ <ns1:KeyInfo>
+ <ns1:X509Data>
+ <ns1:X509Certificate>
+ 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=
+ </ns1:X509Certificate>
+ </ns1:X509Data>
+ </ns1:KeyInfo>
+ </ns0:KeyDescriptor>
+ <ns0:SingleLogoutService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+ Location="http://localhost:8088/slo/soap"/>
+ <ns0:SingleLogoutService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+ Location="http://localhost:8088/slo/post"/>
+ <ns0:SingleLogoutService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
+ Location="http://localhost:8088/slo/redirect"/>
+ <ns0:ManageNameIDService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+ Location="http://localhost:8088/mni/soap"/>
+ <ns0:ManageNameIDService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+ Location="http://localhost:8088/mni/post"/>
+ <ns0:ManageNameIDService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
+ Location="http://localhost:8088/mni/redirect"/>
+ <ns0:ManageNameIDService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
+ Location="http://localhost:8088/mni/art"/>
+ <ns0:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient
+ </ns0:NameIDFormat>
+ <ns0:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
+ </ns0:NameIDFormat>
+ <ns0:SingleSignOnService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
+ Location="http://localhost:8088/sso/redirect"/>
+ <ns0:SingleSignOnService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
+ Location="http://localhost:8088/sso/post"/>
+ <ns0:SingleSignOnService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
+ Location="http://localhost:8088/sso/art"/>
+ <ns0:SingleSignOnService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+ Location="http://localhost:8088/sso/ecp"/>
+ <ns0:NameIDMappingService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+ Location="http://localhost:8088/nim"/>
+ <ns0:AssertionIDRequestService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:URI"
+ Location="http://localhost:8088/airs"/>
+ </ns0:IDPSSODescriptor>
+ <ns0:AuthnAuthorityDescriptor
+ protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <ns0:KeyDescriptor use="encryption">
+ <ns1:KeyInfo>
+ <ns1:X509Data>
+ <ns1:X509Certificate>
+ 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=
+ </ns1:X509Certificate>
+ </ns1:X509Data>
+ </ns1:KeyInfo>
+ </ns0:KeyDescriptor>
+ <ns0:KeyDescriptor use="signing">
+ <ns1:KeyInfo>
+ <ns1:X509Data>
+ <ns1:X509Certificate>
+ 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=
+ </ns1:X509Certificate>
+ </ns1:X509Data>
+ </ns1:KeyInfo>
+ </ns0:KeyDescriptor>
+ <ns0:AuthnQueryService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+ Location="http://localhost:8088/aqs"/>
+ </ns0:AuthnAuthorityDescriptor>
+ <ns0:AttributeAuthorityDescriptor
+ protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
+ <ns0:KeyDescriptor use="encryption">
+ <ns1:KeyInfo>
+ <ns1:X509Data>
+ <ns1:X509Certificate>
+ 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=
+ </ns1:X509Certificate>
+ </ns1:X509Data>
+ </ns1:KeyInfo>
+ </ns0:KeyDescriptor>
+ <ns0:KeyDescriptor use="signing">
+ <ns1:KeyInfo>
+ <ns1:X509Data>
+ <ns1:X509Certificate>
+ 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=
+ </ns1:X509Certificate>
+ </ns1:X509Data>
+ </ns1:KeyInfo>
+ </ns0:KeyDescriptor>
+ <ns0:AttributeService
+ Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP"
+ Location="http://localhost:8088/attr"/>
+ <ns0:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient
+ </ns0:NameIDFormat>
+ <ns0:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent
+ </ns0:NameIDFormat>
+ </ns0:AttributeAuthorityDescriptor>
+ <ns0:Organization>
+ <ns0:OrganizationName xml:lang="en">Rolands Identiteter
+ </ns0:OrganizationName>
+ <ns0:OrganizationDisplayName xml:lang="en">Rolands Identiteter
+ </ns0:OrganizationDisplayName>
+ <ns0:OrganizationURL xml:lang="en">http://www.example.com
+ </ns0:OrganizationURL>
+ </ns0:Organization>
+ <ns0:ContactPerson contactType="technical">
+ <ns0:GivenName>Roland</ns0:GivenName>
+ <ns0:SurName>Hedberg</ns0:SurName>
+ <ns0:EmailAddress>technical@example.com</ns0:EmailAddress>
+ </ns0:ContactPerson>
+ <ns0:ContactPerson contactType="support">
+ <ns0:GivenName>Support</ns0:GivenName>
+ <ns0:EmailAddress>support@example.com</ns0:EmailAddress>
+ </ns0:ContactPerson>
+</ns0:EntityDescriptor>
diff --git a/tests/md_data.py b/tests/md_data.py
index d5176b5a..1a18ce6d 100644
--- a/tests/md_data.py
+++ b/tests/md_data.py
@@ -1,18 +1,5 @@
#!/usr/bin/env python
#
-# Copyright (C) 2007 SIOS Technology, Inc.
-#
-# 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.
"""Test data for md"""
diff --git a/tests/saml2_data.py b/tests/saml2_data.py
index a5f98416..fe650e7b 100644
--- a/tests/saml2_data.py
+++ b/tests/saml2_data.py
@@ -1,18 +1,5 @@
#!/usr/bin/env python
#
-# Copyright (C) 2007 SIOS Technology, Inc.
-#
-# 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.
"""Test data for saml2"""
diff --git a/tests/samlp_data.py b/tests/samlp_data.py
index 22ce0a82..f458d15c 100644
--- a/tests/samlp_data.py
+++ b/tests/samlp_data.py
@@ -1,18 +1,5 @@
#!/usr/bin/env python
#
-# Copyright (C) 2007 SIOS Technology, Inc.
-#
-# 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.
"""Test data for saml2"""
diff --git a/tests/server_conf_syslog.py b/tests/server_conf_syslog.py
index 72e6a748..4dc6a85b 100644
--- a/tests/server_conf_syslog.py
+++ b/tests/server_conf_syslog.py
@@ -3,48 +3,50 @@ __author__ = 'rolandh'
from pathutils import full_path
-CONFIG={
- "entityid" : "urn:mace:example.com:saml:roland:sp",
- "name" : "urn:mace:example.com:saml:roland:sp",
+CONFIG = {
+ "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"
+ },
],
"logger": {
"syslog": {
diff --git a/tests/sp_slo_redirect_conf.py b/tests/sp_slo_redirect_conf.py
index 7856c11e..97751dae 100644
--- a/tests/sp_slo_redirect_conf.py
+++ b/tests/sp_slo_redirect_conf.py
@@ -6,16 +6,16 @@ from pathutils import full_path
HOME = "http://lingon.catalogix.se:8087/"
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":{
+ "endpoints": {
"assertion_consumer_service": [
- (HOME, BINDING_HTTP_REDIRECT)],
- "single_logout_service" : [
- (HOME+"slo",BINDING_HTTP_REDIRECT)],
+ (HOME, BINDING_HTTP_REDIRECT)],
+ "single_logout_service": [
+ (HOME + "slo", BINDING_HTTP_REDIRECT)],
},
"required_attributes": ["surName", "givenName", "mail"],
"optional_attributes": ["title"],
@@ -23,32 +23,33 @@ CONFIG = {
"subject_data": full_path("subject_data.db"),
}
},
- "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_slo_redirect.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",
}
},
"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"
+ },
]
}
diff --git a/tests/test_00_xmldsig.py b/tests/test_00_xmldsig.py
index 8ebd6ef8..8b40e9db 100644
--- a/tests/test_00_xmldsig.py
+++ b/tests/test_00_xmldsig.py
@@ -1,18 +1,5 @@
#!/usr/bin/env python
#
-# Copyright (C) 2007 SIOS Technology, Inc.
-#
-# 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.
"""Tests for xmldsig"""
diff --git a/tests/test_02_saml.py b/tests/test_02_saml.py
index fdc362b4..41beabee 100644
--- a/tests/test_02_saml.py
+++ b/tests/test_02_saml.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# Copyright (C) 2010 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.
"""Tests for saml2.saml"""
diff --git a/tests/test_04_samlp.py b/tests/test_04_samlp.py
index 2cfd59b7..dae76535 100644
--- a/tests/test_04_samlp.py
+++ b/tests/test_04_samlp.py
@@ -1,19 +1,6 @@
#!/usr/bin/env pythony
# -*- coding: utf-8 -*-
#
-# 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.
"""Tests for saml2.samlp"""
diff --git a/tests/test_05_md.py b/tests/test_05_md.py
index f0a8ef03..c02d668d 100644
--- a/tests/test_05_md.py
+++ b/tests/test_05_md.py
@@ -1,19 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
-# 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.
"""Tests for saml2.md"""
diff --git a/tests/test_12_s_utils.py b/tests/test_12_s_utils.py
index f4cfdda8..730ffa76 100644
--- a/tests/test_12_s_utils.py
+++ b/tests/test_12_s_utils.py
@@ -1,37 +1,37 @@
-#!/usr/bin/env python
+# !/usr/bin/env python
# -*- coding: utf-8 -*-
-import zlib
import base64
-import gzip
-from saml2 import make_instance
from saml2 import s_utils as utils
from saml2 import saml
from saml2 import samlp
-from saml2 import md
from saml2.s_utils import do_attribute_statement
-
-from saml2.sigver import make_temp
-
-from saml2.saml import Attribute, NAME_FORMAT_URI, AttributeValue
+from saml2.saml import Attribute
+from saml2.saml import NAME_FORMAT_URI
from py.test import raises
from pathutils import full_path
-SUCCESS_STATUS = """<?xml version=\'1.0\' encoding=\'UTF-8\'?>
-<ns0:Status xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol"><ns0:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></ns0:Status>"""
+SUCCESS_STATUS = ('<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n'
+'<ns0:Status xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol"><ns0:StatusCode '
+'Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></ns0:Status>')
-ERROR_STATUS = """<?xml version='1.0' encoding='UTF-8'?>
-<ns0:Status xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol"><ns0:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder"><ns0:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal" /></ns0:StatusCode><ns0:StatusMessage>Error resolving principal</ns0:StatusMessage></ns0:Status>"""
+ERROR_STATUS = ('<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n'
+'<ns0:Status xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol"><ns0:StatusCode '
+'Value="urn:oasis:names:tc:SAML:2.0:status:Responder"><ns0:StatusCode '
+'Value="urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal" '
+'/></ns0:StatusCode><ns0:StatusMessage>Error resolving '
+'principal</ns0:StatusMessage></ns0:Status>')
-def _eq(l1,l2):
+def _eq(l1, l2):
return set(l1) == set(l2)
-def _oeq(l1,l2):
+
+def _oeq(l1, l2):
if len(l1) != len(l2):
print "Different number of items"
return False
@@ -42,40 +42,45 @@ def _oeq(l1,l2):
print "\t%s" % (ite,)
return False
return True
-
+
+
def test_inflate_then_deflate():
- str = """Selma Lagerlöf (1858-1940) was born in Östra Emterwik, Värmland,
+ txt = """Selma Lagerlöf (1858-1940) was born in Östra Emterwik, Värmland,
Sweden. She was brought up on Mårbacka, the family estate, which she did
not leave until 1881, when she went to a teachers' college at Stockholm"""
-
- interm = utils.deflate_and_base64_encode(str)
- bis = utils.decode_base64_and_inflate(interm)
- assert bis == str
-
+
+ interm = utils.deflate_and_base64_encode(txt)
+ bis = utils.decode_base64_and_inflate(interm)
+ assert bis == txt
+
+
def test_status_success():
status = utils.success_status_factory()
status_text = "%s" % status
assert status_text == SUCCESS_STATUS
assert status.status_code.value == samlp.STATUS_SUCCESS
-
+
+
def test_error_status():
status = utils.status_message_factory("Error resolving principal",
- samlp.STATUS_UNKNOWN_PRINCIPAL,
- samlp.STATUS_RESPONDER)
-
+ samlp.STATUS_UNKNOWN_PRINCIPAL,
+ samlp.STATUS_RESPONDER)
+
status_text = "%s" % status
print status_text
assert status_text == ERROR_STATUS
+
def test_status_from_exception():
e = utils.UnknownPrincipal("Error resolving principal")
stat = utils.error_status_factory(e)
status_text = "%s" % stat
print status_text
assert status_text == ERROR_STATUS
-
+
+
def test_attribute_sn():
- attr = utils.do_attributes({"surName":("Jeter", "")})
+ attr = utils.do_attributes({"surName": ("Jeter", "")})
assert len(attr) == 1
print attr
inst = attr[0]
@@ -84,9 +89,10 @@ def test_attribute_sn():
av = inst.attribute_value[0]
assert av.text == "Jeter"
+
def test_attribute_age():
- attr = utils.do_attributes({"age":(37, "")})
-
+ attr = utils.do_attributes({"age": (37, "")})
+
assert len(attr) == 1
inst = attr[0]
print inst
@@ -96,9 +102,10 @@ def test_attribute_age():
assert av.text == "37"
assert av.get_type() == "xs:integer"
+
def test_attribute_onoff():
- attr = utils.do_attributes({"onoff":(False, "")})
-
+ attr = utils.do_attributes({"onoff": (False, "")})
+
assert len(attr) == 1
inst = attr[0]
print inst
@@ -108,10 +115,11 @@ def test_attribute_onoff():
assert av.text == "false"
assert av.get_type() == "xs:boolean"
+
def test_attribute_base64():
b64sl = base64.b64encode("Selma Lagerlöf")
- attr = utils.do_attributes({"name":(b64sl, "xs:base64Binary")})
-
+ attr = utils.do_attributes({"name": (b64sl, "xs:base64Binary")})
+
assert len(attr) == 1
inst = attr[0]
print inst
@@ -120,18 +128,19 @@ def test_attribute_base64():
av = inst.attribute_value[0]
assert av.get_type() == "xs:base64Binary"
assert av.text.strip() == b64sl
-
+
+
def test_attribute_statement():
- statement = do_attribute_statement({"surName":("Jeter", ""),
- "givenName":("Derek", "")})
+ statement = do_attribute_statement({"surName": ("Jeter", ""),
+ "givenName": ("Derek", "")})
print statement
assert statement.keyswv() == ["attribute"]
assert len(statement.attribute) == 2
attr0 = statement.attribute[0]
- assert _eq(attr0.keyswv(), ["name","attribute_value"])
+ assert _eq(attr0.keyswv(), ["name", "attribute_value"])
assert len(attr0.attribute_value) == 1
attr1 = statement.attribute[1]
- assert _eq(attr1.keyswv(), ["name","attribute_value"])
+ assert _eq(attr1.keyswv(), ["name", "attribute_value"])
assert len(attr1.attribute_value) == 1
if attr0.name == "givenName":
assert attr0.attribute_value[0].text == "Derek"
@@ -143,54 +152,62 @@ def test_attribute_statement():
assert attr1.name == "givenName"
assert attr1.attribute_value[0].text == "Derek"
+
def test_audience():
aud_restr = utils.factory(saml.AudienceRestriction,
- audience=utils.factory(saml.Audience,text="urn:foo:bar"))
-
+ audience=utils.factory(saml.Audience,
+ text="urn:foo:bar"))
+
assert aud_restr.keyswv() == ["audience"]
assert aud_restr.audience.text == "urn:foo:bar"
-
+
+
def test_conditions():
conditions = utils.factory(saml.Conditions,
- not_before="2009-10-30T07:58:10.852Z",
- not_on_or_after="2009-10-30T08:03:10.852Z",
- audience_restriction=[utils.factory(saml.AudienceRestriction,
- audience=utils.factory(saml.Audience,
- text="urn:foo:bar"))])
-
+ not_before="2009-10-30T07:58:10.852Z",
+ not_on_or_after="2009-10-30T08:03:10.852Z",
+ audience_restriction=[
+ utils.factory(saml.AudienceRestriction,
+ audience=utils.factory(
+ saml.Audience,
+ text="urn:foo:bar"))])
+
assert _eq(conditions.keyswv(), ["not_before", "not_on_or_after",
- "audience_restriction"])
- assert conditions.not_before == "2009-10-30T07:58:10.852Z"
+ "audience_restriction"])
+ assert conditions.not_before == "2009-10-30T07:58:10.852Z"
assert conditions.not_on_or_after == "2009-10-30T08:03:10.852Z"
assert conditions.audience_restriction[0].audience.text == "urn:foo:bar"
-
+
+
def test_value_1():
#FriendlyName="givenName" Name="urn:oid:2.5.4.42"
# NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri"
attribute = utils.factory(saml.Attribute, name="urn:oid:2.5.4.42",
- name_format=NAME_FORMAT_URI)
- assert _eq(attribute.keyswv(),["name","name_format"])
+ name_format=NAME_FORMAT_URI)
+ assert _eq(attribute.keyswv(), ["name", "name_format"])
assert attribute.name == "urn:oid:2.5.4.42"
assert attribute.name_format == saml.NAME_FORMAT_URI
+
def test_value_2():
attribute = utils.factory(saml.Attribute, name="urn:oid:2.5.4.42",
- name_format=NAME_FORMAT_URI,
- friendly_name="givenName")
- assert _eq(attribute.keyswv(),["name","name_format","friendly_name"])
+ name_format=NAME_FORMAT_URI,
+ friendly_name="givenName")
+ assert _eq(attribute.keyswv(), ["name", "name_format", "friendly_name"])
assert attribute.name == "urn:oid:2.5.4.42"
assert attribute.name_format == NAME_FORMAT_URI
assert attribute.friendly_name == "givenName"
+
def test_value_3():
- attribute = utils.factory(saml.Attribute,
- attribute_value=[utils.factory(
- saml.AttributeValue, text="Derek")],
- name="urn:oid:2.5.4.42",
- name_format=NAME_FORMAT_URI,
- friendly_name="givenName")
-
- assert _eq(attribute.keyswv(),["name", "name_format",
+ attribute = utils.factory(saml.Attribute,
+ attribute_value=[utils.factory(
+ saml.AttributeValue, text="Derek")],
+ name="urn:oid:2.5.4.42",
+ name_format=NAME_FORMAT_URI,
+ friendly_name="givenName")
+
+ assert _eq(attribute.keyswv(), ["name", "name_format",
"friendly_name", "attribute_value"])
assert attribute.name == "urn:oid:2.5.4.42"
assert attribute.name_format == NAME_FORMAT_URI
@@ -198,43 +215,46 @@ def test_value_3():
assert len(attribute.attribute_value) == 1
assert attribute.attribute_value[0].text == "Derek"
+
def test_value_4():
- attribute = utils.factory(saml.Attribute,
- attribute_value=[utils.factory(
- saml.AttributeValue, text="Derek")],
- friendly_name="givenName")
+ attribute = utils.factory(saml.Attribute,
+ attribute_value=[utils.factory(
+ saml.AttributeValue, text="Derek")],
+ friendly_name="givenName")
- assert _eq(attribute.keyswv(),["friendly_name", "attribute_value"])
+ assert _eq(attribute.keyswv(), ["friendly_name", "attribute_value"])
assert attribute.friendly_name == "givenName"
assert len(attribute.attribute_value) == 1
assert attribute.attribute_value[0].text == "Derek"
+
def test_do_attribute_statement_0():
- statement = do_attribute_statement({"vo_attr":("foobar", "")})
+ statement = do_attribute_statement({"vo_attr": ("foobar", "")})
assert statement.keyswv() == ["attribute"]
assert len(statement.attribute) == 1
attr0 = statement.attribute[0]
- assert _eq(attr0.keyswv(), ["name","attribute_value"])
+ assert _eq(attr0.keyswv(), ["name", "attribute_value"])
assert attr0.name == "vo_attr"
assert len(attr0.attribute_value) == 1
assert attr0.attribute_value[0].text == "foobar"
+
def test_do_attribute_statement():
- statement = do_attribute_statement({"surName":("Jeter", ""),
- "givenName":(["Derek",
- "Sanderson"], "")})
+ statement = do_attribute_statement({"surName": ("Jeter", ""),
+ "givenName": (["Derek",
+ "Sanderson"], "")})
assert statement.keyswv() == ["attribute"]
assert len(statement.attribute) == 2
attr0 = statement.attribute[0]
- assert _eq(attr0.keyswv(), ["name","attribute_value"])
+ assert _eq(attr0.keyswv(), ["name", "attribute_value"])
attr1 = statement.attribute[1]
- assert _eq(attr1.keyswv(), ["name","attribute_value"])
+ assert _eq(attr1.keyswv(), ["name", "attribute_value"])
if attr0.name == "givenName":
assert len(attr0.attribute_value) == 2
assert _eq([av.text for av in attr0.attribute_value],
- ["Derek","Sanderson"])
+ ["Derek", "Sanderson"])
assert attr1.name == "surName"
assert attr1.attribute_value[0].text == "Jeter"
assert len(attr1.attribute_value) == 1
@@ -245,211 +265,234 @@ def test_do_attribute_statement():
assert attr1.name == "givenName"
assert len(attr1.attribute_value) == 2
assert _eq([av.text for av in attr1.attribute_value],
- ["Derek","Sanderson"])
-
+ ["Derek", "Sanderson"])
+
+
def test_do_attribute_statement_multi():
statement = do_attribute_statement(
- {( "urn:oid:1.3.6.1.4.1.5923.1.1.1.7",
- "urn:oasis:names:tc:SAML:2.0:attrname-format:uri",
- "eduPersonEntitlement"):("Jeter", "")})
+ {("urn:oid:1.3.6.1.4.1.5923.1.1.1.7",
+ "urn:oasis:names:tc:SAML:2.0:attrname-format:uri",
+ "eduPersonEntitlement"): ("Jeter", "")})
assert statement.keyswv() == ["attribute"]
assert len(statement.attribute)
assert _eq(statement.attribute[0].keyswv(),
- ["name","name_format","friendly_name","attribute_value"])
+ ["name", "name_format", "friendly_name", "attribute_value"])
attribute = statement.attribute[0]
assert attribute.name == "urn:oid:1.3.6.1.4.1.5923.1.1.1.7"
assert attribute.name_format == (
- "urn:oasis:names:tc:SAML:2.0:attrname-format:uri")
+ "urn:oasis:names:tc:SAML:2.0:attrname-format:uri")
assert attribute.friendly_name == "eduPersonEntitlement"
+
def test_subject():
- subject = utils.factory(saml.Subject, text="_aaa",
+ subject = utils.factory(saml.Subject, text="_aaa",
name_id=saml.NameID(
- text=saml.NAMEID_FORMAT_TRANSIENT))
+ text=saml.NAMEID_FORMAT_TRANSIENT))
- assert _eq(subject.keyswv(),["text", "name_id"])
+ assert _eq(subject.keyswv(), ["text", "name_id"])
assert subject.text == "_aaa"
assert subject.name_id.text == saml.NAMEID_FORMAT_TRANSIENT
+
# ---------------------------------------------------------------------------
def test_parse_attribute_map():
- (forward, backward) = utils.parse_attribute_map([full_path("attribute.map")])
-
+ (forward, backward) = utils.parse_attribute_map(
+ [full_path("attribute.map")])
+
assert _eq(forward.keys(), backward.values())
assert _eq(forward.values(), backward.keys())
print forward.keys()
assert _oeq(forward.keys(), [
- ('urn:oid:1.3.6.1.4.1.5923.1.1.1.7', NAME_FORMAT_URI),
- ('urn:oid:0.9.2342.19200300.100.1.1', NAME_FORMAT_URI),
- ('urn:oid:1.3.6.1.4.1.5923.1.1.1.1', NAME_FORMAT_URI),
- ('urn:oid:2.5.4.42', NAME_FORMAT_URI),
- ('urn:oid:2.5.4.4', NAME_FORMAT_URI),
- ('urn:oid:0.9.2342.19200300.100.1.3', NAME_FORMAT_URI),
- ('urn:oid:2.5.4.12', NAME_FORMAT_URI)])
+ ('urn:oid:1.3.6.1.4.1.5923.1.1.1.7', NAME_FORMAT_URI),
+ ('urn:oid:0.9.2342.19200300.100.1.1', NAME_FORMAT_URI),
+ ('urn:oid:1.3.6.1.4.1.5923.1.1.1.1', NAME_FORMAT_URI),
+ ('urn:oid:2.5.4.42', NAME_FORMAT_URI),
+ ('urn:oid:2.5.4.4', NAME_FORMAT_URI),
+ ('urn:oid:0.9.2342.19200300.100.1.3', NAME_FORMAT_URI),
+ ('urn:oid:2.5.4.12', NAME_FORMAT_URI)])
assert _eq(forward.keys(), [
- ('urn:oid:1.3.6.1.4.1.5923.1.1.1.7', NAME_FORMAT_URI),
- ('urn:oid:0.9.2342.19200300.100.1.1', NAME_FORMAT_URI),
- ('urn:oid:1.3.6.1.4.1.5923.1.1.1.1', NAME_FORMAT_URI),
- ('urn:oid:2.5.4.42', NAME_FORMAT_URI),
- ('urn:oid:2.5.4.4', NAME_FORMAT_URI),
- ('urn:oid:0.9.2342.19200300.100.1.3', NAME_FORMAT_URI),
- ('urn:oid:2.5.4.12', NAME_FORMAT_URI)])
- assert _eq(backward.keys(),["surName","givenName","title","uid","mail",
- "eduPersonAffiliation",
- "eduPersonEntitlement"])
-
+ ('urn:oid:1.3.6.1.4.1.5923.1.1.1.7', NAME_FORMAT_URI),
+ ('urn:oid:0.9.2342.19200300.100.1.1', NAME_FORMAT_URI),
+ ('urn:oid:1.3.6.1.4.1.5923.1.1.1.1', NAME_FORMAT_URI),
+ ('urn:oid:2.5.4.42', NAME_FORMAT_URI),
+ ('urn:oid:2.5.4.4', NAME_FORMAT_URI),
+ ('urn:oid:0.9.2342.19200300.100.1.3', NAME_FORMAT_URI),
+ ('urn:oid:2.5.4.12', NAME_FORMAT_URI)])
+ assert _eq(backward.keys(), ["surName", "givenName", "title", "uid", "mail",
+ "eduPersonAffiliation",
+ "eduPersonEntitlement"])
+
def test_identity_attribute_0():
- (forward, backward) = utils.parse_attribute_map([full_path("attribute.map")])
+ (forward, backward) = utils.parse_attribute_map(
+ [full_path("attribute.map")])
a = Attribute(name="urn:oid:2.5.4.4", name_format=NAME_FORMAT_URI,
- friendly_name="surName")
-
- assert utils.identity_attribute("name",a,forward) == "urn:oid:2.5.4.4"
- assert utils.identity_attribute("friendly",a,forward) == "surName"
-
+ friendly_name="surName")
+
+ assert utils.identity_attribute("name", a, forward) == "urn:oid:2.5.4.4"
+ assert utils.identity_attribute("friendly", a, forward) == "surName"
+
+
def test_identity_attribute_1():
- (forward, backward) = utils.parse_attribute_map([full_path("attribute.map")])
+ (forward, backward) = utils.parse_attribute_map(
+ [full_path("attribute.map")])
a = Attribute(name="urn:oid:2.5.4.4", name_format=NAME_FORMAT_URI)
-
- assert utils.identity_attribute("name",a,forward) == "urn:oid:2.5.4.4"
- assert utils.identity_attribute("friendly",a,forward) == "surName"
+
+ assert utils.identity_attribute("name", a, forward) == "urn:oid:2.5.4.4"
+ assert utils.identity_attribute("friendly", a, forward) == "surName"
+
def test_identity_attribute_2():
- (forward, backward) = utils.parse_attribute_map([full_path("attribute.map")])
+ (forward, backward) = utils.parse_attribute_map(
+ [full_path("attribute.map")])
a = Attribute(name="urn:oid:2.5.4.5", name_format=NAME_FORMAT_URI)
-
- assert utils.identity_attribute("name",a,forward) == "urn:oid:2.5.4.5"
+
+ assert utils.identity_attribute("name", a, forward) == "urn:oid:2.5.4.5"
# if there would be a map it would be serialNumber
- assert utils.identity_attribute("friendly",a,forward) == "urn:oid:2.5.4.5"
+ assert utils.identity_attribute("friendly", a, forward) == "urn:oid:2.5.4.5"
+
def test_identity_attribute_3():
a = Attribute(name="urn:oid:2.5.4.5", name_format=NAME_FORMAT_URI)
-
- assert utils.identity_attribute("name",a) == "urn:oid:2.5.4.5"
+
+ assert utils.identity_attribute("name", a) == "urn:oid:2.5.4.5"
# if there would be a map it would be serialNumber
- assert utils.identity_attribute("friendly",a) == "urn:oid:2.5.4.5"
+ assert utils.identity_attribute("friendly", a) == "urn:oid:2.5.4.5"
+
def test_identity_attribute_4():
a = Attribute(name="urn:oid:2.5.4.5", name_format=NAME_FORMAT_URI,
- friendly_name="serialNumber")
-
- assert utils.identity_attribute("name",a) == "urn:oid:2.5.4.5"
+ friendly_name="serialNumber")
+
+ assert utils.identity_attribute("name", a) == "urn:oid:2.5.4.5"
# if there would be a map it would be serialNumber
- assert utils.identity_attribute("friendly",a) == "serialNumber"
-
-def _givenName(a):
+ assert utils.identity_attribute("friendly", a) == "serialNumber"
+
+
+def given_name(a):
assert a["name"] == "urn:oid:2.5.4.42"
assert a["friendly_name"] == "givenName"
assert len(a["attribute_value"]) == 1
- assert a["attribute_value"] == [{"text":"Derek"}]
+ assert a["attribute_value"] == [{"text": "Derek"}]
-def _surName(a):
+
+def sur_name(a):
assert a["name"] == "urn:oid:2.5.4.4"
assert a["friendly_name"] == "surName"
assert len(a["attribute_value"]) == 1
- assert a["attribute_value"] == [{"text":"Jeter"}]
-
+ assert a["attribute_value"] == [{"text": "Jeter"}]
+
+
def test_nameformat_email():
assert utils.valid_email("foo@example.com")
assert utils.valid_email("a@b.com")
assert utils.valid_email("a@b.se")
- assert utils.valid_email("john@doe@johndoe.com") == False
-
+ assert utils.valid_email("john@doe@johndoe.com") is False
+
+
def test_attribute():
a = utils.factory(saml.Attribute,
- friendly_name="eduPersonScopedAffiliation",
- name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9",
- name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri")
-
- assert _eq(a.keyswv(), ["friendly_name","name", "name_format"])
+ friendly_name="eduPersonScopedAffiliation",
+ name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9",
+ name_format="urn:oasis:names:tc:SAML:2.0:attrname"
+ "-format:uri")
- a = utils.factory(saml.Attribute,
- friendly_name="eduPersonScopedAffiliation",
+ assert _eq(a.keyswv(), ["friendly_name", "name", "name_format"])
+
+ a = utils.factory(
+ saml.Attribute, friendly_name="eduPersonScopedAffiliation",
name="urn:oid:1.3.6.1.4.1.5923.1.1.1.9",
name_format="urn:oasis:names:tc:SAML:2.0:attrname-format:uri",
attribute_value=[saml.AttributeValue(text="member@example.com")])
-
- assert _eq(a.keyswv(), ["friendly_name","name", "name_format",
+
+ assert _eq(a.keyswv(), ["friendly_name", "name", "name_format",
"attribute_value"])
-
-def test_attribute_statement():
- statement = utils.factory( saml.Statement,
- attribute=[
- utils.factory(saml.Attribute,
- attribute_value=[
- utils.factory(
- saml.AttributeValue,text="Derek")],
- friendly_name="givenName"),
- utils.factory(saml.Attribute,
- attribute_value=[
- utils.factory(
- saml.AttributeValue,text="Jeter")],
- friendly_name="surName"),
- ])
+
+
+def test_attribute_statement_2():
+ statement = utils.factory(saml.Statement,
+ attribute=[
+ utils.factory(saml.Attribute,
+ attribute_value=[
+ utils.factory(
+ saml.AttributeValue,
+ text="Derek")],
+ friendly_name="givenName"),
+ utils.factory(saml.Attribute,
+ attribute_value=[
+ utils.factory(
+ saml.AttributeValue,
+ text="Jeter")],
+ friendly_name="surName"),
+ ])
assert statement.keyswv() == ["attribute"]
assert len(statement.attribute) == 2
-
+
+
def test_subject_confirmation_data():
- s = utils.factory( saml.SubjectConfirmation,
- in_response_to="_12345678",
- not_before="2010-02-11T07:30:00Z",
- not_on_or_after="2010-02-11T07:35:00Z",
- recipient="http://example.com/sp/",
- address="192.168.0.10")
-
- assert _eq(s.keyswv(),["in_response_to","not_before","not_on_or_after",
- "recipient", "address"])
-
+ s = utils.factory(saml.SubjectConfirmation,
+ in_response_to="_12345678",
+ not_before="2010-02-11T07:30:00Z",
+ not_on_or_after="2010-02-11T07:35:00Z",
+ recipient="http://example.com/sp/",
+ address="192.168.0.10")
+
+ assert _eq(s.keyswv(), ["in_response_to", "not_before", "not_on_or_after",
+ "recipient", "address"])
+
+
def test_subject_confirmation():
- s = utils.factory( saml.SubjectConfirmation,
- method="urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser",
- base_id="1234",
- name_id="abcd",
- subject_confirmation_data=utils.factory(
- saml.SubjectConfirmationData,
- in_response_to="_1234567890",
- recipient="http://example.com/sp/"))
+ s = utils.factory(saml.SubjectConfirmation,
+ method="urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser",
+ base_id="1234",
+ name_id="abcd",
+ subject_confirmation_data=utils.factory(
+ saml.SubjectConfirmationData,
+ in_response_to="_1234567890",
+ recipient="http://example.com/sp/"))
assert _eq(s.keyswv(),
- ["method","base_id","name_id","subject_confirmation_data"])
+ ["method", "base_id", "name_id", "subject_confirmation_data"])
assert s.method == "urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser"
-
+
def test_authn_context_class_ref():
- a = utils.factory( saml.AuthnContextClassRef,
- text="urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified")
+ a = utils.factory(saml.AuthnContextClassRef,
+ text="urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified")
assert a.keyswv() == ["text"]
assert a.text == "urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified"
-
+
+
def test_authn_context():
- accr = utils.factory( saml.AuthnContext,
- text="urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified")
+ accr = utils.factory(
+ saml.AuthnContext,
+ text="urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified")
a = utils.factory(saml.AuthnContext, authn_context_class_ref=accr)
assert a.keyswv() == ["authn_context_class_ref"]
-
+
+
def test_authn_statement():
- accr = utils.factory( saml.AuthnContextClassRef,
- text="urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified")
- ac = utils.factory( saml.AuthnContext,
- authn_context_class_ref=accr)
- ast = utils.factory( saml.AuthnStatement,
+ accr = utils.factory(
+ saml.AuthnContextClassRef,
+ text="urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified")
+ ac = utils.factory(saml.AuthnContext,
+ authn_context_class_ref=accr)
+ ast = utils.factory(saml.AuthnStatement,
authn_instant="2010-03-10T12:33:00Z",
session_index="_12345",
session_not_on_or_after="2010-03-11T12:00:00Z",
- authn_context=ac
- )
- assert _eq(ast.keyswv(),["authn_instant","session_index",
- "session_not_on_or_after",
- "authn_context"])
-
+ authn_context=ac)
+ assert _eq(ast.keyswv(), ["authn_instant", "session_index",
+ "session_not_on_or_after",
+ "authn_context"])
+
+
def test_signature():
arr = ["foobar", "1234567890"]
csum = utils.signature("abcdef", arr)
arr.append(csum)
-
- assert utils.verify_signature("abcdef", arr)
-
+ assert utils.verify_signature("abcdef", arr)
diff --git a/tests/test_51_client.py b/tests/test_51_client.py
index 11b5cd09..6b93e455 100644
--- a/tests/test_51_client.py
+++ b/tests/test_51_client.py
@@ -593,6 +593,6 @@ class TestClientWithDummy():
# tc.test_response()
if __name__ == "__main__":
- tc = TestClient()
+ tc = TestClientWithDummy()
tc.setup_class()
- tc.test_sign_then_encrypt_assertion2()
+ tc.test_do_attribute_query()
diff --git a/tests/test_67_manage_name_id.py b/tests/test_67_manage_name_id.py
index 7c1dc748..f0e41fb5 100644
--- a/tests/test_67_manage_name_id.py
+++ b/tests/test_67_manage_name_id.py
@@ -55,7 +55,7 @@ def test_flow():
print _req.message
- mnir = idp.create_manage_name_id_response(_req.message, None)
+ mnir = idp.create_manage_name_id_response(_req.message, [binding])
if binding != BINDING_SOAP:
binding, destination = idp.pick_binding("manage_name_id_service",