mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-23 15:40:01 -06:00
Enforce that required attributes can't be set to None in CRUD Update
The `required` parameter attribute didn't distinguish between cases where the parameter is not given and all, and where the parameter is given but empty. The case of updating a required attribute couldn't be validated properly, because when it is given but empty, validators don't run. This patch introduces a new flag, 'nonempty', that specifies the parameter can be missing (if not required), but it can't be None. This flag gets added automatically to required parameters in CRUD Update.
This commit is contained in:
parent
1dc11a01d7
commit
7cfc16ca58
@ -186,20 +186,29 @@ class Update(PKQuery):
|
||||
for option in super(Update, self).get_options():
|
||||
yield option
|
||||
for option in self.obj.params_minus_pk():
|
||||
new_flags = option.flags
|
||||
attribute = 'virtual_attribute' not in option.flags
|
||||
if option.required:
|
||||
# Required options turn into non-required, since not specifying
|
||||
# them means that they are not changed.
|
||||
# However, they cannot be empty (i.e. explicitly set to None).
|
||||
new_flags = new_flags.union(['nonempty'])
|
||||
if 'no_update' in option.flags:
|
||||
continue
|
||||
if 'ask_update' in option.flags:
|
||||
yield option.clone(
|
||||
attribute=attribute, query=False, required=False,
|
||||
autofill=False, alwaysask=True
|
||||
autofill=False, alwaysask=True, flags=new_flags,
|
||||
)
|
||||
elif 'req_update' in option.flags:
|
||||
yield option.clone(
|
||||
attribute=attribute, required=True, alwaysask=False,
|
||||
flags=new_flags,
|
||||
)
|
||||
else:
|
||||
yield option.clone(attribute=attribute, required=False, autofill=False)
|
||||
yield option.clone(attribute=attribute, required=False,
|
||||
autofill=False, flags=new_flags,
|
||||
)
|
||||
if not self.extra_options_first:
|
||||
for option in super(Update, self).get_options():
|
||||
yield option
|
||||
|
@ -651,7 +651,7 @@ class Command(HasParam):
|
||||
"""
|
||||
for param in self.params():
|
||||
value = kw.get(param.name, None)
|
||||
param.validate(value, self.env.context)
|
||||
param.validate(value, self.env.context, supplied=param.name in kw)
|
||||
|
||||
def verify_client_version(self, client_version):
|
||||
"""
|
||||
|
@ -558,9 +558,9 @@ class Param(ReadOnly):
|
||||
else:
|
||||
value = self.convert(self.normalize(value))
|
||||
if hasattr(self, 'env'):
|
||||
self.validate(value, self.env.context) #pylint: disable=E1101
|
||||
self.validate(value, self.env.context, supplied=self.name in kw) #pylint: disable=E1101
|
||||
else:
|
||||
self.validate(value)
|
||||
self.validate(value, supplied=self.name in kw)
|
||||
return value
|
||||
|
||||
def kw(self):
|
||||
@ -820,15 +820,16 @@ class Param(ReadOnly):
|
||||
error=ugettext(self.type_error),
|
||||
)
|
||||
|
||||
def validate(self, value, context=None):
|
||||
def validate(self, value, context=None, supplied=None):
|
||||
"""
|
||||
Check validity of ``value``.
|
||||
|
||||
:param value: A proposed value for this parameter.
|
||||
:param context: The context we are running in.
|
||||
:param supplied: True if this parameter was supplied explicitly.
|
||||
"""
|
||||
if value is None:
|
||||
if self.required:
|
||||
if self.required or (supplied and 'nonempty' in self.flags):
|
||||
if context == 'cli':
|
||||
raise RequirementError(name=self.cli_name)
|
||||
else:
|
||||
|
Loading…
Reference in New Issue
Block a user