mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
ipalib.rpc: now using allow_none=True after conversation with Rob; added xml_dumps() and xml_loads() functions; some name cleanup
This commit is contained in:
parent
2f829d015b
commit
6be5e4a0a5
@ -22,10 +22,10 @@ Core RPC functionality.
|
||||
"""
|
||||
|
||||
from types import NoneType
|
||||
from xmlrpclib import Binary
|
||||
from xmlrpclib import Binary, Fault, dumps, loads
|
||||
|
||||
|
||||
def xmlrpc_wrap(value):
|
||||
def xml_wrap(value):
|
||||
"""
|
||||
Wrap all ``str`` in ``xmlrpclib.Binary``.
|
||||
|
||||
@ -42,13 +42,13 @@ def xmlrpc_wrap(value):
|
||||
converted to UTF-8 encoded ``str`` instances (although as mentioned,
|
||||
not by this function).
|
||||
|
||||
Also see `xmlrpc_unwrap`.
|
||||
Also see `xml_unwrap`.
|
||||
"""
|
||||
if type(value) in (list, tuple):
|
||||
return tuple(xmlrpc_wrap(v) for v in value)
|
||||
return tuple(xml_wrap(v) for v in value)
|
||||
if type(value) is dict:
|
||||
return dict(
|
||||
(k, xmlrpc_wrap(v)) for (k, v) in value.iteritems()
|
||||
(k, xml_wrap(v)) for (k, v) in value.iteritems()
|
||||
)
|
||||
if type(value) is str:
|
||||
return Binary(value)
|
||||
@ -56,7 +56,7 @@ def xmlrpc_wrap(value):
|
||||
return value
|
||||
|
||||
|
||||
def xmlrpc_unwrap(value, encoding='UTF-8'):
|
||||
def xml_unwrap(value, encoding='UTF-8'):
|
||||
"""
|
||||
Unwrap all ``xmlrpc.Binary``, decode all ``str`` into ``unicode``.
|
||||
|
||||
@ -69,13 +69,13 @@ def xmlrpc_unwrap(value, encoding='UTF-8'):
|
||||
* All ``str`` instances are treated as UTF-8 encoded character data.
|
||||
They are decoded and the resulting ``unicode`` instance is returned.
|
||||
|
||||
Also see `xmlrpc_wrap`.
|
||||
Also see `xml_wrap`.
|
||||
"""
|
||||
if type(value) in (list, tuple):
|
||||
return tuple(xmlrpc_unwrap(v, encoding) for v in value)
|
||||
return tuple(xml_unwrap(v, encoding) for v in value)
|
||||
if type(value) is dict:
|
||||
return dict(
|
||||
(k, xmlrpc_unwrap(v, encoding)) for (k, v) in value.iteritems()
|
||||
(k, xml_unwrap(v, encoding)) for (k, v) in value.iteritems()
|
||||
)
|
||||
if type(value) is str:
|
||||
return value.decode(encoding)
|
||||
@ -84,3 +84,21 @@ def xmlrpc_unwrap(value, encoding='UTF-8'):
|
||||
return value.data
|
||||
assert type(value) in (unicode, int, float, bool, NoneType)
|
||||
return value
|
||||
|
||||
|
||||
def xml_dumps(params, methodname=None, methodresponse=False, encoding='UTF-8'):
|
||||
if type(params) is tuple:
|
||||
params = xml_wrap(params)
|
||||
else:
|
||||
assert isinstance(params, Fault)
|
||||
return dumps(params,
|
||||
methodname=methodname,
|
||||
methodresponse=methodresponse,
|
||||
encoding=encoding,
|
||||
allow_none=True,
|
||||
)
|
||||
|
||||
|
||||
def xml_loads(data):
|
||||
(params, method) = loads(data)
|
||||
return (xml_unwrap(params), method)
|
||||
|
@ -24,7 +24,7 @@ Execute an RPC request.
|
||||
from xmlrpclib import dumps, loads, Fault
|
||||
from ipalib import Backend
|
||||
from ipalib.errors import HandledError, CommandError
|
||||
from ipalib.rpc import xmlrpc_wrap, xmlrpc_unwrap
|
||||
from ipalib.rpc import xml_wrap, xml_unwrap
|
||||
|
||||
|
||||
def params_2_args_options(params):
|
||||
@ -44,9 +44,9 @@ class xmlrpc(Backend):
|
||||
self.info('Received RPC call to %r', method)
|
||||
if method not in self.Command:
|
||||
raise CommandError(name=method)
|
||||
(args, options) = params_2_args_options(xmlrpc_unwrap(params))
|
||||
(args, options) = params_2_args_options(xml_unwrap(params))
|
||||
result = self.Command[method](*args, **options)
|
||||
return (xmlrpc_wrap(result),)
|
||||
return (xml_wrap(result),)
|
||||
|
||||
def execute(self, data, ccache=None, client_ip=None, locale=None):
|
||||
try:
|
||||
|
@ -21,64 +21,68 @@
|
||||
Test the `ipalib.rpc` module.
|
||||
"""
|
||||
|
||||
from xmlrpclib import Binary, dumps, loads
|
||||
from tests.util import raises
|
||||
from xmlrpclib import Binary, Fault, dumps, loads
|
||||
from tests.util import raises, assert_equal
|
||||
from tests.data import binary_bytes, utf8_bytes, unicode_str
|
||||
from ipalib import rpc
|
||||
|
||||
|
||||
def dump_n_load(value):
|
||||
(param, method) = loads(
|
||||
dumps((value,))
|
||||
dumps((value,), allow_none=True)
|
||||
)
|
||||
return param[0]
|
||||
|
||||
|
||||
def round_trip(value):
|
||||
return rpc.xmlrpc_unwrap(
|
||||
dump_n_load(rpc.xmlrpc_wrap(value))
|
||||
return rpc.xml_unwrap(
|
||||
dump_n_load(rpc.xml_wrap(value))
|
||||
)
|
||||
|
||||
|
||||
def test_round_trip():
|
||||
"""
|
||||
Test `ipalib.rpc.xmlrpc_wrap` and `ipalib.rpc.xmlrpc_unwrap`.
|
||||
Test `ipalib.rpc.xml_wrap` and `ipalib.rpc.xml_unwrap`.
|
||||
|
||||
This tests the two functions together with ``xmlrpclib.dumps()`` and
|
||||
``xmlrpclib.loads()`` in a full wrap/dumps/loads/unwrap round trip.
|
||||
"""
|
||||
# We first test that our assumptions about xmlrpclib module in the Python
|
||||
# standard library are correct:
|
||||
assert dump_n_load(utf8_bytes) == unicode_str
|
||||
assert dump_n_load(unicode_str) == unicode_str
|
||||
assert dump_n_load(Binary(binary_bytes)).data == binary_bytes
|
||||
assert_equal(dump_n_load(utf8_bytes), unicode_str)
|
||||
assert_equal(dump_n_load(unicode_str), unicode_str)
|
||||
assert_equal(dump_n_load(Binary(binary_bytes)).data, binary_bytes)
|
||||
assert isinstance(dump_n_load(Binary(binary_bytes)), Binary)
|
||||
assert type(dump_n_load('hello')) is str
|
||||
assert type(dump_n_load(u'hello')) is str
|
||||
assert_equal(dump_n_load(''), '')
|
||||
assert_equal(dump_n_load(u''), '')
|
||||
assert dump_n_load(None) is None
|
||||
|
||||
# Now we test our wrap and unwrap methods in combination with dumps, loads:
|
||||
# All str should come back str (because they get wrapped in
|
||||
# xmlrpclib.Binary(). All unicode should come back unicode because str
|
||||
# explicity get decoded by rpc.xmlrpc_unwrap() if they weren't already
|
||||
# explicity get decoded by rpc.xml_unwrap() if they weren't already
|
||||
# decoded by xmlrpclib.loads().
|
||||
assert round_trip(utf8_bytes) == utf8_bytes
|
||||
assert round_trip(unicode_str) == unicode_str
|
||||
assert round_trip(binary_bytes) == binary_bytes
|
||||
assert_equal(round_trip(utf8_bytes), utf8_bytes)
|
||||
assert_equal(round_trip(unicode_str), unicode_str)
|
||||
assert_equal(round_trip(binary_bytes), binary_bytes)
|
||||
assert type(round_trip('hello')) is str
|
||||
assert type(round_trip(u'hello')) is unicode
|
||||
assert round_trip('') == ''
|
||||
assert round_trip(u'') == u''
|
||||
compound = [utf8_bytes, unicode_str, binary_bytes,
|
||||
assert_equal(round_trip(''), '')
|
||||
assert_equal(round_trip(u''), u'')
|
||||
assert round_trip(None) is None
|
||||
compound = [utf8_bytes, None, binary_bytes, (None, unicode_str),
|
||||
dict(utf8=utf8_bytes, chars=unicode_str, data=binary_bytes)
|
||||
]
|
||||
assert round_trip(compound) == tuple(compound)
|
||||
|
||||
|
||||
def test_xmlrpc_wrap():
|
||||
def test_xml_wrap():
|
||||
"""
|
||||
Test the `ipalib.rpc.xmlrpc_wrap` function.
|
||||
Test the `ipalib.rpc.xml_wrap` function.
|
||||
"""
|
||||
f = rpc.xmlrpc_wrap
|
||||
f = rpc.xml_wrap
|
||||
assert f([]) == tuple()
|
||||
assert f({}) == dict()
|
||||
b = f('hello')
|
||||
@ -90,11 +94,11 @@ def test_xmlrpc_wrap():
|
||||
value = f([dict(one=False, two=u'hello'), None, 'hello'])
|
||||
|
||||
|
||||
def test_xmlrpc_unwrap():
|
||||
def test_xml_unwrap():
|
||||
"""
|
||||
Test the `ipalib.rpc.xmlrpc_unwrap` function.
|
||||
Test the `ipalib.rpc.xml_unwrap` function.
|
||||
"""
|
||||
f = rpc.xmlrpc_unwrap
|
||||
f = rpc.xml_unwrap
|
||||
assert f([]) == tuple()
|
||||
assert f({}) == dict()
|
||||
value = f(Binary(utf8_bytes))
|
||||
@ -106,3 +110,63 @@ def test_xmlrpc_unwrap():
|
||||
assert value == (True, 'hello', dict(one=1, two=unicode_str, three=None))
|
||||
assert type(value[1]) is str
|
||||
assert type(value[2]['two']) is unicode
|
||||
|
||||
|
||||
def test_xml_dumps():
|
||||
"""
|
||||
Test the `ipalib.rpc.xml_dumps` function.
|
||||
"""
|
||||
f = rpc.xml_dumps
|
||||
params = (binary_bytes, utf8_bytes, unicode_str, None)
|
||||
|
||||
# Test serializing an RPC request:
|
||||
data = f(params, 'the_method')
|
||||
(p, m) = loads(data)
|
||||
assert_equal(m, u'the_method')
|
||||
assert type(p) is tuple
|
||||
assert rpc.xml_unwrap(p) == params
|
||||
|
||||
# Test serializing an RPC response:
|
||||
data = f((params,), methodresponse=True)
|
||||
(tup, m) = loads(data)
|
||||
assert m is None
|
||||
assert len(tup) == 1
|
||||
assert type(tup) is tuple
|
||||
assert rpc.xml_unwrap(tup[0]) == params
|
||||
|
||||
# Test serializing an RPC response containing a Fault:
|
||||
fault = Fault(69, unicode_str)
|
||||
data = f(fault, methodresponse=True)
|
||||
e = raises(Fault, loads, data)
|
||||
assert e.faultCode == 69
|
||||
assert_equal(e.faultString, unicode_str)
|
||||
|
||||
|
||||
def test_xml_loads():
|
||||
"""
|
||||
Test the `ipalib.rpc.xml_loads` function.
|
||||
"""
|
||||
f = rpc.xml_loads
|
||||
params = (binary_bytes, utf8_bytes, unicode_str, None)
|
||||
wrapped = rpc.xml_wrap(params)
|
||||
|
||||
# Test un-serializing an RPC request:
|
||||
data = dumps(wrapped, 'the_method', allow_none=True)
|
||||
(p, m) = f(data)
|
||||
assert_equal(m, u'the_method')
|
||||
assert_equal(p, params)
|
||||
|
||||
# Test un-serializing an RPC response:
|
||||
data = dumps((wrapped,), methodresponse=True, allow_none=True)
|
||||
(tup, m) = f(data)
|
||||
assert m is None
|
||||
assert len(tup) == 1
|
||||
assert type(tup) is tuple
|
||||
assert_equal(tup[0], params)
|
||||
|
||||
# Test un-serializing an RPC response containing a Fault:
|
||||
fault = Fault(69, unicode_str)
|
||||
data = dumps(fault, methodresponse=True, allow_none=True)
|
||||
e = raises(Fault, f, data)
|
||||
assert e.faultCode == 69
|
||||
assert_equal(e.faultString, unicode_str)
|
||||
|
Loading…
Reference in New Issue
Block a user