2021-08-19 12:58:59 -04:00
|
|
|
import ldap3
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
from ceod.model import Group
|
2024-02-17 19:31:03 -05:00
|
|
|
from tests.conftest_ceod_api import expect_successful_txn
|
2021-08-19 12:58:59 -04:00
|
|
|
|
|
|
|
|
|
|
|
def test_api_group_not_found(client):
|
|
|
|
status, data = client.get('/api/groups/no_such_group')
|
|
|
|
assert status == 404
|
|
|
|
|
|
|
|
|
2024-02-17 19:31:03 -05:00
|
|
|
def create_group(client, cn: str, description: str):
|
2021-08-19 12:58:59 -04:00
|
|
|
status, data = client.post('/api/groups', json={
|
2024-02-17 19:31:03 -05:00
|
|
|
'cn': cn,
|
|
|
|
'description': description,
|
2021-08-19 12:58:59 -04:00
|
|
|
})
|
|
|
|
assert status == 200
|
|
|
|
assert data[-1]['status'] == 'completed'
|
2024-02-17 19:31:03 -05:00
|
|
|
return status, data
|
|
|
|
|
|
|
|
|
|
|
|
def delete_group(client, cn: str):
|
|
|
|
status, data = client.delete(f'/api/groups/{cn}')
|
2021-08-19 12:58:59 -04:00
|
|
|
assert status == 200
|
|
|
|
assert data[-1]['status'] == 'completed'
|
|
|
|
|
|
|
|
|
2024-02-17 19:31:03 -05:00
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def create_group_resp(client):
|
|
|
|
yield create_group(client, 'test_group1', 'Test Group One')
|
|
|
|
delete_group(client, 'test_group1')
|
|
|
|
|
|
|
|
|
2021-08-19 12:58:59 -04:00
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def create_group_result(create_group_resp):
|
|
|
|
# convenience method
|
|
|
|
_, data = create_group_resp
|
|
|
|
return data[-1]['result']
|
|
|
|
|
|
|
|
|
|
|
|
def test_api_create_group(cfg, create_group_resp, ldap_conn):
|
|
|
|
_, data = create_group_resp
|
|
|
|
min_uid = cfg.get('clubs_min_id')
|
|
|
|
users_base = cfg.get('ldap_users_base')
|
|
|
|
sudo_base = cfg.get('ldap_sudo_base')
|
|
|
|
|
|
|
|
expected = [
|
|
|
|
{"status": "in progress", "operation": "add_user_to_ldap"},
|
|
|
|
{"status": "in progress", "operation": "add_group_to_ldap"},
|
|
|
|
{"status": "in progress", "operation": "add_sudo_role"},
|
|
|
|
{"status": "in progress", "operation": "create_home_dir"},
|
|
|
|
{"status": "completed", "result": {
|
|
|
|
"cn": "test_group1",
|
|
|
|
"gid_number": min_uid,
|
|
|
|
"description": "Test Group One",
|
|
|
|
"members": [],
|
|
|
|
}},
|
|
|
|
]
|
|
|
|
assert data == expected
|
|
|
|
|
|
|
|
# verify that a user was also created
|
|
|
|
ldap_conn.search(
|
|
|
|
f'uid=test_group1,{users_base}', '(objectClass=*)',
|
|
|
|
search_scope=ldap3.BASE)
|
|
|
|
assert len(ldap_conn.entries) == 1
|
|
|
|
|
|
|
|
# verify that a sudo role was also created
|
|
|
|
ldap_conn.search(
|
|
|
|
f'cn=%test_group1,{sudo_base}', '(objectClass=*)',
|
|
|
|
search_scope=ldap3.BASE)
|
|
|
|
assert len(ldap_conn.entries) == 1
|
|
|
|
|
|
|
|
|
|
|
|
def test_api_get_group(cfg, client, create_group_result):
|
|
|
|
old_data = create_group_result
|
|
|
|
cn = old_data['cn']
|
|
|
|
|
|
|
|
status, data = client.get(f'/api/groups/{cn}')
|
|
|
|
assert status == 200
|
|
|
|
assert data == old_data
|
|
|
|
|
|
|
|
|
|
|
|
def test_api_add_member_to_group(client, create_group_result, ldap_user):
|
|
|
|
uid = ldap_user.uid
|
|
|
|
cn = create_group_result['cn']
|
|
|
|
|
|
|
|
status, data = client.post(f'/api/groups/{cn}/members/{uid}')
|
|
|
|
assert status == 200
|
|
|
|
expected = [
|
|
|
|
{"status": "in progress", "operation": "add_user_to_group"},
|
|
|
|
{"status": "completed", "result": {"added_to_groups": [cn]}},
|
|
|
|
]
|
|
|
|
assert data == expected
|
|
|
|
|
|
|
|
_, data = client.get(f'/api/groups/{cn}')
|
|
|
|
expected = {
|
|
|
|
"cn": cn,
|
|
|
|
"gid_number": create_group_result['gid_number'],
|
|
|
|
"description": create_group_result['description'],
|
|
|
|
"members": [
|
|
|
|
{
|
|
|
|
"cn": ldap_user.cn,
|
|
|
|
"program": ldap_user.program,
|
|
|
|
"uid": ldap_user.uid,
|
|
|
|
}
|
|
|
|
],
|
|
|
|
}
|
|
|
|
assert data == expected
|
|
|
|
|
|
|
|
status, data = client.delete(f'/api/groups/{cn}/members/{uid}')
|
|
|
|
assert status == 200
|
|
|
|
expected = [
|
|
|
|
{"status": "in progress", "operation": "remove_user_from_group"},
|
|
|
|
{"status": "completed", "result": {"removed_from_groups": [cn]}},
|
|
|
|
]
|
|
|
|
assert data == expected
|
|
|
|
|
|
|
|
_, data = client.get(f'/api/groups/{cn}')
|
|
|
|
assert data['members'] == []
|
|
|
|
|
|
|
|
|
2023-03-04 01:21:04 -05:00
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def create_random_names():
|
2023-07-31 18:11:41 -04:00
|
|
|
# generated with https://www.randomlists.com/random-words
|
2023-03-04 01:21:04 -05:00
|
|
|
random_names = [
|
|
|
|
"intelligent",
|
|
|
|
"skin",
|
|
|
|
"shivering",
|
|
|
|
]
|
|
|
|
yield random_names
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture(scope='module')
|
|
|
|
def create_searchable_groups(client, create_random_names):
|
|
|
|
random_names = create_random_names
|
|
|
|
for name in random_names:
|
2024-02-17 19:31:03 -05:00
|
|
|
create_group(client, name, 'Groups with distinct names for testing searching')
|
2023-03-04 01:21:04 -05:00
|
|
|
yield random_names
|
|
|
|
|
|
|
|
|
|
|
|
def test_api_group_search(client, create_searchable_groups):
|
|
|
|
cns = create_searchable_groups
|
|
|
|
# pairs of cn indices as well as amount of results that should be returned
|
|
|
|
random_numbers = [
|
2023-07-31 18:11:41 -04:00
|
|
|
(0, 68),
|
|
|
|
(1, 54),
|
|
|
|
(2, 97),
|
2023-03-04 01:21:04 -05:00
|
|
|
]
|
|
|
|
|
|
|
|
for tup in random_numbers:
|
|
|
|
cn = cns[tup[0]]
|
|
|
|
status, data = client.get(f'/api/groups/search/{cn}/{tup[1]}')
|
|
|
|
assert status == 200
|
|
|
|
assert len(data) == tup[1]
|
|
|
|
assert data[0] == cn
|
|
|
|
|
|
|
|
for cn in cns:
|
|
|
|
status, data = client.delete(f'/api/groups/{cn}')
|
|
|
|
assert status == 200
|
|
|
|
assert data[-1]['status'] == 'completed'
|
|
|
|
|
|
|
|
|
2021-08-19 12:58:59 -04:00
|
|
|
def test_api_group_auxiliary(cfg, client, ldap_user, g_admin_ctx):
|
|
|
|
# Make sure that syscom has auxiliary mailing lists and groups
|
|
|
|
# defined in ceod_test_local.ini.
|
|
|
|
# Also make sure that the auxiliary mailing lists are defined in
|
|
|
|
# MockMailmanServer.py.
|
|
|
|
aux_groups = cfg.get('auxiliary groups_syscom')
|
|
|
|
aux_lists = cfg.get('auxiliary mailing lists_syscom')
|
|
|
|
min_uid = cfg.get('clubs_min_id')
|
|
|
|
# add one to account for the 'Test Group One' group, above
|
|
|
|
min_uid += 1
|
|
|
|
|
|
|
|
group_names = ['syscom'] + aux_groups
|
|
|
|
groups = []
|
|
|
|
with g_admin_ctx():
|
2022-09-09 17:26:54 -04:00
|
|
|
# the syscom group should already exist, since we need it for auth
|
|
|
|
for group_name in aux_groups:
|
2021-08-19 12:58:59 -04:00
|
|
|
group = Group(
|
|
|
|
cn=group_name,
|
|
|
|
gid_number=min_uid,
|
|
|
|
)
|
|
|
|
group.add_to_ldap()
|
|
|
|
groups.append(group)
|
|
|
|
min_uid += 1
|
|
|
|
|
|
|
|
uid = ldap_user.uid
|
|
|
|
_, data = client.post(f'/api/groups/syscom/members/{uid}')
|
|
|
|
expected = [
|
|
|
|
{"status": "in progress", "operation": "add_user_to_group"},
|
|
|
|
{"status": "in progress", "operation": "add_user_to_auxiliary_groups"},
|
|
|
|
{"status": "in progress", "operation": "subscribe_user_to_auxiliary_mailing_lists"},
|
|
|
|
{"status": "completed", "result": {
|
|
|
|
"added_to_groups": group_names,
|
|
|
|
"subscribed_to_lists": aux_lists,
|
|
|
|
}},
|
|
|
|
]
|
|
|
|
assert data == expected
|
|
|
|
|
|
|
|
_, data = client.delete(f'/api/groups/syscom/members/{uid}')
|
|
|
|
expected = [
|
|
|
|
{"status": "in progress", "operation": "remove_user_from_group"},
|
|
|
|
{"status": "in progress", "operation": "remove_user_from_auxiliary_groups"},
|
|
|
|
{"status": "in progress", "operation": "unsubscribe_user_from_auxiliary_mailing_lists"},
|
|
|
|
{"status": "completed", "result": {
|
|
|
|
"removed_from_groups": group_names,
|
|
|
|
"unsubscribed_from_lists": aux_lists,
|
|
|
|
}},
|
|
|
|
]
|
|
|
|
assert data == expected
|
|
|
|
|
|
|
|
with g_admin_ctx():
|
|
|
|
for group in groups:
|
2022-09-09 17:26:54 -04:00
|
|
|
if group.cn != 'syscom':
|
|
|
|
group.remove_from_ldap()
|
2024-02-17 19:31:03 -05:00
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize('desc,expect_success', [
|
|
|
|
('in_syscom', True),
|
|
|
|
('is_offsck', True),
|
|
|
|
(None, False),
|
|
|
|
])
|
|
|
|
def test_api_add_or_remove_member_from_office(desc, expect_success, cfg, client, ldap_and_krb_user, new_user, g_admin_ctx):
|
|
|
|
uid = ldap_and_krb_user.uid
|
|
|
|
if desc == 'in_syscom':
|
|
|
|
uid = 'ctdalek'
|
|
|
|
elif desc == 'is_offsck':
|
|
|
|
with g_admin_ctx():
|
|
|
|
ldap_and_krb_user.set_positions(['offsck'])
|
|
|
|
|
|
|
|
def handle_resp(status_and_data):
|
|
|
|
if expect_success:
|
|
|
|
expect_successful_txn(status_and_data)
|
|
|
|
else:
|
|
|
|
status = status_and_data[0]
|
|
|
|
assert status == 403
|
|
|
|
|
|
|
|
handle_resp(client.post(f'/api/groups/office/members/{new_user.uid}', principal=uid))
|
|
|
|
handle_resp(client.delete(f'/api/groups/office/members/{new_user.uid}', principal=uid))
|