2009-06-24 08:12:27 -05:00
|
|
|
# Authors:
|
|
|
|
# Rob Crittenden <rcritten@redhat.com>
|
|
|
|
# Pavel Zuna <pzuna@redhat.com>
|
2015-11-09 09:48:55 -06:00
|
|
|
# Filip Skola <fskola@redhat.com>
|
2009-06-24 08:12:27 -05:00
|
|
|
#
|
|
|
|
# Copyright (C) 2008 Red Hat
|
|
|
|
# see file 'COPYING' for use and warranty information
|
|
|
|
#
|
2010-12-09 06:59:11 -06:00
|
|
|
# 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.
|
2009-06-24 08:12:27 -05:00
|
|
|
#
|
|
|
|
# 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
|
2010-12-09 06:59:11 -06:00
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2009-06-24 08:12:27 -05:00
|
|
|
"""
|
2016-04-28 03:30:05 -05:00
|
|
|
Test the `ipaserver/plugins/group.py` module.
|
2009-06-24 08:12:27 -05:00
|
|
|
"""
|
|
|
|
|
2015-08-24 05:04:03 -05:00
|
|
|
import pytest
|
|
|
|
|
2015-11-09 09:48:55 -06:00
|
|
|
from ipalib import errors
|
2013-05-21 06:40:27 -05:00
|
|
|
from ipatests.test_xmlrpc import objectclasses
|
2015-12-16 09:06:03 -06:00
|
|
|
from ipatests.test_xmlrpc.xmlrpc_test import (
|
2015-11-09 09:48:55 -06:00
|
|
|
fuzzy_digits, fuzzy_uuid, fuzzy_set_ci, add_oc,
|
|
|
|
XMLRPC_test, raises_exact
|
|
|
|
)
|
|
|
|
from ipatests.test_xmlrpc.tracker.group_plugin import GroupTracker
|
|
|
|
from ipatests.test_xmlrpc.tracker.user_plugin import UserTracker
|
|
|
|
from ipatests.util import assert_deepequal, get_group_dn
|
|
|
|
|
|
|
|
notagroup = u'notagroup'
|
|
|
|
renamedgroup1 = u'renamedgroup'
|
|
|
|
invalidgroup1 = u'+tgroup1'
|
|
|
|
external_sid1 = u'S-1-1-123456-789-1'
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='class')
|
|
|
|
def group(request):
|
|
|
|
tracker = GroupTracker(name=u'testgroup1', description=u'Test desc1')
|
|
|
|
return tracker.make_fixture(request)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='class')
|
|
|
|
def group2(request):
|
|
|
|
tracker = GroupTracker(name=u'testgroup2', description=u'Test desc2')
|
|
|
|
return tracker.make_fixture(request)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='class')
|
|
|
|
def managed_group(request, user):
|
|
|
|
user.ensure_exists()
|
|
|
|
tracker = GroupTracker(
|
|
|
|
name=user.uid, description=u'User private group for %s' % user.uid
|
|
|
|
)
|
|
|
|
tracker.exists = True
|
|
|
|
# Managed group gets created when user is created
|
|
|
|
tracker.track_create()
|
|
|
|
return tracker
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='class')
|
|
|
|
def user(request):
|
|
|
|
tracker = UserTracker(name=u'user1', givenname=u'Test', sn=u'User1')
|
|
|
|
return tracker.make_fixture(request)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='class')
|
|
|
|
def user_npg2(request, group):
|
|
|
|
""" User tracker fixture for testing users with no private group """
|
|
|
|
tracker = UserTracker(name=u'npguser2', givenname=u'Npguser',
|
|
|
|
sn=u'Npguser2', noprivate=True, gidnumber=1000)
|
|
|
|
tracker.track_create()
|
|
|
|
del tracker.attrs['mepmanagedentry']
|
|
|
|
tracker.attrs.update(
|
|
|
|
gidnumber=[u'1000'], description=[], memberof_group=[group.cn],
|
|
|
|
objectclass=add_oc(objectclasses.user_base, u'ipantuserattrs')
|
|
|
|
)
|
|
|
|
return tracker.make_fixture(request)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='class')
|
|
|
|
def admins(request):
|
|
|
|
# Track the admins group
|
|
|
|
tracker = GroupTracker(
|
|
|
|
name=u'admins', description=u'Account administrators group'
|
|
|
|
)
|
|
|
|
tracker.exists = True
|
|
|
|
tracker.track_create()
|
|
|
|
tracker.attrs.update(member_user=[u'admin'])
|
|
|
|
return tracker
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='class')
|
|
|
|
def trustadmins(request):
|
|
|
|
# Track the 'trust admins' group
|
|
|
|
tracker = GroupTracker(
|
|
|
|
name=u'trust admins', description=u'Trusts administrators group'
|
|
|
|
)
|
|
|
|
tracker.exists = True
|
|
|
|
tracker.track_create()
|
|
|
|
tracker.attrs.update(member_user=[u'admin'])
|
|
|
|
return tracker
|
2009-06-24 08:12:27 -05:00
|
|
|
|
2015-08-24 05:04:03 -05:00
|
|
|
|
2015-11-09 09:48:55 -06:00
|
|
|
@pytest.mark.tier1
|
|
|
|
class TestGroup(XMLRPC_test):
|
|
|
|
def test_create(self, group):
|
|
|
|
""" Create a group """
|
|
|
|
group.create()
|
|
|
|
|
|
|
|
def test_create_duplicate(self, group):
|
|
|
|
""" Try to create a duplicate group """
|
|
|
|
group.ensure_exists()
|
|
|
|
command = group.make_create_command()
|
|
|
|
|
|
|
|
with raises_exact(errors.DuplicateEntry(
|
|
|
|
message=u'group with name "%s" already exists' % group.cn)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_retrieve(self, group):
|
|
|
|
""" Retrieve a group """
|
|
|
|
group.retrieve()
|
|
|
|
|
|
|
|
def test_update(self, group):
|
|
|
|
""" Update a group with new description
|
|
|
|
and perform retrieve command to verify the update """
|
|
|
|
group.update(dict(description=u'New desc'))
|
|
|
|
group.retrieve()
|
|
|
|
|
|
|
|
def test_rename(self, group):
|
|
|
|
""" Rename a group and than rename it back """
|
|
|
|
origname = group.cn
|
|
|
|
|
|
|
|
command = group.make_command('group_mod', *[group.cn],
|
|
|
|
**dict(setattr=u'cn=%s' % renamedgroup1))
|
|
|
|
result = command()
|
|
|
|
group.attrs.update(cn=[renamedgroup1])
|
|
|
|
group.check_update(result)
|
|
|
|
group.cn = renamedgroup1
|
|
|
|
|
|
|
|
command = group.make_command('group_mod', *[group.cn],
|
|
|
|
**dict(setattr=u'cn=%s' % origname))
|
|
|
|
result = command()
|
|
|
|
group.attrs.update(cn=[origname])
|
|
|
|
group.check_update(result)
|
|
|
|
group.cn = origname
|
|
|
|
|
|
|
|
def test_convert_posix_to_external(self, group):
|
|
|
|
""" Try to convert a posix group to external """
|
|
|
|
command = group.make_update_command(dict(external=True))
|
|
|
|
with raises_exact(errors.PosixGroupViolation(
|
|
|
|
reason=u"""This is already a posix group and cannot
|
|
|
|
be converted to external one""")):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_add_with_invalid_name(self, group):
|
|
|
|
""" Try to add group with an invalid name """
|
|
|
|
command = group.make_command(
|
|
|
|
'group_add', *[invalidgroup1], **dict(description=u'Test')
|
|
|
|
)
|
|
|
|
with raises_exact(errors.ValidationError(
|
|
|
|
name='group_name',
|
|
|
|
error=u'may only include letters, numbers, _, -, . and $')):
|
|
|
|
command()
|
2009-12-09 10:09:53 -06:00
|
|
|
|
2015-04-24 07:39:48 -05:00
|
|
|
|
|
|
|
@pytest.mark.tier1
|
2015-11-09 09:48:55 -06:00
|
|
|
class TestFindGroup(XMLRPC_test):
|
|
|
|
def test_search(self, group):
|
|
|
|
""" Search for a group """
|
|
|
|
group.ensure_exists()
|
|
|
|
group.find()
|
|
|
|
|
2016-05-19 06:50:38 -05:00
|
|
|
def test_search_for_all_groups_with_members(self, group, group2):
|
2015-11-09 09:48:55 -06:00
|
|
|
""" Search for all groups """
|
|
|
|
group.ensure_exists()
|
|
|
|
group2.create()
|
2016-05-19 06:50:38 -05:00
|
|
|
command = group.make_command('group_find', no_members=False)
|
2015-11-09 09:48:55 -06:00
|
|
|
result = command()
|
|
|
|
assert_deepequal(dict(
|
|
|
|
summary=u'6 groups matched',
|
|
|
|
count=6,
|
|
|
|
truncated=False,
|
|
|
|
result=[
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('admins'),
|
|
|
|
'member_user': [u'admin'],
|
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
'cn': [u'admins'],
|
|
|
|
'description': [u'Account administrators group'],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('editors'),
|
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
'cn': [u'editors'],
|
|
|
|
'description':
|
|
|
|
[u'Limited admins who can edit other users'],
|
2010-02-12 15:34:21 -06:00
|
|
|
},
|
2015-11-09 09:48:55 -06:00
|
|
|
{
|
|
|
|
'dn': get_group_dn('ipausers'),
|
|
|
|
'cn': [u'ipausers'],
|
|
|
|
'description': [u'Default group for all users'],
|
2010-02-12 15:34:21 -06:00
|
|
|
},
|
2015-11-09 09:48:55 -06:00
|
|
|
{
|
|
|
|
'dn': get_group_dn(group.cn),
|
|
|
|
'cn': [group.cn],
|
|
|
|
'description': [u'Test desc1'],
|
2010-02-23 08:58:03 -06:00
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
},
|
2015-11-09 09:48:55 -06:00
|
|
|
{
|
|
|
|
'dn': get_group_dn(group2.cn),
|
|
|
|
'cn': [group2.cn],
|
|
|
|
'description': [u'Test desc2'],
|
2010-02-23 08:58:03 -06:00
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
},
|
2015-11-09 09:48:55 -06:00
|
|
|
{
|
|
|
|
'dn': get_group_dn('trust admins'),
|
|
|
|
'member_user': [u'admin'],
|
|
|
|
'cn': [u'trust admins'],
|
|
|
|
'description': [u'Trusts administrators group'],
|
|
|
|
},
|
|
|
|
]), result)
|
|
|
|
|
2016-05-19 06:50:38 -05:00
|
|
|
|
|
|
|
def test_search_for_all_groups(self, group, group2):
|
|
|
|
""" Search for all groups """
|
|
|
|
group.ensure_exists()
|
|
|
|
group2.create()
|
|
|
|
command = group.make_command('group_find')
|
|
|
|
result = command()
|
|
|
|
assert_deepequal(dict(
|
|
|
|
summary=u'6 groups matched',
|
|
|
|
count=6,
|
|
|
|
truncated=False,
|
|
|
|
result=[
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('admins'),
|
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
'cn': [u'admins'],
|
|
|
|
'description': [u'Account administrators group'],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('editors'),
|
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
'cn': [u'editors'],
|
|
|
|
'description':
|
|
|
|
[u'Limited admins who can edit other users'],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('ipausers'),
|
|
|
|
'cn': [u'ipausers'],
|
|
|
|
'description': [u'Default group for all users'],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'dn': get_group_dn(group.cn),
|
|
|
|
'cn': [group.cn],
|
|
|
|
'description': [u'Test desc1'],
|
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'dn': get_group_dn(group2.cn),
|
|
|
|
'cn': [group2.cn],
|
|
|
|
'description': [u'Test desc2'],
|
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('trust admins'),
|
|
|
|
'cn': [u'trust admins'],
|
|
|
|
'description': [u'Trusts administrators group'],
|
|
|
|
},
|
|
|
|
]), result)
|
|
|
|
|
|
|
|
|
2015-11-09 09:48:55 -06:00
|
|
|
def test_search_for_all_posix(self, group, group2):
|
|
|
|
""" Search for all posix groups """
|
|
|
|
command = group.make_command(
|
|
|
|
'group_find', **dict(posix=True, all=True)
|
|
|
|
)
|
|
|
|
result = command()
|
|
|
|
assert_deepequal(dict(
|
|
|
|
summary=u'4 groups matched',
|
|
|
|
count=4,
|
|
|
|
truncated=False,
|
|
|
|
result=[
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('admins'),
|
|
|
|
'member_user': [u'admin'],
|
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
'cn': [u'admins'],
|
|
|
|
'description': [u'Account administrators group'],
|
|
|
|
'objectclass': fuzzy_set_ci(add_oc(
|
|
|
|
objectclasses.posixgroup, u'ipantgroupattrs')),
|
|
|
|
'ipauniqueid': [fuzzy_uuid],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('editors'),
|
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
'cn': [u'editors'],
|
|
|
|
'description':
|
|
|
|
[u'Limited admins who can edit other users'],
|
|
|
|
'objectclass': fuzzy_set_ci(add_oc(
|
|
|
|
objectclasses.posixgroup, u'ipantgroupattrs')),
|
|
|
|
'ipauniqueid': [fuzzy_uuid],
|
2012-05-23 04:44:53 -05:00
|
|
|
},
|
2015-11-09 09:48:55 -06:00
|
|
|
{
|
|
|
|
'dn': get_group_dn(group.cn),
|
|
|
|
'cn': [group.cn],
|
|
|
|
'description': [u'Test desc1'],
|
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
'objectclass': fuzzy_set_ci(add_oc(
|
|
|
|
objectclasses.posixgroup, u'ipantgroupattrs')),
|
|
|
|
'ipauniqueid': [fuzzy_uuid],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'dn': get_group_dn(group2.cn),
|
|
|
|
'cn': [group2.cn],
|
|
|
|
'description': [u'Test desc2'],
|
|
|
|
'gidnumber': [fuzzy_digits],
|
|
|
|
'objectclass': fuzzy_set_ci(add_oc(
|
|
|
|
objectclasses.posixgroup, u'ipantgroupattrs')),
|
|
|
|
'ipauniqueid': [fuzzy_uuid],
|
|
|
|
},
|
|
|
|
]), result)
|
2014-07-29 01:40:36 -05:00
|
|
|
|
2015-04-24 07:39:48 -05:00
|
|
|
|
|
|
|
@pytest.mark.tier1
|
2015-11-09 09:48:55 -06:00
|
|
|
class TestNonexistentGroup(XMLRPC_test):
|
|
|
|
def test_retrieve_nonexistent(self, group):
|
|
|
|
""" Try to retrieve a non-existent group """
|
|
|
|
group.ensure_missing()
|
|
|
|
command = group.make_retrieve_command()
|
|
|
|
with raises_exact(errors.NotFound(
|
|
|
|
reason=u'%s: group not found' % group.cn)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_update_nonexistent(self, group):
|
|
|
|
""" Try to update a non-existent group """
|
|
|
|
group.ensure_missing()
|
|
|
|
command = group.make_update_command(
|
|
|
|
updates=dict(description=u'hey'))
|
|
|
|
with raises_exact(errors.NotFound(
|
|
|
|
reason=u'%s: group not found' % group.cn)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_delete_nonexistent(self, group):
|
|
|
|
""" Try to delete a non-existent user """
|
|
|
|
group.ensure_missing()
|
|
|
|
command = group.make_delete_command()
|
|
|
|
with raises_exact(errors.NotFound(
|
|
|
|
reason=u'%s: group not found' % group.cn)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_rename_nonexistent(self, group):
|
|
|
|
""" Try to rename a non-existent user """
|
|
|
|
group.ensure_missing()
|
|
|
|
command = group.make_update_command(
|
|
|
|
updates=dict(setattr=u'cn=%s' % renamedgroup1))
|
|
|
|
with raises_exact(errors.NotFound(
|
|
|
|
reason=u'%s: group not found' % group.cn)):
|
|
|
|
command()
|
2015-03-04 09:47:04 -06:00
|
|
|
|
2015-04-24 07:39:48 -05:00
|
|
|
|
|
|
|
@pytest.mark.tier1
|
2015-11-09 09:48:55 -06:00
|
|
|
class TestNonposixGroup(XMLRPC_test):
|
|
|
|
def test_create_nonposix(self, group):
|
|
|
|
""" Create a non-posix group """
|
|
|
|
group.track_create()
|
|
|
|
command = group.make_create_command(**dict(nonposix=True))
|
|
|
|
result = command()
|
|
|
|
|
|
|
|
del group.attrs['gidnumber']
|
|
|
|
group.attrs.update(objectclass=objectclasses.group)
|
|
|
|
group.check_create(result)
|
|
|
|
|
|
|
|
def test_create_duplicate_to_nonposix(self, group):
|
|
|
|
""" Try to create a duplicate non-posix group """
|
|
|
|
group.ensure_exists()
|
|
|
|
command = group.make_create_command()
|
|
|
|
|
|
|
|
with raises_exact(errors.DuplicateEntry(
|
|
|
|
message=u'group with name "%s" already exists' % group.cn)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_retrieve_nonposix(self, group):
|
|
|
|
""" Retrieve a non-posix group """
|
|
|
|
group.retrieve()
|
|
|
|
|
|
|
|
def test_update_nonposix(self, group):
|
|
|
|
""" Update a non-posix group with new description
|
|
|
|
and perform retrieve command to verify the update """
|
|
|
|
group.update(dict(description=u'New desc'))
|
|
|
|
group.retrieve()
|
|
|
|
|
|
|
|
def test_search_for_all_nonposix(self, group):
|
|
|
|
""" Perform a search for all non-posix groups """
|
|
|
|
command = group.make_command(
|
|
|
|
'group_find', **dict(nonposix=True, all=True)
|
|
|
|
)
|
|
|
|
result = command()
|
|
|
|
assert_deepequal(dict(
|
|
|
|
summary=u'3 groups matched',
|
|
|
|
count=3,
|
|
|
|
truncated=False,
|
|
|
|
result=[
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('ipausers'),
|
|
|
|
'cn': [u'ipausers'],
|
|
|
|
'description': [u'Default group for all users'],
|
|
|
|
'objectclass': fuzzy_set_ci(objectclasses.group),
|
|
|
|
'ipauniqueid': [fuzzy_uuid],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'dn': get_group_dn(group.cn),
|
|
|
|
'cn': [group.cn],
|
|
|
|
'description': [u'New desc'],
|
|
|
|
'objectclass': fuzzy_set_ci(objectclasses.group),
|
|
|
|
'ipauniqueid': [fuzzy_uuid],
|
|
|
|
},
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('trust admins'),
|
|
|
|
'member_user': [u'admin'],
|
|
|
|
'cn': [u'trust admins'],
|
|
|
|
'description': [u'Trusts administrators group'],
|
|
|
|
'objectclass': fuzzy_set_ci(objectclasses.group),
|
2015-03-04 09:47:04 -06:00
|
|
|
'ipauniqueid': [fuzzy_uuid],
|
|
|
|
},
|
2015-11-09 09:48:55 -06:00
|
|
|
],
|
|
|
|
), result)
|
|
|
|
|
|
|
|
def test_upgrade_nonposix_to_posix(self, group):
|
|
|
|
""" Update non-posix group to promote it to posix group """
|
|
|
|
group.attrs.update(gidnumber=[fuzzy_digits])
|
|
|
|
group.update(dict(posix=True), dict(posix=None))
|
|
|
|
group.retrieve()
|
|
|
|
|
|
|
|
def test_search_for_all_nonposix_with_criteria(self, group):
|
|
|
|
""" Search for all non-posix groups with additional
|
|
|
|
criteria filter """
|
|
|
|
command = group.make_command(
|
|
|
|
'group_find', *[u'users'], **dict(nonposix=True, all=True)
|
|
|
|
)
|
|
|
|
result = command()
|
|
|
|
assert_deepequal(dict(
|
|
|
|
summary=u'1 group matched',
|
|
|
|
count=1,
|
|
|
|
truncated=False,
|
|
|
|
result=[
|
|
|
|
{
|
|
|
|
'dn': get_group_dn('ipausers'),
|
|
|
|
'cn': [u'ipausers'],
|
|
|
|
'description': [u'Default group for all users'],
|
|
|
|
'objectclass': fuzzy_set_ci(objectclasses.group),
|
|
|
|
'ipauniqueid': [fuzzy_uuid],
|
2015-03-04 09:47:04 -06:00
|
|
|
},
|
2015-11-09 09:48:55 -06:00
|
|
|
],
|
|
|
|
), result)
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.tier1
|
|
|
|
class TestExternalGroup(XMLRPC_test):
|
|
|
|
def test_create_external(self, group):
|
|
|
|
""" Create a non-posix group """
|
|
|
|
group.track_create()
|
|
|
|
del group.attrs['gidnumber']
|
|
|
|
group.attrs.update(objectclass=objectclasses.externalgroup)
|
|
|
|
command = group.make_create_command(**dict(external=True))
|
|
|
|
result = command()
|
|
|
|
group.check_create(result)
|
|
|
|
|
|
|
|
def test_search_for_external(self, group):
|
|
|
|
""" Search for all external groups """
|
|
|
|
command = group.make_command(
|
|
|
|
'group_find', **dict(external=True, all=True)
|
|
|
|
)
|
|
|
|
result = command()
|
|
|
|
group.check_find(result, all=True)
|
|
|
|
|
|
|
|
def test_convert_external_to_posix(self, group):
|
|
|
|
""" Try to convert an external group to posix """
|
|
|
|
command = group.make_update_command(dict(posix=True))
|
|
|
|
with raises_exact(errors.ExternalGroupViolation(
|
|
|
|
reason=u'This group cannot be posix because it is external')):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_add_external_member_to_external(self, group):
|
|
|
|
""" Try to add an invalid external member to an external
|
|
|
|
group and check that proper exceptions are raised """
|
|
|
|
# When adding external SID member to a group we can't test
|
|
|
|
# it fully due to possibly missing Samba 4 python bindings
|
|
|
|
# and/or not configured AD trusts. Thus, we'll use incorrect
|
|
|
|
# SID value to merely test that proper exceptions are raised
|
|
|
|
command = group.make_command('group_add_member', *[group.cn],
|
|
|
|
**dict(ipaexternalmember=external_sid1))
|
|
|
|
try:
|
|
|
|
command()
|
|
|
|
except Exception as ex:
|
|
|
|
if type(ex) == errors.ValidationError:
|
|
|
|
pass
|
|
|
|
elif type(ex) == errors.NotFound:
|
|
|
|
pass
|
|
|
|
elif 'failed' in str(ex):
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
raise ex
|
|
|
|
|
|
|
|
def test_delete_external_group(self, group):
|
|
|
|
group.delete()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.tier1
|
|
|
|
class TestGroupMember(XMLRPC_test):
|
|
|
|
def test_add_nonexistent_member(self, group):
|
|
|
|
""" Try to add non-existent member to a group """
|
|
|
|
group.create()
|
|
|
|
command = group.make_add_member_command(dict(group=notagroup))
|
|
|
|
result = command()
|
|
|
|
group.check_add_member_negative(result, dict(group=notagroup))
|
|
|
|
|
|
|
|
def test_remove_nonexistent_member(self, group):
|
|
|
|
""" Try to remove non-existent member from a group """
|
|
|
|
group.ensure_exists()
|
|
|
|
command = group.make_remove_member_command(dict(group=notagroup))
|
|
|
|
result = command()
|
|
|
|
group.check_remove_member_negative(result, dict(group=notagroup))
|
|
|
|
|
|
|
|
def test_add_member(self, group, group2):
|
|
|
|
""" Add member group to a group """
|
|
|
|
group.ensure_exists()
|
|
|
|
group2.ensure_exists()
|
|
|
|
group.add_member(dict(group=group2.cn))
|
|
|
|
|
|
|
|
def test_remove_member(self, group, group2):
|
|
|
|
""" Remove a group member """
|
|
|
|
group.ensure_exists()
|
|
|
|
group2.ensure_exists()
|
|
|
|
group.remove_member(dict(group=group2.cn))
|
|
|
|
|
|
|
|
def test_add_and_remove_group_from_admins(self, group, admins):
|
|
|
|
""" Add group to protected admins group and then remove it """
|
|
|
|
# Test scenario from ticket #4448
|
|
|
|
# https://fedorahosted.org/freeipa/ticket/4448
|
|
|
|
group.ensure_exists()
|
|
|
|
admins.add_member(dict(group=group.cn))
|
|
|
|
admins.remove_member(dict(group=group.cn))
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.tier1
|
|
|
|
class TestValidation(XMLRPC_test):
|
|
|
|
# The assumption for this class of tests is that if we don't
|
|
|
|
# get a validation error then the request was processed normally.
|
|
|
|
|
|
|
|
def test_validation_disabled_on_delete(self, group):
|
|
|
|
""" Test that validation is disabled on group deletes """
|
|
|
|
command = group.make_command('group_del', invalidgroup1)
|
|
|
|
with raises_exact(errors.NotFound(
|
|
|
|
reason=u'%s: group not found' % invalidgroup1)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_validation_disabled_on_show(self, group):
|
|
|
|
""" Test that validation is disabled on group retrieves """
|
|
|
|
command = group.make_command('group_show', invalidgroup1)
|
|
|
|
with raises_exact(errors.NotFound(
|
|
|
|
reason=u'%s: group not found' % invalidgroup1)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_validation_disabled_on_mod(self, group):
|
|
|
|
""" Test that validation is disabled on group mods """
|
|
|
|
command = group.make_command('group_mod', invalidgroup1)
|
|
|
|
with raises_exact(errors.NotFound(
|
|
|
|
reason=u'%s: group not found' % invalidgroup1)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.tier1
|
|
|
|
class TestManagedGroups(XMLRPC_test):
|
|
|
|
def test_verify_managed_created(self, managed_group):
|
|
|
|
""" Verify that managed group is created with new user """
|
|
|
|
managed_group.retrieve()
|
|
|
|
|
|
|
|
def test_verify_managed_findable(self, managed_group):
|
|
|
|
""" Verify that managed group can be found """
|
|
|
|
command = managed_group.make_find_command(
|
|
|
|
**dict(cn=managed_group.cn, private=True)
|
|
|
|
)
|
|
|
|
result = command()
|
|
|
|
managed_group.check_find(result)
|
|
|
|
|
|
|
|
def test_delete_managed(self, managed_group):
|
|
|
|
""" Try to delete managed group """
|
|
|
|
command = managed_group.make_delete_command()
|
|
|
|
with raises_exact(errors.ManagedGroupError()):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_detach_managed(self, managed_group):
|
|
|
|
""" Detach managed group from a user """
|
|
|
|
command = managed_group.make_detach_command()
|
|
|
|
result = command()
|
|
|
|
managed_group.check_detach(result)
|
|
|
|
|
|
|
|
def test_delete_detached_managed(self, managed_group, user):
|
|
|
|
""" Delete a previously managed group that is now detached
|
|
|
|
and verify it's really gone """
|
|
|
|
managed_group.delete()
|
|
|
|
command = managed_group.make_retrieve_command()
|
|
|
|
with raises_exact(errors.NotFound(
|
|
|
|
reason=u'%s: group not found' % managed_group.cn)):
|
|
|
|
command()
|
|
|
|
user.ensure_missing()
|
|
|
|
|
|
|
|
def test_verify_managed_missing_for_user_without_upg(self, user_npg2):
|
|
|
|
""" Create a user without user private group and
|
|
|
|
verify private group wasn't created """
|
|
|
|
user_npg2.attrs.update(memberof_group=[u'ipausers'])
|
|
|
|
command = user_npg2.make_create_command()
|
|
|
|
result = command()
|
|
|
|
user_npg2.check_create(result, [u'description', u'memberof_group'])
|
|
|
|
command = user_npg2.make_command('group_show', *[user_npg2.uid])
|
|
|
|
with raises_exact(errors.NotFound(
|
|
|
|
reason=u'%s: group not found' % user_npg2.uid)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.tier1
|
|
|
|
class TestManagedGroupObjectclasses(XMLRPC_test):
|
|
|
|
def test_check_objectclasses_after_detach(self, user, managed_group):
|
|
|
|
""" Check objectclasses after user was detached from managed group """
|
|
|
|
# https://fedorahosted.org/freeipa/ticket/4909#comment:1
|
|
|
|
user.create()
|
|
|
|
user.run_command('group_detach', *[user.uid])
|
|
|
|
managed_group.retrieve(all=True)
|
|
|
|
managed_group.add_member(dict(user=user.uid))
|
|
|
|
managed_group.ensure_missing()
|
|
|
|
user.ensure_missing()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.tier1
|
|
|
|
class TestAdminGroup(XMLRPC_test):
|
|
|
|
def test_remove_admin_from_admins(self, admins):
|
|
|
|
""" Remove the original admin from admins group """
|
|
|
|
command = admins.make_remove_member_command(
|
|
|
|
dict(user=u'admin')
|
|
|
|
)
|
|
|
|
with raises_exact(errors.LastMemberError(
|
|
|
|
key=u'admin', label=u'group', container=admins.cn)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_add_another_admin(self, admins, user):
|
|
|
|
""" Add second member to the admins group """
|
|
|
|
user.ensure_exists()
|
|
|
|
admins.add_member(dict(user=user.uid))
|
|
|
|
|
|
|
|
def test_remove_all_admins_from_admins(self, admins, user):
|
|
|
|
""" Try to remove both original and our admin from admins group """
|
|
|
|
command = admins.make_remove_member_command(
|
|
|
|
dict(user=[u'admin', user.uid])
|
|
|
|
)
|
|
|
|
with raises_exact(errors.LastMemberError(
|
|
|
|
key=u'admin', label=u'group', container=admins.cn)):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_delete_admins(self, admins):
|
|
|
|
""" Try to delete the protected admins group """
|
|
|
|
command = admins.make_delete_command()
|
|
|
|
with raises_exact(errors.ProtectedEntryError(label=u'group',
|
|
|
|
key=admins.cn, reason='privileged group')):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_rename_admins(self, admins):
|
|
|
|
""" Try to rename the protected admins group """
|
|
|
|
command = admins.make_command('group_mod', *[admins.cn],
|
|
|
|
**dict(rename=renamedgroup1))
|
|
|
|
with raises_exact(errors.ProtectedEntryError(label=u'group',
|
|
|
|
key=admins.cn, reason='Cannot be renamed')):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_rename_admins_using_setattr(self, admins):
|
|
|
|
""" Try to rename the protected admins group using setattr """
|
|
|
|
command = admins.make_command('group_mod', *[admins.cn],
|
|
|
|
**dict(setattr=u'cn=%s' % renamedgroup1))
|
|
|
|
with raises_exact(errors.ProtectedEntryError(label=u'group',
|
|
|
|
key=admins.cn, reason='Cannot be renamed')):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_update_admins_to_support_external_membership(self, admins):
|
|
|
|
""" Try to modify the admins group to support external membership """
|
|
|
|
command = admins.make_command('group_mod', *[admins.cn],
|
|
|
|
**dict(external=True))
|
|
|
|
with raises_exact(errors.ProtectedEntryError(label=u'group',
|
|
|
|
key=admins.cn,
|
|
|
|
reason='Cannot support external non-IPA members')):
|
|
|
|
command()
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.tier1
|
|
|
|
class TestTrustAdminGroup(XMLRPC_test):
|
|
|
|
def test_delete_trust_admins(self, trustadmins):
|
|
|
|
""" Try to delete the protected 'trust admins' group """
|
|
|
|
command = trustadmins.make_delete_command()
|
|
|
|
with raises_exact(errors.ProtectedEntryError(label=u'group',
|
|
|
|
key=trustadmins.cn, reason='privileged group')):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_rename_trust_admins(self, trustadmins):
|
|
|
|
""" Try to rename the protected 'trust admins' group """
|
|
|
|
command = trustadmins.make_command('group_mod', *[trustadmins.cn],
|
|
|
|
**dict(rename=renamedgroup1))
|
|
|
|
with raises_exact(errors.ProtectedEntryError(label=u'group',
|
|
|
|
key=trustadmins.cn, reason='Cannot be renamed')):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_rename_trust_admins_using_setattr(self, trustadmins):
|
|
|
|
""" Try to rename the protected 'trust admins' group using setattr """
|
|
|
|
command = trustadmins.make_command(
|
|
|
|
'group_mod', *[trustadmins.cn],
|
|
|
|
**dict(setattr=u'cn=%s' % renamedgroup1)
|
|
|
|
)
|
|
|
|
with raises_exact(errors.ProtectedEntryError(label=u'group',
|
|
|
|
key=trustadmins.cn, reason='Cannot be renamed')):
|
|
|
|
command()
|
|
|
|
|
|
|
|
def test_update_trust_admins_to_support_external_membership(
|
|
|
|
self, trustadmins
|
|
|
|
):
|
|
|
|
""" Try to modify the 'trust admins' group to
|
|
|
|
support external membership """
|
|
|
|
command = trustadmins.make_command(
|
|
|
|
'group_mod', *[trustadmins.cn],
|
|
|
|
**dict(external=True)
|
|
|
|
)
|
|
|
|
with raises_exact(errors.ProtectedEntryError(label=u'group',
|
|
|
|
key=trustadmins.cn,
|
|
|
|
reason='Cannot support external non-IPA members')):
|
|
|
|
command()
|