Source code for univention.testing.fixtures_recyclebin

# SPDX-FileCopyrightText: 2013-2025 Univention GmbH
# SPDX-License-Identifier: AGPL-3.0-only

"""Common functions/fixtures for recyclebin tests."""

import random
from types import SimpleNamespace

import pytest
from ldap.dn import escape_dn_chars

from univention.config_registry import ucr as _ucr
from univention.testing.strings import random_username
from univention.testing.utils import verify_ldap_object


RECYCLEBIN_DN = "cn=recyclebin,cn=internal"


def _deleted_object_dn(dn, u_obj_id):
    """Get the DN of the deleted object in the recyclebin"""
    return f'univentionRecycleBinOriginalDN={escape_dn_chars(dn)}+univentionRecycleBinOriginalUniventionObjectIdentifier={escape_dn_chars(u_obj_id)},{RECYCLEBIN_DN}'


def __recyclebin_policy(udm, ldap_base):
    name = random_username()
    retention_days = random.randint(100, 300)  # days
    pol_dn = udm.create_object(
        'policies/recyclebin',
        position=f'cn=policies,{ldap_base}',
        name=name,
        udm_modules=['users/user', 'groups/group'],
        ignored_object_classes=['pkiUser'],
        retention_days=retention_days,
        wait_for_replication=False,
    )
    con_dn = udm.create_object('container/cn', position=f'{ldap_base}', name=f'recyclebin_{name}', policy_reference=pol_dn, wait_for_replication=False)
    return con_dn, retention_days


[docs] @pytest.fixture(scope='module') def recyclebin_policy_session(udm_session, ldap_base): return __recyclebin_policy(udm_session, ldap_base)
[docs] @pytest.fixture def recyclebin_policy(udm, ldap_base): return __recyclebin_policy(udm, ldap_base)
[docs] @pytest.fixture def deleted_user_object(recyclebin_policy, udm): container_recyclebin_policy, _ = recyclebin_policy user_dn, _ = udm.create_user(position=container_recyclebin_policy, wait_for_replication=False) uoid = udm.get_object('users/user', user_dn)['univentionObjectIdentifier'][0] udm.remove_object('users/user', dn=user_dn) verify_ldap_object(user_dn, should_exist=False) deleted_dn = _deleted_object_dn(user_dn, uoid) verify_ldap_object(deleted_dn, should_exist=True) return user_dn, deleted_dn
[docs] @pytest.fixture(scope='module') def share_for_testing_session(udm_session, ldap_base): """Create a share for testing homeShare attributes""" hostname = _ucr.get('hostname', 'server') domainname = _ucr.get('domainname', 'ucs.test') share_dn = udm_session.create_object( 'shares/share', position=f'cn=shares,{ldap_base}', name='test_recyclebin_share', host=f'{hostname}.{domainname}', path='/home/shares/test_recyclebin', wait_for_replication=False, ) return share_dn
[docs] @pytest.fixture def deleted_object_user_properties(ldap_base) -> SimpleNamespace: data = { 'originalDN': f'uid=testdeluser,cn=users,{ldap_base}', 'purgeAt': '20261212085050Z', 'removalDate': '30261212085050Z', 'originalObjectType': 'users/user', 'originalUniventionObjectIdentifier': 'f2b2e6ff-ad41-47ce-87ea-9d2ac39aaaca', 'originalEntryUUID': 'f2b2e6ff-ad41-47ce-87ea-9d2ac33aaacb', 'originalObjectClasses': [ 'automount', 'univentionMail', 'univentionPWHistory', 'inetOrgPerson', 'person', 'organizationalPerson', 'sambaSamAccount', 'top', 'shadowAccount', 'univentionPerson', 'krb5Principal', 'krb5KDCEntry', 'univentionObject', 'posixAccount', ], 'ldap_attrs': { 'cn': [b'lastname'], 'displayName': [b'lastname'], 'gecos': [b'lastname'], 'gidNumber': [b'5001'], 'homeDirectory': [b'/home/test1'], 'krb5KDCFlags': [b'126'], 'krb5Key': [ b'07\xa1\x1b0\x19\xa0\x03\x02\x01\x11\xa1\x12\x04\x10\xa7\x86\xdc\x0f\xdcn0c\x91\x98Z\xa0\xd2Y\xc7t\xa2\x180\x16\xa0\x03\x02\x01\x03\xa1\x0f\x04\rUCS.TESTtest1', b'07\xa1\x1b0\x19\xa0\x03\x02\x01\x17\xa1\x12\x04\x10\xca\xa1#\x9dD\xda~\xdf\x92k\xce9\xf5\xc6]\x0f\xa2\x180\x16\xa0\x03\x02\x01\x03\xa1\x0f\x04\rUCS.TESTtest1', ], 'krb5KeyVersionNumber': [b'1'], 'krb5MaxLife': [b'86400'], 'krb5MaxRenew': [b'604800'], 'krb5PrincipalName': [b'test1@UCS.TEST'], 'loginShell': [b'/bin/bash'], 'mailForwardCopyToSelf': [b'0'], 'pwhistory': [b' $6$znLCTmtimN7H0T92$2iuAyLCkTT/hjoSqTVzMy7U7Fh5OGHaHc6fGupy4KvYoSA2V4FCsfcw3qfQyKA5goXFclV6hvZNCk.xx3B4/u/'], 'sambaAcctFlags': [b'[U ]'], 'sambaBadPasswordCount': [b'0'], 'sambaBadPasswordTime': [b'0'], 'sambaNTPassword': [b'CAA1239D44DA7EDF926BCE39F5C65D0F'], 'sambaPrimaryGroupSID': [b'S-1-5-21-4050189495-1942909977-1471735533-513'], 'sambaPwdLastSet': [b'1756909087'], 'sambaSID': [b'S-1-5-21-4050189495-1942909977-1471735533-5386'], 'sn': [b'lastname'], 'uid': [b'testdeluser'], 'uidNumber': [b'2193'], 'userPassword': [b'{crypt}$6$Si5dxjbGT8wI147P$AazXJ3prqclvVvCuIiou97V0XkzcuUoRiHqN.bqidlcg8kruJe23IIq6lZCJ00WuSPYbuE6IfTyFmPA3EipgA1'], 'memberOf': [ f'cn=Domain Users,cn=groups,{ldap_base}'.encode(), f'cn=Domain Admins,cn=groups,{ldap_base}'.encode(), f'cn=doesnotexist,cn=groups,{ldap_base}'.encode(), ], }, 'ignore_ldap_attrs': { # these should be ignored 'structuralObjectClass': [b'inetOrgPerson'], 'entryUUID': [b'09679f3a-1867-1040-8fe5-d7f9203edc52'], 'creatorsName': [b'cn=admin,dc=ucs,dc=test'], 'createTimestamp': [b'20250828142840Z'], 'entryCSN': [b'20250912080929.667762Z#000000#000#000000'], 'modifiersName': [b'cn=admin,dc=ucs,dc=test'], 'modifyTimestamp': [b'20250912080929Z'], 'entryDN': [b'uid=Administrator,cn=users,dc=ucs,dc=test'], 'subschemaSubentry': [b'cn=Subschema'], 'hasSubordinates': [b'FALSE'], }, } return SimpleNamespace(**data)