This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
commit d72a226f6499f72c79123e2d929650d4e9c3716f
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Thu Sep 21 14:18:30 2017 -0400
Ticket 49327 - Add CI test for password expiration controls
Description: Add CI script for testing the various expired/expiring
controls.
https://pagure.io/389-ds-base/issue/49327
Reviewed by: spichugi(Thanks!)
---
.../suites/password/pwdPolicy_controls_test.py | 324 +++++++++++++++++++++
1 file changed, 324 insertions(+)
diff --git a/dirsrvtests/tests/suites/password/pwdPolicy_controls_test.py
b/dirsrvtests/tests/suites/password/pwdPolicy_controls_test.py
new file mode 100644
index 0000000..d0b5ae0
--- /dev/null
+++ b/dirsrvtests/tests/suites/password/pwdPolicy_controls_test.py
@@ -0,0 +1,324 @@
+import logging
+import pytest
+import os
+import ldap
+import time
+from ldap.controls.ppolicy import PasswordPolicyControl
+from lib389.topologies import topology_st as topo
+from lib389._constants import (DN_DM, PASSWORD, DN_CONFIG)
+from lib389.tasks import Entry
+
+DEBUGGING = os.getenv("DEBUGGING", default=False)
+if DEBUGGING:
+ logging.getLogger(__name__).setLevel(logging.DEBUG)
+else:
+ logging.getLogger(__name__).setLevel(logging.INFO)
+log = logging.getLogger(__name__)
+
+USER_DN = 'uid=test entry,dc=example,dc=com'
+USER_PW = 'password123'
+
+
+(a)pytest.fixture
+def init_user(topo, request):
+ """Initialize a user - Delete and re-add test user
+ """
+ try:
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
+ topo.standalone.delete_s(USER_DN)
+ except ldap.NO_SUCH_OBJECT:
+ pass
+ except ldap.LDAPError as e:
+ log.error("Failed to delete user, error:
{}".format(e.message['desc']))
+ assert False
+
+ user_data = {'objectClass': 'top person inetOrgPerson'.split(),
+ 'uid': 'test entry',
+ 'cn': 'test entry',
+ 'sn': 'user',
+ 'userPassword': USER_PW}
+ try:
+ topo.standalone.add_s(Entry((USER_DN, user_data)))
+ except ldap.LDAPError as e:
+ log.error("Failed to add user, error:
{}".format(e.message['desc']))
+ assert False
+
+
+def change_passwd(topo):
+ """Reset users password as the user, then re-bind as Directory
Manager
+ """
+ try:
+ topo.standalone.simple_bind_s(USER_DN, USER_PW)
+ topo.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
+ 'userpassword',
+ USER_PW)])
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
+ except ldap.LDAPError as e:
+ log.error("Failed to change user's password, error:
{}".format(e.message['desc']))
+ assert False
+
+
+def bind_and_get_control(topo, err=0):
+ """Bind as the user, and return any controls
+ """
+ res_type = res_data = res_msgid = res_ctrls = None
+ result_id = ''
+
+ try:
+ result_id = topo.standalone.simple_bind(USER_DN, USER_PW,
+ serverctrls=[PasswordPolicyControl()])
+ res_type, res_data, res_msgid, res_ctrls = topo.standalone.result3(result_id)
+ if err:
+ log.fatal('Expected an error, but bind succeeded')
+ assert False
+ except ldap.LDAPError as e:
+ if err:
+ log.debug('Got expected error:
{}'.format(e.message['desc']))
+ pass
+ else:
+ log.fatal('Did not expect an error:
{}'.format(e.message['desc']))
+ assert False
+
+ if DEBUGGING and res_ctrls and len(res_ctrls) > 0:
+ for ctl in res_ctrls:
+ if ctl.timeBeforeExpiration:
+ log.debug('control time before expiration:
{}'.format(ctl.timeBeforeExpiration))
+ if ctl.graceAuthNsRemaining:
+ log.debug('control grace login remaining:
{}'.format(ctl.graceAuthNsRemaining))
+ if ctl.error is not None and ctl.error >= 0:
+ log.debug('control error: {}'.format(ctl.error))
+
+ topo.standalone.simple_bind_s(DN_DM, PASSWORD)
+ return res_ctrls
+
+
+def test_pwd_must_change(topo, init_user):
+ """Test for expiration control when password must be changed because
an
+ admin reset the password
+
+ :id: a3d99be5-0b69-410d-b72f-04eda8821a56
+ :setup: Standalone instance, a user for testing
+ :steps:
+ 1. Configure password policy and reset password as admin
+ 2. Bind, and check for expired control withthe proper error code "2"
+ :expectedresults:
+ 1. Config update succeeds, adn the password is reset
+ 2. The EXPIRED control is returned, and we the expected error code "2"
+ """
+
+ log.info('Configure password policy with paswordMustChange set to
"on"')
+ try:
+ topo.standalone.modify_s(DN_CONFIG, [
+ (ldap.MOD_REPLACE, 'passwordExp', 'on'),
+ (ldap.MOD_REPLACE, 'passwordMaxAge', '200'),
+ (ldap.MOD_REPLACE, 'passwordGraceLimit', '0'),
+ (ldap.MOD_REPLACE, 'passwordWarning', '199'),
+ (ldap.MOD_REPLACE, 'passwordMustChange', 'on')])
+ except ldap.LDAPError as e:
+ log.error("Failed to set password policy, error:
{}".format(e.message['desc']))
+ assert False
+
+ log.info('Reset userpassword as Directory Manager')
+ try:
+ topo.standalone.modify_s(USER_DN, [(ldap.MOD_REPLACE,
+ 'userpassword',
+ USER_PW)])
+ except ldap.LDAPError as e:
+ log.error("Failed to change user's password, error:
{}".format(e.message['desc']))
+ assert False
+
+ log.info('Bind should return ctrl with error code 2 (changeAfterReset)')
+ time.sleep(2)
+ ctrls = bind_and_get_control(topo)
+ if ctrls and len(ctrls) > 0:
+ if ctrls[0].error is None:
+ log.fatal("Response ctrl error code not set")
+ assert False
+ elif ctrls[0].error != 2:
+ log.fatal("Got unexpected error code: {}".format(ctrls[0].error))
+ assert False
+ else:
+ log.fatal("We did not get a response ctrl")
+ assert False
+
+
+def test_pwd_expired_grace_limit(topo, init_user):
+ """Test for expiration control when password is expired, but there
are
+ remaining grace logins
+
+ :id: a3d99be5-0b69-410d-b72f-04eda8821a51
+ :setup: Standalone instance, a user for testing
+ :steps:
+ 1. Configure password policy and reset password,adn allow it to expire
+ 2. Bind, and check for expired control, and grace limit
+ 3. Bind again, consuming the last grace login, control should be returned
+ 4. Bind again, it should fail, and no control returned
+ :expectedresults:
+ 1. Config update and password reset are successful
+ 2. The EXPIRED control is returned, and we get the expected number
+ of grace logins in the control
+ 3. The response control has the expected value for grace logins
+ 4. The bind fails with error 49, and no contorl is returned
+ """
+
+ log.info('Configure password policy with grace limit set tot 2')
+ try:
+ topo.standalone.modify_s(DN_CONFIG, [
+ (ldap.MOD_REPLACE, 'passwordExp', 'on'),
+ (ldap.MOD_REPLACE, 'passwordMaxAge', '5'),
+ (ldap.MOD_REPLACE, 'passwordGraceLimit', '2')])
+ except ldap.LDAPError as e:
+ log.error("Failed to set password policy, error:
{}".format(e.message['desc']))
+ assert False
+
+ log.info('Change password and wait for it to expire')
+ change_passwd(topo)
+ time.sleep(6)
+
+ log.info('Bind and use up one grace login (only one left)')
+ ctrls = bind_and_get_control(topo)
+ if ctrls is None or len(ctrls) == 0:
+ log.fatal('Did not get EXPIRED control in resposne')
+ assert False
+ else:
+ if int(ctrls[0].graceAuthNsRemaining) != 1:
+ log.fatal('Got unexpected value for grace logins:
{}'.format(ctrls[0].graceAuthNsRemaining))
+ assert False
+
+ log.info('Use up last grace login, should get control')
+ ctrls = bind_and_get_control(topo)
+ if ctrls is None or len(ctrls) == 0:
+ log.fatal('Did not get control in response')
+ assert False
+
+ log.info('No grace login available, bind should fail, and no control should be
returned')
+ ctrls = bind_and_get_control(topo, err=49)
+ if ctrls and len(ctrls) > 0:
+ log.fatal('Incorrectly got control in response')
+ assert False
+
+
+def test_pwd_expiring_with_warning(topo, init_user):
+ """Test expiring control response before and after warning is sent
+
+ :id: a3d99be5-0b69-410d-b72f-04eda8821a54
+ :setup: Standalone instance, a user for testing
+ :steps:
+ 1. Configure password policy, and reset password
+ 2. Check for EXPIRING control, and the "time to expire"
+ 3. Bind again, as a warning has now been sent, and check the "time to
expire"
+ :expectedresults:
+ 1. Configuration update and password reset are successful
+ 2. Get the EXPIRING control, and the expected "time to expire" values
+ 3. Get the EXPIRING control, and the expected "time to expire" values
+ """
+
+ log.info('Configure password policy')
+ try:
+ topo.standalone.modify_s(DN_CONFIG, [
+ (ldap.MOD_REPLACE, 'passwordExp', 'on'),
+ (ldap.MOD_REPLACE, 'passwordMaxAge', '50'),
+ (ldap.MOD_REPLACE, 'passwordWarning', '50')])
+ except ldap.LDAPError as e:
+ log.error("Failed to set password policy, error:
{}".format(e.message['desc']))
+ assert False
+
+ log.info('Change password and get controls')
+ change_passwd(topo)
+ ctrls = bind_and_get_control(topo)
+ if ctrls is None or len(ctrls) == 0:
+ log.fatal('Did not get EXPIRING control in response')
+ assert False
+
+ if int(ctrls[0].timeBeforeExpiration) < 50:
+ log.fatal('Got unexpected value for timeBeforeExpiration:
{}'.format(ctrls[0].timeBeforeExpiration))
+ assert False
+
+ log.info('Warning has been sent, try the bind again, and recheck the expiring
time')
+ time.sleep(5)
+ ctrls = bind_and_get_control(topo)
+ if ctrls is None or len(ctrls) == 0:
+ log.fatal('Did not get EXPIRING control in resposne')
+ assert False
+
+ if int(ctrls[0].timeBeforeExpiration) > 50:
+ log.fatal('Got unexpected value for timeBeforeExpiration:
{}'.format(ctrls[0].timeBeforeExpiration))
+ assert False
+
+
+def test_pwd_expiring_with_no_warning(topo, init_user):
+ """Test expiring control response when no warning is sent
+
+ :id: a3d99be5-0b69-410d-b72f-04eda8821a54
+ :setup: Standalone instance, a user for testing
+ :steps:
+ 1. Configure password policy, and reset password
+ 2. Bind, and check that no controls are returned
+ 3. Set passwordSendExpiringTime to "on", bind, and check that the
+ EXPIRING control is returned
+ :expectedresults:
+ 1. Configuration update and passwordreset are successful
+ 2. No control is returned from bind
+ 3. A control is returned after setting "passwordSendExpiringTime"
+ """
+
+ log.info('Configure password policy')
+ try:
+ topo.standalone.modify_s(DN_CONFIG, [
+ (ldap.MOD_REPLACE, 'passwordExp', 'on'),
+ (ldap.MOD_REPLACE, 'passwordMaxAge', '50'),
+ (ldap.MOD_REPLACE, 'passwordWarning', '5')])
+ except ldap.LDAPError as e:
+ log.error("Failed to set password policy, error:
{}".format(e.message['desc']))
+ assert False
+
+ log.info('When the warning is less than the max age, we never send expiring
control response')
+ change_passwd(topo)
+ ctrls = bind_and_get_control(topo)
+ if len(ctrls) > 0:
+ log.fatal('Incorrectly got a response control: {}'.format(ctrls))
+ assert False
+
+ log.info('Turn on sending expiring control regardless of warning')
+ try:
+ topo.standalone.modify_s(DN_CONFIG, [
+ (ldap.MOD_REPLACE, 'passwordSendExpiringTime', 'on')])
+ except ldap.LDAPError as e:
+ log.error("Failed to set passwordSendExpiringTime, error:
{}".format(e.message['desc']))
+ assert False
+
+ ctrls = bind_and_get_control(topo)
+ if ctrls is None or len(ctrls) == 0:
+ log.fatal('Did not get EXPIRED control in response')
+ assert False
+
+ if int(ctrls[0].timeBeforeExpiration) < 49:
+ log.fatal('Got unexpected value for time before expiration:
{}'.format(ctrls[0].timeBeforeExpiration))
+ assert False
+
+ log.info('Check expiring time again')
+ time.sleep(6)
+ ctrls = bind_and_get_control(topo)
+ if ctrls is None or len(ctrls) == 0:
+ log.fatal('Did not get EXPIRED control in resposne')
+ assert False
+
+ if int(ctrls[0].timeBeforeExpiration) > 51:
+ log.fatal('Got unexpected value for time before expiration:
{}'.format(ctrls[0].timeBeforeExpiration))
+ assert False
+
+ log.info('Turn off sending expiring control (restore the default setting)')
+ try:
+ topo.standalone.modify_s(DN_CONFIG, [
+ (ldap.MOD_REPLACE, 'passwordSendExpiringTime', 'off')])
+ except ldap.LDAPError as e:
+ log.error("Failed to set passwordSendExpiringTime, error:
{}".format(e.message['desc']))
+ assert False
+
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
+
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.