Fix selfservice-find crashes

Ignore empty options when performing an ACI search so that the
find command does not crash. Update ipa(1) man page to mention
this common behavior of find commands.

https://fedorahosted.org/freeipa/ticket/2011
https://fedorahosted.org/freeipa/ticket/2012
This commit is contained in:
Martin Kosek 2012-01-06 12:44:59 +01:00
parent 6141919fba
commit ef68c02c6a
3 changed files with 32 additions and 13 deletions

4
ipa.1
View File

@ -16,7 +16,7 @@
.\" .\"
.\" Author: Pavel Zuna <pzuna@redhat.com> .\" Author: Pavel Zuna <pzuna@redhat.com>
.\" .\"
.TH "IPA" "1" "02/22/2010" "IPA 2\&.0\&.0" "IPA CLI Manual" .TH "ipa" "1" "Jan 24 2012" "FreeIPA" "FreeIPA Manual Pages"
.SH "NAME" .SH "NAME"
ipa \- IPA command\-line interface ipa \- IPA command\-line interface
.SH "SYNOPSIS" .SH "SYNOPSIS"
@ -92,7 +92,7 @@ Search for existing objects.
.LP .LP
The above types of commands except \fBfind\fR take the objects primary key (e.g. user name for users) as their only positional argument unless there can be only one object of the given type. They can also take a number of options (some of which might be required in the case of \fBadd\fR) that represent the objects attributes. The above types of commands except \fBfind\fR take the objects primary key (e.g. user name for users) as their only positional argument unless there can be only one object of the given type. They can also take a number of options (some of which might be required in the case of \fBadd\fR) that represent the objects attributes.
\fBfind\fR commands take an optional criteria string as their only positional argument. If present, all objects with an attribute that contains the criteria string are displayed. If an option representing an attribute is set, only object with the attribute exactly matching the specified value are displayed. Without parameters all objects of the corresponding type are displayed. \fBfind\fR commands take an optional criteria string as their only positional argument. If present, all objects with an attribute that contains the criteria string are displayed. If an option representing an attribute is set, only object with the attribute exactly matching the specified value are displayed. Options with empty values are ignored. Without parameters all objects of the corresponding type are displayed.
For IPA objects with attributes that can contain references to other objects (e.g. groups), the following action are usually available: For IPA objects with attributes that can contain references to other objects (e.g. groups), the following action are usually available:
.TP .TP

View File

@ -705,21 +705,21 @@ class aci_find(crud.Search):
else: else:
results = list(acis) results = list(acis)
if 'aciname' in kw: if kw.get('aciname'):
for a in acis: for a in acis:
prefix, name = _parse_aci_name(a.name) prefix, name = _parse_aci_name(a.name)
if name != kw['aciname']: if name != kw['aciname']:
results.remove(a) results.remove(a)
acis = list(results) acis = list(results)
if 'aciprefix' in kw: if kw.get('aciprefix'):
for a in acis: for a in acis:
prefix, name = _parse_aci_name(a.name) prefix, name = _parse_aci_name(a.name)
if prefix != kw['aciprefix']: if prefix != kw['aciprefix']:
results.remove(a) results.remove(a)
acis = list(results) acis = list(results)
if 'attrs' in kw: if kw.get('attrs'):
for a in acis: for a in acis:
if not 'targetattr' in a.target: if not 'targetattr' in a.target:
results.remove(a) results.remove(a)
@ -732,7 +732,7 @@ class aci_find(crud.Search):
results.remove(a) results.remove(a)
acis = list(results) acis = list(results)
if 'permission' in kw: if kw.get('permission'):
try: try:
self.api.Command['permission_show']( self.api.Command['permission_show'](
kw['permission'] kw['permission']
@ -745,7 +745,7 @@ class aci_find(crud.Search):
results.remove(a) results.remove(a)
acis = list(results) acis = list(results)
if 'permissions' in kw: if kw.get('permissions'):
for a in acis: for a in acis:
alist1 = sorted(a.permissions) alist1 = sorted(a.permissions)
alist2 = sorted(kw['permissions']) alist2 = sorted(kw['permissions'])
@ -753,7 +753,7 @@ class aci_find(crud.Search):
results.remove(a) results.remove(a)
acis = list(results) acis = list(results)
if 'memberof' in kw: if kw.get('memberof'):
try: try:
dn = _group_from_memberof(kw['memberof']) dn = _group_from_memberof(kw['memberof'])
except errors.NotFound: except errors.NotFound:
@ -768,7 +768,7 @@ class aci_find(crud.Search):
else: else:
results.remove(a) results.remove(a)
if 'type' in kw: if kw.get('type'):
for a in acis: for a in acis:
if 'target' in a.target: if 'target' in a.target:
target = a.target['target']['expression'] target = a.target['target']['expression']
@ -786,7 +786,7 @@ class aci_find(crud.Search):
except ValueError: except ValueError:
pass pass
if 'selfaci' in kw and kw['selfaci'] == True: if kw.get('selfaci', False) is True:
for a in acis: for a in acis:
if a.bindrule['expression'] != u'ldap:///self': if a.bindrule['expression'] != u'ldap:///self':
try: try:
@ -794,7 +794,7 @@ class aci_find(crud.Search):
except ValueError: except ValueError:
pass pass
if 'group' in kw: if kw.get('group'):
for a in acis: for a in acis:
groupdn = a.bindrule['expression'] groupdn = a.bindrule['expression']
groupdn = groupdn.replace('ldap:///','') groupdn = groupdn.replace('ldap:///','')
@ -808,7 +808,7 @@ class aci_find(crud.Search):
except ValueError: except ValueError:
pass pass
if 'targetgroup' in kw: if kw.get('targetgroup'):
for a in acis: for a in acis:
found = False found = False
if 'target' in a.target: if 'target' in a.target:
@ -825,7 +825,7 @@ class aci_find(crud.Search):
except ValueError: except ValueError:
pass pass
if 'filter' in kw: if kw.get('filter'):
if not kw['filter'].startswith('('): if not kw['filter'].startswith('('):
kw['filter'] = unicode('('+kw['filter']+')') kw['filter'] = unicode('('+kw['filter']+')')
for a in acis: for a in acis:

View File

@ -153,6 +153,25 @@ class test_selfservice(Declarative):
), ),
dict(
desc='Search for %r with empty attrs and permissions' % selfservice1,
command=('selfservice_find', [selfservice1], {'attrs' : None, 'permissions' : None}),
expected=dict(
count=1,
truncated=False,
summary=u'1 selfservice matched',
result=[
{
'attrs': [u'street', u'c', u'l', u'st', u'postalcode'],
'permissions': [u'write'],
'selfaci': True,
'aciname': selfservice1,
},
],
),
),
dict( dict(
desc='Update %r' % selfservice1, desc='Update %r' % selfservice1,
command=( command=(