Allow custom server backend encoding

Server framework does not support encoding of native Python type
values stored in Param classes and sub-classes. When backend (LDAP)
value encoding differs from Python type value representation user
has to has to hard-code the encoders in his processing.

This patch introduces a method Param.encode which is used in server
context to encode native Python Param values. The new encode method
is used for Bool parameter to convert native Python bool type value
(True, False) to LDAP value ("TRUE", "FALSE").

https://fedorahosted.org/freeipa/ticket/2039
This commit is contained in:
Martin Kosek 2011-11-09 14:10:08 +01:00
parent b68ce0313c
commit b5c049ae2e
3 changed files with 56 additions and 0 deletions

View File

@ -428,6 +428,8 @@ class Command(HasParam):
if not self.api.env.in_server and 'version' not in params:
params['version'] = API_VERSION
self.validate(**params)
if self.api.env.in_server:
params = self.encode(**params)
(args, options) = self.params_2_args_options(**params)
ret = self.run(*args, **options)
if (
@ -648,6 +650,14 @@ class Command(HasParam):
(k, self.params[k].convert(v)) for (k, v) in kw.iteritems()
)
def encode(self, **kw):
"""
Return a dictionary of encoded values.
"""
return dict(
(k, self.params[k].encode(v)) for (k, v) in kw.iteritems()
)
def __convert_iter(self, kw):
for param in self.params():
if kw.get(param.name, None) is None:

View File

@ -307,6 +307,7 @@ class Param(ReadOnly):
('multivalue', bool, False),
('primary_key', bool, False),
('normalizer', callable, None),
('encoder', callable, None),
('default_from', DefaultFrom, None),
('create_default', callable, None),
('autofill', bool, False),
@ -768,6 +769,34 @@ class Param(ReadOnly):
rule=rule,
)
def encode(self, value):
"""
Encode Python native type value to chosen backend format. Encoding is
applied for parameters representing actual attributes (attribute=True).
The default encode method `Param._encode` can be overriden in a `Param`
instance with `encoder` attribute:
>>> s = Str('my_str', encoder=lambda x:encode(x))
Note that the default method of encoding values is defined in
`Param._encode()`.
:param value: Encoded value
"""
if not self.attribute: #pylint: disable=E1101
return value
if self.encoder is not None: #pylint: disable=E1101
return self.encoder(value) #pylint: disable=E1101
return self._encode(value)
def _encode(self, value):
"""
Encode a value to backend format.
"""
return value
def get_default(self, **kw):
"""
Return the static default or construct and return a dynamic default.

View File

@ -45,6 +45,7 @@ from ldap.controls import LDAPControl
from ldap.functions import explode_dn
from ipalib.dn import DN
from ipalib import _
from ipalib.parameters import Bool
import krbV
@ -62,6 +63,22 @@ MEMBERS_INDIRECT = 2
# SASL authentication mechanism
SASL_AUTH = _ldap_sasl.sasl({}, 'GSSAPI')
# OID 1.3.6.1.4.1.1466.115.121.1.7 (Boolean) syntax encoding
def _encode_bool(self, value):
def encode_bool_value(value):
if value:
return u'TRUE'
else:
return u'FALSE'
if type(value) in (tuple, list):
return tuple(encode_bool_value(v) for v in value)
else:
return encode_bool_value(value)
# set own Bool parameter encoder
Bool._encode = _encode_bool
# universal LDAPError handler
def _handle_errors(e, **kw):
"""