frontend: perform argument value validation only on server

Do not validate values of command arguments on the client and let the
server handle validation.

This will make the client more lightweight by not having it to carry
validation code and metadata with itself for the price of increasing
network traffic in case the validation fails.

Types of the arguments are still validated on both the client and the
server.

https://fedorahosted.org/freeipa/ticket/4739

Reviewed-By: David Kupka <dkupka@redhat.com>
This commit is contained in:
Jan Cholasta 2016-04-05 13:11:20 +02:00
parent 13b010685b
commit 278fa29906
3 changed files with 16 additions and 5 deletions

View File

@ -448,7 +448,8 @@ class Command(HasParam):
self.debug( self.debug(
'%s(%s)', self.name, ', '.join(self._repr_iter(**params)) '%s(%s)', self.name, ', '.join(self._repr_iter(**params))
) )
self.validate(**params) if self.api.env.in_server:
self.validate(**params)
(args, options) = self.params_2_args_options(**params) (args, options) = self.params_2_args_options(**params)
ret = self.run(*args, **options) ret = self.run(*args, **options)
if isinstance(ret, dict): if isinstance(ret, dict):
@ -686,13 +687,18 @@ class Command(HasParam):
if param.name in dep: if param.name in dep:
if param.name in kw: if param.name in kw:
# Parameter is specified, convert and validate the value. # Parameter is specified, convert and validate the value.
kw[param.name] = param(kw[param.name], **kw) value = param(kw[param.name], **kw)
if self.api.env.in_server:
param.validate(value, supplied=True)
kw[param.name] = value
else: else:
# Parameter is not specified, use default value. Convert # Parameter is not specified, use default value. Convert
# and validate the value, it might not be returned so # and validate the value, it might not be returned so
# there's no guarantee it will be converted and validated # there's no guarantee it will be converted and validated
# later. # later.
default = param(None, **kw) default = param(None, **kw)
if self.api.env.in_server:
param.validate(default)
if default is not None: if default is not None:
kw[param.name] = default kw[param.name] = default
hasdefault = True hasdefault = True

View File

@ -572,7 +572,6 @@ class Param(ReadOnly):
value = self.get_default(**kw) value = self.get_default(**kw)
else: else:
value = self.convert(self.normalize(value)) value = self.convert(self.normalize(value))
self.validate(value, supplied=self.name in kw)
return value return value
def get_param_name(self): def get_param_name(self):

View File

@ -346,7 +346,12 @@ def add_external_pre_callback(membertype, ldap, dn, keys, options):
if membertype == 'host': if membertype == 'host':
validator = validate_host validator = validate_host
else: else:
validator = api.Object[membertype].primary_key param = api.Object[membertype].primary_key
def validator(value):
value = param(value)
param.validate(value)
for value in options[membertype]: for value in options[membertype]:
try: try:
validator(value) validator(value)
@ -1100,7 +1105,8 @@ last, after all sets and adds."""),
raise errors.OnlyOneValueAllowed(attr=attr) raise errors.OnlyOneValueAllowed(attr=attr)
# validate, convert and encode params # validate, convert and encode params
try: try:
value = param(value) value = param(value)
param.validate(value)
except errors.ValidationError as err: except errors.ValidationError as err:
raise errors.ValidationError(name=attr, error=err.error) raise errors.ValidationError(name=attr, error=err.error)
except errors.ConversionError as err: except errors.ConversionError as err: