freeipa/tests/test_xmlrpc/test_role_plugin.py
Rob Crittenden 0099ccbea8 Only apply validation rules when adding and updating.
There may be cases, for whatever reason, that an otherwise illegal
entry gets created that doesn't match the criteria for a valid
user/host/group name. If this happens (i.e. migration) there is no way
to remove this using the IPA tools because we always applied the name
pattern. So you can't, for example, delete a user with an illegal name.

Primary keys are cloned with query=True in PKQuery which causes no
rules to be applied on mod/show/find. This reverts a change from commit
3a5e26a0 which applies class rules when query=True (for enforcing no
white space).

Replace rdnattr with rdn_is_primary_key. This was meant to tell us when
an RDN change was necessary to do a rename. There could be a disconnect
where the rdnattr wasn't the primary key and in that case we don't
need to do an RDN change, so use a boolean instead so that it is
clear that RDN == primary key.

Add a test to ensure that nowhitespace is actually enforced.

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

Related: https://fedorahosted.org/freeipa/ticket/2089

Whitespace tickets:
https://fedorahosted.org/freeipa/ticket/1285
https://fedorahosted.org/freeipa/ticket/1286
https://fedorahosted.org/freeipa/ticket/1287
2012-02-29 18:00:45 -05:00

581 lines
17 KiB
Python

# Authors:
# Rob Crittenden <rcritten@redhat.com>
# Pavel Zuna <pzuna@redhat.com>
# John Dennis <jdennis@redhat.com>
#
# Copyright (C) 2009 Red Hat
# see file 'COPYING' for use and warranty information
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""
Test the `ipalib/plugins/role.py` module.
"""
from ipalib import api, errors
from tests.test_xmlrpc import objectclasses
from xmlrpc_test import Declarative, fuzzy_digits, fuzzy_uuid
from ipalib.dn import *
search = u'test-role'
role1 = u'test-role-1'
role1_dn = DN(('cn',role1),api.env.container_rolegroup,
api.env.basedn)
renamedrole1 = u'test-role'
invalidrole1 = u' whitespace '
role2 = u'test-role-2'
role2_dn = DN(('cn',role2),api.env.container_rolegroup,
api.env.basedn)
group1 = u'testgroup1'
group1_dn = DN(('cn',group1),api.env.container_group,
api.env.basedn)
privilege1 = u'r,w privilege 1'
privilege1_dn = DN(('cn', privilege1), DN(api.env.container_privilege),
api.env.basedn)
def escape_comma(value):
return value.replace(',', '\\,')
class test_role(Declarative):
cleanup_commands = [
('role_del', [role1], {}),
('role_del', [role2], {}),
('group_del', [group1], {}),
('privilege_del', [privilege1], {}),
]
tests = [
dict(
desc='Try to retrieve non-existent %r' % role1,
command=('role_show', [role1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % role1,
command=('role_mod', [role1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to delete non-existent %r' % role1,
command=('role_del', [role1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to rename non-existent %r' % role1,
command=('role_del', [role1], dict(setattr=u'cn=%s' % renamedrole1)),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Search for non-existent %r' % role1,
command=('role_find', [role1], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 roles matched',
result=[],
),
),
dict(
desc='Create invalid %r' % invalidrole1,
command=('role_add', [invalidrole1],
dict(description=u'role desc 1')
),
expected=errors.ValidationError(name='cn', error='Leading and trailing spaces are not allowed'),
),
dict(
desc='Create %r' % role1,
command=('role_add', [role1],
dict(description=u'role desc 1')
),
expected=dict(
value=role1,
summary=u'Added role "%s"' % role1,
result=dict(
dn=lambda x: DN(x) == role1_dn,
cn=[role1],
description=[u'role desc 1'],
objectclass=objectclasses.role,
),
),
),
dict(
desc='Retrieve %r' % role1,
command=('role_show', [role1], {}),
expected=dict(
value=role1,
summary=None,
result=dict(
dn=lambda x: DN(x) == role1_dn,
cn=[role1],
description=[u'role desc 1'],
),
),
),
dict(
desc='Create %r' % group1,
command=(
'group_add', [group1], dict(description=u'group desc 1',
nonposix=True,)
),
expected=dict(
value=group1,
summary=u'Added group "testgroup1"',
result=dict(
dn=lambda x: DN(x) == group1_dn,
cn=[group1],
description=[u'group desc 1'],
objectclass=objectclasses.group,
ipauniqueid=[fuzzy_uuid],
),
),
),
dict(
desc='Create %r' % privilege1,
command=('privilege_add', [privilege1],
dict(description=u'privilege desc. 1')
),
expected=dict(
value=privilege1,
summary=u'Added privilege "%s"' % privilege1,
result=dict(
dn=lambda x: DN(x) == privilege1_dn,
cn=[privilege1],
description=[u'privilege desc. 1'],
objectclass=objectclasses.privilege,
),
),
),
dict(
desc='Add privilege %r to role %r' % (privilege1, role1),
command=('role_add_privilege', [role1],
dict(privilege=escape_comma(privilege1))
),
expected=dict(
completed=1,
failed=dict(
member=dict(
privilege=[],
),
),
result={
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'memberof_privilege': [privilege1],
}
),
),
dict(
desc='Add member %r to %r' % (group1, role1),
command=('role_add_member', [role1], dict(group=group1)),
expected=dict(
completed=1,
failed=dict(
member=dict(
user=[],
group=[],
host=[],
hostgroup=[],
),
),
result={
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
}
),
),
dict(
desc='Retrieve %r to verify member-add' % role1,
command=('role_show', [role1], {}),
expected=dict(
value=role1,
summary=None,
result={
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
),
),
dict(
desc='Search for %r' % role1,
command=('role_find', [role1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 role matched',
result=[
{
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
],
),
),
dict(
desc='Search for %r' % search,
command=('role_find', [search], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 role matched',
result=[
{
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
],
),
),
dict(
desc='Create %r' % role2,
command=('role_add', [role2],
dict(description=u'role desc 2')
),
expected=dict(
value=role2,
summary=u'Added role "%s"' % role2,
result=dict(
dn=lambda x: DN(x) == role2_dn,
cn=[role2],
description=[u'role desc 2'],
objectclass=objectclasses.role,
),
),
),
dict(
desc='Search for %r' % role1,
command=('role_find', [role1], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 role matched',
result=[
{
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
],
),
),
dict(
desc='Search for %r' % search,
command=('role_find', [search], {}),
expected=dict(
count=2,
truncated=False,
summary=u'2 roles matched',
result=[
{
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'role desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
{
'dn': lambda x: DN(x) == role2_dn,
'cn': [role2],
'description': [u'role desc 2'],
},
],
),
),
dict(
desc='Update %r' % role1,
command=(
'role_mod', [role1], dict(description=u'New desc 1')
),
expected=dict(
value=role1,
summary=u'Modified role "%s"' % role1,
result=dict(
cn=[role1],
description=[u'New desc 1'],
member_group=[group1],
memberof_privilege=[privilege1],
),
),
),
dict(
desc='Retrieve %r to verify update' % role1,
command=('role_show', [role1], {}),
expected=dict(
value=role1,
summary=None,
result={
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
'member_group': [group1],
'memberof_privilege': [privilege1],
},
),
),
dict(
desc='Remove member %r from %r' % (group1, role1),
command=('role_remove_member', [role1], dict(group=group1)),
expected=dict(
completed=1,
failed=dict(
member=dict(
user=[],
group=[],
host=[],
hostgroup=[],
),
),
result={
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
'memberof_privilege': [privilege1],
},
),
),
dict(
desc='Retrieve %r to verify member-del' % role1,
command=('role_show', [role1], {}),
expected=dict(
value=role1,
summary=None,
result={
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
'memberof_privilege': [privilege1],
},
),
),
dict(
desc='Delete %r' % group1,
command=('group_del', [group1], {}),
expected=dict(
result=dict(failed=u''),
value=group1,
summary=u'Deleted group "testgroup1"',
)
),
dict(
desc='Rename %r' % role1,
command=('role_mod', [role1], dict(setattr=u'cn=%s' % renamedrole1)),
expected=dict(
value=role1,
result=dict(
cn=[renamedrole1],
description=[u'New desc 1'],
memberof_privilege=[privilege1],
),
summary=u'Modified role "%s"' % role1
)
),
dict(
desc='Rename %r back' % renamedrole1,
command=('role_mod', [renamedrole1], dict(setattr=u'cn=%s' % role1)),
expected=dict(
value=renamedrole1,
result=dict(
cn=[role1],
description=[u'New desc 1'],
memberof_privilege=[privilege1],
),
summary=u'Modified role "%s"' % renamedrole1
)
),
dict(
desc='Remove privilege %r from role %r' % (privilege1, role1),
command=('role_remove_privilege', [role1],
dict(privilege=escape_comma(privilege1))
),
expected=dict(
completed=1,
failed=dict(
member=dict(
privilege=[],
),
),
result={
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
}
),
),
dict(
desc='Remove privilege %r from role %r again' % (privilege1, role1),
command=('role_remove_privilege', [role1],
dict(privilege=escape_comma(privilege1))
),
expected=dict(
completed=0,
failed=dict(
member=dict(
privilege=[(u'%s' % privilege1, u'This entry is not a member'),],
),
),
result={
'dn': lambda x: DN(x) == role1_dn,
'cn': [role1],
'description': [u'New desc 1'],
}
),
),
dict(
desc='Delete %r' % role1,
command=('role_del', [role1], {}),
expected=dict(
result=dict(failed=u''),
value=role1,
summary=u'Deleted role "%s"' % role1,
)
),
dict(
desc='Try to delete non-existent %r' % role1,
command=('role_del', [role1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to retrieve non-existent %r' % role1,
command=('role_show', [group1], {}),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Try to update non-existent %r' % role1,
command=('role_mod', [role1], dict(description=u'Foo')),
expected=errors.NotFound(reason='no such entry'),
),
dict(
desc='Search for %r' % search,
command=('role_find', [search], {}),
expected=dict(
count=1,
truncated=False,
summary=u'1 role matched',
result=[
{
'dn': lambda x: DN(x) == role2_dn,
'cn': [role2],
'description': [u'role desc 2'],
},
],
),
),
dict(
desc='Delete %r' % role2,
command=('role_del', [role2], {}),
expected=dict(
result=dict(failed=u''),
value=role2,
summary=u'Deleted role "%s"' % role2,
)
),
dict(
desc='Search for %r' % search,
command=('role_find', [search], {}),
expected=dict(
count=0,
truncated=False,
summary=u'0 roles matched',
result=[],
),
),
]