Skip to content

Commit 806f4fa

Browse files
committed
unit test passes - ElementTree namespaces initialized globally in saml2.__init__
- code cleanup - SamlBase.register_prefix is now a staticmethod
1 parent ec9d640 commit 806f4fa

File tree

6 files changed

+42
-37
lines changed

6 files changed

+42
-37
lines changed

src/saml2/__init__.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,17 @@
5858
DS_NAMESPACE = 'http://www.w3.org/2000/09/xmldsig#'
5959
MD_NAMESPACE = "urn:oasis:names:tc:SAML:2.0:metadata"
6060
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-
}
69-
61+
XENC_NAMESPACE = "http://www.w3.org/2001/04/xmlenc#"
62+
63+
# this should be configurable by users
64+
OASIS_DEFAULT_NS_PREFIXES = {'saml': NAMESPACE, 'samlp': SAMLP_NAMESPACE,
65+
'ds': DS_NAMESPACE, 'xsi': XSI_NAMESPACE,
66+
'xs': XS_NAMESPACE,
67+
'mdui': MDUI_NAMESPACE,
68+
'md': MD_NAMESPACE,
69+
'xenc': XENC_NAMESPACE,
70+
# mdattr: <ns1:EntityAttributes>
71+
}
7072

7173
NAMEID_FORMAT_EMAILADDRESS = (
7274
"urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")
@@ -570,7 +572,8 @@ def _to_element_tree(self):
570572
self._add_members_to_element_tree(new_tree)
571573
return new_tree
572574

573-
def register_prefix(self, nspair):
575+
@staticmethod
576+
def register_prefix(nspair):
574577
"""
575578
Register with ElementTree a set of namespaces
576579
@@ -698,26 +701,23 @@ def fixup(name):
698701
del elem.attrib[key]
699702

700703
def to_string_force_namespace(self, nspair):
701-
702704
elem = self._to_element_tree()
703-
704705
self.set_prefixes(elem, nspair)
705-
706706
return ElementTree.tostring(elem, encoding="UTF-8")
707707

708-
def to_string(self, nspair=DEFAULT_NS_PREFIXES):
708+
def to_string(self, nspair=None):
709709
"""Converts the Saml object to a string containing XML.
710710
711711
:param nspair: A dictionary of prefixes and uris to use when
712712
constructing the text representation.
713713
:return: String representation of the object
714714
"""
715-
if not nspair and self.c_ns_prefix:
715+
if self.c_ns_prefix:
716716
nspair = self.c_ns_prefix
717717

718718
if nspair:
719719
self.register_prefix(nspair)
720-
720+
721721
return ElementTree.tostring(self._to_element_tree(), encoding="UTF-8")
722722

723723
def __str__(self):
@@ -1056,3 +1056,6 @@ def is_required_attribute(cls, attr):
10561056
:return: True if required
10571057
"""
10581058
return cls.c_attributes[attr][REQUIRED]
1059+
1060+
# this register preferred prefix namespaces
1061+
SamlBase.register_prefix(OASIS_DEFAULT_NS_PREFIXES)

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: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,15 @@
1010
def test_nsprefix():
1111
status_message = samlp.StatusMessage()
1212
status_message.text = "OK"
13-
13+
14+
status_message.register_prefix(nspair={"samla": saml.NAMESPACE,
15+
"samla": samlp.NAMESPACE})
1416
txt = "%s" % status_message
1517

16-
assert "ns0:StatusMessage" in txt
18+
assert "samla:StatusMessage" in txt
1719

18-
status_message.register_prefix({"saml2": saml.NAMESPACE,
19-
"saml2p": samlp.NAMESPACE})
20+
status_message.register_prefix(nspair={"saml2p": samlp.NAMESPACE,
21+
"saml2": saml.NAMESPACE})
2022

2123
txt = "%s" % status_message
2224

@@ -42,4 +44,4 @@ def test_nsprefix2():
4244
assert "saml2:Issuer" in txt
4345

4446
if __name__ == "__main__":
45-
test_nsprefix2()
47+
test_nsprefix2()

0 commit comments

Comments
 (0)