|
|
5d81fc |
From 1e1c2b23c35282481628af7e971ac683da334502 Mon Sep 17 00:00:00 2001
|
|
|
5d81fc |
From: James Chapman <jachapma@redhat.com>
|
|
|
5d81fc |
Date: Tue, 27 Apr 2021 17:00:15 +0100
|
|
|
5d81fc |
Subject: [PATCH 02/12] Issue 4701 - RFE - Exclude attributes from retro
|
|
|
5d81fc |
changelog (#4723)
|
|
|
5d81fc |
|
|
|
5d81fc |
Description: When the retro changelog plugin is enabled it writes the
|
|
|
5d81fc |
added/modified values to the "cn-changelog" suffix. In
|
|
|
5d81fc |
some cases an entries attribute values can be of a
|
|
|
5d81fc |
sensitive nature and should be excluded. This RFE adds
|
|
|
5d81fc |
functionality that will allow an admin exclude certain
|
|
|
5d81fc |
attributes from the retro changelog DB.
|
|
|
5d81fc |
|
|
|
5d81fc |
Relates: https://github.com/389ds/389-ds-base/issues/4701
|
|
|
5d81fc |
|
|
|
5d81fc |
Reviewed by: mreynolds389, droideck (Thanks folks)
|
|
|
5d81fc |
---
|
|
|
5d81fc |
.../tests/suites/retrocl/basic_test.py | 292 ++++++++++++++++++
|
|
|
5d81fc |
1 file changed, 292 insertions(+)
|
|
|
5d81fc |
create mode 100644 dirsrvtests/tests/suites/retrocl/basic_test.py
|
|
|
5d81fc |
|
|
|
5d81fc |
diff --git a/dirsrvtests/tests/suites/retrocl/basic_test.py b/dirsrvtests/tests/suites/retrocl/basic_test.py
|
|
|
5d81fc |
new file mode 100644
|
|
|
5d81fc |
index 000000000..112c73cb9
|
|
|
5d81fc |
--- /dev/null
|
|
|
5d81fc |
+++ b/dirsrvtests/tests/suites/retrocl/basic_test.py
|
|
|
5d81fc |
@@ -0,0 +1,292 @@
|
|
|
5d81fc |
+# --- BEGIN COPYRIGHT BLOCK ---
|
|
|
5d81fc |
+# Copyright (C) 2021 Red Hat, Inc.
|
|
|
5d81fc |
+# All rights reserved.
|
|
|
5d81fc |
+#
|
|
|
5d81fc |
+# License: GPL (version 3 or any later version).
|
|
|
5d81fc |
+# See LICENSE for details.
|
|
|
5d81fc |
+# --- END COPYRIGHT BLOCK ---
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+import logging
|
|
|
5d81fc |
+import ldap
|
|
|
5d81fc |
+import time
|
|
|
5d81fc |
+import pytest
|
|
|
5d81fc |
+from lib389.topologies import topology_st
|
|
|
5d81fc |
+from lib389.plugins import RetroChangelogPlugin
|
|
|
5d81fc |
+from lib389._constants import *
|
|
|
5d81fc |
+from lib389.utils import *
|
|
|
5d81fc |
+from lib389.tasks import *
|
|
|
5d81fc |
+from lib389.cli_base import FakeArgs, connect_instance, disconnect_instance
|
|
|
5d81fc |
+from lib389.cli_base.dsrc import dsrc_arg_concat
|
|
|
5d81fc |
+from lib389.cli_conf.plugins.retrochangelog import retrochangelog_add
|
|
|
5d81fc |
+from lib389.idm.user import UserAccount, UserAccounts, nsUserAccounts
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+pytestmark = pytest.mark.tier1
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+USER1_DN = 'uid=user1,ou=people,'+ DEFAULT_SUFFIX
|
|
|
5d81fc |
+USER2_DN = 'uid=user2,ou=people,'+ DEFAULT_SUFFIX
|
|
|
5d81fc |
+USER_PW = 'password'
|
|
|
5d81fc |
+ATTR_HOMEPHONE = 'homePhone'
|
|
|
5d81fc |
+ATTR_CARLICENSE = 'carLicense'
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+log = logging.getLogger(__name__)
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+def test_retrocl_exclude_attr_add(topology_st):
|
|
|
5d81fc |
+ """ Test exclude attribute feature of the retrocl plugin for add operation
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ :id: 3481650f-2070-45ef-9600-2500cfc51559
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ :setup: Standalone instance
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ :steps:
|
|
|
5d81fc |
+ 1. Enable dynamic plugins
|
|
|
5d81fc |
+ 2. Confige retro changelog plugin
|
|
|
5d81fc |
+ 3. Add an entry
|
|
|
5d81fc |
+ 4. Ensure entry attrs are in the changelog
|
|
|
5d81fc |
+ 5. Exclude an attr
|
|
|
5d81fc |
+ 6. Add another entry
|
|
|
5d81fc |
+ 7. Ensure excluded attr is not in the changelog
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ :expectedresults:
|
|
|
5d81fc |
+ 1. Success
|
|
|
5d81fc |
+ 2. Success
|
|
|
5d81fc |
+ 3. Success
|
|
|
5d81fc |
+ 4. Success
|
|
|
5d81fc |
+ 5. Success
|
|
|
5d81fc |
+ 6. Success
|
|
|
5d81fc |
+ 7. Success
|
|
|
5d81fc |
+ """
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ st = topology_st.standalone
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Enable dynamic plugins')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ st.config.set('nsslapd-dynamic-plugins', 'on')
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ ldap.error('Failed to enable dynamic plugins ' + e.args[0]['desc'])
|
|
|
5d81fc |
+ assert False
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Configure retrocl plugin')
|
|
|
5d81fc |
+ rcl = RetroChangelogPlugin(st)
|
|
|
5d81fc |
+ rcl.disable()
|
|
|
5d81fc |
+ rcl.enable()
|
|
|
5d81fc |
+ rcl.replace('nsslapd-attribute', 'nsuniqueid:targetUniqueId')
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Restarting instance')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ st.restart()
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ ldap.error('Failed to restart instance ' + e.args[0]['desc'])
|
|
|
5d81fc |
+ assert False
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ users = UserAccounts(st, DEFAULT_SUFFIX)
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Adding user1')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ user1 = users.create(properties={
|
|
|
5d81fc |
+ 'sn': '1',
|
|
|
5d81fc |
+ 'cn': 'user 1',
|
|
|
5d81fc |
+ 'uid': 'user1',
|
|
|
5d81fc |
+ 'uidNumber': '11',
|
|
|
5d81fc |
+ 'gidNumber': '111',
|
|
|
5d81fc |
+ 'givenname': 'user1',
|
|
|
5d81fc |
+ 'homePhone': '0861234567',
|
|
|
5d81fc |
+ 'carLicense': '131D16674',
|
|
|
5d81fc |
+ 'mail': 'user1@whereever.com',
|
|
|
5d81fc |
+ 'homeDirectory': '/home/user1',
|
|
|
5d81fc |
+ 'userpassword': USER_PW})
|
|
|
5d81fc |
+ except ldap.ALREADY_EXISTS:
|
|
|
5d81fc |
+ pass
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ log.error("Failed to add user1")
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Verify homePhone and carLicense attrs are in the changelog changestring')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ cllist = st.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(targetDn=%s)' % USER1_DN)
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ log.fatal("Changelog search failed, error: " +str(e))
|
|
|
5d81fc |
+ assert False
|
|
|
5d81fc |
+ assert len(cllist) > 0
|
|
|
5d81fc |
+ if cllist[0].hasAttr('changes'):
|
|
|
5d81fc |
+ clstr = (cllist[0].getValue('changes')).decode()
|
|
|
5d81fc |
+ assert ATTR_HOMEPHONE in clstr
|
|
|
5d81fc |
+ assert ATTR_CARLICENSE in clstr
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Excluding attribute ' + ATTR_HOMEPHONE)
|
|
|
5d81fc |
+ args = FakeArgs()
|
|
|
5d81fc |
+ args.connections = [st.host + ':' + str(st.port) + ':' + DN_DM + ':' + PW_DM]
|
|
|
5d81fc |
+ args.instance = 'standalone1'
|
|
|
5d81fc |
+ args.basedn = None
|
|
|
5d81fc |
+ args.binddn = None
|
|
|
5d81fc |
+ args.starttls = False
|
|
|
5d81fc |
+ args.pwdfile = None
|
|
|
5d81fc |
+ args.bindpw = None
|
|
|
5d81fc |
+ args.prompt = False
|
|
|
5d81fc |
+ args.exclude_attrs = ATTR_HOMEPHONE
|
|
|
5d81fc |
+ args.func = retrochangelog_add
|
|
|
5d81fc |
+ dsrc_inst = dsrc_arg_concat(args, None)
|
|
|
5d81fc |
+ inst = connect_instance(dsrc_inst, False, args)
|
|
|
5d81fc |
+ result = args.func(inst, None, log, args)
|
|
|
5d81fc |
+ disconnect_instance(inst)
|
|
|
5d81fc |
+ assert result is None
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info("5s delay for retrocl plugin to restart")
|
|
|
5d81fc |
+ time.sleep(5)
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Adding user2')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ user2 = users.create(properties={
|
|
|
5d81fc |
+ 'sn': '2',
|
|
|
5d81fc |
+ 'cn': 'user 2',
|
|
|
5d81fc |
+ 'uid': 'user2',
|
|
|
5d81fc |
+ 'uidNumber': '22',
|
|
|
5d81fc |
+ 'gidNumber': '222',
|
|
|
5d81fc |
+ 'givenname': 'user2',
|
|
|
5d81fc |
+ 'homePhone': '0879088363',
|
|
|
5d81fc |
+ 'carLicense': '04WX11038',
|
|
|
5d81fc |
+ 'mail': 'user2@whereever.com',
|
|
|
5d81fc |
+ 'homeDirectory': '/home/user2',
|
|
|
5d81fc |
+ 'userpassword': USER_PW})
|
|
|
5d81fc |
+ except ldap.ALREADY_EXISTS:
|
|
|
5d81fc |
+ pass
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ log.error("Failed to add user2")
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Verify homePhone attr is not in the changelog changestring')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ cllist = st.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(targetDn=%s)' % USER2_DN)
|
|
|
5d81fc |
+ assert len(cllist) > 0
|
|
|
5d81fc |
+ if cllist[0].hasAttr('changes'):
|
|
|
5d81fc |
+ clstr = (cllist[0].getValue('changes')).decode()
|
|
|
5d81fc |
+ assert ATTR_HOMEPHONE not in clstr
|
|
|
5d81fc |
+ assert ATTR_CARLICENSE in clstr
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ log.fatal("Changelog search failed, error: " +str(e))
|
|
|
5d81fc |
+ assert False
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+def test_retrocl_exclude_attr_mod(topology_st):
|
|
|
5d81fc |
+ """ Test exclude attribute feature of the retrocl plugin for mod operation
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ :id: f6bef689-685b-4f86-a98d-f7e6b1fcada3
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ :setup: Standalone instance
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ :steps:
|
|
|
5d81fc |
+ 1. Enable dynamic plugins
|
|
|
5d81fc |
+ 2. Confige retro changelog plugin
|
|
|
5d81fc |
+ 3. Add user1 entry
|
|
|
5d81fc |
+ 4. Ensure entry attrs are in the changelog
|
|
|
5d81fc |
+ 5. Exclude an attr
|
|
|
5d81fc |
+ 6. Modify user1 entry
|
|
|
5d81fc |
+ 7. Ensure excluded attr is not in the changelog
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ :expectedresults:
|
|
|
5d81fc |
+ 1. Success
|
|
|
5d81fc |
+ 2. Success
|
|
|
5d81fc |
+ 3. Success
|
|
|
5d81fc |
+ 4. Success
|
|
|
5d81fc |
+ 5. Success
|
|
|
5d81fc |
+ 6. Success
|
|
|
5d81fc |
+ 7. Success
|
|
|
5d81fc |
+ """
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ st = topology_st.standalone
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Enable dynamic plugins')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ st.config.set('nsslapd-dynamic-plugins', 'on')
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ ldap.error('Failed to enable dynamic plugins ' + e.args[0]['desc'])
|
|
|
5d81fc |
+ assert False
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Configure retrocl plugin')
|
|
|
5d81fc |
+ rcl = RetroChangelogPlugin(st)
|
|
|
5d81fc |
+ rcl.disable()
|
|
|
5d81fc |
+ rcl.enable()
|
|
|
5d81fc |
+ rcl.replace('nsslapd-attribute', 'nsuniqueid:targetUniqueId')
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Restarting instance')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ st.restart()
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ ldap.error('Failed to restart instance ' + e.args[0]['desc'])
|
|
|
5d81fc |
+ assert False
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ users = UserAccounts(st, DEFAULT_SUFFIX)
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Adding user1')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ user1 = users.create(properties={
|
|
|
5d81fc |
+ 'sn': '1',
|
|
|
5d81fc |
+ 'cn': 'user 1',
|
|
|
5d81fc |
+ 'uid': 'user1',
|
|
|
5d81fc |
+ 'uidNumber': '11',
|
|
|
5d81fc |
+ 'gidNumber': '111',
|
|
|
5d81fc |
+ 'givenname': 'user1',
|
|
|
5d81fc |
+ 'homePhone': '0861234567',
|
|
|
5d81fc |
+ 'carLicense': '131D16674',
|
|
|
5d81fc |
+ 'mail': 'user1@whereever.com',
|
|
|
5d81fc |
+ 'homeDirectory': '/home/user1',
|
|
|
5d81fc |
+ 'userpassword': USER_PW})
|
|
|
5d81fc |
+ except ldap.ALREADY_EXISTS:
|
|
|
5d81fc |
+ pass
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ log.error("Failed to add user1")
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Verify homePhone and carLicense attrs are in the changelog changestring')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ cllist = st.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(targetDn=%s)' % USER1_DN)
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ log.fatal("Changelog search failed, error: " +str(e))
|
|
|
5d81fc |
+ assert False
|
|
|
5d81fc |
+ assert len(cllist) > 0
|
|
|
5d81fc |
+ if cllist[0].hasAttr('changes'):
|
|
|
5d81fc |
+ clstr = (cllist[0].getValue('changes')).decode()
|
|
|
5d81fc |
+ assert ATTR_HOMEPHONE in clstr
|
|
|
5d81fc |
+ assert ATTR_CARLICENSE in clstr
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Excluding attribute ' + ATTR_CARLICENSE)
|
|
|
5d81fc |
+ args = FakeArgs()
|
|
|
5d81fc |
+ args.connections = [st.host + ':' + str(st.port) + ':' + DN_DM + ':' + PW_DM]
|
|
|
5d81fc |
+ args.instance = 'standalone1'
|
|
|
5d81fc |
+ args.basedn = None
|
|
|
5d81fc |
+ args.binddn = None
|
|
|
5d81fc |
+ args.starttls = False
|
|
|
5d81fc |
+ args.pwdfile = None
|
|
|
5d81fc |
+ args.bindpw = None
|
|
|
5d81fc |
+ args.prompt = False
|
|
|
5d81fc |
+ args.exclude_attrs = ATTR_CARLICENSE
|
|
|
5d81fc |
+ args.func = retrochangelog_add
|
|
|
5d81fc |
+ dsrc_inst = dsrc_arg_concat(args, None)
|
|
|
5d81fc |
+ inst = connect_instance(dsrc_inst, False, args)
|
|
|
5d81fc |
+ result = args.func(inst, None, log, args)
|
|
|
5d81fc |
+ disconnect_instance(inst)
|
|
|
5d81fc |
+ assert result is None
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info("5s delay for retrocl plugin to restart")
|
|
|
5d81fc |
+ time.sleep(5)
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Modify user1 carLicense attribute')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ st.modify_s(USER1_DN, [(ldap.MOD_REPLACE, ATTR_CARLICENSE, b"123WX321")])
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ log.fatal('test_retrocl_exclude_attr_mod: Failed to update user1 attribute: error ' + e.message['desc'])
|
|
|
5d81fc |
+ assert False
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+ log.info('Verify carLicense attr is not in the changelog changestring')
|
|
|
5d81fc |
+ try:
|
|
|
5d81fc |
+ cllist = st.search_s(RETROCL_SUFFIX, ldap.SCOPE_SUBTREE, '(targetDn=%s)' % USER1_DN)
|
|
|
5d81fc |
+ assert len(cllist) > 0
|
|
|
5d81fc |
+ # There will be 2 entries in the changelog for this user, we are only
|
|
|
5d81fc |
+ #interested in the second one, the modify operation.
|
|
|
5d81fc |
+ if cllist[1].hasAttr('changes'):
|
|
|
5d81fc |
+ clstr = (cllist[1].getValue('changes')).decode()
|
|
|
5d81fc |
+ assert ATTR_CARLICENSE not in clstr
|
|
|
5d81fc |
+ except ldap.LDAPError as e:
|
|
|
5d81fc |
+ log.fatal("Changelog search failed, error: " +str(e))
|
|
|
5d81fc |
+ assert False
|
|
|
5d81fc |
+
|
|
|
5d81fc |
+if __name__ == '__main__':
|
|
|
5d81fc |
+ # Run isolated
|
|
|
5d81fc |
+ # -s for DEBUG mode
|
|
|
5d81fc |
+ CURRENT_FILE = os.path.realpath(__file__)
|
|
|
5d81fc |
+ pytest.main("-s %s" % CURRENT_FILE)
|
|
|
5d81fc |
--
|
|
|
5d81fc |
2.26.3
|
|
|
5d81fc |
|