Initial import

This commit is contained in:
Roland Hedberg
2009-08-19 09:00:10 +02:00
commit bc8715b0fa
24 changed files with 12783 additions and 0 deletions

3
TODO Normal file
View File

@@ -0,0 +1,3 @@
1. Write documentations.
2. Write unittests for signature ralated utility methods.
3. Complete saml2 message class.

36
setup.py Executable file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/python
#
# Copyright (C) 2007 SIOS Technology, Inc.
# Copyright (C) 2009 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.
#
#
from distutils.core import setup
setup(
name='python-saml2',
version='0.0.6',
description='Python client library for SAML Version 2',
long_description = """\
python-saml2 is a library for SAML Version 2.
""",
author='Roland Hedberg',
author_email='roland.hedberg@adm.umu.se',
license='Apache 2.0',
url='http://code.google.com/p/python-saml2/',
packages=['saml2', 'xmldsig'],
package_dir = {'saml2':'src/saml2', 'xmldsig':'src/xmldsig'}
)

437
src/saml2/__init__.py Normal file
View File

@@ -0,0 +1,437 @@
#!/usr/bin/python
#
# Copyright (C) 2006 Google Inc.
# 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.
"""Contains base classes representing Saml elements.
These codes were originally written by Jeffrey Scudder for
representing Atom elements. Takashi Matsuo had added some codes, and
changed some. Roland Hedberg changed and added some more.
Module objective: provide data classes for Saml constructs. These
classes hide the XML-ness of Saml and provide a set of native Python
classes to interact with.
Conversions to and from XML should only be necessary when the Saml classes
"touch the wire" and are sent over HTTP. For this reason this module
provides methods and functions to convert Saml classes to and from strings.
SamlBase: A foundation class on which Saml classes are built. It
handles the parsing of attributes and children which are common to all
Saml classes. By default, the SamlBase class translates all XML child
nodes into ExtensionElements.
ExtensionElement: XML which is not part of the Saml specification,
these are called extension elements. If a classes parser
encounters an unexpected XML construct, it is translated into an
ExtensionElement instance. ExtensionElement is designed to fully
capture the information in the XML. Child nodes in an XML
extension are turned into ExtensionElements as well.
"""
try:
from xml.etree import cElementTree as ElementTree
except ImportError:
try:
import cElementTree as ElementTree
except ImportError:
from elementtree import ElementTree
SAML_NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:assertion'
SAML_TEMPLATE = '{urn:oasis:names:tc:SAML:2.0:assertion}%s'
XSI_NAMESPACE = 'http://www.w3.org/2001/XMLSchema-instance'
NAMEID_FORMAT_EMAILADDRESS = (
"urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress")
URN_PASSWORD = "urn:oasis:names:tc:SAML:2.0:ac:classes:Password"
NAME_FORMAT_UNSPECIFIED = (
"urn:oasis:names:tc:SAML:2.0:attrnam-format:unspecified")
NAME_FORMAT_URI = "urn:oasis:names:tc:SAML:2.0:attrnam-format:uri"
NAME_FORMAT_BASIC = "urn:oasis:names:tc:SAML:2.0:attrnam-format:basic"
SUBJECT_CONFIRMATION_METHOD_BEARER = "urn:oasis:names:tc:SAML:2.0:cm:bearer"
DECISION_TYPE_PERMIT = "Permit"
DECISION_TYPE_DENY = "Deny"
DECISION_TYPE_INDETERMINATE = "Indeterminate"
V2 = "2.0"
BINDING_SOAP = 'urn:oasis:names:tc:SAML:2.0:bindings:SOAP'
BINDING_PAOS = 'urn:oasis:names:tc:SAML:2.0:bindings:PAOS'
BINDING_HTTP_REDIRECT = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
BINDING_HTTP_POST = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
BINDING_HTTP_ARTIFACT = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact'
BINDING_URI = 'urn:oasis:names:tc:SAML:2.0:bindings:URI'
def create_class_from_xml_string(target_class, xml_string):
"""Creates an instance of the target class from the string contents.
:param target_class: The class which will be instantiated and populated
with the contents of the XML. This class must have a c_tag and a
c_namespace class variable.
:param xml_string: A string which contains valid XML. The root element
of the XML string should match the tag and namespace of the desired
class.
:return: An instance of the target class with members assigned according to
the contents of the XML - or None if the root XML tag and namespace did
not match those of the target class.
"""
tree = ElementTree.fromstring(xml_string)
return _create_class_from_element_tree(target_class, tree)
def _create_class_from_element_tree(target_class, tree, namespace=None,
tag=None):
"""Instantiates the class and populates members according to the tree.
Note: Only use this function with classes that have c_namespace and c_tag
class members.
:param target_class: The class which will be instantiated and populated
with the contents of the XML.
:param tree: An element tree whose contents will be converted into
members of the new target_class instance.
:param namespace: The namespace which the XML tree's root node must
match. If omitted, the namespace defaults to the c_namespace of the
target class.
:param tag: The tag which the XML tree's root node must match. If
omitted, the tag defaults to the c_tag class member of the target
class.
:return: An instance of the target class - or None if the tag and namespace
of the XML tree's root node did not match the desired namespace and tag.
"""
if namespace is None:
namespace = target_class.c_namespace
if tag is None:
tag = target_class.c_tag
if tree.tag == '{%s}%s' % (namespace, tag):
target = target_class()
target.harvest_element_tree(tree)
return target
else:
return None
class Error(Exception):
"""Exception class thrown by this module."""
pass
class ExtensionElement(object):
"""Represents extra XML elements contained in Saml classes."""
def __init__(self, tag, namespace=None, attributes=None,
children=None, text=None):
"""Constructor for ExtensionElement
:param namespace: The XML namespace for this element.
:param tag: The tag (without the namespace qualifier) for
this element. To reconstruct the full qualified name of the
element, combine this tag with the namespace.
:param attributes: The attribute value string pairs for the XML
attributes of this element.
:param children: list (optional) A list of ExtensionElements which
represent the XML child nodes of this element.
"""
self.namespace = namespace
self.tag = tag
self.attributes = attributes or {}
self.children = children or []
self.text = text
def to_string(self):
""" Serialize the object into a XML string """
element_tree = self._transfer_to_element_tree(ElementTree.Element(''))
return ElementTree.tostring(element_tree, encoding="UTF-8")
def _transfer_to_element_tree(self, element_tree):
if self.tag is None:
return None
if self.namespace is not None:
element_tree.tag = '{%s}%s' % (self.namespace, self.tag)
else:
element_tree.tag = self.tag
for key, value in self.attributes.iteritems():
element_tree.attrib[key] = value
for child in self.children:
child.become_child_element(element_tree)
element_tree.text = self.text
return element_tree
def become_child_element(self, element_tree):
"""Converts this object into an etree element and adds it as a child
node.
Adds self to the ElementTree. This method is required to avoid verbose
XML which constantly redefines the namespace.
:param element_tree: ElementTree._Element The element to which this
object's XML will be added.
"""
new_element = ElementTree.Element('')
element_tree.append(new_element)
self._transfer_to_element_tree(new_element)
def findc_children(self, tag=None, namespace=None):
"""Searches child nodes for objects with the desired tag/namespace.
Returns a list of extension elements within this object whose tag
and/or namespace match those passed in. To find all children in
a particular namespace, specify the namespace but not the tag name.
If you specify only the tag, the result list may contain extension
elements in multiple namespaces.
Args:
tag: str (optional) The desired tag
namespace: str (optional) The desired namespace
Returns:
A list of elements whose tag and/or namespace match the parameters
values
"""
results = []
if tag and namespace:
for element in self.children:
if element.tag == tag and element.namespace == namespace:
results.append(element)
elif tag and not namespace:
for element in self.children:
if element.tag == tag:
results.append(element)
elif namespace and not tag:
for element in self.children:
if element.namespace == namespace:
results.append(element)
else:
for element in self.children:
results.append(element)
return results
def extension_element_from_string(xml_string):
element_tree = ElementTree.fromstring(xml_string)
return _extension_element_from_element_tree(element_tree)
def _extension_element_from_element_tree(element_tree):
elementc_tag = element_tree.tag
if '}' in elementc_tag:
namespace = elementc_tag[1:elementc_tag.index('}')]
tag = elementc_tag[elementc_tag.index('}')+1:]
else:
namespace = None
tag = elementc_tag
extension = ExtensionElement(namespace=namespace, tag=tag)
for key, value in element_tree.attrib.iteritems():
extension.attributes[key] = value
for child in element_tree:
extension.children.append(_extension_element_from_element_tree(child))
extension.text = element_tree.text
return extension
class ExtensionContainer(object):
c_tag = ""
c_namespace = ""
def __init__(self, text=None, extension_elements=None,
extension_attributes=None):
self.text = text
self.extension_elements = extension_elements or []
self.extension_attributes = extension_attributes or {}
# Three methods to create an object from an ElementTree
def harvest_element_tree(self, tree):
# Fill in the instance members from the contents of the XML tree.
for child in tree:
self._convert_element_tree_to_member(child)
for attribute, value in tree.attrib.iteritems():
self._convert_element_attribute_to_member(attribute, value)
self.text = tree.text
def _convert_element_tree_to_member(self, child_tree):
self.extension_elements.append(_extension_element_from_element_tree(
child_tree))
def _convert_element_attribute_to_member(self, attribute, value):
self.extension_attributes[attribute] = value
# One method to create an ElementTree from an object
def _add_members_to_element_tree(self, tree):
for child in self.extension_elements:
child.become_child_element(tree)
for attribute, value in self.extension_attributes.iteritems():
tree.attrib[attribute] = value
tree.text = self.text
def find_extensions(self, tag=None, namespace=None):
"""Searches extension elements for child nodes with the desired name.
Returns a list of extension elements within this object whose tag
and/or namespace match those passed in. To find all extensions in
a particular namespace, specify the namespace but not the tag name.
If you specify only the tag, the result list may contain extension
elements in multiple namespaces.
Args:
tag: str (optional) The desired tag
namespace: str (optional) The desired namespace
Returns:
A list of elements whose tag and/or namespace match the parameters
values
"""
results = []
if tag and namespace:
for element in self.extension_elements:
if element.tag == tag and element.namespace == namespace:
results.append(element)
elif tag and not namespace:
for element in self.extension_elements:
if element.tag == tag:
results.append(element)
elif namespace and not tag:
for element in self.extension_elements:
if element.namespace == namespace:
results.append(element)
else:
for element in self.extension_elements:
results.append(element)
return results
class SamlBase(ExtensionContainer):
c_children = {}
c_attributes = {}
c_child_order = []
def _get_allc_children_with_order(self):
if len(self.c_child_order) > 0:
for child in self.c_child_order:
yield child
else:
for _, values in self.__class__.c_children.iteritems():
yield values[0]
def _convert_element_tree_to_member(self, child_tree):
# Find the element's tag in this class's list of child members
if self.__class__.c_children.has_key(child_tree.tag):
member_name = self.__class__.c_children[child_tree.tag][0]
member_class = self.__class__.c_children[child_tree.tag][1]
# If the class member is supposed to contain a list, make sure the
# matching member is set to a list, then append the new member
# instance to the list.
if isinstance(member_class, list):
if getattr(self, member_name) is None:
setattr(self, member_name, [])
getattr(self, member_name).append(
_create_class_from_element_tree(
member_class[0], child_tree))
else:
setattr(self, member_name,
_create_class_from_element_tree(member_class,
child_tree))
else:
ExtensionContainer._convert_element_tree_to_member(self,
child_tree)
def _convert_element_attribute_to_member(self, attribute, value):
# Find the attribute in this class's list of attributes.
if self.__class__.c_attributes.has_key(attribute):
# Find the member of this class which corresponds to the XML
# attribute(lookup in current_class.c_attributes) and set this
# member to the desired value (using self.__dict__).
setattr(self, self.__class__.c_attributes[attribute], value)
else:
ExtensionContainer._convert_element_attribute_to_member(self,
attribute, value)
# Three methods to create an ElementTree from an object
def _add_members_to_element_tree(self, tree):
# Convert the members of this class which are XML child nodes.
# This uses the class's c_children dictionary to find the members which
# should become XML child nodes.
for member_name in self._get_allc_children_with_order():
member = getattr(self, member_name)
if member is None:
pass
elif isinstance(member, list):
for instance in member:
instance.become_child_element(tree)
else:
member.become_child_element(tree)
# Convert the members of this class which are XML attributes.
for xml_attribute, member_name in \
self.__class__.c_attributes.iteritems():
member = getattr(self, member_name)
if member is not None:
tree.attrib[xml_attribute] = member
# Lastly, call the ExtensionContainers's _add_members_to_element_tree
# to convert any extension attributes.
ExtensionContainer._add_members_to_element_tree(self, tree)
def become_child_element(self, tree):
"""
Note: Only for use with classes that have a c_tag and c_namespace class
member. It is in AtomBase so that it can be inherited but it should
not be called on instances of AtomBase.
"""
new_child = ElementTree.Element('')
tree.append(new_child)
new_child.tag = '{%s}%s' % (self.__class__.c_namespace,
self.__class__.c_tag)
self._add_members_to_element_tree(new_child)
def _to_element_tree(self):
"""
Note, this method is designed to be used only with classes that have a
c_tag and c_namespace. It is placed in AtomBase for inheritance but should
not be called on this class.
"""
new_tree = ElementTree.Element('{%s}%s' % (self.__class__.c_namespace,
self.__class__.c_tag))
self._add_members_to_element_tree(new_tree)
return new_tree
def to_string(self):
"""Converts the Atom object to a string containing XML."""
return ElementTree.tostring(self._to_element_tree(), encoding="UTF-8")
def __str__(self):
return self.to_string()

20
src/saml2/conftest.py Normal file
View File

@@ -0,0 +1,20 @@
import py
import os
import time
from subprocess import Popen
CONTACT = """<?xml version="1.0" encoding="utf-8"?>
<ContactPerson xmlns="urn:oasis:names:tc:SAML:2.0:metadata" contactType="technical">
<GivenName>Roland</GivenName>
<SurName>Hedberg</SurName>
<EmailAddress>roland.hedberg@adm.umu.se</EmailAddress>
</ContactPerson>"""
def pytest_funcarg__idp_metadata(request):
f = open('/Users/rolandh/code/om2/pysaml2/src/saml2/xeno_metadata.xml')
data = f.read()
f.close
return data
def pytest_funcarg__contact(request):
return CONTACT

357
src/saml2/ds_test_data.py Normal file
View File

@@ -0,0 +1,357 @@
#!/usr/bin/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"""
__author__ = 'tmatsuo@sios.com (Takashi MATSUO)'
TEST_OBJECT = """<?xml version="1.0" encoding="utf-8"?>
<Object Id="object_id" Encoding="http://www.w3.org/2000/09/xmldsig#base64"
xmlns="http://www.w3.org/2000/09/xmldsig#">
V2VkIEp1biAgNCAxMjoxMTowMyBFRFQgMjAwMwo
</Object>
"""
TEST_MGMT_DATA = """<?xml version="1.0" encoding="utf-8"?>
<MgmtData xmlns="http://www.w3.org/2000/09/xmldsig#">
mgmt data
</MgmtData>
"""
TEST_SPKI_SEXP = """<?xml version="1.0" encoding="utf-8"?>
<SPKISexp xmlns="http://www.w3.org/2000/09/xmldsig#">
spki sexp
</SPKISexp>
"""
TEST_SPKI_DATA = """<?xml version="1.0" encoding="utf-8"?>
<SPKIData xmlns="http://www.w3.org/2000/09/xmldsig#">
<SPKISexp>spki sexp</SPKISexp>
<SPKISexp>spki sexp2</SPKISexp>
</SPKIData>
"""
TEST_PGP_DATA = """<?xml version="1.0" encoding="utf-8"?>
<PGPData xmlns="http://www.w3.org/2000/09/xmldsig#">
<PGPKeyID>pgp key id</PGPKeyID>
<PGPKeyPacket>pgp key packet</PGPKeyPacket>
</PGPData>
"""
TEST_X509_ISSUER_SERIAL = """<?xml version="1.0" encoding="utf-8"?>
<X509IssuerSerial xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509IssuerName>issuer name</X509IssuerName>
<X509IssuerNumber>1</X509IssuerNumber>
</X509IssuerSerial>
"""
TEST_X509_DATA = """<?xml version="1.0" encoding="utf-8"?>
<X509Data xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509IssuerSerial>
<X509IssuerName>issuer name</X509IssuerName>
<X509IssuerNumber>1</X509IssuerNumber>
</X509IssuerSerial>
<X509SKI>x509 ski</X509SKI>
<X509SubjectName>x509 subject name</X509SubjectName>
<X509Certificate>x509 certificate</X509Certificate>
<X509CRL>x509 crl</X509CRL>
</X509Data>
"""
TEST_TRANSFORM = """<?xml version="1.0" encoding="utf-8"?>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"
xmlns="http://www.w3.org/2000/09/xmldsig#">
<XPath>xpath</XPath>
</Transform>
"""
TEST_TRANSFORMS = """<?xml version="1.0" encoding="utf-8"?>
<Transforms xmlns="http://www.w3.org/2000/09/xmldsig#">
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
"""
TEST_RETRIEVAL_METHOD = """<?xml version="1.0" encoding="utf-8"?>
<RetrievalMethod xmlns="http://www.w3.org/2000/09/xmldsig#"
URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
</RetrievalMethod>
"""
TEST_RSA_KEY_VALUE = """<?xml version="1.0" encoding="utf-8"?>
<RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
<Modulus>modulus</Modulus>
<Exponent>exponent</Exponent>
</RSAKeyValue>
"""
TEST_DSA_KEY_VALUE = """<?xml version="1.0" encoding="utf-8"?>
<DSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
<P>p</P>
<Q>q</Q>
<G>g</G>
<Y>y</Y>
<J>j</J>
<Seed>seed</Seed>
<PgenCounter>pgen counter</PgenCounter>
</DSAKeyValue>
"""
TEST_KEY_VALUE1 = """<?xml version="1.0" encoding="utf-8"?>
<KeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
<DSAKeyValue>
<P>p</P>
<Q>q</Q>
<G>g</G>
<Y>y</Y>
<J>j</J>
<Seed>seed</Seed>
<PgenCounter>pgen counter</PgenCounter>
</DSAKeyValue>
</KeyValue>
"""
TEST_KEY_VALUE2 = """<?xml version="1.0" encoding="utf-8"?>
<KeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
<RSAKeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
<Modulus>modulus</Modulus>
<Exponent>exponent</Exponent>
</RSAKeyValue>
</KeyValue>
"""
TEST_KEY_NAME = """<?xml version="1.0" encoding="utf-8"?>
<KeyName xmlns="http://www.w3.org/2000/09/xmldsig#">
key name
</KeyName>
"""
TEST_KEY_INFO = """<?xml version="1.0" encoding="utf-8"?>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#" Id="id">
<KeyName>
key name
</KeyName>
<KeyValue>
<DSAKeyValue>
<P>p</P>
<Q>q</Q>
<G>g</G>
<Y>y</Y>
<J>j</J>
<Seed>seed</Seed>
<PgenCounter>pgen counter</PgenCounter>
</DSAKeyValue>
</KeyValue>
<RetrievalMethod URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
</RetrievalMethod>
<X509Data>
<X509IssuerSerial>
<X509IssuerName>issuer name</X509IssuerName>
<X509IssuerNumber>1</X509IssuerNumber>
</X509IssuerSerial>
<X509SKI>x509 ski</X509SKI>
<X509SubjectName>x509 subject name</X509SubjectName>
<X509Certificate>x509 certificate</X509Certificate>
<X509CRL>x509 crl</X509CRL>
</X509Data>
<PGPData>
<PGPKeyID>pgp key id</PGPKeyID>
<PGPKeyPacket>pgp key packet</PGPKeyPacket>
</PGPData>
<MgmtData>
mgmt data
</MgmtData>
<SPKIData>
<SPKISexp>spki sexp</SPKISexp>
<SPKISexp>spki sexp2</SPKISexp>
</SPKIData>
</KeyInfo>
"""
TEST_DIGEST_VALUE = """<?xml version="1.0" encoding="utf-8"?>
<DigestValue xmlns="http://www.w3.org/2000/09/xmldsig#">
digest value
</DigestValue>
"""
TEST_DIGEST_METHOD = """<?xml version="1.0" encoding="utf-8"?>
<DigestMethod xmlns="http://www.w3.org/2000/09/xmldsig#"
Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
"""
TEST_REFERENCE = """<?xml version="1.0" encoding="utf-8"?>
<Reference xmlns="http://www.w3.org/2000/09/xmldsig#" Id="id"
URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>digest value</DigestValue>
</Reference>
"""
TEST_SIGNATURE_METHOD = """<?xml version="1.0" encoding="utf-8"?>
<SignatureMethod xmlns="http://www.w3.org/2000/09/xmldsig#"
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
<HMACOutputLength>8</HMACOutputLength>
</SignatureMethod>
"""
TEST_CANONICALIZATION_METHOD = """<?xml version="1.0" encoding="utf-8"?>
<CanonicalizationMethod xmlns="http://www.w3.org/2000/09/xmldsig#"
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments">
</CanonicalizationMethod>
"""
TEST_SIGNED_INFO = """<?xml version="1.0" encoding="utf-8"?>
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#" Id="id">
<CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments">
</CanonicalizationMethod>
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
<HMACOutputLength>8</HMACOutputLength>
</SignatureMethod>
<Reference Id="id" URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>digest value</DigestValue>
</Reference>
</SignedInfo>
"""
TEST_SIGNATURE_VALUE = """<?xml version="1.0" encoding="utf-8"?>
<SignatureValue xmlns="http://www.w3.org/2000/09/xmldsig#" Id="id">
signature value
</SignatureValue>
"""
TEST_SIGNATURE = """<?xml version="1.0" encoding="utf-8"?>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="id">
<SignedInfo Id="id">
<CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments">
</CanonicalizationMethod>
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
<HMACOutputLength>8</HMACOutputLength>
</SignatureMethod>
<Reference Id="id" URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>digest value</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue Id="id">
signature value
</SignatureValue>
<KeyInfo Id="id">
<KeyName>
key name
</KeyName>
<KeyValue>
<DSAKeyValue>
<P>p</P>
<Q>q</Q>
<G>g</G>
<Y>y</Y>
<J>j</J>
<Seed>seed</Seed>
<PgenCounter>pgen counter</PgenCounter>
</DSAKeyValue>
</KeyValue>
<RetrievalMethod URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
</RetrievalMethod>
<X509Data>
<X509IssuerSerial>
<X509IssuerName>issuer name</X509IssuerName>
<X509IssuerNumber>1</X509IssuerNumber>
</X509IssuerSerial>
<X509SKI>x509 ski</X509SKI>
<X509SubjectName>x509 subject name</X509SubjectName>
<X509Certificate>x509 certificate</X509Certificate>
<X509CRL>x509 crl</X509CRL>
</X509Data>
<PGPData>
<PGPKeyID>pgp key id</PGPKeyID>
<PGPKeyPacket>pgp key packet</PGPKeyPacket>
</PGPData>
<MgmtData>
mgmt data
</MgmtData>
<SPKIData>
<SPKISexp>spki sexp</SPKISexp>
<SPKISexp>spki sexp2</SPKISexp>
</SPKIData>
</KeyInfo>
<Object Id="object_id" Encoding="http://www.w3.org/2000/09/xmldsig#base64">
V2VkIEp1biAgNCAxMjoxMTowMyBFRFQgMjAwMwo
</Object>
</Signature>
"""

1166
src/saml2/md.py Normal file

File diff suppressed because it is too large Load Diff

1358
src/saml2/md_test_data.py Normal file

File diff suppressed because it is too large Load Diff

951
src/saml2/saml.py Normal file
View File

@@ -0,0 +1,951 @@
#!/usr/bin/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.
"""Contains classes representing Saml elements.
Module objective: provide data classes for Saml constructs. These
classes hide the XML-ness of Saml and provide a set of native Python
classes to interact with.
Conversions to and from XML should only be necessary when the Saml classes
"touch the wire" and are sent over HTTP. For this reason this module
provides methods and functions to convert Saml classes to and from strings.
SamlBase: A foundation class on which Saml classes are built. It
handles the parsing of attributes and children which are common to all
Saml classes. By default, the SamlBase class translates all XML child
nodes into ExtensionElements.
ExtensionElement: XML which is not part of the Saml specification,
these are called extension elements. If a classes parser
encounters an unexpected XML construct, it is translated into an
ExtensionElement instance. ExtensionElement is designed to fully
capture the information in the XML. Child nodes in an XML
extension are turned into ExtensionElements as well.
"""
import xmldsig as ds
import saml2
from saml2 import SamlBase
SAML_NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:assertion'
SAML_TEMPLATE = '{urn:oasis:names:tc:SAML:2.0:assertion}%s'
XSI_NAMESPACE = 'http://www.w3.org/2001/XMLSchema-instance'
NAMEID_FORMAT_EMAILADDRESS = (
"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")
NAMEID_FORMAT_UNSPECIFIED = (
"urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified")
NAMEID_FORMAT_ENCRYPTED = (
"urn:oasis:names:tc:SAML:2.0:nameid-format:encrypted")
NAMEID_FORMAT_PERSISTENT = (
"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent")
PROFILE_ATTRIBUTE_BASIC = (
"urn:oasis:names:tc:SAML:2.0:profiles:attribute:basic")
URN_PASSWORD = "urn:oasis:names:tc:SAML:2.0:ac:classes:Password"
NAME_FORMAT_UNSPECIFIED = (
"urn:oasis:names:tc:SAML:2.0:attrnam-format:unspecified")
NAME_FORMAT_URI = "urn:oasis:names:tc:SAML:2.0:attrnam-format:uri"
NAME_FORMAT_BASIC = "urn:oasis:names:tc:SAML:2.0:attrnam-format:basic"
SUBJECT_CONFIRMATION_METHOD_BEARER = "urn:oasis:names:tc:SAML:2.0:cm:bearer"
DECISION_TYPE_PERMIT = "Permit"
DECISION_TYPE_DENY = "Deny"
DECISION_TYPE_INDETERMINATE = "Indeterminate"
CONSENT_UNSPECIFIED = "urn:oasis:names:tc:SAML:2.0:consent:unspecified"
V2 = "2.0"
class BaseID(SamlBase):
"""The saml:BaseID element"""
c_tag = 'BaseID'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['NameQualifier'] = 'name_qualifier'
c_attributes['SPNameQualifier'] = 'sp_name_qualifier'
def __init__(self, name_qualifier=None, sp_name_qualifier=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for BaseID
:param name_qualifier: NameQualifier attribute
:param sp_name_qualifier: SPNameQualifier attribute
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.name_qualifier = name_qualifier
self.sp_name_qualifier = sp_name_qualifier
def base_id_from_string(xml_string):
""" Create BaseID instance from an XML string """
return saml2.create_class_from_xml_string(BaseID, xml_string)
class NameID(BaseID):
"""The saml:NameID element"""
c_tag = 'NameID'
c_namespace = SAML_NAMESPACE
c_children = BaseID.c_children.copy()
c_attributes = BaseID.c_attributes.copy()
c_attributes['Format'] = 'name_format'
c_attributes['SPProvidedID'] = 'sp_provided_id'
def __init__(self, name_qualifier=None, sp_name_qualifier=None,
name_format=None, sp_provided_id=None,
text=None, extension_elements=None,
extension_attributes=None):
"""Constructor for NameID
:param format: Format attribute
:param sp_provided_id: SPProvidedID attribute
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
BaseID.__init__(self, name_qualifier, sp_name_qualifier, text,
extension_elements, extension_attributes)
self.name_format = name_format
self.sp_provided_id = sp_provided_id
def name_id_from_string(xml_string):
""" Create NameID instance from an XML string """
return saml2.create_class_from_xml_string(NameID, xml_string)
class Issuer(NameID):
"""The saml:Issuer element"""
c_tag = 'Issuer'
c_children = NameID.c_children.copy()
c_attributes = NameID.c_attributes.copy()
def issuer_from_string(xml_string):
""" Create Issuer instance from an XML string """
return saml2.create_class_from_xml_string(Issuer, xml_string)
class SubjectLocality(SamlBase):
"""The saml:SubjectLocality element"""
c_tag = 'SubjectLocality'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['Address'] = 'address'
c_attributes['DNSName'] = 'dns_name'
def __init__(self, address=None, dns_name=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for SubjectLocality
:param address: Address attribute
:param dns_name: DNSName attribute
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.address = address
self.dns_name = dns_name
def subject_locality_from_string(xml_string):
""" Create SubjectLocality instance from an XML string """
return saml2.create_class_from_xml_string(SubjectLocality, xml_string)
class AuthnContextClassRef(SamlBase):
"""The saml:AuthnContextClassRef element"""
c_tag = 'AuthnContextClassRef'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def authn_context_class_ref_from_string(xml_string):
""" Create AuthnContextClassRef instance from an XML string """
return saml2.create_class_from_xml_string(AuthnContextClassRef, xml_string)
class AuthnContextDeclRef(SamlBase):
"""The saml:AuthnContextDeclRef element"""
c_tag = 'AuthnContextDeclRef'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def authn_context_decl_ref_from_string(xml_string):
""" Create AuthnContextDeclRef instance from an XML string """
return saml2.create_class_from_xml_string(AuthnContextDeclRef, xml_string)
class AuthnContextDecl(SamlBase):
"""The saml:AuthnContextDecl element"""
c_tag = 'AuthnContextDecl'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def authn_context_decl_from_string(xml_string):
""" Create AuthnContextDecl instance from an XML string """
return saml2.create_class_from_xml_string(AuthnContextDecl, xml_string)
class AuthenticatingAuthority(SamlBase):
"""The saml:AuthenticatingAuthority element"""
c_tag = 'AuthenticatingAuthority'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def authenticating_authority_from_string(xml_string):
""" Create AuthenticatingAuthority instance from an XML string """
return saml2.create_class_from_xml_string(AuthenticatingAuthority,
xml_string)
class AuthnContext(SamlBase):
"""The saml:AuthnContext element"""
c_tag = 'AuthnContext'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_children['{%s}AuthnContextClassRef' % SAML_NAMESPACE] = (
'authn_context_class_ref', AuthnContextClassRef)
c_children['{%s}AuthnContextDeclRef' % SAML_NAMESPACE] = (
'authn_context_decl_ref', AuthnContextDeclRef)
c_children['{%s}AuthnContextDecl' % SAML_NAMESPACE] = (
'authn_context_decl', AuthnContextDecl)
c_children['{%s}AuthenticatingAuthority' % SAML_NAMESPACE] = (
'authenticating_authority', [AuthenticatingAuthority])
c_child_order = ['authn_context_class_ref', 'authn_context_decl_ref',
'authn_context_decl', 'authenticating_authority']
def __init__(self, authn_context_class_ref=None,
authn_context_decl_ref=None,
authn_context_decl=None, authenticating_authority=None,
text=None, extension_elements=None,
extension_attributes=None):
"""Constructor for AuthnContext
Args:
:param authn_context_class_ref: AuthnContextClassRef element
:param authn_context_decl_ref: AuthnContextDeclRef element
:param authn_context_decl: AuthnContextDecl element
:param authenticating_authority: AuthenticatingAuthority element
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.authn_context_class_ref = authn_context_class_ref
self.authn_context_decl_ref = authn_context_decl_ref
self.authn_context_decl = authn_context_decl
self.authenticating_authority = authenticating_authority or []
def authn_context_from_string(xml_string):
""" Create AuthnContext instance from an XML string """
return saml2.create_class_from_xml_string(AuthnContext, xml_string)
class Statement(SamlBase):
"""The saml:Statement element"""
c_tag = 'Statement'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def statement_from_string(xml_string):
""" Create Statement instance from an XML string """
return saml2.create_class_from_xml_string(Statement, xml_string)
class AuthnStatement(Statement):
"""The saml:AuthnStatement element"""
c_tag = 'AuthnStatement'
c_namespace = SAML_NAMESPACE
c_children = Statement.c_children.copy()
c_attributes = Statement.c_attributes.copy()
c_attributes['AuthnInstant'] = 'authn_instant'
c_attributes['SessionIndex'] = 'session_index'
c_attributes['SessionNotOnOrAfter'] = 'session_not_on_or_after'
c_children['{%s}SubjectLocality' % SAML_NAMESPACE] = (
'subject_locality', SubjectLocality)
c_children['{%s}AuthnContext' % SAML_NAMESPACE] = (
'authn_context', AuthnContext)
c_child_order = ['subject_locality', 'authn_context']
def __init__(self, authn_instant=None, session_index=None,
session_not_on_or_after=None, subject_locality=None,
authn_context=None, text=None, extension_elements=None,
extension_attributes=None):
"""Constructor for AuthnStatement
:param authn_instant: AuthnInstant attribute
:param session_index: SessionIndex attribute
:param session_not_on_or_after: SessionNotOnOrAfter attribute
:param subject_locality: SubjectLocality element
:param authn_context: AuthnContext element
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
Statement.__init__(self, extension_elements, extension_attributes,
text)
self.authn_instant = authn_instant
self.session_index = session_index
self.session_not_on_or_after = session_not_on_or_after
self.subject_locality = subject_locality
self.authn_context = authn_context
def authn_statement_from_string(xml_string):
""" Create AuthnStatement instance from an XML string """
return saml2.create_class_from_xml_string(AuthnStatement, xml_string)
# TODO: EncryptedAttribute
class AttributeValue(SamlBase):
"""The saml:AttributeValue element"""
c_tag = 'AttributeValue'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def attribute_value_from_string(xml_string):
""" Create AttributeValue instance from an XML string """
return saml2.create_class_from_xml_string(AttributeValue, xml_string)
class Attribute(SamlBase):
"""The saml:Attribute element"""
c_tag = 'Attribute'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['Name'] = 'name'
c_attributes['NameFormat'] = 'name_format'
c_attributes['FriendlyName'] = 'friendly_name'
c_children['{%s}AttributeValue' % SAML_NAMESPACE] = ('attribute_value',
[AttributeValue])
def __init__(self, name=None, name_format=None, friendly_name=None,
attribute_value=None, text=None, extension_elements=None,
extension_attributes=None):
"""Constructor for Attribute
:param name: Name attribute
:param name_format: NameFormat attribute
:param friendly_name: FriendlyName attribute
:param attribute_value: AttributeValue elements
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.name = name
self.name_format = name_format
self.friendly_name = friendly_name
self.attribute_value = attribute_value or []
def attribute_from_string(xml_string):
""" Create Attribute instance from an XML string """
return saml2.create_class_from_xml_string(Attribute, xml_string)
class AttributeStatement(Statement):
"""The saml:AttributeStatement element"""
# TODO: EncryptedAttribute
c_tag = 'AttributeStatement'
c_namespace = SAML_NAMESPACE
c_children = Statement.c_children.copy()
c_attributes = Statement.c_attributes.copy()
c_children['{%s}Attribute' % SAML_NAMESPACE] = ('attribute', [Attribute])
def __init__(self, attribute=None, text=None, extension_elements=None,
extension_attributes=None):
"""Constructor for AttributeStatement
:param attribute: Attribute elements
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
Statement.__init__(self, extension_elements, extension_attributes,
text)
self.attribute = attribute or []
def attribute_statement_from_string(xml_string):
""" Create AttributeStatement instance from an XML string """
return saml2.create_class_from_xml_string(AttributeStatement, xml_string)
# TODO: AuthzDecisionStatement
class Action(SamlBase):
"""The saml:Action element"""
c_tag = 'Action'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['Namespace'] = 'namespace'
def __init__(self, namespace=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for Action
:param namespace: Namespace attribute
:param text: The text data in this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.namespace = namespace
def action_from_string(xml_string):
""" Create Action instance from an XML string """
return saml2.create_class_from_xml_string(Action, xml_string)
class SubjectConfirmationData(SamlBase):
"""The saml:SubjectConfirmationData element"""
c_tag = 'SubjectConfirmationData'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['NotBefore'] = 'not_before'
c_attributes['NotOnOrAfter'] = 'not_on_or_after'
c_attributes['Recipient'] = 'recipient'
c_attributes['InResponseTo'] = 'in_response_to'
c_attributes['Address'] = 'address'
def __init__(self, not_before=None, not_on_or_after=None, recipient=None,
in_response_to=None, address=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for SubjectConfirmationData
:param not_before: NotBefore attribute
:param not_on_or_after: NotOnOrAfter attribute
:param recipient: Recipient attribute
:param in_response_to: InResponseTo attribute
:param address: Address attribute
:param text: The text data in this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.not_before = not_before
self.not_on_or_after = not_on_or_after
self.recipient = recipient
self.in_response_to = in_response_to
self.address = address
def subject_confirmation_data_from_string(xml_string):
""" Create SubjectConfirmationData instance from an XML string """
return saml2.create_class_from_xml_string(SubjectConfirmationData,
xml_string)
class SubjectConfirmation(SamlBase):
"""The saml:SubjectConfirmation element"""
# TODO: BaseID, EncryptedID element
c_tag = 'SubjectConfirmation'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['Method'] = 'method'
c_children['{%s}NameID' % SAML_NAMESPACE] = ('name_id', NameID)
c_children['{%s}SubjectConfirmationData' % SAML_NAMESPACE] = (
'subject_confirmation_data', SubjectConfirmationData)
c_child_order = ['name_id', 'subject_confirmation_data']
def __init__(self, method=None, name_id=None,
subject_confirmation_data=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for SubjectConfirmation
:param method: Method attribute
:param name_id: NameID element
:param subject_confirmation_data: SubjectConfirmationData element
:param text: The text data in this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string
pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.method = method
self.name_id = name_id
self.subject_confirmation_data = subject_confirmation_data
def subject_confirmation_from_string(xml_string):
""" Create SubjectConfirmation instance from an XML string """
return saml2.create_class_from_xml_string(SubjectConfirmation, xml_string)
class Subject(SamlBase):
"""The saml:Subject element"""
# TODO: BaseID, EncryptedID element
c_tag = 'Subject'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_children['{%s}NameID' % SAML_NAMESPACE] = ('name_id', NameID)
c_children['{%s}SubjectConfirmation' % SAML_NAMESPACE] = (
'subject_confirmation', [SubjectConfirmation])
c_child_order = ['name_id', 'subject_confirmation']
def __init__(self, name_id=None, subject_confirmation=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for SubjectConfirmation
:param name_id: NameID element
:param subject_confirmation: SubjectConfirmation element
:param text: The text data in this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string
pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.name_id = name_id
self.subject_confirmation = subject_confirmation or []
def subject_from_string(xml_string):
""" Create Subject instance from an XML string """
return saml2.create_class_from_xml_string(Subject, xml_string)
class Condition(SamlBase):
"""The saml:Condition element"""
c_tag = 'Condition'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def condition_from_string(xml_string):
""" Create Condition instance from an XML string """
return saml2.create_class_from_xml_string(Condition, xml_string)
class Audience(SamlBase):
"""The saml:Audience element"""
c_tag = 'Audience'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def audience_from_string(xml_string):
""" Create Audience instance from an XML string """
return saml2.create_class_from_xml_string(Audience, xml_string)
class AudienceRestriction(Condition):
"""The saml:AudienceRestriction element"""
c_tag = 'AudienceRestriction'
c_namespace = SAML_NAMESPACE
c_children = Condition.c_children.copy()
c_attributes = Condition.c_attributes.copy()
c_children['{%s}Audience' % SAML_NAMESPACE] = ('audience', Audience)
def __init__(self, text=None, audience=None,
extension_elements=None, extension_attributes=None):
"""Constructor for AudienceRestriction
:param text: The text data in this element
:param audience: Audience elements
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string
pairs
"""
Condition.__init__(self, extension_elements, extension_attributes,
text)
self.audience = audience
def audience_restriction_from_string(xml_string):
""" Create AudienceRestriction instance from an XML string """
return saml2.create_class_from_xml_string(AudienceRestriction, xml_string)
class OneTimeUse(Condition):
"""The saml:OneTimeUse element"""
c_tag = 'OneTimeUse'
c_children = Condition.c_children.copy()
c_attributes = Condition.c_attributes.copy()
def one_time_use_from_string(xml_string):
""" Create OneTimeUse instance from an XML string """
return saml2.create_class_from_xml_string(OneTimeUse, xml_string)
class ProxyRestriction(Condition):
"""The saml:Condition element"""
c_tag = 'ProxyRestriction'
c_namespace = SAML_NAMESPACE
c_children = Condition.c_children.copy()
c_attributes = Condition.c_attributes.copy()
c_attributes['Count'] = 'count'
c_children['{%s}Audience' % SAML_NAMESPACE] = ('audience', [Audience])
def __init__(self, text=None, count=None, audience=None,
extension_elements=None, extension_attributes=None):
"""Constructor for ProxyRestriction
:param text: The text data in this element
:param count: Count attribute
:param audience: Audience elements
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string
pairs
"""
Condition.__init__(self, extension_elements, extension_attributes,
text)
self.count = count
self.audience = audience or []
def proxy_restriction_from_string(xml_string):
""" Create ProxyRestriction instance from an XML string """
return saml2.create_class_from_xml_string(ProxyRestriction, xml_string)
class Conditions(SamlBase):
"""The saml:Conditions element"""
c_tag = 'Conditions'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['NotBefore'] = 'not_before'
c_attributes['NotOnOrAfter'] = 'not_on_or_after'
c_children['{%s}Condition' % SAML_NAMESPACE] = ('condition', [Condition])
c_children['{%s}AudienceRestriction' % SAML_NAMESPACE] = (
'audience_restriction', [AudienceRestriction])
c_children['{%s}OneTimeUse' % SAML_NAMESPACE] = (
'one_time_use', [OneTimeUse])
c_children['{%s}ProxyRestriction' % SAML_NAMESPACE] = (
'proxy_restriction', [ProxyRestriction])
c_child_order = ['condition', 'audience_restriction', 'one_time_use',
'proxy_restriction']
def __init__(self, text=None, not_before=None, not_on_or_after=None,
condition=None, audience_restriction=None,
one_time_use=None, proxy_restriction=None,
extension_elements=None, extension_attributes=None):
"""Constructor for ProxyRestriction
:param text: The text data in this element
:param not_before: NotBefore attribute
:param not_on_or_after: NotOnOrAfter attribute
:param condition: Condition elements
:param audience_restriction: AudienceRestriction elements
:param one_time_use: OneTimeUse elements
:param proxy_restriction: ProxyRestriction elements
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string
pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.not_before = not_before
self.not_on_or_after = not_on_or_after
self.condition = condition or []
self.audience_restriction = audience_restriction or []
self.one_time_use = one_time_use or []
self.proxy_restriction = proxy_restriction or []
def conditions_from_string(xml_string):
""" Create Conditions instance from an XML string """
return saml2.create_class_from_xml_string(Conditions, xml_string)
class AssertionIDRef(SamlBase):
"""The saml:AssertionIDRef element"""
c_tag = 'AssertionIDRef'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def assertion_id_ref_from_string(xml_string):
""" Create AssertionIDRef instance from an XML string """
return saml2.create_class_from_xml_string(AssertionIDRef, xml_string)
class AssertionURIRef(SamlBase):
"""The saml:AssertionURIRef element"""
c_tag = 'AssertionURIRef'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def assertion_uri_ref_from_string(xml_string):
""" Create AssertionURIRef instance from an XML string """
return saml2.create_class_from_xml_string(AssertionURIRef, xml_string)
class Evidence(SamlBase):
"""The saml:Evidence element"""
c_tag = 'Evidence'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_children['{%s}AssertionIDRef' % SAML_NAMESPACE] = ('assertion_id_ref',
[AssertionIDRef])
c_children['{%s}AssertionURIRef' % SAML_NAMESPACE] = ('assertion_uri_ref',
[AssertionURIRef])
def __init__(self, assertion_id_ref=None, assertion_uri_ref=None,
assertion=None, encrypted_assertion=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for Evidence
:param assertion_id_ref: AssertionIDRef elements
:param assertion_uri_ref: AssertionURIRef elements
:param assertion: Assertion elements
:param encrypted_assertion: EncryptedAssertion elements
:param text: The text data in this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string
pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.assertion_id_ref = assertion_id_ref or []
self.assertion_uri_ref = assertion_uri_ref or []
self.assertion = assertion or []
self.encrypted_assertion = encrypted_assertion or []
def evidence_from_string(xml_string):
""" Create Evidence instance from an XML string """
return saml2.create_class_from_xml_string(Evidence, xml_string)
class Advice(SamlBase):
"""The saml:Advice element"""
c_tag = 'Advice'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_children['{%s}AssertionIDRef' % SAML_NAMESPACE] = ('assertion_id_ref',
[AssertionIDRef])
c_children['{%s}AssertionURIRef' % SAML_NAMESPACE] = ('assertion_uri_ref',
[AssertionURIRef])
def __init__(self, assertion_id_ref=None, assertion_uri_ref=None,
assertion=None, encrypted_assertion=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for Advice
:param assertion_id_ref: AssertionIDRef elements
:param assertion_uri_ref: AssertionURIRef elements
:param assertion: Assertion elements
:param encrypted_assertion: EncryptedAssertion elements
:param text: The text data in this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string
pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.assertion_id_ref = assertion_id_ref or []
self.assertion_uri_ref = assertion_uri_ref or []
self.assertion = assertion or []
self.encrypted_assertion = encrypted_assertion or []
def advice_from_string(xml_string):
""" Create Advice instance from an XML string """
return saml2.create_class_from_xml_string(Advice, xml_string)
class Assertion(SamlBase):
"""The saml:Assertion element"""
c_tag = 'Assertion'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['Version'] = 'version'
c_attributes['ID'] = 'identifier'
c_attributes['IssueInstant'] = 'issue_instant'
c_children['{%s}Issuer' % SAML_NAMESPACE] = ('issuer', Issuer)
c_children['{%s}Signature' % ds.DS_NAMESPACE] = ('signature', ds.Signature)
c_children['{%s}Subject' % SAML_NAMESPACE] = ('subject', Subject)
c_children['{%s}Conditions' % SAML_NAMESPACE] = ('conditions', Conditions)
c_children['{%s}Advice' % SAML_NAMESPACE] = ('advice', Advice)
c_children['{%s}Statement' % SAML_NAMESPACE] = ('statement', [Statement])
c_children['{%s}AuthnStatement' % SAML_NAMESPACE] = (
'authn_statement', [AuthnStatement])
c_children['{%s}AttributeStatement' % SAML_NAMESPACE] = (
'attribute_statement', [AttributeStatement])
c_child_order = ['issuer', 'signature', 'subject', 'conditions', 'advice',
'statement', 'authn_statement', 'authz_decision_statement',
'attribute_statement']
def __init__(self, version=None, identifier=None, issue_instant=None,
issuer=None, signature=None, subject=None, conditions=None,
advice=None, statement=None, authn_statement=None,
authz_decision_statement=None, attribute_statement=None,
text=None, extension_elements=None,
extension_attributes=None):
"""Constructor for Assertion
:param version: Version attribute
:param identifier: ID attribute
:param issue_instant: IssueInstant attribute
:param issuer: Issuer element
:param signature: ds:Signature element
:param subject: Subject element
:param conditions: Conditions element
:param advice: Advice element
:param statement: Statement elements
:param authn_statement: AuthnStatement elements
:param authz_decision_statement: AuthzDecisionStatement elements
:param attribute_statement: AttributeStatement elements
:param text: The text data in this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string
pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.version = version
self.identifier = identifier
self.issue_instant = issue_instant
self.issuer = issuer
self.signature = signature
self.subject = subject
self.conditions = conditions
self.advice = advice
self.statement = statement or []
self.authn_statement = authn_statement or []
self.authz_decision_statement = authz_decision_statement or []
self.attribute_statement = attribute_statement or []
def assertion_from_string(xml_string):
""" Create Assertion instance from an XML string """
return saml2.create_class_from_xml_string(Assertion, xml_string)
Evidence.c_children['{%s}Assertion' % SAML_NAMESPACE] = (
'assertion', [Assertion])
Advice.c_children['{%s}Assertion' % SAML_NAMESPACE] = (
'assertion', [Assertion])
class EncryptedID(SamlBase):
"""The saml:EncryptedID element"""
c_tag = 'EncryptedID'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
# TODO: This is just a skelton yet.
def encrypted_id_from_string(xml_string):
""" Create EncryptedID instance from an XML string """
return saml2.create_class_from_xml_string(EncryptedID, xml_string)
class EncryptedAssertion(SamlBase):
"""The saml:EncryptedAssertion element"""
c_tag = 'EncryptedAssertion'
c_namespace = SAML_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
# TODO: This is just a skelton yet.
def encrypted_assertion_from_string(xml_string):
""" Create EncryptedAssertion instance from an XML string """
return saml2.create_class_from_xml_string(EncryptedAssertion, xml_string)
Evidence.c_children['{%s}EncryptedAssertion' % SAML_NAMESPACE] = (
'encrypted_assertion', [EncryptedAssertion])
Advice.c_children['{%s}EncryptedAssertion' % SAML_NAMESPACE] = (
'encrypted_assertion', [EncryptedAssertion])
class AuthzDecisionStatement(Statement):
"""The saml:AuthzDecisionStatement element"""
c_tag = 'AuthzDecisionStatement'
c_namespace = SAML_NAMESPACE
c_children = Statement.c_children.copy()
c_attributes = Statement.c_attributes.copy()
c_attributes['Resource'] = 'resource'
c_attributes['Decision'] = 'decision'
c_children['{%s}Action' % SAML_NAMESPACE] = ('action', [Action])
c_children['{%s}Evidence' % SAML_NAMESPACE] = ('evidence', [Evidence])
c_child_order = ['action', 'evidence']
def __init__(self, text=None, resource=None, decision=None, action=None,
evidence=None, extension_elements=None,
extension_attributes=None):
"""Constructor for AuthzDecisionStatement
:param text: str The text data in this element
:param resource: Resource attribute
:param decision: Decision attribute
:param action: Action Elements
:param evidence: Evidence Elements
:param extension_elements:A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string
pairs
"""
Statement.__init__(self, extension_elements, extension_attributes,
text)
self.resource = resource
self.decision = decision
self.action = action or []
self.evidence = evidence or []
def authz_decision_statement_from_string(xml_string):
""" Create AuthzDecisionStatement instance from an XML string """
return saml2.create_class_from_xml_string(AuthzDecisionStatement,
xml_string)
Assertion.c_children['{%s}AuthzDecisionStatement' % SAML_NAMESPACE] = (
'authz_decision_statement', [AuthzDecisionStatement])

697
src/saml2/samlp.py Normal file
View File

@@ -0,0 +1,697 @@
#!/usr/bin/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.
"""Contains classes representing Samlp elements.
Module objective: provide data classes for Samlp constructs. These
classes hide the XML-ness of Saml and provide a set of native Python
classes to interact with.
"""
from saml2 import saml, SamlBase, create_class_from_xml_string
import xmldsig as ds
SAMLP_NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:protocol'
SAMLP_TEMPLATE = '{urn:oasis:names:tc:SAML:2.0:protocol}%s'
STATUS_SUCCESS = 'urn:oasis:names:tc:SAML:2.0:status:Success'
STATUS_REQUESTER = 'urn:oasis:names:tc:SAML:2.0:status:Requester'
STATUS_RESPONDER = 'urn:oasis:names:tc:SAML:2.0:status:Responder'
STATUS_VERSION_MISMATCH = 'urn:oasis:names:tc:SAML:2.0:status:VersionMismatch'
STATUS_AUTHN_FAILED = 'urn:oasis:names:tc:SAML:2.0:status:AuthnFailed'
STATUS_INVALID_ATTR_NAME_OR_VALUE = (
'urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue')
STATUS_INVALID_NAMEID_POLICY = (
'urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy')
STATUS_NO_AUTHN_CONTEXT = 'urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext'
STATUS_NO_AVAILABLE_IDP = 'urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP'
STATUS_NO_PASSIVE = 'urn:oasis:names:tc:SAML:2.0:status:NoPassive'
STATUS_NO_SUPPORTED_IDP = 'urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP'
STATUS_PARTIAL_LOGOUT = 'urn:oasis:names:tc:SAML:2.0:status:PartialLogout'
STATUS_PROXY_COUNT_EXCEEDED = (
'urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded')
STATUS_REQUEST_DENIED = 'urn:oasis:names:tc:SAML:2.0:status:RequestDenied'
STATUS_REQUEST_UNSUPPORTED = (
'urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported')
STATUS_REQUEST_VERSION_DEPRECATED = (
'urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated')
STATUS_REQUEST_VERSION_TOO_HIGH = (
'urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh')
STATUS_REQUEST_VERSION_TOO_LOW = (
'urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow')
STATUS_RESOURCE_NOT_RECOGNIZED = (
'urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized')
STATUS_TOO_MANY_RESPONSES = (
'urn:oasis:names:tc:SAML:2.0:status:TooManyResponses')
STATUS_UNKNOWN_ATTR_PROFILE = (
'urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile')
STATUS_UNKNOWN_PRINCIPAL = (
'urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal')
STATUS_UNSUPPORTED_BINDING = (
'urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding')
class Extensions(SamlBase):
"""The samlp:Extensions element"""
c_tag = 'Extensions'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def extensions_from_string(xml_string):
""" Create Extensions instance from an XML string """
return create_class_from_xml_string(Extensions, xml_string)
class AbstractRequest(SamlBase):
"""The samlp:RequestAbstractType element"""
c_tag = 'AbstractRequest'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['ID'] = 'identifier'
c_attributes['Version'] = 'version'
c_attributes['IssueInstant'] = 'issue_instant'
c_attributes['Destination'] = 'destination'
c_attributes['Consent'] = 'consent'
c_children['{%s}Issuer' % saml.SAML_NAMESPACE] = ('issuer', saml.Issuer)
c_children['{%s}Signature' % ds.DS_NAMESPACE] = ('signature', ds.Signature)
c_children['{%s}Extensions' % SAMLP_NAMESPACE] = ('extensions', Extensions)
c_child_order = ['issuer', 'signature', 'extensions']
def __init__(self, identifier=None, version=None, issue_instant=None,
destination=None, consent=None, issuer=None, signature=None,
extensions=None, text=None, extension_elements=None,
extension_attributes=None):
"""Constructor for AbstractRequest
:param identifier: ID attribute
:param version: Version attribute
:param issue_instant: IssueInstant attribute
:param destination: Destination attribute
:param consent: Consent attribute
:param issuer: Issuer element
:param signature: Signature element
:param extensions: Extensions element
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.identifier = identifier
self.version = version
self.issue_instant = issue_instant
self.destination = destination
self.consent = consent
self.issuer = issuer
self.signature = signature
self.extensions = extensions
def abstract_request_from_string(xml_string):
""" Create AbstractRequest instance from an XML string """
return create_class_from_xml_string(AbstractRequest, xml_string)
class StatusDetail(SamlBase):
"""The samlp:StatusDetail element"""
c_tag = 'StatusDetail'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def status_detail_from_string(xml_string):
""" Create StatusDetail instance from an XML string """
return create_class_from_xml_string(StatusDetail, xml_string)
class StatusMessage(SamlBase):
"""The samlp:StatusMessage element"""
c_tag = 'StatusMessage'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def status_message_from_string(xml_string):
""" Create StatusMessage instance from an XML string """
return create_class_from_xml_string(StatusMessage, xml_string)
class StatusCode(SamlBase):
"""The samlp:StatusCode element"""
c_tag = 'StatusCode'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['Value'] = 'value'
def __init__(self, value=None, status_code=None,
text=None, extension_elements=None, extension_attributes=None):
"""Constructor for Status
:param value: Value attribute
:param status_code: StatusCode element
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.value = value
self.status_code = status_code
def status_code_from_string(xml_string):
""" Create StatusCode instance from an XML string """
return create_class_from_xml_string(StatusCode, xml_string)
StatusCode.c_children['{%s}StatusCode' % SAMLP_NAMESPACE] = (
'status_code', StatusCode)
class Status(SamlBase):
"""The samlp:Status element"""
c_tag = 'Status'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_children['{%s}StatusCode' % SAMLP_NAMESPACE] = ('status_code', StatusCode)
c_children['{%s}StatusMessage' % SAMLP_NAMESPACE] = (
'status_message', StatusMessage)
c_children['{%s}StatusDetail' % SAMLP_NAMESPACE] = (
'status_detail', StatusDetail)
c_child_order = ['status_code', 'status_message', 'status_detail']
def __init__(self, status_code=None, status_message=None,
status_detail=None, text=None, extension_elements=None,
extension_attributes=None):
"""Constructor for Status
:param status_code: StatusCode element
:param status_message: StatusMessage element
:param status_detail: StatusDetail element
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.status_code = status_code
self.status_message = status_message
self.status_detail = status_detail
def status_from_string(xml_string):
""" Create Status instance from an XML string """
return create_class_from_xml_string(Status, xml_string)
class StatusResponse(SamlBase):
"""The samlp:StatusResponse element"""
c_tag = 'StatusResponse'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['ID'] = 'identifier'
c_attributes['InResponseTo'] = 'in_response_to'
c_attributes['Version'] = 'version'
c_attributes['IssueInstant'] = 'issue_instant'
c_attributes['Destination'] = 'destination'
c_attributes['Consent'] = 'consent'
c_children['{%s}Issuer' % saml.SAML_NAMESPACE] = ('issuer', saml.Issuer)
c_children['{%s}Signature' % ds.DS_NAMESPACE] = ('signature', ds.Signature)
c_children['{%s}Extensions' % SAMLP_NAMESPACE] = ('extensions', Extensions)
c_children['{%s}Status' % SAMLP_NAMESPACE] = ('status', Status)
c_child_order = ['issuer', 'signature', 'extensions', 'status']
def __init__(self, identifier=None, in_response_to=None, version=None,
issue_instant=None, destination=None, consent=None,
issuer=None, signature=None, extensions=None, status=None,
text=None, extension_elements=None, extension_attributes=None):
"""Constructor for StatusResponse
:param identifier: ID attribute
:param in_respones_to: InResponseTo attribute
:param version: Version attribute
:param issue_instant: IssueInstant attribute
:param destination: Destination attribute
:param consent: Consent attribute
:param issuer: Issuer element
:param signature: Signature element
:param extensions: Extensions element
:param status: Status element
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.identifier = identifier
self.in_response_to = in_response_to
self.version = version
self.issue_instant = issue_instant
self.destination = destination
self.consent = consent
self.issuer = issuer
self.signature = signature
self.extensions = extensions
self.status = status
def status_response_from_string(xml_string):
""" Create StatusResponse instance from an XML string """
return create_class_from_xml_string(StatusResponse, xml_string)
class Response(StatusResponse):
"""The samlp:Response element"""
c_tag = 'Response'
c_namespace = SAMLP_NAMESPACE
c_children = StatusResponse.c_children.copy()
c_attributes = StatusResponse.c_attributes.copy()
c_children['{%s}Assertion' % saml.SAML_NAMESPACE] = (
'assertion', [saml.Assertion])
c_children['{%s}EncryptedAssertion' % saml.SAML_NAMESPACE] = (
'encrypted_assertion', [saml.EncryptedAssertion])
c_child_order = ['issuer', 'signature', 'extensions', 'status', 'assertion',
'encrypted_assertion']
def __init__(self, identifier=None, in_response_to=None, version=None,
issue_instant=None, destination=None, consent=None,
issuer=None, signature=None, extensions=None, status=None,
assertion=None, encrypted_assertion=None,
text=None, extension_elements=None, extension_attributes=None):
"""Constructor for Response
:param identifier: ID attribute
:param in_respones_to: InResponseTo attribute
:param version: Version attribute
:param issue_instant: IssueInstant attribute
:param destination: Destination attribute
:param consent: Consent attribute
:param issuer: Issuer element
:param signature: Signature element
:param extensions: Extensions element
:param status: Status element
:param assertion: Assertion elements
:param encrypted_assertion: EncryptedAssertion elements
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
StatusResponse.__init__(self, identifier, in_response_to,
version, issue_instant,
destination, consent,
issuer, signature,
extensions, status, text,
extension_elements, extension_attributes)
self.assertion = assertion or []
self.encrypted_assertion = encrypted_assertion or []
def response_from_string(xml_string):
""" Create Response instance from an XML string """
return create_class_from_xml_string(Response, xml_string)
class NameIDPolicy(SamlBase):
"""The samlp:NameIDPolicy element"""
c_tag = 'NameIDPolicy'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['Format'] = 'form'
c_attributes['SPNameQualifier'] = 'sp_name_qualifier'
c_attributes['AllowCreate'] = 'allow_create'
def __init__(self, form=None, sp_name_qualifier=None, allow_create=None,
text=None, extension_elements=None, extension_attributes=None):
"""Constructor for NameIDPolicy
:param form: Format attribute
:param sp_name_qualifier: SPNameQualifier attribute
:param allow_create: AllowCreate attribute
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.form = form
self.sp_name_qualifier = sp_name_qualifier
self.allow_create = allow_create
def name_id_policy_from_string(xml_string):
""" Create NameIDPolicy instance from an XML string """
return create_class_from_xml_string(NameIDPolicy, xml_string)
class IDPEntry(SamlBase):
"""The samlp:IDPEntry element"""
c_tag = 'IDPEntry'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['ProviderID'] = 'provider_id'
c_attributes['Name'] = 'name'
c_attributes['Loc'] = 'loc'
def __init__(self, provider_id=None, name=None, loc=None,
text=None, extension_elements=None, extension_attributes=None):
"""Constructor for IDPEntry
:param provider_id: ProviderID attribute
:param name: Name attribute
:param loc: Loc attribute
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.provider_id = provider_id
self.name = name
self.loc = loc
def idp_entry_from_string(xml_string):
""" Create IDPEntry instance from an XML string """
return create_class_from_xml_string(IDPEntry, xml_string)
class GetComplete(SamlBase):
"""The samlp:GetComplete element"""
c_tag = 'GetComplete'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def get_complete_from_string(xml_string):
""" Create GetComplete instance from an XML string """
return create_class_from_xml_string(GetComplete, xml_string)
class IDPList(SamlBase):
"""The samlp:IDPList element"""
c_tag = 'IDPList'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_children['{%s}IDPEntry' % SAMLP_NAMESPACE] = ('idp_entry', [IDPEntry])
c_children['{%s}GetComplete' % SAMLP_NAMESPACE] = (
'get_complete', GetComplete)
c_child_order = ['idp_entry', 'get_complete']
def __init__(self, idp_entry=None, get_complete=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for IDPList
:param idp_entry: IDPEntry elements
:param get_complete: GetComplete element
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.idp_entry = idp_entry or []
self.get_complete = get_complete
def idp_list_from_string(xml_string):
""" Create IDPList instance from an XML string """
return create_class_from_xml_string(IDPList, xml_string)
class RequesterID(SamlBase):
"""The samlp:RequesterID element"""
c_tag = 'RequesterID'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def requester_id_from_string(xml_string):
""" Create RequesterID instance from an XML string """
return create_class_from_xml_string(RequesterID, xml_string)
class Scoping(SamlBase):
"""The samlp:Scoping element"""
c_tag = 'Scoping'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['ProxyCount'] = 'proxy_count'
c_children['{%s}IDPList' % SAMLP_NAMESPACE] = ('idp_list', IDPList)
c_children['{%s}RequesterID' % SAMLP_NAMESPACE] = (
'requester_id', [RequesterID])
c_child_order = ['idp_list', 'requester_id']
def __init__(self, proxy_count=None, idp_list=None, requester_id=None,
text=None, extension_elements=None, extension_attributes=None):
"""Constructor for Scoping
:param proxy_count: ProxyCount attribute
:param idp_list: IDPList element
:param requester_id: list A list of RequesterID instances
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.proxy_count = proxy_count
self.idp_list = idp_list
self.requester_id = requester_id or []
def scoping_from_string(xml_string):
""" Create Scoping instance from an XML string """
return create_class_from_xml_string(Scoping, xml_string)
class RequestedAuthnContext(SamlBase):
"""The samlp:RequestedAuthnContext element"""
c_tag = 'RequestedAuthnContext'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
c_attributes['Comparison'] = 'comparison'
c_children['{%s}AuthnContextClassRef' % saml.SAML_NAMESPACE] = (
'authn_context_class_ref', [saml.AuthnContextClassRef])
c_children['{%s}AuthnContextDeclRef' % saml.SAML_NAMESPACE] = (
'authn_context_decl_ref', [saml.AuthnContextDeclRef])
def __init__(self, comparison=None, authn_context_class_ref=None,
authn_context_decl_ref=None,
text=None, extension_elements=None, extension_attributes=None):
"""Constructor for RequestedAuthnContext
:param comparison: Comparison attribute
:param authn_context_class_ref: list A list of AuthnContextClassRef instances
:param authn_context_decl_ref: list A list of AuthnContextDeclRef instances
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
SamlBase.__init__(self, text, extension_elements, extension_attributes)
self.comparison = comparison
self.authn_context_class_ref = authn_context_class_ref or []
self.authn_context_decl_ref = authn_context_decl_ref or []
def requested_authn_context_from_string(xml_string):
""" Create RequestedAuthnContext instance from an XML string """
return create_class_from_xml_string(RequestedAuthnContext, xml_string)
class AuthnRequest(AbstractRequest):
"""The samlp:AuthnRequest element"""
c_tag = 'AuthnRequest'
c_namespace = SAMLP_NAMESPACE
c_children = AbstractRequest.c_children.copy()
c_attributes = AbstractRequest.c_attributes.copy()
c_attributes['ForceAuthn'] = 'force_authn'
c_attributes['IsPassive'] = 'is_passive'
c_attributes['AssertionConsumerServiceIndex'] = \
'assertion_consumer_service_index'
c_attributes['AssertionConsumerServiceURL'] = \
'assertion_consumer_service_url'
c_attributes['ProtocolBinding'] = 'protocol_binding'
c_attributes['AssertionConsumingServiceIndex'] = \
'assertion_consuming_service_index'
c_attributes['ProviderName'] = 'provider_name'
c_children['{%s}Subject' % saml.SAML_NAMESPACE] = ('subject', saml.Subject)
c_children['{%s}NameIDPolicy' % SAMLP_NAMESPACE] = (
'name_id_policy', NameIDPolicy)
c_children['{%s}Conditions' % saml.SAML_NAMESPACE] = (
'conditions', saml.Conditions)
c_children['{%s}RequestedAuthnContext' % SAMLP_NAMESPACE] = (
'requested_authn_context', RequestedAuthnContext)
c_children['{%s}Scoping' % SAMLP_NAMESPACE] = ('scoping', Scoping)
c_child_order = ['issuer', 'signature', 'extensions', 'subject',
'name_id_policy', 'conditions', 'requested_authn_context',
'scoping']
def __init__(self, identifier=None, version=None, issue_instant=None,
destination=None, consent=None, issuer=None, signature=None,
extensions=None, subject=None, name_id_policy=None,
conditions=None, requested_authn_context=None, scoping=None,
force_authn=None, is_passive=None,
assertion_consumer_service_index=None,
assertion_consumer_service_url=None,
protocol_binding=None, assertion_consuming_service_index=None,
provider_name=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for AuthnRequest
:param identifier: ID attribute
:param version: Version attribute
:param issue_instant: IssueInstant attribute
:param destination: Destination attribute
:param consent: Consent attribute
:param issuer: Issuer element
:param signature: Signature element
:param extensions: Extensions element
:param subject: Subject element
:param name_id_policy: NameIDPolicy element
:param conditions: Conditions element
:param requested_authn_context: RequestedAuthnContext element
:param scoping: Scoping element
:param force_authn: ForceAuthn attribute
:param is_passive: IsPassive attribute
:param assertion_consumer_service_index: AssertionConsumerServiceIndex
element
:param assertion_consumer_service_url: AssertionConsumerServiceURL
element
:param protocol_binding: ProtocolBinding element
:param assertion_consuming_service_index:
AssertionConsumingServiceIndex element
:param provider_name: ProviderName element
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string
pairs
"""
AbstractRequest.__init__(self, identifier, version, issue_instant,
destination, consent, issuer, signature,
extensions, text, extension_elements,
extension_attributes)
self.subject = subject
self.name_id_policy = name_id_policy
self.conditions = conditions
self.requested_authn_context = requested_authn_context
self.conditions = conditions
self.requested_authn_context = requested_authn_context
self.scoping = scoping
self.force_authn = force_authn
self.is_passive = is_passive
self.assertion_consumer_service_index = assertion_consumer_service_index
self.assertion_consumer_service_url = assertion_consumer_service_url
self.protocol_binding = protocol_binding
self.assertion_consuming_service_index = \
assertion_consuming_service_index
self.provider_name = provider_name
def authn_request_from_string(xml_string):
""" Create AuthnRequest instance from an XML string """
return create_class_from_xml_string(AuthnRequest, xml_string)
class SessionIndex(SamlBase):
"""The samlp:SessionIndex element"""
c_tag = 'SessionIndex'
c_namespace = SAMLP_NAMESPACE
c_children = SamlBase.c_children.copy()
c_attributes = SamlBase.c_attributes.copy()
def session_index_from_string(xml_string):
""" Create SessionIndex instance from an XML string """
return create_class_from_xml_string(SessionIndex, xml_string)
class LogoutRequest(AbstractRequest):
"""The samlp:LogoutRequest element"""
c_tag = 'LogoutRequest'
c_namespace = SAMLP_NAMESPACE
c_children = AbstractRequest.c_children.copy()
c_attributes = AbstractRequest.c_attributes.copy()
c_attributes['NotOnOrAfter'] = 'not_on_or_after'
c_attributes['Reason'] = 'reason'
c_children['{%s}BaseID' % saml.SAML_NAMESPACE] = ('base_id', saml.BaseID)
c_children['{%s}NameID' % saml.SAML_NAMESPACE] = ('name_id', saml.NameID)
c_children['{%s}EncryptedID' % saml.SAML_NAMESPACE] = (
'encrypted_id', saml.EncryptedID)
c_children['{%s}SessionIndex' % SAMLP_NAMESPACE] = (
'session_index', SessionIndex)
c_child_order = ['issuer', 'signature', 'extensions', 'base_id', 'name_id',
'encrypted_id', 'session_index']
def __init__(self, identifier=None, version=None, issue_instant=None,
destination=None, consent=None, issuer=None, signature=None,
extensions=None, not_on_or_after=None, reason=None,
base_id=None, name_id=None, encrypted_id=None,
session_index=None, text=None,
extension_elements=None, extension_attributes=None):
"""Constructor for LogoutRequest
:param identifier: ID attribute
:param version: Version attribute
:param issue_instant: IssueInstant attribute
:param destination: Destination attribute
:param consent: Consent attribute
:param issuer: Issuer element
:param signature: Signature element
:param extensions: Extensions element
:param not_on_or_after: NotOnOrAfter attribute
:param reason: Reason attribute
:param base_id: BaseID element
:param name_id: NameID element
:param encrypted_id: EncryptedID element
:param session_index: SessionIndex element
:param text: The text data in the this element
:param extension_elements: A list of ExtensionElement instances
:param extension_attributes: A dictionary of attribute value string pairs
"""
AbstractRequest.__init__(self, identifier, version, issue_instant,
destination, consent, issuer, signature,
extensions, text, extension_elements,
extension_attributes)
self.not_on_or_after = not_on_or_after
self.reason = reason
self.base_id = base_id
self.name_id = name_id
self.encrypted_id = encrypted_id
self.session_index = session_index
def logout_request_from_string(xml_string):
""" Create LogoutRequest instance from an XML string """
return create_class_from_xml_string(LogoutRequest, xml_string)
class LogoutResponse(StatusResponse):
"""The samlp:LogoutResponse element"""
c_tag = 'LogoutResponse'
c_namespace = SAMLP_NAMESPACE
c_children = StatusResponse.c_children.copy()
c_attributes = StatusResponse.c_attributes.copy()
def logout_response_from_string(xml_string):
""" Create LogoutResponse instance from an XML string """
return create_class_from_xml_string(LogoutResponse, xml_string)

View File

@@ -0,0 +1,454 @@
#!/usr/bin/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"""
__author__ = 'tmatsuo@sios.com (Takashi MATSUO)'
TEST_STATUS_CODE = """<?xml version="1.0" encoding="utf-8"?>
<StatusCode xmlns="urn:oasis:names:tc:SAML:2.0:protocol"
Value="urn:oasis:names:tc:SAML:2.0:status:Responder">
<StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:RequestDenied" />
</StatusCode>
"""
TEST_STATUS = """<?xml version="1.0" encoding="utf-8"?>
<Status xmlns="urn:oasis:names:tc:SAML:2.0:protocol">
<StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder">
<StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding" />
</StatusCode>
<StatusMessage>status message</StatusMessage>
<StatusDetail><foo bar="bar" /></StatusDetail>
</Status>
"""
TEST_NAME_ID_POLICY = """<?xml version="1.0" encoding="utf-8"?>
<NameIDPolicy xmlns="urn:oasis:names:tc:SAML:2.0:protocol"
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SPNameQualifier="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
AllowCreate="false"
/>
"""
TEST_IDP_ENTRY = """<?xml version="1.0" encoding="utf-8"?>
<IDPEntry xmlns="urn:oasis:names:tc:SAML:2.0:protocol"
ProviderID="http://www.sios.com/provider"
Name="the provider"
Loc="http://www.sios.com/Loc"
/>
"""
TEST_IDP_LIST = """<?xml version="1.0" encoding="utf-8"?>
<IDPList xmlns="urn:oasis:names:tc:SAML:2.0:protocol">
<IDPEntry ProviderID="http://www.sios.com/provider"
Name="the provider"
Loc="http://www.sios.com/Loc" />
<GetComplete>http://www.sios.com/GetComplete</GetComplete>
</IDPList>
"""
TEST_SCOPING = """<?xml version="1.0" encoding="utf-8"?>
<Scoping xmlns="urn:oasis:names:tc:SAML:2.0:protocol" ProxyCount="1">
<IDPList>
<IDPEntry ProviderID="http://www.sios.com/provider"
Name="the provider"
Loc="http://www.sios.com/Loc" />
<GetComplete>http://www.sios.com/GetComplete</GetComplete>
</IDPList>
<RequesterID>http://www.sios.com/RequesterID</RequesterID>
</Scoping>
"""
TEST_REQUESTED_AUTHN_CONTEXT = """<?xml version="1.0" encoding="utf-8"?>
<RequestedAuthnContext xmlns="urn:oasis:names:tc:SAML:2.0:protocol"
Comparison="exact">
<AuthnContextClassRef xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/authnContextClassRef
</AuthnContextClassRef>
<AuthnContextDeclRef xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/authnContextDeclRef
</AuthnContextDeclRef>
</RequestedAuthnContext>
"""
TEST_AUTHN_REQUEST = """<?xml version="1.0" encoding="utf-8"?>
<AuthnRequest
ID="request id"
Version="2.0"
IssueInstant="2007-09-14T01:05:02Z"
Destination="http://www.sios.com/Destination"
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
ForceAuthn="true"
IsPassive="true"
AssertionConsumerServiceIndex="1"
AssertionConsumerServiceURL="http://www.sios.com/acs"
ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
AssertionConsumingServiceIndex="2"
ProviderName="provider name"
xmlns="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/test
</Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="id">
<SignedInfo Id="id">
<CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments">
</CanonicalizationMethod>
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
<HMACOutputLength>8</HMACOutputLength>
</SignatureMethod>
<Reference Id="id" URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>digest value</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue Id="id">
signature value
</SignatureValue>
<KeyInfo Id="id">
<KeyName>
key name
</KeyName>
<KeyValue>
<DSAKeyValue>
<P>p</P>
<Q>q</Q>
<G>g</G>
<Y>y</Y>
<J>j</J>
<Seed>seed</Seed>
<PgenCounter>pgen counter</PgenCounter>
</DSAKeyValue>
</KeyValue>
<RetrievalMethod URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
</RetrievalMethod>
<X509Data>
<X509IssuerSerial>
<X509IssuerName>issuer name</X509IssuerName>
<X509IssuerNumber>1</X509IssuerNumber>
</X509IssuerSerial>
<X509SKI>x509 ski</X509SKI>
<X509SubjectName>x509 subject name</X509SubjectName>
<X509Certificate>x509 certificate</X509Certificate>
<X509CRL>x509 crl</X509CRL>
</X509Data>
<PGPData>
<PGPKeyID>pgp key id</PGPKeyID>
<PGPKeyPacket>pgp key packet</PGPKeyPacket>
</PGPData>
<MgmtData>
mgmt data
</MgmtData>
<SPKIData>
<SPKISexp>spki sexp</SPKISexp>
<SPKISexp>spki sexp2</SPKISexp>
</SPKIData>
</KeyInfo>
<Object Id="object_id" Encoding="http://www.w3.org/2000/09/xmldsig#base64">
V2VkIEp1biAgNCAxMjoxMTowMyBFRFQgMjAwMwo
</Object>
</Signature>
<Extensions><test/></Extensions>
<Subject xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SPProvidedID="sp provided id">
tmatsuo@sios.com
</NameID>
<SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SPProvidedID="sp provided id2">
admin@sios.com
</NameID>
<SubjectConfirmationData
NotBefore="2007-08-31T01:05:02Z"
NotOnOrAfter="2007-09-14T01:05:02Z"
Recipient="recipient"
InResponseTo="responseID"
Address="127.0.0.1">
</SubjectConfirmationData>
</SubjectConfirmation>
</Subject>
<NameIDPolicy xmlns="urn:oasis:names:tc:SAML:2.0:protocol"
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SPNameQualifier="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
AllowCreate="false"/>
<Conditions
xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
NotBefore="2007-08-31T01:05:02Z"
NotOnOrAfter="2007-09-14T01:05:02Z">
<Condition
xsi:type="test"
ExtendedAttribute="value"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<AudienceRestriction>
<Audience>
http://www.sios.com/Audience
</Audience>
</AudienceRestriction>
<OneTimeUse />
<ProxyRestriction Count="2">
<Audience>http://www.sios.com/Audience</Audience>
</ProxyRestriction>
</Conditions>
<RequestedAuthnContext xmlns="urn:oasis:names:tc:SAML:2.0:protocol"
Comparison="exact">
<AuthnContextClassRef xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/authnContextClassRef
</AuthnContextClassRef>
<AuthnContextDeclRef xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/authnContextDeclRef
</AuthnContextDeclRef>
</RequestedAuthnContext>
<Scoping xmlns="urn:oasis:names:tc:SAML:2.0:protocol" ProxyCount="1">
<IDPList>
<IDPEntry ProviderID="http://www.sios.com/provider"
Name="the provider"
Loc="http://www.sios.com/Loc" />
<GetComplete>http://www.sios.com/GetComplete</GetComplete>
</IDPList>
<RequesterID>http://www.sios.com/RequesterID</RequesterID>
</Scoping>
</AuthnRequest>
"""
TEST_LOGOUT_REQUEST = """<?xml version="1.0" encoding="utf-8"?>
<LogoutRequest
ID="request id"
Version="2.0"
IssueInstant="2007-09-14T01:05:02Z"
Destination="http://www.sios.com/Destination"
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
NotOnOrAfter="2007-10-14T01:05:02Z"
Reason="http://www.sios.com/Reason"
xmlns="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/test
</Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="id">
<SignedInfo Id="id">
<CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments">
</CanonicalizationMethod>
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
<HMACOutputLength>8</HMACOutputLength>
</SignatureMethod>
<Reference Id="id" URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>digest value</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue Id="id">
signature value
</SignatureValue>
<KeyInfo Id="id">
<KeyName>
key name
</KeyName>
<KeyValue>
<DSAKeyValue>
<P>p</P>
<Q>q</Q>
<G>g</G>
<Y>y</Y>
<J>j</J>
<Seed>seed</Seed>
<PgenCounter>pgen counter</PgenCounter>
</DSAKeyValue>
</KeyValue>
<RetrievalMethod URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
</RetrievalMethod>
<X509Data>
<X509IssuerSerial>
<X509IssuerName>issuer name</X509IssuerName>
<X509IssuerNumber>1</X509IssuerNumber>
</X509IssuerSerial>
<X509SKI>x509 ski</X509SKI>
<X509SubjectName>x509 subject name</X509SubjectName>
<X509Certificate>x509 certificate</X509Certificate>
<X509CRL>x509 crl</X509CRL>
</X509Data>
<PGPData>
<PGPKeyID>pgp key id</PGPKeyID>
<PGPKeyPacket>pgp key packet</PGPKeyPacket>
</PGPData>
<MgmtData>
mgmt data
</MgmtData>
<SPKIData>
<SPKISexp>spki sexp</SPKISexp>
<SPKISexp>spki sexp2</SPKISexp>
</SPKIData>
</KeyInfo>
<Object Id="object_id" Encoding="http://www.w3.org/2000/09/xmldsig#base64">
V2VkIEp1biAgNCAxMjoxMTowMyBFRFQgMjAwMwo
</Object>
</Signature>
<Extensions><test/></Extensions>
<BaseID xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SPProvidedID="sp provided id">
tmatsuo@sios.com
</BaseID>
<NameID xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SPProvidedID="sp provided id">
tmatsuo@sios.com
</NameID>
<EncryptedID xmlns="urn:oasis:names:tc:SAML:2.0:assertion" />
<SessionIndex>session index</SessionIndex>
</LogoutRequest>
"""
TEST_LOGOUT_RESPONSE = """<?xml version="1.0" encoding="utf-8"?>
<LogoutResponse
ID="response id"
InResponseTo="request id"
Version="2.0"
IssueInstant="2007-09-14T01:05:02Z"
Destination="http://www.sios.com/Destination"
Consent="urn:oasis:names:tc:SAML:2.0:consent:unspecified"
xmlns="urn:oasis:names:tc:SAML:2.0:protocol">
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/test
</Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="id">
<SignedInfo Id="id">
<CanonicalizationMethod
Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments">
</CanonicalizationMethod>
<SignatureMethod
Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
<HMACOutputLength>8</HMACOutputLength>
</SignatureMethod>
<Reference Id="id" URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>digest value</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue Id="id">
signature value
</SignatureValue>
<KeyInfo Id="id">
<KeyName>
key name
</KeyName>
<KeyValue>
<DSAKeyValue>
<P>p</P>
<Q>q</Q>
<G>g</G>
<Y>y</Y>
<J>j</J>
<Seed>seed</Seed>
<PgenCounter>pgen counter</PgenCounter>
</DSAKeyValue>
</KeyValue>
<RetrievalMethod URI="http://www.sios.com/URI"
Type="http://www.sios.com/Type">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
<XPath>xpath</XPath>
</Transform>
</Transforms>
</RetrievalMethod>
<X509Data>
<X509IssuerSerial>
<X509IssuerName>issuer name</X509IssuerName>
<X509IssuerNumber>1</X509IssuerNumber>
</X509IssuerSerial>
<X509SKI>x509 ski</X509SKI>
<X509SubjectName>x509 subject name</X509SubjectName>
<X509Certificate>x509 certificate</X509Certificate>
<X509CRL>x509 crl</X509CRL>
</X509Data>
<PGPData>
<PGPKeyID>pgp key id</PGPKeyID>
<PGPKeyPacket>pgp key packet</PGPKeyPacket>
</PGPData>
<MgmtData>
mgmt data
</MgmtData>
<SPKIData>
<SPKISexp>spki sexp</SPKISexp>
<SPKISexp>spki sexp2</SPKISexp>
</SPKIData>
</KeyInfo>
<Object Id="object_id" Encoding="http://www.w3.org/2000/09/xmldsig#base64">
V2VkIEp1biAgNCAxMjoxMTowMyBFRFQgMjAwMwo
</Object>
</Signature>
<Extensions><test/></Extensions>
<Status>
<StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Responder">
<StatusCode
Value="urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding" />
</StatusCode>
<StatusMessage>status message</StatusMessage>
<StatusDetail><foo bar="bar" /></StatusDetail>
</Status>
</LogoutResponse>
"""

62
src/saml2/test_base.py Normal file
View File

@@ -0,0 +1,62 @@
import saml2
from saml2 import SamlBase
DS_NAMESPACE = 'http://www.w3.org/2000/09/xmldsig#'
class Foo(SamlBase):
etag = "Foo"
enamespace = DS_NAMESPACE
def __init__(self, extension_elements=None, extension_attributes=None,
text=None):
SamlBase.__init__(self, extension_elements, extension_attributes, text)
def cmplist(list0,list1):
return set(list0) == set(list1)
class TestBase:
def test_init(self):
b = saml2.SamlBase()
assert b._attributes == {}
assert cmplist(b.__dict__.keys(), ['extension_attributes', '_children',
'text', '_attributes', 'etag',
'enamespace', '_child_order', 'extension_elements'])
assert b.text == None
assert b.etag == ''
assert b.enamespace == ''
assert b._attributes == {}
assert b._children == {}
assert b._child_order == []
assert b.extension_attributes == {}
assert b.extension_elements == []
def test_init_attr(self):
b = saml2.SamlBase()
b._init_attribute('Id','identifier',"urn:mace:example.org:foo#bar")
assert b._attributes == {'Id': 'identifier'}
assert b.identifier == 'urn:mace:example.org:foo#bar'
assert b.text == None
assert b.etag == ''
assert b.enamespace == ''
assert b._children == {}
assert b._child_order == []
assert b.extension_attributes == {}
assert b.extension_elements == []
def test_init_child(self):
b = saml2.SamlBase()
xml_name = '{%s}Foo' % DS_NAMESPACE
b._init_child(xml_name, 'foo', [Foo], [])
assert b.text == None
assert b.etag == ''
assert b.enamespace == ''
assert b._attributes == {}
assert b._children.has_key(xml_name)
assert b._children[xml_name] == ("foo", [Foo])
assert b._child_order == []
assert b.extension_attributes == {}
assert b.extension_elements == []

227
src/saml2/test_data.py Normal file
View File

@@ -0,0 +1,227 @@
#!/usr/bin/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"""
__author__ = 'tmatsuo@sios.com (Takashi MATSUO)'
TEST_NAME_ID = """<?xml version="1.0" encoding="utf-8"?>
<NameID xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SPProvidedID="sp provided id">
tmatsuo@sios.com
</NameID>
"""
TEST_ISSUER = """<?xml version="1.0" encoding="utf-8"?>
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/test
</Issuer>
"""
TEST_SUBJECT_LOCALITY = """<?xml version="1.0" encoding="utf-8"?>
<SubjectLocality xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
Address="127.0.0.1" DNSName="localhost"/>
"""
TEST_AUTHN_CONTEXT_CLASS_REF = """<?xml version="1.0" encoding="utf-8"?>
<AuthnContextClassRef xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/authnContextClassRef
</AuthnContextClassRef>
"""
TEST_AUTHN_CONTEXT_DECL_REF = """<?xml version="1.0" encoding="utf-8"?>
<AuthnContextDeclRef xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/authnContextDeclRef
</AuthnContextDeclRef>
"""
TEST_AUTHN_CONTEXT_DECL = """<?xml version="1.0" encoding="utf-8"?>
<AuthnContextDecl xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/authnContextDecl
</AuthnContextDecl>
"""
TEST_AUTHENTICATING_AUTHORITY = """<?xml version="1.0" encoding="utf-8"?>
<AuthenticatingAuthority xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/authenticatingAuthority
</AuthenticatingAuthority>
"""
TEST_AUTHN_CONTEXT = """<?xml version="1.0" encoding="utf-8"?>
<AuthnContext xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
</AuthnContext>
"""
TEST_AUTHN_STATEMENT = """<?xml version="1.0" encoding="utf-8"?>
<AuthnStatement xmlns="urn:oasis:names:tc:SAML:2.0:assertion" AuthnInstant="2007-08-31T01:05:02Z" SessionNotOnOrAfter="2007-09-14T01:05:02Z">
<AuthnContext>
<AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
</AuthnContext>
</AuthnStatement>
"""
TEST_ATTRIBUTE_VALUE = """<?xml version="1.0" encoding="utf-8"?>
<AttributeValue xmlns="urn:oasis:names:tc:SAML:2.0:assertion">value for test attribute</AttributeValue>
"""
TEST_ATTRIBUTE = """<?xml version="1.0" encoding="utf-8"?>
<Attribute Name="testAttribute"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrnam-format:unspecified"
FriendlyName="test attribute"
xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<AttributeValue >value1 of test attribute</AttributeValue>
<AttributeValue >value2 of test attribute</AttributeValue>
</Attribute>
"""
TEST_ATTRIBUTE_STATEMENT = """<?xml version="1.0" encoding="utf-8"?>
<AttributeStatement xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Attribute Name="testAttribute"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrnam-format:unspecified"
FriendlyName="test attribute">
<AttributeValue >value1 of test attribute</AttributeValue>
<AttributeValue >value2 of test attribute</AttributeValue>
</Attribute>
<Attribute Name="http://www.sios.com/testAttribute2"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrnam-format:uri"
FriendlyName="test attribute2">
<AttributeValue >value1 of test attribute2</AttributeValue>
<AttributeValue >value2 of test attribute2</AttributeValue>
</Attribute>
</AttributeStatement>
"""
TEST_SUBJECT_CONFIRMATION_DATA = """<?xml version="1.0" encoding="utf-8"?>
<SubjectConfirmationData
NotBefore="2007-08-31T01:05:02Z"
NotOnOrAfter="2007-09-14T01:05:02Z"
Recipient="recipient"
InResponseTo="responseID"
Address="127.0.0.1"
xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
</SubjectConfirmationData>
"""
TEST_SUBJECT_CONFIRMATION = """<?xml version="1.0" encoding="utf-8"?>
<SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"
xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<NameID xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SPProvidedID="sp provided id">
tmatsuo@sios.com
</NameID>
<SubjectConfirmationData
NotBefore="2007-08-31T01:05:02Z"
NotOnOrAfter="2007-09-14T01:05:02Z"
Recipient="recipient"
InResponseTo="responseID"
Address="127.0.0.1">
</SubjectConfirmationData>
</SubjectConfirmation>
"""
TEST_SUBJECT = """<?xml version="1.0" encoding="utf-8"?>
<Subject xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SPProvidedID="sp provided id">
tmatsuo@sios.com
</NameID>
<SubjectConfirmation
Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
SPProvidedID="sp provided id2">
admin@sios.com
</NameID>
<SubjectConfirmationData
NotBefore="2007-08-31T01:05:02Z"
NotOnOrAfter="2007-09-14T01:05:02Z"
Recipient="recipient"
InResponseTo="responseID"
Address="127.0.0.1">
</SubjectConfirmationData>
</SubjectConfirmation>
</Subject>
"""
TEST_CONDITION = """<?xml version="1.0" encoding="utf-8"?>
<Condition xmlns="urn:oasis:names:tc:SAML:2.0:assertion" xsi:type="test" ExtendedAttribute="value" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
"""
TEST_AUDIENCE = """<?xml version="1.0" encoding="utf-8"?>
<Audience xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/Audience
</Audience>
"""
TEST_AUDIENCE_RESTRICTION = """<?xml version="1.0" encoding="utf-8"?>
<AudienceRestriction xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
<Audience>
http://www.sios.com/Audience
</Audience>
</AudienceRestriction>
"""
TEST_ONE_TIME_USE = """<?xml version="1.0" encoding="utf-8"?>
<OneTimeUse xmlns="urn:oasis:names:tc:SAML:2.0:assertion"/>
"""
TEST_PROXY_RESTRICTION = """<?xml version="1.0" encoding="utf-8"?>
<ProxyRestriction xmlns="urn:oasis:names:tc:SAML:2.0:assertion" Count="2">
<Audience>http://www.sios.com/Audience</Audience>
</ProxyRestriction>
"""
TEST_CONDITIONS = """<?xml version="1.0" encoding="utf-8"?>
<Conditions
xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
NotBefore="2007-08-31T01:05:02Z"
NotOnOrAfter="2007-09-14T01:05:02Z">
<Condition
xsi:type="test"
ExtendedAttribute="value"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
<AudienceRestriction>
<Audience>
http://www.sios.com/Audience
</Audience>
</AudienceRestriction>
<OneTimeUse />
<ProxyRestriction Count="2">
<Audience>http://www.sios.com/Audience</Audience>
</ProxyRestriction>
</Conditions>
"""
TEST_ASSERTION_ID_REF = """<?xml version="1.0" encoding="utf-8"?>
<AssertionIDRef xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
zzlieajngjbkjggjldmgindkckkolcblndbghlhm
</AssertionIDRef>
"""
TEST_ASSERTION_URI_REF = """<?xml version="1.0" encoding="utf-8"?>
<AssertionURIRef xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
http://www.sios.com/AssertionURIRef
</AssertionURIRef>
"""
TEST_ACTION = """<?xml version="1.0" encoding="utf-8"?>
<Action xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
Namespace="http://www.sios.com/Namespace"/>
"""

30
src/saml2/test_utils.py Normal file
View File

@@ -0,0 +1,30 @@
#!/usr/bin/env python
import string
import time
from saml2 import utils
def test_id():
oid = utils.create_id()
print oid
assert len(oid) == 40
for c in oid:
assert c in string.lowercase
def test_get_date_and_time_now():
dt = utils.get_date_and_time()
# Should return something similar to 2009-07-09T10:24:28Z
print dt
assert isinstance(dt,basestring)
assert len(dt) == 20
def test_get_date_and_time_old():
t = time.struct_time((2009, 7, 9, 10, 39, 36, 3, 190,0))
dt = utils.get_date_and_time(time.mktime(t))
print dt
assert isinstance(dt,basestring)
assert len(dt) == 20
assert dt == "2009-07-09T09:39:36Z"
def test_lib_init():
utils.lib_init()

View File

@@ -0,0 +1,86 @@
#!/usr/bin/env python
try:
from xml.etree import ElementTree
except ImportError:
from elementtree import ElementTree
import saml2
from saml2 import saml, samlp, md
import xmldsig as ds
import base64
def _verify_contact_person(person):
assert person.contact_type == "technical"
assert person.given_name.text == "Roland"
assert person.sur_name.text == "Hedberg"
assert person.email_address[0].text == "roland.hedberg@adm.umu.se"
def _verify_contact_person(person):
assert person.contact_type == "technical"
assert person.given_name.text == "Roland"
assert person.sur_name.text == "Hedberg"
assert person.email_address[0].text == "roland.hedberg@adm.umu.se"
def _verify_single_sign_on_service(sso):
assert sso.binding == "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
assert sso.location == "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/SSOService.php"
def _verify_single_logout_service(sso):
assert sso.binding == "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
assert sso.location == "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/SingleLogoutService.php"
def _get_keys(key_descriptors):
res = {}
for kd in key_descriptors:
use = kd.use
coded_key = kd.key_info.x509_data[0].x509_certificate[0].text
key = base64.b64decode(coded_key)
try:
res[use].append(key)
except KeyError:
res[use] = [key]
return res
def _verify_idp_sso_description(idpssodesc):
for ssoserv in idpssodesc.single_sign_on_service: # only one
_verify_single_sign_on_service(ssoserv)
for sloserv in idpssodesc.single_logout_service: # only one
_verify_single_logout_service(sloserv)
assert idpssodesc.name_id_format[0].text == "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
assert len(idpssodesc.key_descriptor) == 2
keys = _get_keys(idpssodesc.key_descriptor)
assert set(keys.keys()) == set(["signing","encryption"])
# one key for signing and one for encryption
assert len(keys["signing"]) == 1
assert len(keys["encryption"]) == 1
def test_contactdata(contact):
person = md.contact_person_from_string(contact)
_verify_contact_person(person)
def test_entity_descriptor(idp_metadata):
ed = md.entity_descriptor_from_string(idp_metadata)
assert ed.entity_id == "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php"
contact_person = ed.contact_person[0]
_verify_contact_person(contact_person)
idpsso = ed.idp_sso_descriptor[0]
_verify_idp_sso_description(idpsso)
assert ed.entity_id == "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php"
print ed.to_string()
# all other attributes are supposed to be None,'',[] or {}
for key,val in ed.__dict__.items():
if key in ["contact_person", "idp_sso_descriptor", "entity_id"]:
continue
else:
if isinstance(val,basestring):
val = val.strip('\t\r\n ')
assert val in [None,'',[],{}]
# def test_idp_metadata(idp_metadata):
# entities_descriptor = md.entities_descriptor_from_string(idp_metadata)
# print type(idp_metadata)
# print idp_metadata
# print entities_descriptor.to_string()
# assert False

206
src/saml2/utils.py Normal file
View File

@@ -0,0 +1,206 @@
#!/opt/local/bin/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.
"""Contains utility methods used with SAML-2."""
import saml2
import libxml2
import xmlsec
import random
import time
# TODO: write tests for these methods
def create_id():
ret = ""
for _ in range(40):
ret = ret + chr(random.randint(0, 15) + ord('a'))
return ret
def get_date_and_time(base=None):
if base is None:
base = time.time()
return time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(base))
def lib_init():
# Init libxml library
libxml2.initParser()
libxml2.substituteEntitiesDefault(1)
# Init xmlsec library
if xmlsec.init() < 0:
raise(saml2.Error("Error: xmlsec initialization failed."))
# Check loaded library version
if xmlsec.checkVersion() != 1:
raise(saml2.Error(
"Error: loaded xmlsec library version is not compatible.\n"))
# Init crypto library
if xmlsec.cryptoAppInit(None) < 0:
raise(saml2.Error("Error: crypto initialization failed."))
# Init xmlsec-crypto library
if xmlsec.cryptoInit() < 0:
raise(saml2.Error("Error: xmlsec-crypto initialization failed."))
def lib_shutdown():
# Shutdown xmlsec-crypto library
xmlsec.cryptoShutdown()
# Shutdown crypto library
xmlsec.cryptoAppShutdown()
# Shutdown xmlsec library
xmlsec.shutdown()
# Shutdown LibXML2
libxml2.cleanupParser()
def verify(xml, key_file):
lib_init()
ret = verify_xml(xml, key_file)
lib_shutdown()
return ret == 0
# Verifies XML signature in xml_file using public key from key_file.
# Returns 0 on success or a negative value if an error occurs.
def verify_xml(xml, key_file):
doc = libxml2.parseDoc(xml)
if doc is None or doc.getRootElement() is None:
cleanup(doc)
raise saml2.Error("Error: unable to parse file \"%s\"" % xml)
# Find start node
node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature,
xmlsec.DSigNs)
# Create signature context, we don't need keys manager in this example
dsig_ctx = xmlsec.DSigCtx()
if dsig_ctx is None:
cleanup(doc)
raise saml2.Error("Error: failed to create signature context")
# Load public key, assuming that there is not password
if key_file.endswith(".der"):
key = xmlsec.cryptoAppKeyLoad(key_file, xmlsec.KeyDataFormatDer,
None, None, None)
else:
key = xmlsec.cryptoAppKeyLoad(key_file, xmlsec.KeyDataFormatPem,
None, None, None)
if key is None:
cleanup(doc, dsig_ctx)
raise saml2.Error(
"Error: failed to load public key from \"%s\"" % key_file)
dsig_ctx.signKey = key
# Set key name to the file name, this is just an example!
if key.setName(key_file) < 0:
cleanup(doc, dsig_ctx)
raise saml2.Error(
"Error: failed to set key name for key from \"%s\"" % key_file)
# Verify signature
if dsig_ctx.verify(node) < 0:
cleanup(doc, dsig_ctx)
raise saml2.Error("Error: signature verify")
# Print verification result to stdout
if dsig_ctx.status == xmlsec.DSigStatusSucceeded:
ret = 0
else:
ret = -1
# Success
cleanup(doc, dsig_ctx)
return ret
def sign(xml, key_file, cert_file=None):
lib_init()
ret = sign_xml(xml, key_file, cert_file)
lib_shutdown()
return ret
# Signs the xml_file using private key from key_file and dynamicaly
# created enveloped signature template.
# Returns 0 on success or a negative value if an error occurs.
def sign_xml(xml, key_file, cert_file=None):
# Load template
doc = libxml2.parseDoc(xml)
if doc is None or doc.getRootElement() is None:
cleanup(doc)
raise saml2.Error("Error: unable to parse string \"%s\"" % xml)
node = xmlsec.findNode(doc.getRootElement(), xmlsec.NodeSignature,
xmlsec.DSigNs)
if node is None:
cleanup(doc)
raise saml2.Error("Error: start node not found.")
# Create signature context, we don't need keys manager in this example
dsig_ctx = xmlsec.DSigCtx()
if dsig_ctx is None:
cleanup(doc)
raise saml2.Error("Error: failed to create signature context")
# Load private key, assuming that there is not password
key = xmlsec.cryptoAppKeyLoad(key_file, xmlsec.KeyDataFormatPem,
None, None, None)
if key is None:
cleanup(doc, dsig_ctx)
raise saml2.Error(
"Error: failed to load private pem key from \"%s\"" % key_file)
dsig_ctx.signKey = key
if cert_file is not None:
if xmlsec.cryptoAppKeyCertLoad(
dsig_ctx.signKey, cert_file, xmlsec.KeyDataFormatPem) < 0:
cleanup(doc, dsig_ctx)
raise saml2.Error(
"Error: failed to load cert pem from \"%s\"" % cert_file)
else:
pass
# Set key name to the file name, this is just an example!
if key.setName(key_file) < 0:
cleanup(doc, dsig_ctx)
raise saml2.Error(
"Error: failed to set key name for key from \"%s\"" % key_file)
# Sign the template
if dsig_ctx.sign(node) < 0:
cleanup(doc, dsig_ctx)
raise saml2.Error("Error: signature failed")
# signed document to string
ret = doc.__str__()
# Success
cleanup(doc, dsig_ctx, 1)
return ret
def cleanup(doc=None, dsig_ctx=None, res=-1):
if dsig_ctx is not None:
dsig_ctx.destroy()
if doc is not None:
doc.freeDoc()
return res

1058
src/xmldsig/__init__.py Normal file

File diff suppressed because it is too large Load Diff

655
tests/ds_test.py Normal file
View File

@@ -0,0 +1,655 @@
#!/usr/bin/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 saml2.saml"""
__author__ = 'tmatsuo@sios.com (Takashi MATSUO)'
import unittest
try:
from xml.etree import ElementTree
except ImportError:
from elementtree import ElementTree
from saml2 import ds_test_data
import xmldsig as ds
class ObjectTest(unittest.TestCase):
def setUp(self):
self.object = ds.Object()
def testAccessors(self):
"""Test for Object accessors"""
self.object.id = "object_id"
self.object.mime_type = "test/plain; charset=UTF-8"
self.object.encoding = ds.ENCODING_BASE64
new_object = ds.ObjectFromString(self.object.ToString())
self.assert_(new_object.id == "object_id")
self.assert_(new_object.mime_type == "test/plain; charset=UTF-8")
self.assert_(new_object.encoding == ds.ENCODING_BASE64)
def testUsingTestData(self):
"""Test for ObjectFromString() using test data"""
new_object = ds.ObjectFromString(ds_test_data.TEST_OBJECT)
self.assert_(new_object.id == "object_id")
self.assert_(new_object.encoding == ds.ENCODING_BASE64)
self.assert_(new_object.text.strip() ==
"V2VkIEp1biAgNCAxMjoxMTowMyBFRFQgMjAwMwo")
class MgmtDataTest(unittest.TestCase):
def setUp(self):
self.mgmt_data = ds.MgmtData()
def testAccessors(self):
"""Test for MgmtData accessors"""
self.mgmt_data.text = "mgmt data"
new_mgmt_data = ds.MgmtDataFromString(self.mgmt_data.ToString())
self.assert_(new_mgmt_data.text.strip() == "mgmt data")
def testUsingTestData(self):
"""Test for MgmtDataFromString() using test data"""
new_mgmt_data = ds.MgmtDataFromString(ds_test_data.TEST_MGMT_DATA)
self.assert_(new_mgmt_data.text.strip() == "mgmt data")
class SPKISexpTest(unittest.TestCase):
def setUp(self):
self.spki_sexp = ds.SPKISexp()
def testAccessors(self):
"""Test for SPKISexp accessors"""
self.spki_sexp.text = "spki sexp"
new_spki_sexp = ds.SPKISexpFromString(self.spki_sexp.ToString())
self.assert_(new_spki_sexp.text.strip() == "spki sexp")
def testUsingTestData(self):
"""Test for SPKISexpFromString() using test data"""
new_spki_sexp = ds.SPKISexpFromString(ds_test_data.TEST_SPKI_SEXP)
self.assert_(new_spki_sexp.text.strip() == "spki sexp")
class SPKIDataTest(unittest.TestCase):
def setUp(self):
self.spki_data = ds.SPKIData()
def testAccessors(self):
"""Test for SPKIData accessors"""
self.spki_data.spki_sexp.append(
ds.SPKISexpFromString(ds_test_data.TEST_SPKI_SEXP))
new_spki_data = ds.SPKIDataFromString(self.spki_data.ToString())
self.assert_(new_spki_data.spki_sexp[0].text.strip() == "spki sexp")
def testUsingTestData(self):
"""Test for SPKIDataFromString() using test data"""
new_spki_data = ds.SPKIDataFromString(ds_test_data.TEST_SPKI_DATA)
self.assert_(new_spki_data.spki_sexp[0].text.strip() == "spki sexp")
self.assert_(new_spki_data.spki_sexp[1].text.strip() == "spki sexp2")
class PGPDataTest(unittest.TestCase):
def setUp(self):
self.pgp_data = ds.PGPData()
def testAccessors(self):
"""Test for PGPData accessors"""
self.pgp_data.pgp_key_id = ds.PGPKeyID(text="pgp key id")
self.pgp_data.pgp_key_packet = ds.PGPKeyPacket(text="pgp key packet")
new_pgp_data = ds.PGPDataFromString(self.pgp_data.ToString())
self.assert_(isinstance(new_pgp_data.pgp_key_id, ds.PGPKeyID))
self.assert_(isinstance(new_pgp_data.pgp_key_packet, ds.PGPKeyPacket))
self.assert_(new_pgp_data.pgp_key_id.text.strip() == "pgp key id")
self.assert_(new_pgp_data.pgp_key_packet.text.strip() == "pgp key packet")
def testUsingTestData(self):
"""Test for PGPDataFromString() using test data"""
new_pgp_data = ds.PGPDataFromString(ds_test_data.TEST_PGP_DATA)
self.assert_(isinstance(new_pgp_data.pgp_key_id, ds.PGPKeyID))
self.assert_(isinstance(new_pgp_data.pgp_key_packet, ds.PGPKeyPacket))
self.assert_(new_pgp_data.pgp_key_id.text.strip() == "pgp key id")
self.assert_(new_pgp_data.pgp_key_packet.text.strip() == "pgp key packet")
class X509IssuerSerialTest(unittest.TestCase):
def setUp(self):
self.x509_issuer_serial = ds.X509IssuerSerial()
def testAccessors(self):
"""Test for X509IssuerSerial accessors"""
self.x509_issuer_serial.x509_issuer_name = ds.X509IssuerName(
text="issuer name")
self.x509_issuer_serial.x509_issuer_number = ds.X509IssuerNumber(text="1")
new_x509_issuer_serial = ds.X509IssuerSerialFromString(
self.x509_issuer_serial.ToString())
self.assert_(new_x509_issuer_serial.x509_issuer_name.text.strip() ==
"issuer name")
self.assert_(new_x509_issuer_serial.x509_issuer_number.text.strip() == "1")
def testUsingTestData(self):
"""Test for X509IssuerSerialFromString() using test data"""
new_x509_issuer_serial = ds.X509IssuerSerialFromString(
ds_test_data.TEST_X509_ISSUER_SERIAL)
self.assert_(new_x509_issuer_serial.x509_issuer_name.text.strip() ==
"issuer name")
self.assert_(new_x509_issuer_serial.x509_issuer_number.text.strip() == "1")
class X509DataTest(unittest.TestCase):
def setUp(self):
self.x509_data = ds.X509Data()
def testAccessors(self):
"""Test for X509Data accessors"""
self.x509_data.x509_issuer_serial.append(ds.X509IssuerSerialFromString(
ds_test_data.TEST_X509_ISSUER_SERIAL))
self.x509_data.x509_ski.append(ds.X509SKI(text="x509 ski"))
self.x509_data.x509_subject_name.append(ds.X509SubjectName(
text="x509 subject name"))
self.x509_data.x509_certificate.append(ds.X509Certificate(
text="x509 certificate"))
self.x509_data.x509_crl.append(ds.X509CRL(text="x509 crl"))
new_x509_data = ds.X509DataFromString(self.x509_data.ToString())
self.assert_(isinstance(new_x509_data.x509_issuer_serial[0],
ds.X509IssuerSerial))
self.assert_(new_x509_data.x509_ski[0].text.strip() == "x509 ski")
self.assert_(isinstance(new_x509_data.x509_ski[0], ds.X509SKI))
self.assert_(new_x509_data.x509_subject_name[0].text.strip() ==
"x509 subject name")
self.assert_(isinstance(new_x509_data.x509_subject_name[0],
ds.X509SubjectName))
self.assert_(new_x509_data.x509_certificate[0].text.strip() ==
"x509 certificate")
self.assert_(isinstance(new_x509_data.x509_certificate[0],
ds.X509Certificate))
self.assert_(new_x509_data.x509_crl[0].text.strip() == "x509 crl")
self.assert_(isinstance(new_x509_data.x509_crl[0],ds.X509CRL))
def testUsingTestData(self):
"""Test for X509DataFromString() using test data"""
new_x509_data = ds.X509DataFromString(ds_test_data.TEST_X509_DATA)
self.assert_(isinstance(new_x509_data.x509_issuer_serial[0],
ds.X509IssuerSerial))
self.assert_(new_x509_data.x509_ski[0].text.strip() == "x509 ski")
self.assert_(isinstance(new_x509_data.x509_ski[0], ds.X509SKI))
self.assert_(new_x509_data.x509_subject_name[0].text.strip() ==
"x509 subject name")
self.assert_(isinstance(new_x509_data.x509_subject_name[0],
ds.X509SubjectName))
self.assert_(new_x509_data.x509_certificate[0].text.strip() ==
"x509 certificate")
self.assert_(isinstance(new_x509_data.x509_certificate[0],
ds.X509Certificate))
self.assert_(new_x509_data.x509_crl[0].text.strip() == "x509 crl")
self.assert_(isinstance(new_x509_data.x509_crl[0],ds.X509CRL))
class TransformTest(unittest.TestCase):
def setUp(self):
self.transform = ds.Transform()
def testAccessors(self):
"""Test for Transform accessors"""
self.transform.xpath.append(ds.XPath(text="xpath"))
self.transform.algorithm = ds.TRANSFORM_ENVELOPED
new_transform = ds.TransformFromString(self.transform.ToString())
self.assert_(isinstance(new_transform.xpath[0], ds.XPath))
self.assert_(new_transform.xpath[0].text.strip() == "xpath")
self.assert_(new_transform.algorithm == ds.TRANSFORM_ENVELOPED)
def testUsingTestData(self):
"""Test for TransformFromString() using test data"""
new_transform = ds.TransformFromString(ds_test_data.TEST_TRANSFORM)
self.assert_(isinstance(new_transform.xpath[0], ds.XPath))
self.assert_(new_transform.xpath[0].text.strip() == "xpath")
self.assert_(new_transform.algorithm == ds.TRANSFORM_ENVELOPED)
class TransformsTest(unittest.TestCase):
def setUp(self):
self.transforms = ds.Transforms()
def testAccessors(self):
"""Test for Transforms accessors"""
self.transforms.transform.append(
ds.TransformFromString(ds_test_data.TEST_TRANSFORM))
self.transforms.transform.append(
ds.TransformFromString(ds_test_data.TEST_TRANSFORM))
new_transforms = ds.TransformsFromString(self.transforms.ToString())
self.assert_(isinstance(new_transforms.transform[0], ds.Transform))
self.assert_(isinstance(new_transforms.transform[1], ds.Transform))
self.assert_(new_transforms.transform[0].algorithm ==
ds.TRANSFORM_ENVELOPED)
self.assert_(new_transforms.transform[1].algorithm ==
ds.TRANSFORM_ENVELOPED)
self.assert_(new_transforms.transform[0].xpath[0].text.strip() == "xpath")
self.assert_(new_transforms.transform[1].xpath[0].text.strip() == "xpath")
def testUsingTestData(self):
"""Test for TransformFromString() using test data"""
new_transforms = ds.TransformsFromString(ds_test_data.TEST_TRANSFORMS)
self.assert_(isinstance(new_transforms.transform[0], ds.Transform))
self.assert_(isinstance(new_transforms.transform[1], ds.Transform))
self.assert_(new_transforms.transform[0].algorithm ==
ds.TRANSFORM_ENVELOPED)
self.assert_(new_transforms.transform[1].algorithm ==
ds.TRANSFORM_ENVELOPED)
self.assert_(new_transforms.transform[0].xpath[0].text.strip() == "xpath")
self.assert_(new_transforms.transform[1].xpath[0].text.strip() == "xpath")
class RetrievalMethodTest(unittest.TestCase):
def setUp(self):
self.retrieval_method = ds.RetrievalMethod()
def testAccessors(self):
"""Test for RetrievalMethod accessors"""
self.retrieval_method.uri = "http://www.sios.com/URI"
self.retrieval_method.type = "http://www.sios.com/Type"
self.retrieval_method.transforms.append(ds.TransformsFromString(
ds_test_data.TEST_TRANSFORMS))
new_retrieval_method = ds.RetrievalMethodFromString(
self.retrieval_method.ToString())
self.assert_(new_retrieval_method.uri == "http://www.sios.com/URI")
self.assert_(new_retrieval_method.type == "http://www.sios.com/Type")
self.assert_(isinstance(new_retrieval_method.transforms[0], ds.Transforms))
def testUsingTestData(self):
"""Test for RetrievalMethodFromString() using test data"""
new_retrieval_method = ds.RetrievalMethodFromString(
ds_test_data.TEST_RETRIEVAL_METHOD)
self.assert_(new_retrieval_method.uri == "http://www.sios.com/URI")
self.assert_(new_retrieval_method.type == "http://www.sios.com/Type")
self.assert_(isinstance(new_retrieval_method.transforms[0], ds.Transforms))
class RSAKeyValueTest(unittest.TestCase):
def setUp(self):
self.rsa_key_value = ds.RSAKeyValue()
def testAccessors(self):
"""Test for RSAKeyValue accessors"""
self.rsa_key_value.modulus = ds.Modulus(text="modulus")
self.rsa_key_value.exponent = ds.Exponent(text="exponent")
new_rsa_key_value = ds.RSAKeyValueFromString(self.rsa_key_value.ToString())
self.assert_(isinstance(new_rsa_key_value.modulus, ds.Modulus))
self.assert_(isinstance(new_rsa_key_value.exponent, ds.Exponent))
self.assert_(new_rsa_key_value.modulus.text.strip() == "modulus")
self.assert_(new_rsa_key_value.exponent.text.strip() == "exponent")
def testUsingTestData(self):
"""Test for RSAKeyValueFromString() using test data"""
new_rsa_key_value = ds.RSAKeyValueFromString(
ds_test_data.TEST_RSA_KEY_VALUE)
self.assert_(isinstance(new_rsa_key_value.modulus, ds.Modulus))
self.assert_(isinstance(new_rsa_key_value.exponent, ds.Exponent))
self.assert_(new_rsa_key_value.modulus.text.strip() == "modulus")
self.assert_(new_rsa_key_value.exponent.text.strip() == "exponent")
class DSAKeyValueTest(unittest.TestCase):
def setUp(self):
self.dsa_key_value = ds.DSAKeyValue()
def testAccessors(self):
"""Test for DSAKeyValue accessors"""
self.dsa_key_value.p = ds.P(text="p")
self.dsa_key_value.q = ds.Q(text="q")
self.dsa_key_value.g = ds.G(text="g")
self.dsa_key_value.y = ds.Y(text="y")
self.dsa_key_value.j = ds.J(text="j")
self.dsa_key_value.seed = ds.Seed(text="seed")
self.dsa_key_value.pgen_counter = ds.PgenCounter(text="pgen counter")
new_dsa_key_value = ds.DSAKeyValueFromString(self.dsa_key_value.ToString())
self.assert_(isinstance(new_dsa_key_value.p, ds.P))
self.assert_(isinstance(new_dsa_key_value.q, ds.Q))
self.assert_(isinstance(new_dsa_key_value.g, ds.G))
self.assert_(isinstance(new_dsa_key_value.y, ds.Y))
self.assert_(isinstance(new_dsa_key_value.j, ds.J))
self.assert_(isinstance(new_dsa_key_value.seed, ds.Seed))
self.assert_(isinstance(new_dsa_key_value.pgen_counter, ds.PgenCounter))
self.assert_(new_dsa_key_value.p.text.strip() == "p")
self.assert_(new_dsa_key_value.q.text.strip() == "q")
self.assert_(new_dsa_key_value.g.text.strip() == "g")
self.assert_(new_dsa_key_value.y.text.strip() == "y")
self.assert_(new_dsa_key_value.j.text.strip() == "j")
self.assert_(new_dsa_key_value.seed.text.strip() == "seed")
self.assert_(new_dsa_key_value.pgen_counter.text.strip() == "pgen counter")
def testUsingTestData(self):
"""Test for DSAKeyValueFromString() using test data"""
new_dsa_key_value = ds.DSAKeyValueFromString(
ds_test_data.TEST_DSA_KEY_VALUE)
self.assert_(isinstance(new_dsa_key_value.p, ds.P))
self.assert_(isinstance(new_dsa_key_value.q, ds.Q))
self.assert_(isinstance(new_dsa_key_value.g, ds.G))
self.assert_(isinstance(new_dsa_key_value.y, ds.Y))
self.assert_(isinstance(new_dsa_key_value.j, ds.J))
self.assert_(isinstance(new_dsa_key_value.seed, ds.Seed))
self.assert_(isinstance(new_dsa_key_value.pgen_counter, ds.PgenCounter))
self.assert_(new_dsa_key_value.p.text.strip() == "p")
self.assert_(new_dsa_key_value.q.text.strip() == "q")
self.assert_(new_dsa_key_value.g.text.strip() == "g")
self.assert_(new_dsa_key_value.y.text.strip() == "y")
self.assert_(new_dsa_key_value.j.text.strip() == "j")
self.assert_(new_dsa_key_value.seed.text.strip() == "seed")
self.assert_(new_dsa_key_value.pgen_counter.text.strip() == "pgen counter")
class KeyValueTest(unittest.TestCase):
def setUp(self):
self.key_value = ds.KeyValue()
def testAccessors(self):
"""Test for KeyValue accessors"""
self.key_value.dsa_key_value = ds.DSAKeyValueFromString(
ds_test_data.TEST_DSA_KEY_VALUE)
new_key_value = ds.KeyValueFromString(self.key_value.ToString())
self.assert_(isinstance(new_key_value.dsa_key_value, ds.DSAKeyValue))
self.key_value.dsa_key_value = None
self.key_value.rsa_key_value = ds.RSAKeyValueFromString(
ds_test_data.TEST_RSA_KEY_VALUE)
new_key_value = ds.KeyValueFromString(self.key_value.ToString())
self.assert_(isinstance(new_key_value.rsa_key_value, ds.RSAKeyValue))
def testUsingTestData(self):
"""Test for KeyValueFromString() using test data"""
new_key_value = ds.KeyValueFromString(ds_test_data.TEST_KEY_VALUE1)
self.assert_(isinstance(new_key_value.dsa_key_value, ds.DSAKeyValue))
self.key_value.dsa_key_value = None
self.key_value.rsa_key_value = ds.RSAKeyValueFromString(
ds_test_data.TEST_RSA_KEY_VALUE)
new_key_value = ds.KeyValueFromString(ds_test_data.TEST_KEY_VALUE2)
self.assert_(isinstance(new_key_value.rsa_key_value, ds.RSAKeyValue))
class KeyNameTest(unittest.TestCase):
def setUp(self):
self.key_name = ds.KeyName()
def testAccessors(self):
"""Test for KeyName accessors"""
self.key_name.text = "key name"
new_key_name = ds.KeyNameFromString(self.key_name.ToString())
self.assert_(new_key_name.text.strip() == "key name")
def testUsingTestData(self):
"""Test for KeyNameFromString() using test data"""
new_key_name = ds.KeyNameFromString(ds_test_data.TEST_KEY_NAME)
self.assert_(new_key_name.text.strip() == "key name")
class KeyInfoTest(unittest.TestCase):
def setUp(self):
self.key_info = ds.KeyInfo()
def testAccessors(self):
"""Test for KeyInfo accessors"""
self.key_info.key_name.append(
ds.KeyNameFromString(ds_test_data.TEST_KEY_NAME))
self.key_info.key_value.append(
ds.KeyValueFromString(ds_test_data.TEST_KEY_VALUE1))
self.key_info.retrieval_method.append(
ds.RetrievalMethodFromString(ds_test_data.TEST_RETRIEVAL_METHOD))
self.key_info.x509_data.append(
ds.X509DataFromString(ds_test_data.TEST_X509_DATA))
self.key_info.pgp_data.append(
ds.PGPDataFromString(ds_test_data.TEST_PGP_DATA))
self.key_info.spki_data.append(
ds.SPKIDataFromString(ds_test_data.TEST_SPKI_DATA))
self.key_info.mgmt_data.append(
ds.MgmtDataFromString(ds_test_data.TEST_MGMT_DATA))
self.key_info.id = "id"
new_key_info = ds.KeyInfoFromString(self.key_info.ToString())
self.assert_(isinstance(new_key_info.key_name[0], ds.KeyName))
self.assert_(isinstance(new_key_info.key_value[0], ds.KeyValue))
self.assert_(isinstance(new_key_info.retrieval_method[0],
ds.RetrievalMethod))
self.assert_(isinstance(new_key_info.x509_data[0], ds.X509Data))
self.assert_(isinstance(new_key_info.pgp_data[0], ds.PGPData))
self.assert_(isinstance(new_key_info.spki_data[0], ds.SPKIData))
self.assert_(isinstance(new_key_info.mgmt_data[0], ds.MgmtData))
self.assert_(new_key_info.id == "id")
def testUsingTestData(self):
"""Test for KeyInfoFromString() using test data"""
new_key_info = ds.KeyInfoFromString(ds_test_data.TEST_KEY_INFO)
self.assert_(isinstance(new_key_info.key_name[0], ds.KeyName))
self.assert_(isinstance(new_key_info.key_value[0], ds.KeyValue))
self.assert_(isinstance(new_key_info.retrieval_method[0],
ds.RetrievalMethod))
self.assert_(isinstance(new_key_info.x509_data[0], ds.X509Data))
self.assert_(isinstance(new_key_info.pgp_data[0], ds.PGPData))
self.assert_(isinstance(new_key_info.spki_data[0], ds.SPKIData))
self.assert_(isinstance(new_key_info.mgmt_data[0], ds.MgmtData))
self.assert_(new_key_info.id == "id")
class DigestValueTest(unittest.TestCase):
def setUp(self):
self.digest_value = ds.DigestValue()
def testAccessors(self):
"""Test for DigestValue accessors"""
self.digest_value.text = "digest value"
new_digest_value = ds.DigestValueFromString(self.digest_value.ToString())
self.assert_(new_digest_value.text.strip() == "digest value")
def testUsingTestData(self):
"""Test for DigestValueFromString() using test data"""
new_digest_value = ds.DigestValueFromString(ds_test_data.TEST_DIGEST_VALUE)
self.assert_(new_digest_value.text.strip() == "digest value")
class DigestMethodTest(unittest.TestCase):
def setUp(self):
self.digest_method = ds.DigestMethod()
def testAccessors(self):
"""Test for DigestMethod accessors"""
self.digest_method.algorithm = ds.DIGEST_SHA1
new_digest_method = ds.DigestMethodFromString(
self.digest_method.ToString())
self.assert_(new_digest_method.algorithm == ds.DIGEST_SHA1)
def testUsingTestData(self):
"""Test for DigestMethodFromString() using test data"""
new_digest_method = ds.DigestMethodFromString(
ds_test_data.TEST_DIGEST_METHOD)
self.assert_(new_digest_method.algorithm == ds.DIGEST_SHA1)
class ReferenceTest(unittest.TestCase):
def setUp(self):
self.reference = ds.Reference()
def testAccessors(self):
"""Test for Reference accessors"""
self.reference.transforms.append(ds.TransformsFromString(
ds_test_data.TEST_TRANSFORMS))
self.reference.digest_method.append(ds.DigestMethodFromString(
ds_test_data.TEST_DIGEST_METHOD))
self.reference.digest_value.append(ds.DigestValueFromString(
ds_test_data.TEST_DIGEST_VALUE))
self.reference.id = "id"
self.reference.uri = "http://www.sios.com/URI"
self.reference.type = "http://www.sios.com/Type"
new_reference = ds.ReferenceFromString(self.reference.ToString())
self.assert_(isinstance(new_reference.transforms[0], ds.Transforms))
self.assert_(isinstance(new_reference.digest_method[0], ds.DigestMethod))
self.assert_(isinstance(new_reference.digest_value[0], ds.DigestValue))
self.assert_(new_reference.id == "id")
self.assert_(new_reference.uri == "http://www.sios.com/URI")
self.assert_(new_reference.type == "http://www.sios.com/Type")
def testUsingTestData(self):
"""Test for ReferenceFromString() using test data"""
new_reference = ds.ReferenceFromString(ds_test_data.TEST_REFERENCE)
self.assert_(isinstance(new_reference.transforms[0], ds.Transforms))
self.assert_(isinstance(new_reference.digest_method[0], ds.DigestMethod))
self.assert_(isinstance(new_reference.digest_value[0], ds.DigestValue))
self.assert_(new_reference.id == "id")
self.assert_(new_reference.uri == "http://www.sios.com/URI")
self.assert_(new_reference.type == "http://www.sios.com/Type")
class SignatureMethodTest(unittest.TestCase):
def setUp(self):
self.signature_method = ds.SignatureMethod()
def testAccessors(self):
"""Test for SignatureMethod accessors"""
self.signature_method.algorithm = ds.SIG_RSA_SHA1
self.signature_method.hmac_output_length = ds.HMACOutputLength(text="8")
new_signature_method = ds.SignatureMethodFromString(
self.signature_method.ToString())
self.assert_(isinstance(new_signature_method.hmac_output_length,
ds.HMACOutputLength))
self.assert_(new_signature_method.hmac_output_length.text.strip() == "8")
self.assert_(new_signature_method.algorithm == ds.SIG_RSA_SHA1)
def testUsingTestData(self):
"""Test for SignatureMethodFromString() using test data"""
new_signature_method = ds.SignatureMethodFromString(
ds_test_data.TEST_SIGNATURE_METHOD)
self.assert_(isinstance(new_signature_method.hmac_output_length,
ds.HMACOutputLength))
self.assert_(new_signature_method.hmac_output_length.text.strip() == "8")
self.assert_(new_signature_method.algorithm == ds.SIG_RSA_SHA1)
class CanonicalizationMethodTest(unittest.TestCase):
def setUp(self):
self.canonicalization_method = ds.CanonicalizationMethod()
def testAccessors(self):
"""Test for CanonicalizationMethod accessors"""
self.canonicalization_method.algorithm = ds.C14N_WITH_C
new_canonicalization_method = ds.CanonicalizationMethodFromString(
self.canonicalization_method.ToString())
self.assert_(new_canonicalization_method.algorithm == ds.C14N_WITH_C)
def testUsingTestData(self):
"""Test for CanonicalizationMethodFromString() using test data"""
new_canonicalization_method = ds.CanonicalizationMethodFromString(
ds_test_data.TEST_CANONICALIZATION_METHOD)
self.assert_(new_canonicalization_method.algorithm == ds.C14N_WITH_C)
class SignedInfoTest(unittest.TestCase):
def setUp(self):
self.si = ds.SignedInfo()
def testAccessors(self):
"""Test for SignedInfo accessors"""
self.si.id = "id"
self.si.canonicalization_method = ds.CanonicalizationMethodFromString(
ds_test_data.TEST_CANONICALIZATION_METHOD)
self.si.signature_method = ds.SignatureMethodFromString(
ds_test_data.TEST_SIGNATURE_METHOD)
self.si.reference.append(ds.ReferenceFromString(
ds_test_data.TEST_REFERENCE))
new_si = ds.SignedInfoFromString(self.si.ToString())
self.assert_(new_si.id == "id")
self.assert_(isinstance(new_si.canonicalization_method,
ds.CanonicalizationMethod))
self.assert_(isinstance(new_si.signature_method, ds.SignatureMethod))
self.assert_(isinstance(new_si.reference[0], ds.Reference))
def testUsingTestData(self):
"""Test for SignedInfoFromString() using test data"""
new_si = ds.SignedInfoFromString(ds_test_data.TEST_SIGNED_INFO)
self.assert_(new_si.id == "id")
self.assert_(isinstance(new_si.canonicalization_method,
ds.CanonicalizationMethod))
self.assert_(isinstance(new_si.signature_method, ds.SignatureMethod))
self.assert_(isinstance(new_si.reference[0], ds.Reference))
class SignatureValueTest(unittest.TestCase):
def setUp(self):
self.signature_value = ds.SignatureValue()
def testAccessors(self):
"""Test for SignatureValue accessors"""
self.signature_value.id = "id"
self.signature_value.text = "signature value"
new_signature_value = ds.SignatureValueFromString(
self.signature_value.ToString())
self.assert_(new_signature_value.id == "id")
self.assert_(new_signature_value.text.strip() == "signature value")
def testUsingTestData(self):
"""Test for SignatureValueFromString() using test data"""
new_signature_value = ds.SignatureValueFromString(
ds_test_data.TEST_SIGNATURE_VALUE)
self.assert_(new_signature_value.id == "id")
self.assert_(new_signature_value.text.strip() == "signature value")
class SignatureTest(unittest.TestCase):
def setUp(self):
self.signature = ds.Signature()
def testAccessors(self):
"""Test for Signature accessors"""
self.signature.id = "id"
self.signature.signed_info = ds.SignedInfoFromString(
ds_test_data.TEST_SIGNED_INFO)
self.signature.signature_value = ds.SignatureValueFromString(
ds_test_data.TEST_SIGNATURE_VALUE)
self.signature.key_info = ds.KeyInfoFromString(ds_test_data.TEST_KEY_INFO)
self.signature.object.append(ds.ObjectFromString(ds_test_data.TEST_OBJECT))
new_signature = ds.SignatureFromString(self.signature.ToString())
self.assert_(new_signature.id == "id")
self.assert_(isinstance(new_signature.signed_info, ds.SignedInfo))
self.assert_(isinstance(new_signature.signature_value, ds.SignatureValue))
self.assert_(isinstance(new_signature.key_info, ds.KeyInfo))
self.assert_(isinstance(new_signature.object[0], ds.Object))
def testUsingTestData(self):
"""Test for SignatureValueFromString() using test data"""
new_signature = ds.SignatureFromString(ds_test_data.TEST_SIGNATURE)
self.assert_(new_signature.id == "id")
self.assert_(isinstance(new_signature.signed_info, ds.SignedInfo))
self.assert_(isinstance(new_signature.signature_value, ds.SignatureValue))
self.assert_(isinstance(new_signature.key_info, ds.KeyInfo))
self.assert_(isinstance(new_signature.object[0], ds.Object))
if __name__ == '__main__':
unittest.main()

1221
tests/md_test.py Normal file

File diff suppressed because it is too large Load Diff

933
tests/saml_test.py Normal file
View File

@@ -0,0 +1,933 @@
#!/usr/bin/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 saml2.saml"""
__author__ = 'tmatsuo@sios.com (Takashi MATSUO)'
import unittest
try:
from xml.etree import ElementTree
except ImportError:
from elementtree import ElementTree
import saml2
from saml2 import saml, test_data, ds_test_data
import xmldsig as ds
class NameIDTest(unittest.TestCase):
def setUp(self):
self.name_id = saml.NameID()
def testEmptyExtensionsList(self):
"""Test if NameID has empty extensions list"""
self.assert_(isinstance(self.name_id.extension_elements, list))
self.assert_(len(self.name_id.extension_elements) == 0)
def testFormatAttribute(self):
"""Test for Format attribute accessors"""
self.name_id.format = saml.NAMEID_FORMAT_EMAILADDRESS
self.assert_(self.name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS)
self.assert_(len(self.name_id.extension_elements) == 0)
new_name_id = saml.NameIDFromString(self.name_id.ToString())
self.assert_(len(new_name_id.extension_elements) == 0)
self.name_id.extension_elements.append(saml2.ExtensionElement(
'foo', text='bar'))
self.assert_(len(self.name_id.extension_elements) == 1)
self.assert_(self.name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS)
def testNameIDText(self):
"""Test text value of NameID element"""
self.name_id.text = "tmatsuo@sios.com"
self.assert_(self.name_id.text == "tmatsuo@sios.com")
def testSPProvidedID(self):
"""Test for SPProvidedID attribute accessors"""
self.name_id.sp_provided_id = "provided id"
self.assert_(self.name_id.sp_provided_id == "provided id")
def testEmptyNameIDToAndFromStringMatch(self):
"""Test NameIDFromString() with empty NameID"""
string_from_name_id = self.name_id.ToString()
new_name_id = saml.NameIDFromString(string_from_name_id)
string_from_new_name_id = new_name_id.ToString()
self.assert_(string_from_name_id == string_from_new_name_id)
def testNameIDToAndFromStringMatch(self):
"""Test NameIDFromString() with data"""
self.name_id.format = saml.NAMEID_FORMAT_EMAILADDRESS
self.name_id.text = "tmatsuo@sios.com"
self.name_id.name_qualifier = "name_qualifier"
self.name_id.sp_name_qualifier = "sp_name_qualifier"
string_from_name_id = self.name_id.ToString()
new_name_id = saml.NameIDFromString(string_from_name_id)
self.assert_(new_name_id.name_qualifier == "name_qualifier")
self.assert_(new_name_id.sp_name_qualifier == "sp_name_qualifier")
string_from_new_name_id = new_name_id.ToString()
self.assert_(string_from_name_id == string_from_new_name_id)
def testExtensionAttributes(self):
"""Test extension attributes"""
self.name_id.extension_attributes['hoge'] = 'fuga'
self.name_id.extension_attributes['moge'] = 'muga'
self.assert_(self.name_id.extension_attributes['hoge'] == 'fuga')
self.assert_(self.name_id.extension_attributes['moge'] == 'muga')
new_name_id = saml.NameIDFromString(self.name_id.ToString())
self.assert_(new_name_id.extension_attributes['hoge'] == 'fuga')
self.assert_(new_name_id.extension_attributes['moge'] == 'muga')
def testNameIDFromString(self):
"""Test NameIDFromString() using test data"""
name_id = saml.NameIDFromString(test_data.TEST_NAME_ID)
self.assert_(name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS)
self.assert_(name_id.text.strip() == "tmatsuo@sios.com")
self.assert_(name_id.sp_provided_id == "sp provided id")
class IssuerTest(unittest.TestCase):
def setUp(self):
self.issuer = saml.Issuer()
def testIssuerToAndFromString(self):
"""Test IssuerFromString()"""
self.issuer.text = "http://www.sios.com/test"
self.issuer.name_qualifier = "name_qualifier"
self.issuer.sp_name_qualifier = "sp_name_qualifier"
new_issuer = saml.IssuerFromString(self.issuer.ToString())
self.assert_(self.issuer.text == new_issuer.text)
self.assert_(self.issuer.name_qualifier == new_issuer.name_qualifier)
self.assert_(self.issuer.sp_name_qualifier == new_issuer.sp_name_qualifier)
self.assert_(self.issuer.extension_elements ==
new_issuer.extension_elements)
def testUsingTestData(self):
"""Test IssuerFromString() using test data"""
issuer = saml.IssuerFromString(test_data.TEST_ISSUER)
self.assert_(issuer.text.strip() == "http://www.sios.com/test")
new_issuer = saml.IssuerFromString(issuer.ToString())
self.assert_(issuer.text == new_issuer.text)
self.assert_(issuer.extension_elements ==
new_issuer.extension_elements)
class SubjectLocalityTest(unittest.TestCase):
def setUp(self):
self.subject_locality = saml.SubjectLocality()
def testAccessors(self):
"""Test for SubjectLocality accessors"""
self.subject_locality.address = "127.0.0.1"
self.subject_locality.dns_name = "localhost"
self.assert_(self.subject_locality.address == "127.0.0.1")
self.assert_(self.subject_locality.dns_name == "localhost")
new_subject_locality = saml.SubjectLocalityFromString(
self.subject_locality.ToString())
self.assert_(new_subject_locality.address == "127.0.0.1")
self.assert_(new_subject_locality.dns_name == "localhost")
def testUsingTestData(self):
"""Test SubjectLocalityFromString() using test data"""
subject_locality = saml.SubjectLocalityFromString(
test_data.TEST_SUBJECT_LOCALITY)
self.assert_(subject_locality.address == "127.0.0.1")
self.assert_(subject_locality.dns_name == "localhost")
new_subject_locality = saml.SubjectLocalityFromString(
subject_locality.ToString())
self.assert_(new_subject_locality.address == "127.0.0.1")
self.assert_(new_subject_locality.dns_name == "localhost")
self.assert_(subject_locality.ToString() ==
new_subject_locality.ToString())
class AuthnContextClassRefTest(unittest.TestCase):
def setUp(self):
self.authn_context_class_ref = saml.AuthnContextClassRef()
def testAccessors(self):
"""Test for AuthnContextClassRef accessors"""
self.authn_context_class_ref.text = (
"http://www.sios.com/authnContextClassRef")
self.assert_(self.authn_context_class_ref.text ==
"http://www.sios.com/authnContextClassRef")
new_authn_context_class_ref = saml.AuthnContextClassRefFromString(
self.authn_context_class_ref.ToString())
self.assert_(new_authn_context_class_ref.text ==
"http://www.sios.com/authnContextClassRef")
self.assert_(self.authn_context_class_ref.ToString() ==
new_authn_context_class_ref.ToString())
def testUsingTestData(self):
"""Test AuthnContextClassRefFromString() using test data"""
authn_context_class_ref = saml.AuthnContextClassRefFromString(
test_data.TEST_AUTHN_CONTEXT_CLASS_REF)
self.assert_(authn_context_class_ref.text.strip() ==
"http://www.sios.com/authnContextClassRef")
class AuthnContextDeclRefTest(unittest.TestCase):
def setUp(self):
self.authn_context_decl_ref = saml.AuthnContextDeclRef()
def testAccessors(self):
"""Test for AuthnContextDeclRef accessors"""
self.authn_context_decl_ref.text = (
"http://www.sios.com/authnContextDeclRef")
self.assert_(self.authn_context_decl_ref.text ==
"http://www.sios.com/authnContextDeclRef")
new_authn_context_decl_ref = saml.AuthnContextDeclRefFromString(
self.authn_context_decl_ref.ToString())
self.assert_(new_authn_context_decl_ref.text ==
"http://www.sios.com/authnContextDeclRef")
self.assert_(self.authn_context_decl_ref.ToString() ==
new_authn_context_decl_ref.ToString())
def testUsingTestData(self):
"""Test AuthnContextDeclRefFromString() using test data"""
authn_context_decl_ref = saml.AuthnContextDeclRefFromString(
test_data.TEST_AUTHN_CONTEXT_DECL_REF)
self.assert_(authn_context_decl_ref.text.strip() ==
"http://www.sios.com/authnContextDeclRef")
class AuthnContextDeclTest(unittest.TestCase):
def setUp(self):
self.authn_context_decl = saml.AuthnContextDecl()
def testAccessors(self):
"""Test for AuthnContextDecl accessors"""
self.authn_context_decl.text = (
"http://www.sios.com/authnContextDecl")
self.assert_(self.authn_context_decl.text ==
"http://www.sios.com/authnContextDecl")
new_authn_context_decl = saml.AuthnContextDeclFromString(
self.authn_context_decl.ToString())
self.assert_(new_authn_context_decl.text ==
"http://www.sios.com/authnContextDecl")
self.assert_(self.authn_context_decl.ToString() ==
new_authn_context_decl.ToString())
def testUsingTestData(self):
"""Test AuthnContextDeclFromString() using test data"""
authn_context_decl = saml.AuthnContextDeclFromString(
test_data.TEST_AUTHN_CONTEXT_DECL)
self.assert_(authn_context_decl.text.strip() ==
"http://www.sios.com/authnContextDecl")
class AuthenticatingAuthorityTest(unittest.TestCase):
def setUp(self):
self.authenticating_authority = saml.AuthenticatingAuthority()
def testAccessors(self):
"""Test for AuthenticatingAuthority accessors"""
self.authenticating_authority.text = (
"http://www.sios.com/authenticatingAuthority")
self.assert_(self.authenticating_authority.text ==
"http://www.sios.com/authenticatingAuthority")
new_authenticating_authority = saml.AuthenticatingAuthorityFromString(
self.authenticating_authority.ToString())
self.assert_(new_authenticating_authority.text ==
"http://www.sios.com/authenticatingAuthority")
self.assert_(self.authenticating_authority.ToString() ==
new_authenticating_authority.ToString())
def testUsingTestData(self):
"""Test AuthenticatingAuthorityFromString() using test data"""
authenticating_authority = saml.AuthenticatingAuthorityFromString(
test_data.TEST_AUTHENTICATING_AUTHORITY)
self.assert_(authenticating_authority.text.strip() ==
"http://www.sios.com/authenticatingAuthority")
class AuthnContextTest(unittest.TestCase):
def setUp(self):
self.authn_context = saml.AuthnContext()
def testAccessors(self):
"""Test for AuthnContext accessors"""
self.authn_context.authn_context_class_ref = \
saml.AuthnContextClassRefFromString(
test_data.TEST_AUTHN_CONTEXT_CLASS_REF)
self.authn_context.authn_context_decl_ref = \
saml.AuthnContextDeclRefFromString(
test_data.TEST_AUTHN_CONTEXT_DECL_REF)
self.authn_context.authn_context_decl = \
saml.AuthnContextDeclFromString(
test_data.TEST_AUTHN_CONTEXT_DECL)
self.authn_context.authenticating_authority.append(
saml.AuthenticatingAuthorityFromString(
test_data.TEST_AUTHENTICATING_AUTHORITY))
self.assert_(self.authn_context.authn_context_class_ref.text.strip() ==
"http://www.sios.com/authnContextClassRef")
self.assert_(self.authn_context.authn_context_decl_ref.text.strip() ==
"http://www.sios.com/authnContextDeclRef")
self.assert_(self.authn_context.authn_context_decl.text.strip() ==
"http://www.sios.com/authnContextDecl")
self.assert_(self.authn_context.authenticating_authority[0].text.strip() ==
"http://www.sios.com/authenticatingAuthority")
new_authn_context = saml.AuthnContextFromString(
self.authn_context.ToString())
self.assert_(self.authn_context.ToString() == new_authn_context.ToString())
def testUsingTestData(self):
"""Test AuthnContextFromString() using test data"""
authn_context = saml.AuthnContextFromString(test_data.TEST_AUTHN_CONTEXT)
self.assert_(authn_context.authn_context_class_ref.text.strip() ==
saml.URN_PASSWORD)
class AuthnStatementTest(unittest.TestCase):
def setUp(self):
self.as = saml.AuthnStatement()
def testAccessors(self):
"""Test for AuthnStatement accessors"""
self.as.authn_instant = "2007-08-31T01:05:02Z"
self.as.session_not_on_or_after = "2007-09-14T01:05:02Z"
self.as.session_index = "sessionindex"
self.as.authn_context = saml.AuthnContext()
self.as.authn_context.authn_context_class_ref = \
saml.AuthnContextClassRefFromString(
test_data.TEST_AUTHN_CONTEXT_CLASS_REF)
self.as.authn_context.authn_context_decl_ref = \
saml.AuthnContextDeclRefFromString(
test_data.TEST_AUTHN_CONTEXT_DECL_REF)
self.as.authn_context.authn_context_decl = \
saml.AuthnContextDeclFromString(
test_data.TEST_AUTHN_CONTEXT_DECL)
self.as.authn_context.authenticating_authority.append(
saml.AuthenticatingAuthorityFromString(
test_data.TEST_AUTHENTICATING_AUTHORITY))
new_as = saml.AuthnStatementFromString(self.as.ToString())
self.assert_(new_as.authn_instant == "2007-08-31T01:05:02Z")
self.assert_(new_as.session_index == "sessionindex")
self.assert_(new_as.session_not_on_or_after == "2007-09-14T01:05:02Z")
self.assert_(new_as.authn_context.authn_context_class_ref.text.strip() ==
"http://www.sios.com/authnContextClassRef")
self.assert_(new_as.authn_context.authn_context_decl_ref.text.strip() ==
"http://www.sios.com/authnContextDeclRef")
self.assert_(new_as.authn_context.authn_context_decl.text.strip() ==
"http://www.sios.com/authnContextDecl")
self.assert_(new_as.authn_context.authenticating_authority[0].text.strip()
== "http://www.sios.com/authenticatingAuthority")
self.assert_(self.as.ToString() == new_as.ToString())
def testUsingTestData(self):
"""Test AuthnStatementFromString() using test data"""
as = saml.AuthnStatementFromString(test_data.TEST_AUTHN_STATEMENT)
self.assert_(as.authn_instant == "2007-08-31T01:05:02Z")
self.assert_(as.session_not_on_or_after == "2007-09-14T01:05:02Z")
self.assert_(as.authn_context.authn_context_class_ref.text.strip() ==
saml.URN_PASSWORD)
class AttributeValueTest(unittest.TestCase):
def setUp(self):
self.attribute_value = saml.AttributeValue()
def testAccessors(self):
"""Test for AttributeValue accessors"""
self.attribute_value.text = "value for test attribute"
new_attribute_value = saml.AttributeValueFromString(
self.attribute_value.ToString())
self.assert_(new_attribute_value.text.strip() ==
"value for test attribute")
def testUsingTestData(self):
"""Test AttributeValueFromString() using test data"""
attribute_value = saml.AttributeValueFromString(
test_data.TEST_ATTRIBUTE_VALUE)
self.assert_(attribute_value.text.strip() == "value for test attribute")
class AttributeTest(unittest.TestCase):
def setUp(self):
self.attribute = saml.Attribute()
def testAccessors(self):
"""Test for Attribute accessors"""
self.attribute.name = "testAttribute"
self.attribute.name_format = saml.NAME_FORMAT_URI
self.attribute.friendly_name = "test attribute"
self.attribute.attribute_value.append(saml.AttributeValue())
self.attribute.attribute_value[0].text = "value of test attribute"
new_attribute = saml.AttributeFromString(self.attribute.ToString())
self.assert_(new_attribute.name == "testAttribute")
self.assert_(new_attribute.name_format == saml.NAME_FORMAT_URI)
self.assert_(new_attribute.friendly_name == "test attribute")
self.assert_(new_attribute.attribute_value[0].text.strip() ==
"value of test attribute")
def testUsingTestData(self):
"""Test AttributeFromString() using test data"""
attribute = saml.AttributeFromString(test_data.TEST_ATTRIBUTE)
self.assert_(attribute.name == "testAttribute")
self.assert_(attribute.name_format == saml.NAME_FORMAT_UNSPECIFIED)
self.assert_(attribute.friendly_name == "test attribute")
self.assert_(attribute.attribute_value[0].text.strip() ==
"value1 of test attribute")
self.assert_(attribute.attribute_value[1].text.strip() ==
"value2 of test attribute")
# test again
attribute = saml.AttributeFromString(attribute.ToString())
self.assert_(attribute.name == "testAttribute")
self.assert_(attribute.name_format == saml.NAME_FORMAT_UNSPECIFIED)
self.assert_(attribute.friendly_name == "test attribute")
self.assert_(attribute.attribute_value[0].text.strip() ==
"value1 of test attribute")
self.assert_(attribute.attribute_value[1].text.strip() ==
"value2 of test attribute")
class AttributeStatementTest(unittest.TestCase):
def setUp(self):
self.as = saml.AttributeStatement()
def testAccessors(self):
"""Test for Attribute accessors"""
self.as.attribute.append(saml.Attribute())
self.as.attribute.append(saml.Attribute())
self.as.attribute[0].name = "testAttribute"
self.as.attribute[0].name_format = saml.NAME_FORMAT_URI
self.as.attribute[0].friendly_name = "test attribute"
self.as.attribute[0].attribute_value.append(saml.AttributeValue())
self.as.attribute[0].attribute_value[0].text = "value of test attribute"
self.as.attribute[1].name = "testAttribute2"
self.as.attribute[1].name_format = saml.NAME_FORMAT_UNSPECIFIED
self.as.attribute[1].friendly_name = "test attribute2"
self.as.attribute[1].attribute_value.append(saml.AttributeValue())
self.as.attribute[1].attribute_value[0].text = "value2 of test attribute"
new_as = saml.AttributeStatementFromString(self.as.ToString())
self.assert_(new_as.attribute[0].name == "testAttribute")
self.assert_(new_as.attribute[0].name_format == saml.NAME_FORMAT_URI)
self.assert_(new_as.attribute[0].friendly_name == "test attribute")
self.assert_(new_as.attribute[0].attribute_value[0].text.strip() ==
"value of test attribute")
self.assert_(new_as.attribute[1].name == "testAttribute2")
self.assert_(new_as.attribute[1].name_format ==
saml.NAME_FORMAT_UNSPECIFIED)
self.assert_(new_as.attribute[1].friendly_name == "test attribute2")
self.assert_(new_as.attribute[1].attribute_value[0].text.strip() ==
"value2 of test attribute")
def testUsingTestData(self):
"""Test AttributeStatementFromString() using test data"""
as = saml.AttributeStatementFromString(test_data.TEST_ATTRIBUTE_STATEMENT)
self.assert_(as.attribute[0].name == "testAttribute")
self.assert_(as.attribute[0].name_format == saml.NAME_FORMAT_UNSPECIFIED)
self.assert_(as.attribute[0].friendly_name == "test attribute")
self.assert_(as.attribute[0].attribute_value[0].text.strip() ==
"value1 of test attribute")
self.assert_(as.attribute[0].attribute_value[1].text.strip() ==
"value2 of test attribute")
self.assert_(as.attribute[1].name == "http://www.sios.com/testAttribute2")
self.assert_(as.attribute[1].name_format == saml.NAME_FORMAT_URI)
self.assert_(as.attribute[1].friendly_name == "test attribute2")
self.assert_(as.attribute[1].attribute_value[0].text.strip() ==
"value1 of test attribute2")
self.assert_(as.attribute[1].attribute_value[1].text.strip() ==
"value2 of test attribute2")
# test again
as = saml.AttributeStatementFromString(as.ToString())
self.assert_(as.attribute[0].name == "testAttribute")
self.assert_(as.attribute[0].name_format == saml.NAME_FORMAT_UNSPECIFIED)
self.assert_(as.attribute[0].friendly_name == "test attribute")
self.assert_(as.attribute[0].attribute_value[0].text.strip() ==
"value1 of test attribute")
self.assert_(as.attribute[0].attribute_value[1].text.strip() ==
"value2 of test attribute")
self.assert_(as.attribute[1].name == "http://www.sios.com/testAttribute2")
self.assert_(as.attribute[1].name_format == saml.NAME_FORMAT_URI)
self.assert_(as.attribute[1].friendly_name == "test attribute2")
self.assert_(as.attribute[1].attribute_value[0].text.strip() ==
"value1 of test attribute2")
self.assert_(as.attribute[1].attribute_value[1].text.strip() ==
"value2 of test attribute2")
class SubjectConfirmationDataTest(unittest.TestCase):
def setUp(self):
self.scd = saml.SubjectConfirmationData()
def testAccessors(self):
"""Test for SubjectConfirmationData accessors"""
self.scd.not_before = "2007-08-31T01:05:02Z"
self.scd.not_on_or_after = "2007-09-14T01:05:02Z"
self.scd.recipient = "recipient"
self.scd.in_response_to = "responseID"
self.scd.address = "127.0.0.1"
new_scd = saml.SubjectConfirmationDataFromString(self.scd.ToString())
self.assert_(new_scd.not_before == "2007-08-31T01:05:02Z")
self.assert_(new_scd.not_on_or_after == "2007-09-14T01:05:02Z")
self.assert_(new_scd.recipient == "recipient")
self.assert_(new_scd.in_response_to == "responseID")
self.assert_(new_scd.address == "127.0.0.1")
def testUsingTestData(self):
"""Test SubjectConfirmationDataFromString() using test data"""
scd = saml.SubjectConfirmationDataFromString(
test_data.TEST_SUBJECT_CONFIRMATION_DATA)
self.assert_(scd.not_before == "2007-08-31T01:05:02Z")
self.assert_(scd.not_on_or_after == "2007-09-14T01:05:02Z")
self.assert_(scd.recipient == "recipient")
self.assert_(scd.in_response_to == "responseID")
self.assert_(scd.address == "127.0.0.1")
class SubjectConfirmationTest(unittest.TestCase):
def setUp(self):
self.sc = saml.SubjectConfirmation()
def testAccessors(self):
"""Test for SubjectConfirmation accessors"""
self.sc.name_id = saml.NameIDFromString(test_data.TEST_NAME_ID)
self.sc.method = saml.SUBJECT_CONFIRMATION_METHOD_BEARER
self.sc.subject_confirmation_data = saml.SubjectConfirmationDataFromString(
test_data.TEST_SUBJECT_CONFIRMATION_DATA)
new_sc = saml.SubjectConfirmationFromString(self.sc.ToString())
self.assert_(new_sc.name_id.sp_provided_id == "sp provided id")
self.assert_(new_sc.method == saml.SUBJECT_CONFIRMATION_METHOD_BEARER)
self.assert_(new_sc.subject_confirmation_data.not_before ==
"2007-08-31T01:05:02Z")
self.assert_(new_sc.subject_confirmation_data.not_on_or_after ==
"2007-09-14T01:05:02Z")
self.assert_(new_sc.subject_confirmation_data.recipient == "recipient")
self.assert_(new_sc.subject_confirmation_data.in_response_to ==
"responseID")
self.assert_(new_sc.subject_confirmation_data.address == "127.0.0.1")
def testUsingTestData(self):
"""Test SubjectConfirmationFromString() using test data"""
sc = saml.SubjectConfirmationFromString(
test_data.TEST_SUBJECT_CONFIRMATION)
self.assert_(sc.name_id.sp_provided_id == "sp provided id")
self.assert_(sc.method == saml.SUBJECT_CONFIRMATION_METHOD_BEARER)
self.assert_(sc.subject_confirmation_data.not_before ==
"2007-08-31T01:05:02Z")
self.assert_(sc.subject_confirmation_data.not_on_or_after ==
"2007-09-14T01:05:02Z")
self.assert_(sc.subject_confirmation_data.recipient == "recipient")
self.assert_(sc.subject_confirmation_data.in_response_to ==
"responseID")
self.assert_(sc.subject_confirmation_data.address == "127.0.0.1")
class SubjectTest(unittest.TestCase):
def setUp(self):
self.subject = saml.Subject()
def testAccessors(self):
"""Test for Subject accessors"""
self.subject.name_id = saml.NameIDFromString(test_data.TEST_NAME_ID)
self.subject.subject_confirmation.append(
saml.SubjectConfirmationFromString(
test_data.TEST_SUBJECT_CONFIRMATION))
new_subject = saml.SubjectFromString(self.subject.ToString())
self.assert_(new_subject.name_id.sp_provided_id == "sp provided id")
self.assert_(new_subject.name_id.text.strip() == "tmatsuo@sios.com")
self.assert_(new_subject.name_id.format ==
saml.NAMEID_FORMAT_EMAILADDRESS)
self.assert_(isinstance(new_subject.subject_confirmation[0],
saml.SubjectConfirmation))
def testUsingTestData(self):
"""Test for SubjectFromString() using test data."""
subject = saml.SubjectFromString(test_data.TEST_SUBJECT)
self.assert_(subject.name_id.sp_provided_id == "sp provided id")
self.assert_(subject.name_id.text.strip() == "tmatsuo@sios.com")
self.assert_(subject.name_id.format ==
saml.NAMEID_FORMAT_EMAILADDRESS)
self.assert_(isinstance(subject.subject_confirmation[0],
saml.SubjectConfirmation))
class ConditionTest(unittest.TestCase):
def setUp(self):
self.condition = saml.Condition()
def testAccessors(self):
"""Test for Condition accessors."""
self.condition.extension_attributes["{%s}type" % saml.XSI_NAMESPACE] = \
"test"
self.condition.extension_attributes['ExtendedAttribute'] = "value"
new_condition = saml.ConditionFromString(self.condition.ToString())
self.assert_(
new_condition.extension_attributes["{%s}type" % saml.XSI_NAMESPACE] ==
"test")
self.assert_(new_condition.extension_attributes["ExtendedAttribute"] ==
"value")
def testUsingTestData(self):
"""Test for ConditionFromString() using test data."""
condition = saml.ConditionFromString(test_data.TEST_CONDITION)
self.assert_(
condition.extension_attributes["{%s}type" % saml.XSI_NAMESPACE] ==
"test")
self.assert_(condition.extension_attributes["ExtendedAttribute"] ==
"value")
class AudienceTest(unittest.TestCase):
def setUp(self):
self.audience = saml.Audience()
def testAccessors(self):
"""Test for Audience accessors"""
self.audience.text = "http://www.sios.com/Audience"
new_audience = saml.AudienceFromString(self.audience.ToString())
self.assert_(new_audience.text.strip() == "http://www.sios.com/Audience")
def testUsingTestData(self):
"""Test AudienceFromString using test data"""
audience = saml.AudienceFromString(test_data.TEST_AUDIENCE)
self.assert_(audience.text.strip() == "http://www.sios.com/Audience")
class AudienceRestrictionTest(unittest.TestCase):
def setUp(self):
self.audience_restriction = saml.AudienceRestriction()
def testAccessors(self):
"""Test for AudienceRestriction accessors"""
self.audience_restriction.audience = saml.AudienceFromString(
test_data.TEST_AUDIENCE)
new_audience = saml.AudienceRestrictionFromString(
self.audience_restriction.ToString())
self.assert_(self.audience_restriction.audience.text.strip() ==
"http://www.sios.com/Audience")
def testUsingTestData(self):
"""Test AudienceRestrictionFromString using test data"""
audience_restriction = saml.AudienceRestrictionFromString(
test_data.TEST_AUDIENCE_RESTRICTION)
self.assert_(audience_restriction.audience.text.strip() ==
"http://www.sios.com/Audience")
class OneTimeUseTest(unittest.TestCase):
def setUp(self):
self.one_time_use = saml.OneTimeUse()
def testAccessors(self):
"""Test for OneTimeUse accessors"""
self.assert_(isinstance(self.one_time_use, saml.OneTimeUse))
self.assert_(isinstance(self.one_time_use, saml.Condition))
def testUsingTestData(self):
"""Test OneTimeUseFromString() using test data"""
one_time_use = saml.OneTimeUseFromString(test_data.TEST_ONE_TIME_USE)
self.assert_(isinstance(one_time_use, saml.OneTimeUse))
self.assert_(isinstance(one_time_use, saml.Condition))
class ProxyRestrictionTest(unittest.TestCase):
def setUp(self):
self.proxy_restriction = saml.ProxyRestriction()
def testAccessors(self):
"""Test for ProxyRestriction accessors"""
self.assert_(isinstance(self.proxy_restriction, saml.Condition))
self.proxy_restriction.count = "2"
self.proxy_restriction.audience.append(saml.AudienceFromString(
test_data.TEST_AUDIENCE))
new_proxy_restriction = saml.ProxyRestrictionFromString(
self.proxy_restriction.ToString())
self.assert_(new_proxy_restriction.count == "2")
self.assert_(new_proxy_restriction.audience[0].text.strip() ==
"http://www.sios.com/Audience")
def testUsingTestData(self):
"""Test ProxyRestrictionFromString() using test data"""
proxy_restriction = saml.ProxyRestrictionFromString(
test_data.TEST_PROXY_RESTRICTION)
self.assert_(proxy_restriction.count == "2")
self.assert_(proxy_restriction.audience[0].text.strip() ==
"http://www.sios.com/Audience")
class ConditionsTest(unittest.TestCase):
def setUp(self):
self.conditions = saml.Conditions()
def testAccessors(self):
"""Test for Conditions accessors"""
self.conditions.not_before = "2007-08-31T01:05:02Z"
self.conditions.not_on_or_after = "2007-09-14T01:05:02Z"
self.conditions.condition.append(saml.Condition())
self.conditions.audience_restriction.append(saml.AudienceRestriction())
self.conditions.one_time_use.append(saml.OneTimeUse())
self.conditions.proxy_restriction.append(saml.ProxyRestriction())
new_conditions = saml.ConditionsFromString(self.conditions.ToString())
self.assert_(new_conditions.not_before == "2007-08-31T01:05:02Z")
self.assert_(new_conditions.not_on_or_after == "2007-09-14T01:05:02Z")
self.assert_(isinstance(new_conditions.condition[0], saml.Condition))
self.assert_(isinstance(new_conditions.audience_restriction[0],
saml.AudienceRestriction))
self.assert_(isinstance(new_conditions.one_time_use[0],
saml.OneTimeUse))
self.assert_(isinstance(new_conditions.proxy_restriction[0],
saml.ProxyRestriction))
def testUsingTestData(self):
"""Test ConditionsFromString() using test data"""
new_conditions = saml.ConditionsFromString(test_data.TEST_CONDITIONS)
self.assert_(new_conditions.not_before == "2007-08-31T01:05:02Z")
self.assert_(new_conditions.not_on_or_after == "2007-09-14T01:05:02Z")
self.assert_(isinstance(new_conditions.condition[0], saml.Condition))
self.assert_(isinstance(new_conditions.audience_restriction[0],
saml.AudienceRestriction))
self.assert_(isinstance(new_conditions.one_time_use[0],
saml.OneTimeUse))
self.assert_(isinstance(new_conditions.proxy_restriction[0],
saml.ProxyRestriction))
class AssertionIDRefTest(unittest.TestCase):
def setUp(self):
self.assertion_id_ref = saml.AssertionIDRef()
def testAccessors(self):
"""Test for AssertionIDRef accessors"""
self.assertion_id_ref.text = "zzlieajngjbkjggjldmgindkckkolcblndbghlhm"
new_assertion_id_ref = saml.AssertionIDRefFromString(
self.assertion_id_ref.ToString())
self.assert_(new_assertion_id_ref.text ==
"zzlieajngjbkjggjldmgindkckkolcblndbghlhm")
def testUsingTestData(self):
"""Test AssertionIDRefFromString() using test data"""
new_assertion_id_ref = saml.AssertionIDRefFromString(
test_data.TEST_ASSERTION_ID_REF)
self.assert_(new_assertion_id_ref.text.strip() ==
"zzlieajngjbkjggjldmgindkckkolcblndbghlhm")
class AssertionURIRefTest(unittest.TestCase):
def setUp(self):
self.assertion_uri_ref = saml.AssertionURIRef()
def testAccessors(self):
"""Test for AssertionURIRef accessors"""
self.assertion_uri_ref.text = "http://www.sios.com/AssertionURIRef"
new_assertion_uri_ref = saml.AssertionURIRefFromString(
self.assertion_uri_ref.ToString())
self.assert_(new_assertion_uri_ref.text ==
"http://www.sios.com/AssertionURIRef")
def testUsingTestData(self):
"""Test AssertionURIRefFromString() using test data"""
new_assertion_uri_ref = saml.AssertionURIRefFromString(
test_data.TEST_ASSERTION_URI_REF)
self.assert_(new_assertion_uri_ref.text.strip() ==
"http://www.sios.com/AssertionURIRef")
class ActionTest(unittest.TestCase):
def setUp(self):
self.action = saml.Action()
def testAccessors(self):
"""Test for Action accessors"""
self.action.namespace = "http://www.sios.com/Namespace"
new_action = saml.ActionFromString(self.action.ToString())
self.assert_(new_action.namespace == "http://www.sios.com/Namespace")
def testUsingTestData(self):
"""Test ActionFromString() using test data"""
new_action = saml.ActionFromString(test_data.TEST_ACTION)
self.assert_(new_action.namespace == "http://www.sios.com/Namespace")
class EvidenceTest(unittest.TestCase):
def setUp(self):
self.evidence = saml.Evidence()
def testAccessors(self):
"""Test for Evidence accessors"""
self.evidence.assertion_id_ref.append(saml.AssertionIDRef())
self.evidence.assertion_uri_ref.append(saml.AssertionURIRef())
self.evidence.assertion.append(saml.Assertion())
self.evidence.encrypted_assertion.append(saml.EncryptedAssertion())
new_evidence = saml.EvidenceFromString(self.evidence.ToString())
self.assert_(self.evidence.ToString() == new_evidence.ToString())
self.assert_(isinstance(new_evidence.assertion_id_ref[0],
saml.AssertionIDRef))
self.assert_(isinstance(new_evidence.assertion_uri_ref[0],
saml.AssertionURIRef))
self.assert_(isinstance(new_evidence.assertion[0], saml.Assertion))
self.assert_(isinstance(new_evidence.encrypted_assertion[0],
saml.EncryptedAssertion))
def testUsingTestData(self):
"""Test EvidenceFromString() using test data"""
# TODO:
pass
class AuthzDecisionStatementTest(unittest.TestCase):
def setUp(self):
self.authz_decision_statement = saml.AuthzDecisionStatement()
def testAccessors(self):
"""Test for AuthzDecisionStatement accessors"""
self.authz_decision_statement.resource = "http://www.sios.com/Resource"
self.authz_decision_statement.decision = saml.DECISION_TYPE_PERMIT
self.authz_decision_statement.action.append(saml.Action())
self.authz_decision_statement.evidence.append(saml.Evidence())
new_authz_decision_statement = saml.AuthzDecisionStatementFromString(
self.authz_decision_statement.ToString())
self.assert_(self.authz_decision_statement.ToString() ==
new_authz_decision_statement.ToString())
self.assert_(new_authz_decision_statement.resource ==
"http://www.sios.com/Resource")
self.assert_(new_authz_decision_statement.decision ==
saml.DECISION_TYPE_PERMIT)
self.assert_(isinstance(new_authz_decision_statement.action[0],
saml.Action))
self.assert_(isinstance(new_authz_decision_statement.evidence[0],
saml.Evidence))
def testUsingTestData(self):
"""Test AuthzDecisionStatementFromString() using test data"""
# TODO:
pass
class AdviceTest(unittest.TestCase):
def setUp(self):
self.advice = saml.Advice()
def testAccessors(self):
"""Test for Advice accessors"""
self.advice.assertion_id_ref.append(saml.AssertionIDRef())
self.advice.assertion_uri_ref.append(saml.AssertionURIRef())
self.advice.assertion.append(saml.Assertion())
self.advice.encrypted_assertion.append(saml.EncryptedAssertion())
new_advice = saml.AdviceFromString(self.advice.ToString())
self.assert_(self.advice.ToString() == new_advice.ToString())
self.assert_(isinstance(new_advice.assertion_id_ref[0],
saml.AssertionIDRef))
self.assert_(isinstance(new_advice.assertion_uri_ref[0],
saml.AssertionURIRef))
self.assert_(isinstance(new_advice.assertion[0], saml.Assertion))
self.assert_(isinstance(new_advice.encrypted_assertion[0],
saml.EncryptedAssertion))
def testUsingTestData(self):
"""Test AdviceFromString() using test data"""
# TODO:
pass
class AssertionTest(unittest.TestCase):
def setUp(self):
self.assertion = saml.Assertion()
def testAccessors(self):
"""Test for Assertion accessors"""
self.assertion.id = "assertion id"
self.assertion.version = saml.V2
self.assertion.issue_instant = "2007-08-31T01:05:02Z"
self.assertion.issuer = saml.IssuerFromString(test_data.TEST_ISSUER)
self.assertion.signature = ds.SignatureFromString(
ds_test_data.TEST_SIGNATURE)
self.assertion.subject = saml.SubjectFromString(test_data.TEST_SUBJECT)
self.assertion.conditions = saml.ConditionsFromString(
test_data.TEST_CONDITIONS)
self.assertion.advice = saml.Advice()
self.assertion.statement.append(saml.Statement())
self.assertion.authn_statement.append(saml.AuthnStatementFromString(
test_data.TEST_AUTHN_STATEMENT))
self.assertion.authz_decision_statement.append(
saml.AuthzDecisionStatement())
self.assertion.attribute_statement.append(
saml.AttributeStatementFromString(
test_data.TEST_ATTRIBUTE_STATEMENT))
new_assertion = saml.AssertionFromString(self.assertion.ToString())
self.assert_(new_assertion.id == "assertion id")
self.assert_(new_assertion.version == saml.V2)
self.assert_(new_assertion.issue_instant == "2007-08-31T01:05:02Z")
self.assert_(isinstance(new_assertion.issuer, saml.Issuer))
self.assert_(isinstance(new_assertion.signature, ds.Signature))
self.assert_(isinstance(new_assertion.subject, saml.Subject))
self.assert_(isinstance(new_assertion.conditions, saml.Conditions))
self.assert_(isinstance(new_assertion.advice, saml.Advice))
self.assert_(isinstance(new_assertion.statement[0], saml.Statement))
self.assert_(isinstance(new_assertion.authn_statement[0],
saml.AuthnStatement))
self.assert_(isinstance(new_assertion.authz_decision_statement[0],
saml.AuthzDecisionStatement))
self.assert_(isinstance(new_assertion.attribute_statement[0],
saml.AttributeStatement))
def testUsingTestData(self):
"""Test AssertionFromString() using test data"""
# TODO
pass
if __name__ == '__main__':
unittest.main()

535
tests/samlp_test.py Normal file
View File

@@ -0,0 +1,535 @@
#!/usr/bin/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 saml2.samlp"""
__author__ = 'tmatsuo@sios.com (Takashi MATSUO)'
import unittest
try:
from xml.etree import ElementTree
except ImportError:
from elementtree import ElementTree
import saml2
from saml2 import saml, samlp, test_data, ds_test_data, samlp_test_data
import xmldsig as ds
class AbstractRequestTest(unittest.TestCase):
def setUp(self):
self.ar = samlp.AbstractRequest()
def testAccessors(self):
"""Test for AbstractRequest accessors"""
self.ar.id = "request id"
self.ar.version = saml.V2
self.ar.issue_instant = "2007-09-14T01:05:02Z"
self.ar.destination = "http://www.sios.com/Destination"
self.ar.consent = saml.CONSENT_UNSPECIFIED
self.ar.issuer = saml.Issuer()
self.ar.signature = ds.GetEmptySignature()
self.ar.extensions = samlp.Extensions()
new_ar = samlp.AbstractRequestFromString(self.ar.ToString())
self.assert_(new_ar.id == "request id")
self.assert_(new_ar.version == saml.V2)
self.assert_(new_ar.issue_instant == "2007-09-14T01:05:02Z")
self.assert_(new_ar.destination == "http://www.sios.com/Destination")
self.assert_(new_ar.consent == saml.CONSENT_UNSPECIFIED)
self.assert_(isinstance(new_ar.issuer, saml.Issuer))
self.assert_(isinstance(new_ar.signature, ds.Signature))
self.assert_(isinstance(new_ar.extensions, samlp.Extensions))
def testUsingTestData(self):
"""Test for AbstractRequestFromString() using test data"""
# TODO:
pass
class StatusDetailTest(unittest.TestCase):
def setUp(self):
self.status_detail = samlp.StatusDetail()
def testAccessors(self):
"""Test for StatusDetail accessors"""
# TODO:
pass
class StatusMessageTest(unittest.TestCase):
def setUp(self):
self.status_message = samlp.StatusMessage()
def testAccessors(self):
"""Test for StatusMessage accessors"""
# TODO:
pass
class StatusCodeTest(unittest.TestCase):
def setUp(self):
self.status_code = samlp.StatusCode()
def testAccessors(self):
"""Test for StatusCode accessors"""
self.status_code.value = samlp.STATUS_RESPONDER
self.status_code.status_code = samlp.StatusCode(
value=samlp.STATUS_REQUEST_DENIED)
new_status_code = samlp.StatusCodeFromString(self.status_code.ToString())
self.assert_(new_status_code.value == samlp.STATUS_RESPONDER)
self.assert_(new_status_code.status_code.value ==
samlp.STATUS_REQUEST_DENIED)
def testUsingTestData(self):
"""Test for StatusCodeFromString() using test data"""
new_status_code = samlp.StatusCodeFromString(
samlp_test_data.TEST_STATUS_CODE)
self.assert_(new_status_code.value == samlp.STATUS_RESPONDER)
self.assert_(new_status_code.status_code.value ==
samlp.STATUS_REQUEST_DENIED)
class StatusTest(unittest.TestCase):
def setUp(self):
self.status = samlp.Status()
def testAccessors(self):
"""Test for Status accessors"""
self.status.status_code = samlp.StatusCode()
self.status.status_message = samlp.StatusMessage()
self.status.status_detail = samlp.StatusDetail()
new_status = samlp.StatusFromString(self.status.ToString())
self.assert_(isinstance(new_status.status_code, samlp.StatusCode))
self.assert_(isinstance(new_status.status_message, samlp.StatusMessage))
self.assert_(isinstance(new_status.status_detail, samlp.StatusDetail))
def testUsingTestData(self):
"""Test for StatusFromString using test data"""
new_status = samlp.StatusFromString(samlp_test_data.TEST_STATUS)
self.assert_(isinstance(new_status.status_code, samlp.StatusCode))
self.assert_(isinstance(new_status.status_code.status_code,
samlp.StatusCode))
self.assert_(isinstance(new_status.status_message, samlp.StatusMessage))
self.assert_(isinstance(new_status.status_detail, samlp.StatusDetail))
class StatusResponseTest(unittest.TestCase):
def setUp(self):
self.sr = samlp.StatusResponse()
def testAccessors(self):
"""Test for StatusResponse accessors"""
self.sr.id = "response id"
self.sr.in_response_to = "request id"
self.sr.version = saml.V2
self.sr.issue_instant = "2007-09-14T01:05:02Z"
self.sr.destination = "http://www.sios.com/Destination"
self.sr.consent = saml.CONSENT_UNSPECIFIED
self.sr.issuer = saml.Issuer()
self.sr.signature = ds.GetEmptySignature()
self.sr.extensions = samlp.Extensions()
self.sr.status = samlp.Status()
new_sr = samlp.StatusResponseFromString(self.sr.ToString())
self.assert_(new_sr.id == "response id")
self.assert_(new_sr.in_response_to == "request id")
self.assert_(new_sr.version == saml.V2)
self.assert_(new_sr.issue_instant == "2007-09-14T01:05:02Z")
self.assert_(new_sr.destination == "http://www.sios.com/Destination")
self.assert_(new_sr.consent == saml.CONSENT_UNSPECIFIED)
self.assert_(isinstance(new_sr.issuer, saml.Issuer))
self.assert_(isinstance(new_sr.signature, ds.Signature))
self.assert_(isinstance(new_sr.extensions, samlp.Extensions))
self.assert_(isinstance(new_sr.status, samlp.Status))
def testUsingTestData(self):
"""Test for StatusResponseFromString() using test data"""
# TODO:
pass
class ResponseTest(unittest.TestCase):
def setUp(self):
self.response = samlp.Response()
def testAccessors(self):
"""Test for Response accessors"""
self.response.id = "response id"
self.response.in_response_to = "request id"
self.response.version = saml.V2
self.response.issue_instant = "2007-09-14T01:05:02Z"
self.response.destination = "http://www.sios.com/Destination"
self.response.consent = saml.CONSENT_UNSPECIFIED
self.response.issuer = saml.Issuer()
self.response.signature = ds.GetEmptySignature()
self.response.extensions = samlp.Extensions()
self.response.status = samlp.Status()
self.response.assertion.append(saml.Assertion())
self.response.encrypted_assertion.append(saml.EncryptedAssertion())
new_response = samlp.ResponseFromString(self.response.ToString())
self.assert_(new_response.id == "response id")
self.assert_(new_response.in_response_to == "request id")
self.assert_(new_response.version == saml.V2)
self.assert_(new_response.issue_instant == "2007-09-14T01:05:02Z")
self.assert_(new_response.destination == "http://www.sios.com/Destination")
self.assert_(new_response.consent == saml.CONSENT_UNSPECIFIED)
self.assert_(isinstance(new_response.issuer, saml.Issuer))
self.assert_(isinstance(new_response.signature, ds.Signature))
self.assert_(isinstance(new_response.extensions, samlp.Extensions))
self.assert_(isinstance(new_response.status, samlp.Status))
self.assert_(isinstance(new_response.assertion[0], saml.Assertion))
self.assert_(isinstance(new_response.encrypted_assertion[0],
saml.EncryptedAssertion))
def testUsingTestData(self):
"""Test for ResponseFromString() using test data"""
# TODO:
pass
class NameIDPolicyTest(unittest.TestCase):
def setUp(self):
self.name_id_policy = samlp.NameIDPolicy()
def testAccessors(self):
"""Test for NameIDPolicy accessors"""
self.name_id_policy.format = saml.NAMEID_FORMAT_EMAILADDRESS
self.name_id_policy.sp_name_qualifier = saml.NAMEID_FORMAT_PERSISTENT
self.name_id_policy.allow_create = 'false'
new_name_id_policy = samlp.NameIDPolicyFromString(
self.name_id_policy.ToString())
self.assert_(new_name_id_policy.format == saml.NAMEID_FORMAT_EMAILADDRESS)
self.assert_(new_name_id_policy.sp_name_qualifier ==
saml.NAMEID_FORMAT_PERSISTENT)
self.assert_(new_name_id_policy.allow_create == 'false')
def testUsingTestData(self):
"""Test for NameIDPolicyFromString() using test data"""
new_name_id_policy = samlp.NameIDPolicyFromString(
samlp_test_data.TEST_NAME_ID_POLICY)
self.assert_(new_name_id_policy.format == saml.NAMEID_FORMAT_EMAILADDRESS)
self.assert_(new_name_id_policy.sp_name_qualifier ==
saml.NAMEID_FORMAT_PERSISTENT)
self.assert_(new_name_id_policy.allow_create == 'false')
class IDPEntryTest(unittest.TestCase):
def setUp(self):
self.idp_entry = samlp.IDPEntry()
def testAccessors(self):
"""Test for IDPEntry accessors"""
self.idp_entry.provider_id = "http://www.sios.com/provider"
self.idp_entry.name = "the provider"
self.idp_entry.loc = "http://www.sios.com/Loc"
new_idp_entry = samlp.IDPEntryFromString(self.idp_entry.ToString())
self.assert_(new_idp_entry.provider_id == "http://www.sios.com/provider")
self.assert_(new_idp_entry.name == "the provider")
self.assert_(new_idp_entry.loc == "http://www.sios.com/Loc")
def testUsingTestData(self):
"""Test for IDPEntryFromString() using test data"""
new_idp_entry = samlp.IDPEntryFromString(samlp_test_data.TEST_IDP_ENTRY)
self.assert_(new_idp_entry.provider_id == "http://www.sios.com/provider")
self.assert_(new_idp_entry.name == "the provider")
self.assert_(new_idp_entry.loc == "http://www.sios.com/Loc")
class IDPListTest(unittest.TestCase):
def setUp(self):
self.idp_list = samlp.IDPList()
def testAccessors(self):
"""Test for IDPList accessors"""
self.idp_list.idp_entry.append(samlp.IDPEntryFromString(
samlp_test_data.TEST_IDP_ENTRY))
self.idp_list.get_complete = samlp.GetComplete(
text="http://www.sios.com/GetComplete")
new_idp_list = samlp.IDPListFromString(self.idp_list.ToString())
self.assert_(isinstance(new_idp_list.idp_entry[0], samlp.IDPEntry))
self.assert_(new_idp_list.get_complete.text.strip() ==
"http://www.sios.com/GetComplete")
def testUsingTestData(self):
"""Test for IDPListFromString() using test data"""
new_idp_list = samlp.IDPListFromString(samlp_test_data.TEST_IDP_LIST)
self.assert_(isinstance(new_idp_list.idp_entry[0], samlp.IDPEntry))
self.assert_(new_idp_list.get_complete.text.strip() ==
"http://www.sios.com/GetComplete")
class ScopingTest(unittest.TestCase):
def setUp(self):
self.scoping = samlp.Scoping()
def testAccessors(self):
"""Test for Scoping accessors"""
self.scoping.proxy_count = "1"
self.scoping.idp_list = samlp.IDPList()
self.scoping.requester_id.append(samlp.RequesterID())
new_scoping = samlp.ScopingFromString(self.scoping.ToString())
self.assert_(new_scoping.proxy_count == "1")
self.assert_(isinstance(new_scoping.idp_list, samlp.IDPList))
self.assert_(isinstance(new_scoping.requester_id[0], samlp.RequesterID))
def testUsingTestData(self):
"""Test for ScopingFromString() using test data"""
new_scoping = samlp.ScopingFromString(samlp_test_data.TEST_SCOPING)
self.assert_(new_scoping.proxy_count == "1")
self.assert_(isinstance(new_scoping.idp_list, samlp.IDPList))
self.assert_(isinstance(new_scoping.requester_id[0], samlp.RequesterID))
class RequestedAuthnContextTest(unittest.TestCase):
def setUp(self):
self.context = samlp.RequestedAuthnContext()
def testAccessors(self):
"""Test for RequestedAuthnContext accessors"""
self.context.authn_context_class_ref.append(saml.AuthnContextClassRef())
self.context.authn_context_decl_ref.append(saml.AuthnContextDeclRef())
self.context.comparison = "exact"
new_context = samlp.RequestedAuthnContextFromString(
self.context.ToString())
self.assert_(isinstance(new_context.authn_context_class_ref[0],
saml.AuthnContextClassRef))
self.assert_(isinstance(new_context.authn_context_decl_ref[0],
saml.AuthnContextDeclRef))
self.assert_(new_context.comparison == "exact")
def testUsingTestData(self):
"""Test for RequestedAuthnContextFromString() using test data"""
new_context = samlp.RequestedAuthnContextFromString(
samlp_test_data.TEST_REQUESTED_AUTHN_CONTEXT)
self.assert_(isinstance(new_context.authn_context_class_ref[0],
saml.AuthnContextClassRef))
self.assert_(isinstance(new_context.authn_context_decl_ref[0],
saml.AuthnContextDeclRef))
self.assert_(new_context.comparison == "exact")
class AuthnRequestTest(unittest.TestCase):
def setUp(self):
self.ar = samlp.AuthnRequest()
def testAccessors(self):
"""Test for AuthnRequest accessors"""
self.ar.id = "request id"
self.ar.version = saml.V2
self.ar.issue_instant = "2007-09-14T01:05:02Z"
self.ar.destination = "http://www.sios.com/Destination"
self.ar.consent = saml.CONSENT_UNSPECIFIED
self.ar.issuer = saml.Issuer()
self.ar.signature = ds.GetEmptySignature()
self.ar.extensions = samlp.Extensions()
self.ar.subject = saml.Subject()
self.ar.name_id_policy = samlp.NameIDPolicy()
self.ar.conditions = saml.Conditions()
self.ar.requested_authn_context = samlp.RequestedAuthnContext()
self.ar.scoping = samlp.Scoping()
self.ar.force_authn = 'true'
self.ar.is_passive = 'true'
self.ar.assertion_consumer_service_index = "1"
self.ar.assertion_consumer_service_url = "http://www.sios.com/acs"
self.ar.protocol_binding = saml2.BINDING_HTTP_POST
self.ar.assertion_consuming_service_index = "2"
self.ar.provider_name = "provider name"
new_ar = samlp.AuthnRequestFromString(self.ar.ToString())
self.assert_(new_ar.id == "request id")
self.assert_(new_ar.version == saml.V2)
self.assert_(new_ar.issue_instant == "2007-09-14T01:05:02Z")
self.assert_(new_ar.destination == "http://www.sios.com/Destination")
self.assert_(new_ar.consent == saml.CONSENT_UNSPECIFIED)
self.assert_(isinstance(new_ar.issuer, saml.Issuer))
self.assert_(isinstance(new_ar.signature, ds.Signature))
self.assert_(isinstance(new_ar.extensions, samlp.Extensions))
self.assert_(isinstance(new_ar.subject, saml.Subject))
self.assert_(isinstance(new_ar.name_id_policy, samlp.NameIDPolicy))
self.assert_(isinstance(new_ar.conditions, saml.Conditions))
self.assert_(isinstance(new_ar.requested_authn_context,
samlp.RequestedAuthnContext))
self.assert_(isinstance(new_ar.scoping, samlp.Scoping))
self.assert_(new_ar.force_authn == 'true')
self.assert_(new_ar.is_passive == 'true')
self.assert_(new_ar.assertion_consumer_service_index == '1')
self.assert_(new_ar.assertion_consumer_service_url ==
'http://www.sios.com/acs')
self.assert_(new_ar.protocol_binding == saml2.BINDING_HTTP_POST)
self.assert_(new_ar.assertion_consuming_service_index == '2')
self.assert_(new_ar.provider_name == "provider name")
def testUsingTestData(self):
"""Test for AuthnRequestFromString() using test data"""
new_ar = samlp.AuthnRequestFromString(samlp_test_data.TEST_AUTHN_REQUEST)
self.assert_(new_ar.id == "request id")
self.assert_(new_ar.version == saml.V2)
self.assert_(new_ar.issue_instant == "2007-09-14T01:05:02Z")
self.assert_(new_ar.destination == "http://www.sios.com/Destination")
self.assert_(new_ar.consent == saml.CONSENT_UNSPECIFIED)
self.assert_(isinstance(new_ar.issuer, saml.Issuer))
self.assert_(isinstance(new_ar.signature, ds.Signature))
self.assert_(isinstance(new_ar.extensions, samlp.Extensions))
self.assert_(isinstance(new_ar.subject, saml.Subject))
self.assert_(isinstance(new_ar.name_id_policy, samlp.NameIDPolicy))
self.assert_(isinstance(new_ar.conditions, saml.Conditions))
self.assert_(isinstance(new_ar.requested_authn_context,
samlp.RequestedAuthnContext))
self.assert_(isinstance(new_ar.scoping, samlp.Scoping))
self.assert_(new_ar.force_authn == 'true')
self.assert_(new_ar.is_passive == 'true')
self.assert_(new_ar.assertion_consumer_service_index == '1')
self.assert_(new_ar.assertion_consumer_service_url ==
'http://www.sios.com/acs')
self.assert_(new_ar.protocol_binding == saml2.BINDING_HTTP_POST)
self.assert_(new_ar.assertion_consuming_service_index == '2')
self.assert_(new_ar.provider_name == "provider name")
class LogoutRequestTest(unittest.TestCase):
def setUp(self):
self.lr = samlp.LogoutRequest()
def testAccessors(self):
"""Test for LogoutRequest accessors"""
self.lr.id = "request id"
self.lr.version = saml.V2
self.lr.issue_instant = "2007-09-14T01:05:02Z"
self.lr.destination = "http://www.sios.com/Destination"
self.lr.consent = saml.CONSENT_UNSPECIFIED
self.lr.issuer = saml.Issuer()
self.lr.signature = ds.GetEmptySignature()
self.lr.extensions = samlp.Extensions()
self.lr.not_on_or_after = "2007-10-14T01:05:02Z"
self.lr.reason = "http://www.sios.com/Reason"
self.lr.base_id = saml.BaseID()
self.lr.name_id = saml.NameID()
self.lr.encrypted_id = saml.EncryptedID()
self.lr.session_index = samlp.SessionIndex()
new_lr = samlp.LogoutRequestFromString(self.lr.ToString())
self.assert_(new_lr.id == "request id")
self.assert_(new_lr.version == saml.V2)
self.assert_(new_lr.issue_instant == "2007-09-14T01:05:02Z")
self.assert_(new_lr.destination == "http://www.sios.com/Destination")
self.assert_(new_lr.consent == saml.CONSENT_UNSPECIFIED)
self.assert_(isinstance(new_lr.issuer, saml.Issuer))
self.assert_(isinstance(new_lr.signature, ds.Signature))
self.assert_(isinstance(new_lr.extensions, samlp.Extensions))
self.assert_(new_lr.not_on_or_after == "2007-10-14T01:05:02Z")
self.assert_(new_lr.reason == "http://www.sios.com/Reason")
self.assert_(isinstance(new_lr.base_id, saml.BaseID))
self.assert_(isinstance(new_lr.name_id, saml.NameID))
self.assert_(isinstance(new_lr.encrypted_id, saml.EncryptedID))
self.assert_(isinstance(new_lr.session_index, samlp.SessionIndex))
def testUsingTestData(self):
"""Test for LogoutRequestFromString() using test data"""
new_lr = samlp.LogoutRequestFromString(samlp_test_data.TEST_LOGOUT_REQUEST)
self.assert_(new_lr.id == "request id")
self.assert_(new_lr.version == saml.V2)
self.assert_(new_lr.issue_instant == "2007-09-14T01:05:02Z")
self.assert_(new_lr.destination == "http://www.sios.com/Destination")
self.assert_(new_lr.consent == saml.CONSENT_UNSPECIFIED)
self.assert_(isinstance(new_lr.issuer, saml.Issuer))
self.assert_(isinstance(new_lr.signature, ds.Signature))
self.assert_(isinstance(new_lr.extensions, samlp.Extensions))
self.assert_(new_lr.not_on_or_after == "2007-10-14T01:05:02Z")
self.assert_(new_lr.reason == "http://www.sios.com/Reason")
self.assert_(isinstance(new_lr.base_id, saml.BaseID))
self.assert_(isinstance(new_lr.name_id, saml.NameID))
self.assert_(isinstance(new_lr.encrypted_id, saml.EncryptedID))
self.assert_(isinstance(new_lr.session_index, samlp.SessionIndex))
self.assert_(new_lr.session_index.text.strip() == "session index")
class LogoutResponseTest(unittest.TestCase):
def setUp(self):
self.lr = samlp.LogoutResponse()
def testAccessors(self):
"""Test for LogoutResponse accessors"""
self.lr.id = "response id"
self.lr.in_response_to = "request id"
self.lr.version = saml.V2
self.lr.issue_instant = "2007-09-14T01:05:02Z"
self.lr.destination = "http://www.sios.com/Destination"
self.lr.consent = saml.CONSENT_UNSPECIFIED
self.lr.issuer = saml.Issuer()
self.lr.signature = ds.GetEmptySignature()
self.lr.extensions = samlp.Extensions()
self.lr.status = samlp.Status()
new_lr = samlp.LogoutResponseFromString(self.lr.ToString())
self.assert_(new_lr.id == "response id")
self.assert_(new_lr.in_response_to == "request id")
self.assert_(new_lr.version == saml.V2)
self.assert_(new_lr.issue_instant == "2007-09-14T01:05:02Z")
self.assert_(new_lr.destination == "http://www.sios.com/Destination")
self.assert_(new_lr.consent == saml.CONSENT_UNSPECIFIED)
self.assert_(isinstance(new_lr.issuer, saml.Issuer))
self.assert_(isinstance(new_lr.signature, ds.Signature))
self.assert_(isinstance(new_lr.extensions, samlp.Extensions))
self.assert_(isinstance(new_lr.status, samlp.Status))
def testUsingTestData(self):
"""Test for LogoutResponseFromString() using test data"""
new_lr = samlp.LogoutResponseFromString(
samlp_test_data.TEST_LOGOUT_RESPONSE)
self.assert_(new_lr.id == "response id")
self.assert_(new_lr.in_response_to == "request id")
self.assert_(new_lr.version == saml.V2)
self.assert_(new_lr.issue_instant == "2007-09-14T01:05:02Z")
self.assert_(new_lr.destination == "http://www.sios.com/Destination")
self.assert_(new_lr.consent == saml.CONSENT_UNSPECIFIED)
self.assert_(isinstance(new_lr.issuer, saml.Issuer))
self.assert_(isinstance(new_lr.signature, ds.Signature))
self.assert_(isinstance(new_lr.extensions, samlp.Extensions))
self.assert_(isinstance(new_lr.status, samlp.Status))
if __name__ == '__main__':
unittest.main()

62
tests/test_b64.py Normal file
View File

@@ -0,0 +1,62 @@
import base64
import saml2
from saml2 import samlp, saml
import urllib
import zlib
SERVICE_URL = "http://lingon.catalogix.se/cgi-bin/repo"
MY_NAME = "My Test SP"
SSO_LOCATION = \
"http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/SSOService.php"
def create_authn_request(query_id, destination, position=SERVICE_URL, provider=MY_NAME):
""" Creates an Authenication Request
:param query_id: Query identifier
:param destination: Where to send the request
:param position: Where the user should be sent afterwards
:param provider: Who I am
:return: A string representation of the authentication request
"""
authn_request = samlp.AuthnRequest(query_id)
authn_request.assertion_consumer_service_url = position
authn_request.destination = destination
authn_request.protocol_binding = saml2.BINDING_HTTP_POST
authn_request.provider_name = provider
name_id_policy = samlp.NameIDPolicy()
name_id_policy.format = saml.NAMEID_FORMAT_EMAILADDRESS
name_id_policy.sp_name_qualifier = saml.NAMEID_FORMAT_PERSISTENT
name_id_policy.allow_create = 'false'
authn_request.name_id_policy = name_id_policy
return "%s" % authn_request
authn_req = create_authn_request("0123456789",SSO_LOCATION)
b64 = base64.b64encode(authn_req)
print base64.b64decode(b64)
sr = """<?xml version='1.0' encoding='UTF-8'?>
<ns0:AuthnRequest AssertionConsumerServiceURL="http://lingon.catalogix.se/cgi-bin/repo" Destination="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/SSOService.php" ID="oglagncepmkklpejlhmkhdpifonhjffgnmjidljj" ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" ProviderName="My Test SP" xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol"><ns0:NameIDPolicy AllowCreate="false" SPNameQualifier="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" /></ns0:AuthnRequest>"""
for i in range(1,9):
fb = urllib.quote_plus(base64.b64encode(zlib.compress(sr,i)))
print
print zlib.decompress(base64.b64decode(urllib.unquote_plus(fb)))
one = """fZHBbtswDIbvA%2FYOgi45xc56GoQ4RdagaIF29Wr3AVSZtulIlCbKWfr2k9Nihx164YH4%2F4%2Fkz%2B312VlxgsjoqVp9KzYrAWR8hzRUq5f2dv19db37%2BmVLvFH7OY30DL9n4CT2zBBTdt144tlBbCCe0MDL80Mlx5SCKkubKZ4Ko5O2fsBzwVCaAdevSGWE4KU4ZBSSXjj%2FXGcgzw7tzMXsOpPLvBgZXbDA2tlyKVcldqFsmqePuUUYgxT3h0r6weqBDAR3PNoAkx3dcewC9p7Gqe8HchN2dpqkqKNP3nj7A%2BlysJwjKa8ZWZF2wCoZ1ewfH9RVsVGv7yJWd21br%2Bunpr0ATthB%2FJnVlXx8E%2B0STVNLkWOlTOHN59DwsYHcXRJeOPeH2ls0b2Jvrf9zE0GnzO61ZZAZvUh%2BzdpijxA%2Fhy8d7Na9j04nFZYncwJKUpS7bfn%2FR3d%2FAQ%3D%3D"""
print zlib.decompress(base64.b64decode(urllib.unquote_plus(one)), -15)
# d1 = base64.b64decode(d0)
# print zlib.decompress(d1)
zl = zlib.compress(sr)
# This is supposed to be safe
zl = zl[2:-4]
print urllib.quote_plus(base64.b64encode(zl))

193
tests/test_from_string.py Normal file
View File

@@ -0,0 +1,193 @@
#!/usr/bin/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 saml2.saml"""
__author__ = 'roland.hedberg@adm.umu.se'
try:
from xml.etree import ElementTree
except ImportError:
from elementtree import ElementTree
from saml2 import md
import xmldsig as ds
X509DATA = """<?xml version="1.0" encoding="utf-8"?>
<X509Data xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBg</X509Certificate>
</X509Data>"""
KEY_INFO = """<?xml version="1.0"?>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBg</X509Certificate>
</X509Data>
</KeyInfo>"""
KEY_DESCRIPTOR = """<?xml version="1.0"?>
<KeyDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBg</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>"""
IDP = """
"""
ED = """<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php">
<IDPSSODescriptor xmlns:ds="http://www.w3.org/2000/09/xmldsig#" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/SingleLogoutService.php"/>
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/SSOService.php"/>
</IDPSSODescriptor>
<ContactPerson contactType="technical">
<GivenName>Roland</GivenName>
<SurName>Hedberg</SurName>
<EmailAddress>roland.hedberg@adm.umu.se</EmailAddress>
</ContactPerson>
</EntityDescriptor>"""
ED2 = """<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" entityID="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php">
<IDPSSODescriptor xmlns:ds="http://www.w3.org/2000/09/xmldsig#" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<KeyDescriptor use="encryption">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>MIICgTCCAeoCCQCbOlrWDdX7FTANBgkqhkiG9w0BAQUFADCBhDELMAkGA1UEBhMCTk8xGDAWBgNVBAgTD0FuZHJlYXMgU29sYmVyZzEMMAoGA1UEBxMDRm9vMRAwDgYDVQQKEwdVTklORVRUMRgwFgYDVQQDEw9mZWlkZS5lcmxhbmcubm8xITAfBgkqhkiG9w0BCQEWEmFuZHJlYXNAdW5pbmV0dC5ubzAeFw0wNzA2MTUxMjAxMzVaFw0wNzA4MTQxMjAxMzVaMIGEMQswCQYDVQQGEwJOTzEYMBYGA1UECBMPQW5kcmVhcyBTb2xiZXJnMQwwCgYDVQQHEwNGb28xEDAOBgNVBAoTB1VOSU5FVFQxGDAWBgNVBAMTD2ZlaWRlLmVybGFuZy5ubzEhMB8GCSqGSIb3DQEJARYSYW5kcmVhc0B1bmluZXR0Lm5vMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDivbhR7P516x/S3BqKxupQe0LONoliupiBOesCO3SHbDrl3+q9IbfnfmE04rNuMcPsIxB161TdDpIesLCn7c8aPHISKOtPlAeTZSnb8QAu7aRjZq3+PbrP5uW3TcfCGPtKTytHOge/OlJbo078dVhXQ14d1EDwXJW1rRXuUt4C8QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBACDVfp86HObqY+e8BUoWQ9+VMQx1ASDohBjwOsg2WykUqRXF+dLfcUH9dWR63CtZIKFDbStNomPnQz7nbK+onygwBspVEbnHuUihZq3ZUdmumQqCw4Uvs/1Uvq3orOo/WJVhTyvLgFVK2QarQ4/67OZfHd7R+POBXhophSMv1ZOo</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/SingleLogoutService.php"/>
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/SSOService.php"/>
</IDPSSODescriptor>
<ContactPerson contactType="technical">
<GivenName>Roland</GivenName>
<SurName>Hedberg</SurName>
<EmailAddress>roland.hedberg@adm.umu.se</EmailAddress>
</ContactPerson>
</EntityDescriptor>"""
def _verify_x509data(x509data):
assert x509data.x509_certificate != []
assert len(x509data.x509_certificate) == 1
cert = x509data.x509_certificate[0]
assert cert.text == "MIICgTCCAeoCCQCbOlrWDdX7FTANBg"
def test_x509data():
x509data = ds.x509_data_from_string(X509DATA)
_verify_x509data(x509data)
def _verify_info(info):
assert info.x509_data != []
assert len(info.x509_data) == 1
x509data = info.x509_data[0]
_verify_x509data(x509data)
def test_key_info():
info = ds.key_info_from_string(KEY_INFO)
_verify_info(info)
def test_key_descriptor():
desc = md.key_descriptor_from_string(KEY_DESCRIPTOR)
assert desc.use == "signing"
print desc.__dict__
assert desc.key_info != None
info = desc.key_info
_verify_info(info)
def _verify_contact_person(person):
assert person.contact_type == "technical"
assert person.given_name.text == "Roland"
assert person.sur_name.text == "Hedberg"
assert person.email_address[0].text == "roland.hedberg@adm.umu.se"
def _verify_single_sign_on_service(sso):
assert sso.binding == "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
assert sso.location == "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/SSOService.php"
def _verify_single_logout_service(sso):
assert sso.binding == "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
assert sso.location == "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/SingleLogoutService.php"
def _verify_idp_sso_description(idpssodesc):
for ssoserv in idpssodesc.single_sign_on_service: # only one
_verify_single_sign_on_service(ssoserv)
for sloserv in idpssodesc.single_logout_service: # only one
_verify_single_logout_service(sloserv)
assert idpssodesc.name_id_format[0].text == "urn:oasis:names:tc:SAML:2.0:nameid-format:transient"
def test_entity_descriptor():
ed = md.entity_descriptor_from_string(ED)
assert ed.entity_id == "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php"
contact_person = ed.contact_person[0]
_verify_contact_person(contact_person)
idpsso = ed.idp_sso_descriptor[0]
_verify_idp_sso_description(idpsso)
assert ed.entity_id == "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php"
print ed.to_string()
# all other attributes are supposed to be None,'',[] or {}
for key,val in ed.__dict__.items():
if key in ["contact_person", "idp_sso_descriptor", "entity_id"]:
continue
else:
if isinstance(val,basestring):
val = val.strip('\t\r\n ')
assert val in [None,'',[],{}]
def test_entity_descriptor_2():
ed = md.entity_descriptor_from_string(ED2)
assert ed.entity_id == "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php"
contact_person = ed.contact_person[0]
_verify_contact_person(contact_person)
idpsso = ed.idp_sso_descriptor[0]
_verify_idp_sso_description(idpsso)
assert ed.entity_id == "http://xenosmilus.umdc.umu.se/simplesaml/saml2/idp/metadata.php"
print ed.to_string()
# all other attributes are supposed to be None,'',[] or {}
for key,val in ed.__dict__.items():
if key in ["contact_person", "idp_sso_descriptor", "entity_id"]:
continue
else:
if isinstance(val,basestring):
val = val.strip('\t\r\n ')
assert val in [None,'',[],{}]

1152
tests/test_md.py Normal file

File diff suppressed because it is too large Load Diff

884
tests/test_saml.py Normal file
View File

@@ -0,0 +1,884 @@
#!/usr/bin/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 saml2.saml"""
try:
from xml.etree import ElementTree
except ImportError:
from elementtree import ElementTree
import saml2
from saml2 import saml, test_data, ds_test_data
import xmldsig as ds
class TestNameID:
def setup_class(self):
self.name_id = saml.NameID()
def testEmptyExtensionsList(self):
"""Test if NameID has empty extensions list"""
assert isinstance(self.name_id.extension_elements, list)
assert len(self.name_id.extension_elements) == 0
def testFormatAttribute(self):
"""Test for Format attribute accessors"""
self.name_id.format = saml.NAMEID_FORMAT_EMAILADDRESS
assert self.name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS
assert len(self.name_id.extension_elements) == 0
new_name_id = saml.NameIDFromString(self.name_id.to_string())
assert len(new_name_id.extension_elements) == 0
self.name_id.extension_elements.append(saml2.ExtensionElement(
'foo', text='bar'))
assert len(self.name_id.extension_elements) == 1
assert self.name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS
def testNameIDText(self):
"""Test text value of NameID element"""
self.name_id.text = "tmatsuo@sios.com"
assert self.name_id.text == "tmatsuo@sios.com"
def testSPProvidedID(self):
"""Test for SPProvidedID attribute accessors"""
self.name_id.sp_provided_id = "provided id"
assert self.name_id.sp_provided_id == "provided id"
def testEmptyNameIDToAndFromStringMatch(self):
"""Test NameIDFromString() with empty NameID"""
string_from_name_id = self.name_id.to_string()
new_name_id = saml.NameIDFromString(string_from_name_id)
string_from_new_name_id = new_name_id.to_string()
assert string_from_name_id == string_from_new_name_id
def testNameIDToAndFromStringMatch(self):
"""Test NameIDFromString() with data"""
self.name_id.format = saml.NAMEID_FORMAT_EMAILADDRESS
self.name_id.text = "tmatsuo@sios.com"
self.name_id.name_qualifier = "name_qualifier"
self.name_id.sp_name_qualifier = "sp_name_qualifier"
string_from_name_id = self.name_id.to_string()
new_name_id = saml.NameIDFromString(string_from_name_id)
assert new_name_id.name_qualifier == "name_qualifier"
assert new_name_id.sp_name_qualifier == "sp_name_qualifier"
string_from_new_name_id = new_name_id.to_string()
assert string_from_name_id == string_from_new_name_id
def testExtensionAttributes(self):
"""Test extension attributes"""
self.name_id.extension_attributes['hoge'] = 'fuga'
self.name_id.extension_attributes['moge'] = 'muga'
assert self.name_id.extension_attributes['hoge'] == 'fuga'
assert self.name_id.extension_attributes['moge'] == 'muga'
new_name_id = saml.NameIDFromString(self.name_id.to_string())
assert new_name_id.extension_attributes['hoge'] == 'fuga'
assert new_name_id.extension_attributes['moge'] == 'muga'
def testNameIDFromString(self):
"""Test NameIDFromString() using test data"""
name_id = saml.NameIDFromString(test_data.TEST_NAME_ID)
assert name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS
assert name_id.text.strip() == "tmatsuo@sios.com"
assert name_id.sp_provided_id == "sp provided id"
class TestIssuer:
def setup_class(self):
self.issuer = saml.Issuer()
def testIssuerToAndFromString(self):
"""Test IssuerFromString()"""
self.issuer.text = "http://www.sios.com/test"
self.issuer.name_qualifier = "name_qualifier"
self.issuer.sp_name_qualifier = "sp_name_qualifier"
new_issuer = saml.IssuerFromString(self.issuer.to_string())
assert self.issuer.text == new_issuer.text
assert self.issuer.name_qualifier == new_issuer.name_qualifier
assert self.issuer.sp_name_qualifier == new_issuer.sp_name_qualifier
assert self.issuer.extension_elements == new_issuer.extension_elements
def testUsingTestData(self):
"""Test IssuerFromString() using test data"""
issuer = saml.IssuerFromString(test_data.TEST_ISSUER)
assert issuer.text.strip() == "http://www.sios.com/test"
new_issuer = saml.IssuerFromString(issuer.to_string())
assert issuer.text == new_issuer.text
assert issuer.extension_elements == new_issuer.extension_elements
class TestSubjectLocality:
def setup_class(self):
self.subject_locality = saml.SubjectLocality()
def testAccessors(self):
"""Test for SubjectLocality accessors"""
self.subject_locality.address = "127.0.0.1"
self.subject_locality.dns_name = "localhost"
assert self.subject_locality.address == "127.0.0.1"
assert self.subject_locality.dns_name == "localhost"
new_subject_locality = saml.SubjectLocalityFromString(
self.subject_locality.to_string())
assert new_subject_locality.address == "127.0.0.1"
assert new_subject_locality.dns_name == "localhost"
def testUsingTestData(self):
"""Test SubjectLocalityFromString() using test data"""
subject_locality = saml.SubjectLocalityFromString(
test_data.TEST_SUBJECT_LOCALITY)
assert subject_locality.address == "127.0.0.1"
assert subject_locality.dns_name == "localhost"
new_subject_locality = saml.SubjectLocalityFromString(
subject_locality.to_string())
assert new_subject_locality.address == "127.0.0.1"
assert new_subject_locality.dns_name == "localhost"
assert subject_locality.to_string() == new_subject_locality.to_string()
class TestAuthnContextClassRef:
def setup_class(self):
self.authn_context_class_ref = saml.AuthnContextClassRef()
text = "http://www.sios.com/authnContextClassRef"
def testAccessors(self):
"""Test for AuthnContextClassRef accessors"""
self.authn_context_class_ref.text = self.text
assert self.authn_context_class_ref.text == self.text
new_authn_context_class_ref = saml.AuthnContextClassRefFromString(
self.authn_context_class_ref.to_string())
assert new_authn_context_class_ref.text == self.text
assert self.authn_context_class_ref.to_string() == \
new_authn_context_class_ref.to_string()
def testUsingTestData(self):
"""Test AuthnContextClassRefFromString() using test data"""
authn_context_class_ref = saml.AuthnContextClassRefFromString(
test_data.TEST_AUTHN_CONTEXT_CLASS_REF)
assert authn_context_class_ref.text.strip() == self.text
class TestAuthnContextDeclRef:
def setup_class(self):
self.authn_context_decl_ref = saml.AuthnContextDeclRef()
ref = "http://www.sios.com/authnContextDeclRef"
def testAccessors(self):
"""Test for AuthnContextDeclRef accessors"""
self.authn_context_decl_ref.text = self.ref
assert self.authn_context_decl_ref.text == self.ref
new_authn_context_decl_ref = saml.AuthnContextDeclRefFromString(
self.authn_context_decl_ref.to_string())
assert new_authn_context_decl_ref.text == self.ref
assert self.authn_context_decl_ref.to_string() == \
new_authn_context_decl_ref.to_string()
def testUsingTestData(self):
"""Test AuthnContextDeclRefFromString() using test data"""
authn_context_decl_ref = saml.AuthnContextDeclRefFromString(
test_data.TEST_AUTHN_CONTEXT_DECL_REF)
assert authn_context_decl_ref.text.strip() == self.ref
class TestAuthnContextDecl:
def setup_class(self):
self.authn_context_decl = saml.AuthnContextDecl()
self.text = "http://www.sios.com/authnContextDecl"
def testAccessors(self):
"""Test for AuthnContextDecl accessors"""
self.authn_context_decl.text = self.text
assert self.authn_context_decl.text == self.text
new_authn_context_decl = saml.AuthnContextDeclFromString(
self.authn_context_decl.to_string())
assert new_authn_context_decl.text == self.text
assert self.authn_context_decl.to_string() == \
new_authn_context_decl.to_string()
def testUsingTestData(self):
"""Test AuthnContextDeclFromString() using test data"""
authn_context_decl = saml.AuthnContextDeclFromString(
test_data.TEST_AUTHN_CONTEXT_DECL)
assert authn_context_decl.text.strip() == self.text
class TestAuthenticatingAuthority:
def setup_class(self):
self.authenticating_authority = saml.AuthenticatingAuthority()
self.text = "http://www.sios.com/authenticatingAuthority"
def testAccessors(self):
"""Test for AuthenticatingAuthority accessors"""
self.authenticating_authority.text = self.text
assert self.authenticating_authority.text == self.text
new_authenticating_authority = saml.AuthenticatingAuthorityFromString(
self.authenticating_authority.to_string())
assert new_authenticating_authority.text == self.text
assert self.authenticating_authority.to_string() == \
new_authenticating_authority.to_string()
def testUsingTestData(self):
"""Test AuthenticatingAuthorityFromString() using test data"""
authenticating_authority = saml.AuthenticatingAuthorityFromString(
test_data.TEST_AUTHENTICATING_AUTHORITY)
assert authenticating_authority.text.strip() == self.text
class TestAuthnContext:
def setup_class(self):
self.authn_context = saml.AuthnContext()
def testAccessors(self):
"""Test for AuthnContext accessors"""
self.authn_context.authn_context_class_ref = \
saml.AuthnContextClassRefFromString(
test_data.TEST_AUTHN_CONTEXT_CLASS_REF)
self.authn_context.authn_context_decl_ref = \
saml.AuthnContextDeclRefFromString(
test_data.TEST_AUTHN_CONTEXT_DECL_REF)
self.authn_context.authn_context_decl = \
saml.AuthnContextDeclFromString(
test_data.TEST_AUTHN_CONTEXT_DECL)
self.authn_context.authenticating_authority.append(
saml.AuthenticatingAuthorityFromString(
test_data.TEST_AUTHENTICATING_AUTHORITY))
assert self.authn_context.authn_context_class_ref.text.strip() == \
"http://www.sios.com/authnContextClassRef"
assert self.authn_context.authn_context_decl_ref.text.strip() == \
"http://www.sios.com/authnContextDeclRef"
assert self.authn_context.authn_context_decl.text.strip() == \
"http://www.sios.com/authnContextDecl"
assert self.authn_context.authenticating_authority[0].text.strip() == \
"http://www.sios.com/authenticatingAuthority"
new_authn_context = saml.AuthnContextFromString(
self.authn_context.to_string())
assert self.authn_context.to_string() == new_authn_context.to_string()
def testUsingTestData(self):
"""Test AuthnContextFromString() using test data"""
authn_context = saml.AuthnContextFromString(test_data.TEST_AUTHN_CONTEXT)
assert authn_context.authn_context_class_ref.text.strip() == \
saml.URN_PASSWORD
class TestAuthnStatement:
def setup_class(self):
self.authn_statem = saml.AuthnStatement()
def testAccessors(self):
"""Test for AuthnStatement accessors"""
self.authn_statem.authn_instant = "2007-08-31T01:05:02Z"
self.authn_statem.session_not_on_or_after = "2007-09-14T01:05:02Z"
self.authn_statem.session_index = "sessionindex"
self.authn_statem.authn_context = saml.AuthnContext()
self.authn_statem.authn_context.authn_context_class_ref = \
saml.AuthnContextClassRefFromString(
test_data.TEST_AUTHN_CONTEXT_CLASS_REF)
self.authn_statem.authn_context.authn_context_decl_ref = \
saml.AuthnContextDeclRefFromString(
test_data.TEST_AUTHN_CONTEXT_DECL_REF)
self.authn_statem.authn_context.authn_context_decl = \
saml.AuthnContextDeclFromString(
test_data.TEST_AUTHN_CONTEXT_DECL)
self.authn_statem.authn_context.authenticating_authority.append(
saml.AuthenticatingAuthorityFromString(
test_data.TEST_AUTHENTICATING_AUTHORITY))
new_as = saml.AuthnStatementFromString(self.authn_statem.to_string())
assert new_as.authn_instant == "2007-08-31T01:05:02Z"
assert new_as.session_index == "sessionindex"
assert new_as.session_not_on_or_after == "2007-09-14T01:05:02Z"
assert new_as.authn_context.authn_context_class_ref.text.strip() == \
"http://www.sios.com/authnContextClassRef"
assert new_as.authn_context.authn_context_decl_ref.text.strip() == \
"http://www.sios.com/authnContextDeclRef"
assert new_as.authn_context.authn_context_decl.text.strip() == \
"http://www.sios.com/authnContextDecl"
assert new_as.authn_context.authenticating_authority[0].text.strip() \
== "http://www.sios.com/authenticatingAuthority"
assert self.authn_statem.to_string() == new_as.to_string()
def testUsingTestData(self):
"""Test AuthnStatementFromString() using test data"""
authn_statem = saml.AuthnStatementFromString(test_data.TEST_AUTHN_STATEMENT)
assert authn_statem.authn_instant == "2007-08-31T01:05:02Z"
assert authn_statem.session_not_on_or_after == "2007-09-14T01:05:02Z"
assert authn_statem.authn_context.authn_context_class_ref.text.strip() == \
saml.URN_PASSWORD
class TestAttributeValue:
def setup_class(self):
self.attribute_value = saml.AttributeValue()
self.text = "value for test attribute"
def testAccessors(self):
"""Test for AttributeValue accessors"""
self.attribute_value.text = self.text
new_attribute_value = saml.AttributeValueFromString(
self.attribute_value.to_string())
assert new_attribute_value.text.strip() == self.text
def testUsingTestData(self):
"""Test AttributeValueFromString() using test data"""
attribute_value = saml.AttributeValueFromString(
test_data.TEST_ATTRIBUTE_VALUE)
assert attribute_value.text.strip() == self.text
class TestAttribute:
def setup_class(self):
self.attribute = saml.Attribute()
self.text = ["value of test attribute",
"value1 of test attribute",
"value2 of test attribute"]
def testAccessors(self):
"""Test for Attribute accessors"""
self.attribute.name = "testAttribute"
self.attribute.name_format = saml.NAME_FORMAT_URI
self.attribute.friendly_name = "test attribute"
self.attribute.attribute_value.append(saml.AttributeValue())
self.attribute.attribute_value[0].text = self.text[0]
new_attribute = saml.AttributeFromString(self.attribute.to_string())
assert new_attribute.name == "testAttribute"
assert new_attribute.name_format == saml.NAME_FORMAT_URI
assert new_attribute.friendly_name == "test attribute"
assert new_attribute.attribute_value[0].text.strip() == self.text[0]
def testUsingTestData(self):
"""Test AttributeFromString() using test data"""
attribute = saml.AttributeFromString(test_data.TEST_ATTRIBUTE)
assert attribute.name == "testAttribute"
assert attribute.name_format == saml.NAME_FORMAT_UNSPECIFIED
assert attribute.friendly_name == "test attribute"
assert attribute.attribute_value[0].text.strip() == self.text[1]
assert attribute.attribute_value[1].text.strip() == self.text[2]
# test again
attribute = saml.AttributeFromString(attribute.to_string())
assert attribute.name == "testAttribute"
assert attribute.name_format == saml.NAME_FORMAT_UNSPECIFIED
assert attribute.friendly_name == "test attribute"
assert attribute.attribute_value[0].text.strip() == self.text[1]
assert attribute.attribute_value[1].text.strip() == self.text[2]
class TestAttributeStatement:
def setup_class(self):
self.attr_statem = saml.AttributeStatement()
self.text = ["value of test attribute",
"value1 of test attribute",
"value2 of test attribute"]
def testAccessors(self):
"""Test for Attribute accessors"""
self.attr_statem.attribute.append(saml.Attribute())
self.attr_statem.attribute.append(saml.Attribute())
self.attr_statem.attribute[0].name = "testAttribute"
self.attr_statem.attribute[0].name_format = saml.NAME_FORMAT_URI
self.attr_statem.attribute[0].friendly_name = "test attribute"
self.attr_statem.attribute[0].attribute_value.append(saml.AttributeValue())
self.attr_statem.attribute[0].attribute_value[0].text = self.text[0]
self.attr_statem.attribute[1].name = "testAttribute2"
self.attr_statem.attribute[1].name_format = saml.NAME_FORMAT_UNSPECIFIED
self.attr_statem.attribute[1].friendly_name = self.text[2]
self.attr_statem.attribute[1].attribute_value.append(saml.AttributeValue())
self.attr_statem.attribute[1].attribute_value[0].text = self.text[2]
new_as = saml.AttributeStatementFromString(self.attr_statem.to_string())
assert new_as.attribute[0].name == "testAttribute"
assert new_as.attribute[0].name_format == saml.NAME_FORMAT_URI
assert new_as.attribute[0].friendly_name == "test attribute"
assert new_as.attribute[0].attribute_value[0].text.strip() == self.text[0]
assert new_as.attribute[1].name == "testAttribute2"
assert new_as.attribute[1].name_format == saml.NAME_FORMAT_UNSPECIFIED
assert new_as.attribute[1].friendly_name == "test attribute2"
assert new_as.attribute[1].attribute_value[0].text.strip() == self.text[2]
def testUsingTestData(self):
"""Test AttributeStatementFromString() using test data"""
attr_statem = saml.AttributeStatementFromString(test_data.TEST_ATTRIBUTE_STATEMENT)
assert attr_statem.attribute[0].name == "testAttribute"
assert attr_statem.attribute[0].name_format == saml.NAME_FORMAT_UNSPECIFIED
assert attr_statem.attribute[0].friendly_name == "test attribute"
assert attr_statem.attribute[0].attribute_value[0].text.strip() == self.text[1]
assert attr_statem.attribute[0].attribute_value[1].text.strip() == self.text[2]
assert attr_statem.attribute[1].name == "http://www.sios.com/testAttribute2"
assert attr_statem.attribute[1].name_format == saml.NAME_FORMAT_URI
assert attr_statem.attribute[1].friendly_name == "test attribute2"
assert attr_statem.attribute[1].attribute_value[0].text.strip() == self.text[1]
assert attr_statem.attribute[1].attribute_value[1].text.strip() == self.text[2]
# test again
attr_statem2 = saml.AttributeStatementFromString(attr_statem.to_string())
assert attr_statem2.attribute[0].name == "testAttribute"
assert attr_statem2.attribute[0].name_format == saml.NAME_FORMAT_UNSPECIFIED
assert attr_statem2.attribute[0].friendly_name == "test attribute"
assert attr_statem2.attribute[0].attribute_value[0].text.strip() == self.text[1]
assert attr_statem2.attribute[0].attribute_value[1].text.strip() == self.text[2]
assert attr_statem2.attribute[1].name == "http://www.sios.com/testAttribute2"
assert attr_statem2.attribute[1].name_format == saml.NAME_FORMAT_URI
assert attr_statem2.attribute[1].friendly_name == "test attribute2"
assert attr_statem2.attribute[1].attribute_value[0].text.strip() == self.text[1]
assert attr_statem2.attribute[1].attribute_value[1].text.strip() == self.text[2]
class TestSubjectConfirmationData:
def setup_class(self):
self.scd = saml.SubjectConfirmationData()
def testAccessors(self):
"""Test for SubjectConfirmationData accessors"""
self.scd.not_before = "2007-08-31T01:05:02Z"
self.scd.not_on_or_after = "2007-09-14T01:05:02Z"
self.scd.recipient = "recipient"
self.scd.in_response_to = "responseID"
self.scd.address = "127.0.0.1"
new_scd = saml.SubjectConfirmationDataFromString(self.scd.to_string())
assert new_scd.not_before == "2007-08-31T01:05:02Z"
assert new_scd.not_on_or_after == "2007-09-14T01:05:02Z"
assert new_scd.recipient == "recipient"
assert new_scd.in_response_to == "responseID"
assert new_scd.address == "127.0.0.1"
def testUsingTestData(self):
"""Test SubjectConfirmationDataFromString() using test data"""
scd = saml.SubjectConfirmationDataFromString(
test_data.TEST_SUBJECT_CONFIRMATION_DATA)
assert scd.not_before == "2007-08-31T01:05:02Z"
assert scd.not_on_or_after == "2007-09-14T01:05:02Z"
assert scd.recipient == "recipient"
assert scd.in_response_to == "responseID"
assert scd.address == "127.0.0.1"
class TestSubjectConfirmation:
def setup_class(self):
self.sc = saml.SubjectConfirmation()
def testAccessors(self):
"""Test for SubjectConfirmation accessors"""
self.sc.name_id = saml.NameIDFromString(test_data.TEST_NAME_ID)
self.sc.method = saml.SUBJECT_CONFIRMATION_METHOD_BEARER
self.sc.subject_confirmation_data = saml.SubjectConfirmationDataFromString(
test_data.TEST_SUBJECT_CONFIRMATION_DATA)
new_sc = saml.SubjectConfirmationFromString(self.sc.to_string())
assert new_sc.name_id.sp_provided_id == "sp provided id"
assert new_sc.method == saml.SUBJECT_CONFIRMATION_METHOD_BEARER
assert new_sc.subject_confirmation_data.not_before == \
"2007-08-31T01:05:02Z"
assert new_sc.subject_confirmation_data.not_on_or_after == \
"2007-09-14T01:05:02Z"
assert new_sc.subject_confirmation_data.recipient == "recipient"
assert new_sc.subject_confirmation_data.in_response_to == "responseID"
assert new_sc.subject_confirmation_data.address == "127.0.0.1"
def testUsingTestData(self):
"""Test SubjectConfirmationFromString() using test data"""
sc = saml.SubjectConfirmationFromString(
test_data.TEST_SUBJECT_CONFIRMATION)
assert sc.name_id.sp_provided_id == "sp provided id"
assert sc.method == saml.SUBJECT_CONFIRMATION_METHOD_BEARER
assert sc.subject_confirmation_data.not_before == "2007-08-31T01:05:02Z"
assert sc.subject_confirmation_data.not_on_or_after == "2007-09-14T01:05:02Z"
assert sc.subject_confirmation_data.recipient == "recipient"
assert sc.subject_confirmation_data.in_response_to == "responseID"
assert sc.subject_confirmation_data.address == "127.0.0.1"
class TestSubject:
def setup_class(self):
self.subject = saml.Subject()
def testAccessors(self):
"""Test for Subject accessors"""
self.subject.name_id = saml.NameIDFromString(test_data.TEST_NAME_ID)
self.subject.subject_confirmation.append(
saml.SubjectConfirmationFromString(
test_data.TEST_SUBJECT_CONFIRMATION))
new_subject = saml.SubjectFromString(self.subject.to_string())
assert new_subject.name_id.sp_provided_id == "sp provided id"
assert new_subject.name_id.text.strip() == "tmatsuo@sios.com"
assert new_subject.name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS
assert isinstance(new_subject.subject_confirmation[0],
saml.SubjectConfirmation)
def testUsingTestData(self):
"""Test for SubjectFromString() using test data."""
subject = saml.SubjectFromString(test_data.TEST_SUBJECT)
assert subject.name_id.sp_provided_id == "sp provided id"
assert subject.name_id.text.strip() == "tmatsuo@sios.com"
assert subject.name_id.format == saml.NAMEID_FORMAT_EMAILADDRESS
assert isinstance(subject.subject_confirmation[0],
saml.SubjectConfirmation)
class TestCondition:
def setup_class(self):
self.condition = saml.Condition()
self.name = "{%s}type" % saml.XSI_NAMESPACE
def testAccessors(self):
"""Test for Condition accessors."""
self.condition.extension_attributes[self.name] = "test"
self.condition.extension_attributes['ExtendedAttribute'] = "value"
new_condition = saml.ConditionFromString(self.condition.to_string())
assert new_condition.extension_attributes[self.name] == "test"
assert new_condition.extension_attributes["ExtendedAttribute"] == "value"
def testUsingTestData(self):
"""Test for ConditionFromString() using test data."""
condition = saml.ConditionFromString(test_data.TEST_CONDITION)
assert condition.extension_attributes[self.name] == "test"
assert condition.extension_attributes["ExtendedAttribute"] == "value"
class TestAudience:
def setup_class(self):
self.audience = saml.Audience()
def testAccessors(self):
"""Test for Audience accessors"""
self.audience.text = "http://www.sios.com/Audience"
new_audience = saml.AudienceFromString(self.audience.to_string())
assert new_audience.text.strip() == "http://www.sios.com/Audience"
def testUsingTestData(self):
"""Test AudienceFromString using test data"""
audience = saml.AudienceFromString(test_data.TEST_AUDIENCE)
assert audience.text.strip() == "http://www.sios.com/Audience"
class TestAudienceRestriction:
def setup_class(self):
self.audience_restriction = saml.AudienceRestriction()
def testAccessors(self):
"""Test for AudienceRestriction accessors"""
self.audience_restriction.audience = \
saml.AudienceFromString(test_data.TEST_AUDIENCE)
new_audience = saml.AudienceRestrictionFromString(
self.audience_restriction.to_string())
assert self.audience_restriction.audience.text.strip() == \
"http://www.sios.com/Audience"
def testUsingTestData(self):
"""Test AudienceRestrictionFromString using test data"""
audience_restriction = saml.AudienceRestrictionFromString(
test_data.TEST_AUDIENCE_RESTRICTION)
assert audience_restriction.audience.text.strip() == \
"http://www.sios.com/Audience"
class TestOneTimeUse:
def setup_class(self):
self.one_time_use = saml.OneTimeUse()
def testAccessors(self):
"""Test for OneTimeUse accessors"""
assert isinstance(self.one_time_use, saml.OneTimeUse)
assert isinstance(self.one_time_use, saml.Condition)
def testUsingTestData(self):
"""Test OneTimeUseFromString() using test data"""
one_time_use = saml.OneTimeUseFromString(test_data.TEST_ONE_TIME_USE)
assert isinstance(one_time_use, saml.OneTimeUse)
assert isinstance(one_time_use, saml.Condition)
class TestProxyRestriction:
def setup_class(self):
self.proxy_restriction = saml.ProxyRestriction()
def testAccessors(self):
"""Test for ProxyRestriction accessors"""
assert isinstance(self.proxy_restriction, saml.Condition)
self.proxy_restriction.count = "2"
self.proxy_restriction.audience.append(saml.AudienceFromString(
test_data.TEST_AUDIENCE))
new_proxy_restriction = saml.ProxyRestrictionFromString(
self.proxy_restriction.to_string())
assert new_proxy_restriction.count == "2"
assert new_proxy_restriction.audience[0].text.strip() == \
"http://www.sios.com/Audience"
def testUsingTestData(self):
"""Test ProxyRestrictionFromString() using test data"""
proxy_restriction = saml.ProxyRestrictionFromString(
test_data.TEST_PROXY_RESTRICTION)
assert proxy_restriction.count == "2"
assert proxy_restriction.audience[0].text.strip() == \
"http://www.sios.com/Audience"
class TestConditions:
def setup_class(self):
self.conditions = saml.Conditions()
def testAccessors(self):
"""Test for Conditions accessors"""
self.conditions.not_before = "2007-08-31T01:05:02Z"
self.conditions.not_on_or_after = "2007-09-14T01:05:02Z"
self.conditions.condition.append(saml.Condition())
self.conditions.audience_restriction.append(saml.AudienceRestriction())
self.conditions.one_time_use.append(saml.OneTimeUse())
self.conditions.proxy_restriction.append(saml.ProxyRestriction())
new_conditions = saml.ConditionsFromString(self.conditions.to_string())
assert new_conditions.not_before == "2007-08-31T01:05:02Z"
assert new_conditions.not_on_or_after == "2007-09-14T01:05:02Z"
assert isinstance(new_conditions.condition[0], saml.Condition)
assert isinstance(new_conditions.audience_restriction[0],
saml.AudienceRestriction)
assert isinstance(new_conditions.one_time_use[0],
saml.OneTimeUse)
assert isinstance(new_conditions.proxy_restriction[0],
saml.ProxyRestriction)
def testUsingTestData(self):
"""Test ConditionsFromString() using test data"""
new_conditions = saml.ConditionsFromString(test_data.TEST_CONDITIONS)
assert new_conditions.not_before == "2007-08-31T01:05:02Z"
assert new_conditions.not_on_or_after == "2007-09-14T01:05:02Z"
assert isinstance(new_conditions.condition[0], saml.Condition)
assert isinstance(new_conditions.audience_restriction[0],
saml.AudienceRestriction)
assert isinstance(new_conditions.one_time_use[0],
saml.OneTimeUse)
assert isinstance(new_conditions.proxy_restriction[0],
saml.ProxyRestriction)
class TestAssertionIDRef:
def setup_class(self):
self.assertion_id_ref = saml.AssertionIDRef()
def testAccessors(self):
"""Test for AssertionIDRef accessors"""
self.assertion_id_ref.text = "zzlieajngjbkjggjldmgindkckkolcblndbghlhm"
new_assertion_id_ref = saml.AssertionIDRefFromString(
self.assertion_id_ref.to_string())
assert new_assertion_id_ref.text == \
"zzlieajngjbkjggjldmgindkckkolcblndbghlhm"
def testUsingTestData(self):
"""Test AssertionIDRefFromString() using test data"""
new_assertion_id_ref = saml.AssertionIDRefFromString(
test_data.TEST_ASSERTION_ID_REF)
assert new_assertion_id_ref.text.strip() == \
"zzlieajngjbkjggjldmgindkckkolcblndbghlhm"
class TestAssertionURIRef:
def setup_class(self):
self.assertion_uri_ref = saml.AssertionURIRef()
def testAccessors(self):
"""Test for AssertionURIRef accessors"""
self.assertion_uri_ref.text = "http://www.sios.com/AssertionURIRef"
new_assertion_uri_ref = saml.AssertionURIRefFromString(
self.assertion_uri_ref.to_string())
assert new_assertion_uri_ref.text == \
"http://www.sios.com/AssertionURIRef"
def testUsingTestData(self):
"""Test AssertionURIRefFromString() using test data"""
new_assertion_uri_ref = saml.AssertionURIRefFromString(
test_data.TEST_ASSERTION_URI_REF)
assert new_assertion_uri_ref.text.strip() == \
"http://www.sios.com/AssertionURIRef"
class TestAction:
def setup_class(self):
self.action = saml.Action()
def testAccessors(self):
"""Test for Action accessors"""
self.action.namespace = "http://www.sios.com/Namespace"
new_action = saml.ActionFromString(self.action.to_string())
assert new_action.namespace == "http://www.sios.com/Namespace"
def testUsingTestData(self):
"""Test ActionFromString() using test data"""
new_action = saml.ActionFromString(test_data.TEST_ACTION)
assert new_action.namespace == "http://www.sios.com/Namespace"
class TestEvidence:
def setup_class(self):
self.evidence = saml.Evidence()
def testAccessors(self):
"""Test for Evidence accessors"""
self.evidence.assertion_id_ref.append(saml.AssertionIDRef())
self.evidence.assertion_uri_ref.append(saml.AssertionURIRef())
self.evidence.assertion.append(saml.Assertion())
self.evidence.encrypted_assertion.append(saml.EncryptedAssertion())
new_evidence = saml.EvidenceFromString(self.evidence.to_string())
assert self.evidence.to_string() == new_evidence.to_string()
assert isinstance(new_evidence.assertion_id_ref[0],
saml.AssertionIDRef)
assert isinstance(new_evidence.assertion_uri_ref[0],
saml.AssertionURIRef)
assert isinstance(new_evidence.assertion[0], saml.Assertion)
assert isinstance(new_evidence.encrypted_assertion[0],
saml.EncryptedAssertion)
def testUsingTestData(self):
"""Test EvidenceFromString() using test data"""
# TODO:
pass
class TestAuthzDecisionStatement:
def setup_class(self):
self.authz_decision_statement = saml.AuthzDecisionStatement()
def testAccessors(self):
"""Test for AuthzDecisionStatement accessors"""
self.authz_decision_statement.resource = "http://www.sios.com/Resource"
self.authz_decision_statement.decision = saml.DECISION_TYPE_PERMIT
self.authz_decision_statement.action.append(saml.Action())
self.authz_decision_statement.evidence.append(saml.Evidence())
new_authz_decision_statement = saml.AuthzDecisionStatementFromString(
self.authz_decision_statement.to_string())
assert self.authz_decision_statement.to_string() == \
new_authz_decision_statement.to_string()
assert new_authz_decision_statement.resource == \
"http://www.sios.com/Resource"
assert new_authz_decision_statement.decision == \
saml.DECISION_TYPE_PERMIT
assert isinstance(new_authz_decision_statement.action[0],
saml.Action)
assert isinstance(new_authz_decision_statement.evidence[0],
saml.Evidence)
def testUsingTestData(self):
"""Test AuthzDecisionStatementFromString() using test data"""
# TODO:
pass
class TestAdvice:
def setup_class(self):
self.advice = saml.Advice()
def testAccessors(self):
"""Test for Advice accessors"""
self.advice.assertion_id_ref.append(saml.AssertionIDRef())
self.advice.assertion_uri_ref.append(saml.AssertionURIRef())
self.advice.assertion.append(saml.Assertion())
self.advice.encrypted_assertion.append(saml.EncryptedAssertion())
new_advice = saml.AdviceFromString(self.advice.to_string())
assert self.advice.to_string() == new_advice.to_string()
assert isinstance(new_advice.assertion_id_ref[0],
saml.AssertionIDRef)
assert isinstance(new_advice.assertion_uri_ref[0],
saml.AssertionURIRef)
assert isinstance(new_advice.assertion[0], saml.Assertion)
assert isinstance(new_advice.encrypted_assertion[0],
saml.EncryptedAssertion)
def testUsingTestData(self):
"""Test AdviceFromString() using test data"""
# TODO:
pass
class TestAssertion:
def setup_class(self):
self.assertion = saml.Assertion()
def testAccessors(self):
"""Test for Assertion accessors"""
self.assertion.id = "assertion id"
self.assertion.version = saml.V2
self.assertion.issue_instant = "2007-08-31T01:05:02Z"
self.assertion.issuer = saml.IssuerFromString(test_data.TEST_ISSUER)
self.assertion.signature = ds.SignatureFromString(
ds_test_data.TEST_SIGNATURE)
self.assertion.subject = saml.SubjectFromString(test_data.TEST_SUBJECT)
self.assertion.conditions = saml.ConditionsFromString(
test_data.TEST_CONDITIONS)
self.assertion.advice = saml.Advice()
self.assertion.statement.append(saml.Statement())
self.assertion.authn_statement.append(saml.AuthnStatementFromString(
test_data.TEST_AUTHN_STATEMENT))
self.assertion.authz_decision_statement.append(
saml.AuthzDecisionStatement())
self.assertion.attribute_statement.append(
saml.AttributeStatementFromString(
test_data.TEST_ATTRIBUTE_STATEMENT))
new_assertion = saml.AssertionFromString(self.assertion.to_string())
assert new_assertion.id == "assertion id"
assert new_assertion.version == saml.V2
assert new_assertion.issue_instant == "2007-08-31T01:05:02Z"
assert isinstance(new_assertion.issuer, saml.Issuer)
assert isinstance(new_assertion.signature, ds.Signature)
assert isinstance(new_assertion.subject, saml.Subject)
assert isinstance(new_assertion.conditions, saml.Conditions)
assert isinstance(new_assertion.advice, saml.Advice)
assert isinstance(new_assertion.statement[0], saml.Statement)
assert isinstance(new_assertion.authn_statement[0],
saml.AuthnStatement)
assert isinstance(new_assertion.authz_decision_statement[0],
saml.AuthzDecisionStatement)
assert isinstance(new_assertion.attribute_statement[0],
saml.AttributeStatement)
def testUsingTestData(self):
"""Test AssertionFromString() using test data"""
# TODO
pass