summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ipalib/plugins/baseldap.py52
-rw-r--r--tests/test_xmlrpc/test_attr.py113
2 files changed, 148 insertions, 17 deletions
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index 38f369a7..daf1b07f 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -794,8 +794,6 @@ last, after all sets and adds."""),
Convert a string in the form of name/value pairs into a dictionary.
The incoming attribute may be a string or a list.
- Any attribute found that is also a param is validated.
-
:param attrs: A list of name/value pairs
:param append: controls whether this returns a list of values or a single
@@ -811,15 +809,6 @@ last, after all sets and adds."""),
if len(value) == 0:
# None means "delete this attribute"
value = None
- if attr in self.params:
- try:
- value = self.params[attr](value)
- except errors.ValidationError, err:
- raise errors.ValidationError(name=attr, error=err.error)
- except errors.ConversionError, err:
- raise errors.ValidationError(name=attr, error=err.error)
- if self.api.env.in_server:
- value = self.params[attr].encode(value)
if append and attr in newdict:
if type(value) in (tuple,):
newdict[attr] += list(value)
@@ -923,12 +912,41 @@ last, after all sets and adds."""),
# normalize all values
changedattrs = setattrs | addattrs | delattrs
for attr in changedattrs:
- # remove duplicite and invalid values
- entry_attrs[attr] = list(set([val for val in entry_attrs[attr] if val]))
- if not entry_attrs[attr]:
- entry_attrs[attr] = None
- elif isinstance(entry_attrs[attr], (tuple, list)) and len(entry_attrs[attr]) == 1:
- entry_attrs[attr] = entry_attrs[attr][0]
+ if attr in self.obj.params:
+ # convert single-value params to scalars
+ value = entry_attrs[attr]
+ try:
+ param = self.params[attr]
+ except KeyError:
+ # The CRUD classes filter their disallowed parameters out.
+ # Yet {set,add,del}attr are powerful enough to change these
+ # (e.g. Config's ipacertificatesubjectbase)
+ # So, use the parent's attribute
+ param = self.obj.params[attr]
+ if not param.multivalue:
+ if len(value) == 1:
+ value = value[0]
+ elif not value:
+ value = None
+ else:
+ raise errors.OnlyOneValueAllowed(attr=attr)
+ # validate, convert and encode params
+ try:
+ value = param(value)
+ except errors.ValidationError, err:
+ raise errors.ValidationError(name=attr, error=err.error)
+ except errors.ConversionError, err:
+ raise errors.ConversionError(name=attr, error=err.error)
+ value = param.encode(value)
+ entry_attrs[attr] = value
+ else:
+ # unknown attribute: remove duplicite and invalid values
+ entry_attrs[attr] = list(set([val for val in entry_attrs[attr] if val]))
+ if not entry_attrs[attr]:
+ entry_attrs[attr] = None
+ elif isinstance(entry_attrs[attr], (tuple, list)) and len(entry_attrs[attr]) == 1:
+ entry_attrs[attr] = entry_attrs[attr][0]
+
class LDAPCreate(BaseLDAPCommand, crud.Create):
"""
diff --git a/tests/test_xmlrpc/test_attr.py b/tests/test_xmlrpc/test_attr.py
index ef239709..e6872a67 100644
--- a/tests/test_xmlrpc/test_attr.py
+++ b/tests/test_xmlrpc/test_attr.py
@@ -402,4 +402,117 @@ class test_attr(Declarative):
),
),
+ dict(
+ desc='Lock %r using setattr' % user1,
+ command=(
+ 'user_mod', [user1], dict(setattr=u'nsaccountlock=TrUe')
+ ),
+ expected=dict(
+ result=dict(
+ givenname=[u'Finkle'],
+ homedirectory=[u'/home/tuser1'],
+ loginshell=[u'/bin/sh'],
+ sn=[u'User1'],
+ uid=[user1],
+ uidnumber=[fuzzy_digits],
+ gidnumber=[fuzzy_digits],
+ mail=[u'test@example.com', u'test2@example.com'],
+ memberof_group=[u'ipausers'],
+ telephonenumber=[u'202-888-9833'],
+ nsaccountlock=True,
+ has_keytab=False,
+ has_password=False,
+ ),
+ summary=u'Modified user "tuser1"',
+ value=user1,
+ ),
+ ),
+
+ dict(
+ desc='Unlock %r using addattr&delattr' % user1,
+ command=(
+ 'user_mod', [user1], dict(
+ addattr=u'nsaccountlock=FaLsE',
+ delattr=u'nsaccountlock=True')
+ ),
+ expected=dict(
+ result=dict(
+ givenname=[u'Finkle'],
+ homedirectory=[u'/home/tuser1'],
+ loginshell=[u'/bin/sh'],
+ sn=[u'User1'],
+ uid=[user1],
+ uidnumber=[fuzzy_digits],
+ gidnumber=[fuzzy_digits],
+ mail=[u'test@example.com', u'test2@example.com'],
+ memberof_group=[u'ipausers'],
+ telephonenumber=[u'202-888-9833'],
+ nsaccountlock=False,
+ has_keytab=False,
+ has_password=False,
+ ),
+ summary=u'Modified user "tuser1"',
+ value=user1,
+ ),
+ ),
+
+ dict(
+ desc='Try adding a new group search fields config entry',
+ command=(
+ 'config_mod', [], dict(addattr=u'ipagroupsearchfields=newattr')
+ ),
+ expected=errors.OnlyOneValueAllowed(attr='ipagroupsearchfields'),
+ ),
+
+ dict(
+ desc='Try adding a new cert subject base config entry',
+ command=(
+ 'config_mod', [], dict(addattr=u'ipacertificatesubjectbase=0=DOMAIN.COM')
+ ),
+ expected=errors.OnlyOneValueAllowed(attr='ipacertificatesubjectbase'),
+ ),
+
+ dict(
+ desc='Try deleting a required config entry',
+ command=(
+ 'config_mod', [], dict(delattr=u'ipasearchrecordslimit=100')
+ ),
+ expected=errors.RequirementError(name='ipasearchrecordslimit'),
+ ),
+
+ dict(
+ desc='Try setting nonexistent attribute',
+ command=('config_mod', [], dict(setattr=u'invalid_attr=false')),
+ expected=errors.ObjectclassViolation(
+ info='attribute "invalid_attr" not allowed'),
+ ),
+
+ dict(
+ desc='Try setting out-of-range krbpwdmaxfailure',
+ command=('pwpolicy_mod', [], dict(setattr=u'krbpwdmaxfailure=-1')),
+ expected=errors.ValidationError(name='krbpwdmaxfailure',
+ error='must be at least 0'),
+ ),
+
+ dict(
+ desc='Try setting out-of-range maxfail',
+ command=('pwpolicy_mod', [], dict(krbpwdmaxfailure=u'-1')),
+ expected=errors.ValidationError(name='maxfail',
+ error='must be at least 0'),
+ ),
+
+ dict(
+ desc='Try setting non-numeric krbpwdmaxfailure',
+ command=('pwpolicy_mod', [], dict(setattr=u'krbpwdmaxfailure=abc')),
+ expected=errors.ConversionError(name='krbpwdmaxfailure',
+ error='must be an integer'),
+ ),
+
+ dict(
+ desc='Try setting non-numeric maxfail',
+ command=('pwpolicy_mod', [], dict(krbpwdmaxfailure=u'abc')),
+ expected=errors.ConversionError(name='maxfail',
+ error='must be an integer'),
+ ),
+
]