Skip to content

Commit 2be14b0

Browse files
committed
unit test passes - ElementTree namespaces initialized globally in saml2.__init__
1 parent ec9d640 commit 2be14b0

File tree

6 files changed

+59
-31
lines changed

6 files changed

+59
-31
lines changed

src/saml2/__init__.py

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
provides methods and functions to convert SAML classes to and from strings.
1818
"""
1919

20+
import copy
2021
import logging
2122

2223
import six
@@ -58,14 +59,28 @@
5859
DS_NAMESPACE = 'http://www.w3.org/2000/09/xmldsig#'
5960
MD_NAMESPACE = "urn:oasis:names:tc:SAML:2.0:metadata"
6061
MDUI_NAMESPACE = "urn:oasis:names:tc:SAML:metadata:ui"
61-
DEFAULT_NS_PREFIXES = {'saml': NAMESPACE, 'samlp': SAMLP_NAMESPACE,
62-
'ds': DS_NAMESPACE, 'xsi': XSI_NAMESPACE,
63-
'xs': XS_NAMESPACE,
64-
'mdui': MDUI_NAMESPACE,
65-
'md': MD_NAMESPACE,
66-
# 'alg': TODO: algsupport.DIGEST_METHODS|SIGNING_METHODS shoulb be moved before mapping them here
67-
# TODO: <ns1:EntityAttributes>
68-
}
62+
XENC_NAMESPACE = "http://www.w3.org/2001/04/xmlenc#"
63+
64+
# this should be configurable by users
65+
OASIS_DEFAULT_NS_PREFIXES = {'saml': NAMESPACE, 'samlp': SAMLP_NAMESPACE,
66+
'ds': DS_NAMESPACE, 'xsi': XSI_NAMESPACE,
67+
'xs': XS_NAMESPACE,
68+
'mdui': MDUI_NAMESPACE,
69+
'md': MD_NAMESPACE,
70+
'xenc': XENC_NAMESPACE,
71+
# mdattr: <ns1:EntityAttributes>
72+
}
73+
74+
75+
# make DEFAULT_NS_PREFIXES as default without register ns in every entities
76+
for prefix, uri in OASIS_DEFAULT_NS_PREFIXES.items():
77+
try:
78+
ElementTree.register_namespace(prefix, uri)
79+
except AttributeError:
80+
# Backwards compatibility with ET < 1.3
81+
ElementTree._namespace_map[uri] = prefix
82+
except ValueError:
83+
pass
6984

7085

7186
NAMEID_FORMAT_EMAILADDRESS = (
@@ -90,6 +105,13 @@
90105
BINDING_HTTP_ARTIFACT = 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact'
91106
BINDING_URI = 'urn:oasis:names:tc:SAML:2.0:bindings:URI'
92107

108+
def replace_ns_prefixes(value, ns):
109+
"""function to adapt ns to user's customs
110+
"""
111+
if not SWAPPED_NS_PREFIXES:
112+
return value
113+
return value.replace(DEFAULT_SWAPPED_NS_PREFIXES[ns],
114+
SWAPPED_NS_PREFIXES[ns])
93115

94116
def class_name(instance):
95117
return "%s:%s" % (instance.c_namespace, instance.c_tag)
@@ -705,19 +727,19 @@ def to_string_force_namespace(self, nspair):
705727

706728
return ElementTree.tostring(elem, encoding="UTF-8")
707729

708-
def to_string(self, nspair=DEFAULT_NS_PREFIXES):
730+
def to_string(self, nspair=None):
709731
"""Converts the Saml object to a string containing XML.
710732
711733
:param nspair: A dictionary of prefixes and uris to use when
712734
constructing the text representation.
713735
:return: String representation of the object
714736
"""
715-
if not nspair and self.c_ns_prefix:
737+
if self.c_ns_prefix:
716738
nspair = self.c_ns_prefix
717739

718740
if nspair:
719741
self.register_prefix(nspair)
720-
742+
721743
return ElementTree.tostring(self._to_element_tree(), encoding="UTF-8")
722744

723745
def __str__(self):

tests/test_02_saml.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,11 +226,11 @@ def test_to_string_nspair(self):
226226
foo = saml2.make_vals("lions", AttributeValue, part=True)
227227
txt = foo.to_string().decode('utf-8')
228228
nsstr = foo.to_string({"saml": saml.NAMESPACE}).decode('utf-8')
229-
assert nsstr != txt
229+
assert nsstr == txt # this must be the same
230230
print(txt)
231231
print(nsstr)
232232
assert "saml:AttributeValue" in nsstr
233-
assert "saml:AttributeValue" not in txt
233+
assert "saml:AttributeValue" in txt # this must be contained
234234

235235
def test_set_text_empty(self):
236236
av = AttributeValue()

tests/test_12_s_utils.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,25 @@
2020
XML_HEADER = '<?xml version=\'1.0\' encoding=\'UTF-8\'?>\n'
2121

2222
SUCCESS_STATUS_NO_HEADER = (
23-
'<ns0:Status xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol"><ns0'
23+
'<samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><samlp'
2424
':StatusCode '
25-
'Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></ns0:Status>')
25+
'Value="urn:oasis:names:tc:SAML:2.0:status:Success" /></samlp:Status>')
2626
SUCCESS_STATUS = '%s%s' % (XML_HEADER, SUCCESS_STATUS_NO_HEADER)
2727

2828
ERROR_STATUS_NO_HEADER = (
29-
'<ns0:Status xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol"><ns0'
29+
'<samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><samlp'
3030
':StatusCode '
31-
'Value="urn:oasis:names:tc:SAML:2.0:status:Responder"><ns0:StatusCode '
31+
'Value="urn:oasis:names:tc:SAML:2.0:status:Responder"><samlp:StatusCode '
3232
'Value="urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal" '
33-
'/></ns0:StatusCode><ns0:StatusMessage>Error resolving '
34-
'principal</ns0:StatusMessage></ns0:Status>')
33+
'/></samlp:StatusCode><samlp:StatusMessage>Error resolving '
34+
'principal</samlp:StatusMessage></samlp:Status>')
3535

3636
ERROR_STATUS_NO_HEADER_EMPTY = (
37-
'<ns0:Status xmlns:ns0="urn:oasis:names:tc:SAML:2.0:protocol"><ns0'
37+
'<samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"><samlp'
3838
':StatusCode '
39-
'Value="urn:oasis:names:tc:SAML:2.0:status:Responder"><ns0:StatusCode '
39+
'Value="urn:oasis:names:tc:SAML:2.0:status:Responder"><samlp:StatusCode '
4040
'Value="urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal" '
41-
'/></ns0:StatusCode></ns0:Status>')
41+
'/></samlp:StatusCode></samlp:Status>')
4242

4343
ERROR_STATUS = '%s%s' % (XML_HEADER, ERROR_STATUS_NO_HEADER)
4444
ERROR_STATUS_EMPTY = '%s%s' % (XML_HEADER, ERROR_STATUS_NO_HEADER_EMPTY)

tests/test_42_enc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
__author__ = 'roland'
1111

12-
TMPL_NO_HEADER = """<ns0:EncryptedData xmlns:ns0="http://www.w3.org/2001/04/xmlenc#" xmlns:ns1="http://www.w3.org/2000/09/xmldsig#" Id="ED" Type="http://www.w3.org/2001/04/xmlenc#Element"><ns0:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" /><ns1:KeyInfo><ns0:EncryptedKey Id="EK"><ns0:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /><ns1:KeyInfo><ns1:KeyName>my-rsa-key</ns1:KeyName></ns1:KeyInfo><ns0:CipherData><ns0:CipherValue /></ns0:CipherData></ns0:EncryptedKey></ns1:KeyInfo><ns0:CipherData><ns0:CipherValue /></ns0:CipherData></ns0:EncryptedData>"""
12+
TMPL_NO_HEADER = """<xenc:EncryptedData xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED" Type="http://www.w3.org/2001/04/xmlenc#Element"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc" /><ds:KeyInfo><xenc:EncryptedKey Id="EK"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5" /><ds:KeyInfo><ds:KeyName>my-rsa-key</ds:KeyName></ds:KeyInfo><xenc:CipherData><xenc:CipherValue /></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData><xenc:CipherValue /></xenc:CipherData></xenc:EncryptedData>"""
1313
TMPL = "<?xml version='1.0' encoding='UTF-8'?>\n%s" % TMPL_NO_HEADER
1414

1515
IDENTITY = {"eduPersonAffiliation": ["staff", "member"],

tests/test_51_client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1476,7 +1476,7 @@ def test_do_logout_post(self):
14761476
_dic = unpack_form(info["data"])
14771477
res = self.server.parse_logout_request(_dic["SAMLRequest"],
14781478
BINDING_HTTP_POST)
1479-
assert b'<ns0:SessionIndex>_foo</ns0:SessionIndex>' in res.xmlstr
1479+
assert b'<samlp:SessionIndex>_foo</samlp:SessionIndex>' in res.xmlstr
14801480

14811481
def test_do_logout_session_expired(self):
14821482
# information about the user from an IdP
@@ -1506,7 +1506,7 @@ def test_do_logout_session_expired(self):
15061506
_dic = unpack_form(info["data"])
15071507
res = self.server.parse_logout_request(_dic["SAMLRequest"],
15081508
BINDING_HTTP_POST)
1509-
assert b'<ns0:SessionIndex>_foo</ns0:SessionIndex>' in res.xmlstr
1509+
assert b'<samlp:SessionIndex>_foo</samlp:SessionIndex>' in res.xmlstr
15101510

15111511
def test_signature_wants(self):
15121512

@@ -3053,7 +3053,7 @@ def test_do_logout_post(self):
30533053
_dic = unpack_form(info["data"])
30543054
res = self.server.parse_logout_request(_dic["SAMLRequest"],
30553055
BINDING_HTTP_POST)
3056-
assert b'<ns0:SessionIndex>_foo</ns0:SessionIndex>' in res.xmlstr
3056+
assert b'<samlp:SessionIndex>_foo</samlp:SessionIndex>' in res.xmlstr
30573057

30583058
def test_do_logout_session_expired(self):
30593059
# information about the user from an IdP
@@ -3083,7 +3083,7 @@ def test_do_logout_session_expired(self):
30833083
_dic = unpack_form(info["data"])
30843084
res = self.server.parse_logout_request(_dic["SAMLRequest"],
30853085
BINDING_HTTP_POST)
3086-
assert b'<ns0:SessionIndex>_foo</ns0:SessionIndex>' in res.xmlstr
3086+
assert b'<samlp:SessionIndex>_foo</samlp:SessionIndex>' in res.xmlstr
30873087

30883088
# Below can only be done with dummy Server
30893089
IDP = "urn:mace:example.com:saml:roland:idp"

tests/test_88_nsprefix.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,18 @@ def test_nsprefix():
1111
status_message = samlp.StatusMessage()
1212
status_message.text = "OK"
1313

14+
# not possibile: ns0 -> raise ValueError("Prefix format reserved for internal use")
15+
#status_message.register_prefix(nspair={"ns0": saml.NAMESPACE,
16+
#"ns0": samlp.NAMESPACE})
17+
18+
status_message.register_prefix(nspair={"samla": saml.NAMESPACE,
19+
"samla": samlp.NAMESPACE})
1420
txt = "%s" % status_message
1521

16-
assert "ns0:StatusMessage" in txt
22+
assert "samla:StatusMessage" in txt
1723

18-
status_message.register_prefix({"saml2": saml.NAMESPACE,
19-
"saml2p": samlp.NAMESPACE})
24+
status_message.register_prefix(nspair={"saml2p": samlp.NAMESPACE,
25+
"saml2": saml.NAMESPACE})
2026

2127
txt = "%s" % status_message
2228

@@ -42,4 +48,4 @@ def test_nsprefix2():
4248
assert "saml2:Issuer" in txt
4349

4450
if __name__ == "__main__":
45-
test_nsprefix2()
51+
test_nsprefix2()

0 commit comments

Comments
 (0)