Add missing docstrings and 1 unittest for LDAP utf-8 fixes
A minimal backport of these accepted master commits: https://review.openstack.org/#/c/82396/ https://review.openstack.org/#/c/82398/ https://review.openstack.org/#/c/82399/ was done for Icehouse in the following: https://review.openstack.org/#/c/91883/ In the above backport review it was requested docstrings be added for some functions and an additional unittest be added. That work was done for the Icehouse backport and was positively reviewed, at the same it was requested the those changes be reflected back into master so as not to lose them going forward. This patch does that, adds the docstrings and one additional small unittest. Change-Id: I881ba9b274692427d4c7b9f5357ee4735b4e6699 Related-Bug: #1172106
This commit is contained in:
parent
fb0e4c5ef1
commit
f1cb3d0fc3
|
@ -46,6 +46,15 @@ _utf8_encoder = codecs.getencoder('utf-8')
|
|||
|
||||
|
||||
def utf8_encode(value):
|
||||
"""Encode a basestring to UTF-8.
|
||||
|
||||
If the string is unicode encode it to UTF-8, if the string is
|
||||
str then assume it's already encoded. Otherwise raise a TypeError.
|
||||
|
||||
:param value: A basestring
|
||||
:returns: UTF-8 encoded version of value
|
||||
:raises: TypeError if value is not basestring
|
||||
"""
|
||||
if isinstance(value, six.text_type):
|
||||
return _utf8_encoder(value)[0]
|
||||
elif isinstance(value, six.binary_type):
|
||||
|
@ -58,12 +67,32 @@ _utf8_decoder = codecs.getdecoder('utf-8')
|
|||
|
||||
|
||||
def utf8_decode(value):
|
||||
"""Decode a from UTF-8 into unicode.
|
||||
|
||||
If the value is a binary string assume it's UTF-8 encoded and decode
|
||||
it into a unicode string. Otherwise convert the value from its
|
||||
type into a unicode string.
|
||||
|
||||
:param value: value to be returned as unicode
|
||||
:returns: value as unicode
|
||||
:raises: UnicodeDecodeError for invalid UTF-8 encoding
|
||||
"""
|
||||
if isinstance(value, six.binary_type):
|
||||
return _utf8_decoder(value)[0]
|
||||
return six.text_type(value)
|
||||
|
||||
|
||||
def py2ldap(val):
|
||||
"""Type convert a Python value to a type accepted by LDAP (unicode).
|
||||
|
||||
The LDAP API only accepts strings for values therefore convert
|
||||
the value's type to a unicode string. A subsequent type conversion
|
||||
will encode the unicode as UTF-8 as required by the python-ldap API,
|
||||
but for now we just want a string representation of the value.
|
||||
|
||||
:param val: The value to convert to a LDAP string representation
|
||||
:returns: unicode string representation of value.
|
||||
"""
|
||||
if isinstance(val, bool):
|
||||
return u'TRUE' if val else u'FALSE'
|
||||
else:
|
||||
|
@ -71,6 +100,15 @@ def py2ldap(val):
|
|||
|
||||
|
||||
def ldap2py(val):
|
||||
"""Convert an LDAP formatted value to Python type used by OpenStack.
|
||||
|
||||
Virtually all LDAP values are stored as UTF-8 encoded strings.
|
||||
OpenStack prefers values which are Python types, e.g. unicode,
|
||||
boolean, integer, etc.
|
||||
|
||||
:param val: LDAP formatted value
|
||||
:returns: val converted to preferred Python type
|
||||
"""
|
||||
try:
|
||||
return LDAP_VALUES[val]
|
||||
except KeyError:
|
||||
|
@ -83,6 +121,23 @@ def ldap2py(val):
|
|||
|
||||
|
||||
def convert_ldap_result(ldap_result):
|
||||
"""Convert LDAP search result to Python types used by OpenStack.
|
||||
|
||||
Each result tuple is of the form (dn, attrs), where dn is a string
|
||||
containing the DN (distinguished name) of the entry, and attrs is
|
||||
a dictionary containing the attributes associated with the
|
||||
entry. The keys of attrs are strings, and the associated values
|
||||
are lists of strings.
|
||||
|
||||
OpenStack wants to use Python types of its choosing. Strings will
|
||||
be unicode, truth values boolean, whole numbers int's, etc. DN's will
|
||||
also be decoded from UTF-8 to unicode.
|
||||
|
||||
:param ldap_result: LDAP search result
|
||||
:returns: list of 2-tuples containing (dn, attrs) where dn is unicode
|
||||
and attrs is a dict whose values are type converted to
|
||||
OpenStack preferred types.
|
||||
"""
|
||||
py_result = []
|
||||
at_least_one_referral = False
|
||||
for dn, attrs in ldap_result:
|
||||
|
|
|
@ -740,6 +740,29 @@ class BaseLDAPIdentity(test_backend.IdentityTests):
|
|||
|
||||
self.assertEqual(role_id, role_ref['id'])
|
||||
|
||||
def test_utf8_conversion(self):
|
||||
value_unicode = u'fäké1'
|
||||
value_utf8 = value_unicode.encode('utf-8')
|
||||
|
||||
result_utf8 = common_ldap_core.utf8_encode(value_unicode)
|
||||
self.assertEqual(value_utf8, result_utf8)
|
||||
|
||||
result_utf8 = common_ldap_core.utf8_encode(value_utf8)
|
||||
self.assertEqual(value_utf8, result_utf8)
|
||||
|
||||
result_unicode = common_ldap_core.utf8_decode(value_utf8)
|
||||
self.assertEqual(value_unicode, result_unicode)
|
||||
|
||||
result_unicode = common_ldap_core.utf8_decode(value_unicode)
|
||||
self.assertEqual(value_unicode, result_unicode)
|
||||
|
||||
self.assertRaises(TypeError,
|
||||
common_ldap_core.utf8_encode,
|
||||
100)
|
||||
|
||||
result_unicode = common_ldap_core.utf8_decode(100)
|
||||
self.assertEqual(u'100', result_unicode)
|
||||
|
||||
|
||||
class LDAPIdentity(BaseLDAPIdentity, tests.TestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue