Skip to content

Commit 23b3bc5

Browse files
committed
Allow any namespace prefix
If the xsd string comes with a namespace prefix, it is left intact. If the xsd string has no namespace prefix and the xsd type is known, the xsd namespace is set to 'xs'. If the xsd string has no namespace and the type is unknown, the xsd namespace is left empty. Signed-off-by: Ivan Kanakarakis <[email protected]>
1 parent 6bf134b commit 23b3bc5

File tree

1 file changed

+45
-33
lines changed

1 file changed

+45
-33
lines changed

src/saml2/saml.py

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
SCM_SENDER_VOUCHES = "urn:oasis:names:tc:SAML:2.0:cm:sender-vouches"
8484
SCM_BEARER = "urn:oasis:names:tc:SAML:2.0:cm:bearer"
8585

86-
XSD = "xs:"
86+
XSD = "xs"
8787
NS_SOAP_ENC = "http://schemas.xmlsoap.org/soap/encoding/"
8888

8989

@@ -163,81 +163,81 @@ def clear_type(self):
163163
pass
164164

165165
def set_text(self, value, base64encode=False):
166-
def _wrong_type_value(xs_type, value):
167-
msg = _str('Type and value do not match: {xs_type}:{type}:{value}')
168-
msg = msg.format(xs_type=xs_type, type=type(value), value=value)
166+
def _wrong_type_value(xsd, value):
167+
msg = _str('Type and value do not match: {xsd}:{type}:{value}')
168+
msg = msg.format(xsd=xsd, type=type(value), value=value)
169169
raise ValueError(msg)
170170

171171
# only work with six.string_types
172172
_str = unicode if six.PY2 else str
173173
if isinstance(value, six.binary_type):
174174
value = value.decode()
175175

176-
xs_type_from_type = {
177-
_str: 'xs:string',
178-
int: 'xs:integer',
179-
float: 'xs:float',
180-
bool: 'xs:boolean',
176+
type_to_xsd = {
177+
_str: 'string',
178+
int: 'integer',
179+
float: 'float',
180+
bool: 'boolean',
181181
type(None): '',
182182
}
183183

184-
# entries of xs-types each declaring:
184+
# entries of xsd-types each declaring:
185185
# - a corresponding python type
186186
# - a function to turn a string into that type
187187
# - a function to turn that type into a text-value
188-
xs_types_map = {
189-
'xs:string': {
188+
xsd_types_props = {
189+
'string': {
190190
'type': _str,
191191
'to_type': _str,
192192
'to_text': _str,
193193
},
194-
'xs:integer': {
194+
'integer': {
195195
'type': int,
196196
'to_type': int,
197197
'to_text': _str,
198198
},
199-
'xs:short': {
199+
'short': {
200200
'type': int,
201201
'to_type': int,
202202
'to_text': _str,
203203
},
204-
'xs:int': {
204+
'int': {
205205
'type': int,
206206
'to_type': int,
207207
'to_text': _str,
208208
},
209-
'xs:long': {
209+
'long': {
210210
'type': int,
211211
'to_type': int,
212212
'to_text': _str,
213213
},
214-
'xs:float': {
214+
'float': {
215215
'type': float,
216216
'to_type': float,
217217
'to_text': _str,
218218
},
219-
'xs:double': {
219+
'double': {
220220
'type': float,
221221
'to_type': float,
222222
'to_text': _str,
223223
},
224-
'xs:boolean': {
224+
'boolean': {
225225
'type': bool,
226226
'to_type': lambda x: {
227227
'true': True,
228228
'false': False,
229229
}[_str(x).lower()],
230230
'to_text': lambda x: _str(x).lower(),
231231
},
232-
'xs:base64Binary': {
232+
'base64Binary': {
233233
'type': _str,
234234
'to_type': _str,
235235
'to_text': lambda x:
236236
_b64_encode_fn(x.encode())
237237
if base64encode
238238
else x,
239239
},
240-
'xs:anyType': {
240+
'anyType': {
241241
'type': type(value),
242242
'to_type': lambda x: x,
243243
'to_text': lambda x: x,
@@ -249,29 +249,41 @@ def _wrong_type_value(xs_type, value):
249249
},
250250
}
251251

252-
xs_type = \
253-
'xs:base64Binary' \
254-
if base64encode \
255-
else self.get_type() \
256-
or xs_type_from_type.get(type(value), type(None))
257-
xs_type_map = xs_types_map.get(xs_type, {})
258-
valid_type = xs_type_map.get('type', type(None))
259-
to_type = xs_type_map.get('to_type', str)
260-
to_text = xs_type_map.get('to_text', str)
252+
xsd_string = (
253+
'base64Binary' if base64encode
254+
else self.get_type()
255+
or type_to_xsd.get(type(value)))
256+
257+
xsd_ns, xsd_type = (
258+
['', type(None)] if xsd_string is None
259+
else ['', ''] if xsd_string is ''
260+
else [
261+
XSD if xsd_string in xsd_types_props else '',
262+
xsd_string
263+
] if ':' not in xsd_string
264+
else xsd_string.split(':', 1))
265+
266+
xsd_type_props = xsd_types_props.get(xsd_type, {})
267+
valid_type = xsd_type_props.get('type', type(None))
268+
to_type = xsd_type_props.get('to_type', str)
269+
to_text = xsd_type_props.get('to_text', str)
261270

262271
# cast to correct type before type-checking
263272
if type(value) is _str and valid_type is not _str:
264273
try:
265274
value = to_type(value)
266275
except (TypeError, ValueError, KeyError) as e:
267276
# the cast failed
268-
_wrong_type_value(xs_type=xs_type, value=value)
277+
_wrong_type_value(xsd=xsd_type, value=value)
269278

270279
if type(value) is not valid_type:
271-
_wrong_type_value(xs_type=xs_type, value=value)
280+
_wrong_type_value(xsd=xsd_type, value=value)
272281

273282
text = to_text(value)
274-
self.set_type(xs_type)
283+
self.set_type(
284+
'{ns}:{type}'.format(ns=xsd_ns, type=xsd_type) if xsd_ns
285+
else xsd_type if xsd_type
286+
else '')
275287
SamlBase.__setattr__(self, 'text', text)
276288
return self
277289

0 commit comments

Comments
 (0)