ticket47714_test.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. # --- BEGIN COPYRIGHT BLOCK ---
  2. # Copyright (C) 2015 Red Hat, Inc.
  3. # All rights reserved.
  4. #
  5. # License: GPL (version 3 or any later version).
  6. # See LICENSE for details.
  7. # --- END COPYRIGHT BLOCK ---
  8. #
  9. import os
  10. import sys
  11. import time
  12. import ldap
  13. import logging
  14. import pytest
  15. import shutil
  16. from lib389 import DirSrv, Entry, tools
  17. from lib389.tools import DirSrvTools
  18. from lib389._constants import *
  19. from lib389.properties import *
  20. log = logging.getLogger(__name__)
  21. installation_prefix = None
  22. ACCT_POLICY_CONFIG_DN = 'cn=config,cn=%s,cn=plugins,cn=config' % PLUGIN_ACCT_POLICY
  23. ACCT_POLICY_DN = 'cn=Account Inactivation Pplicy,%s' % SUFFIX
  24. INACTIVITY_LIMIT = '9'
  25. SEARCHFILTER = '(objectclass=*)'
  26. TEST_USER = 'ticket47714user'
  27. TEST_USER_DN = 'uid=%s,%s' % (TEST_USER, SUFFIX)
  28. TEST_USER_PW = '%s' % TEST_USER
  29. class TopologyStandalone(object):
  30. def __init__(self, standalone):
  31. standalone.open()
  32. self.standalone = standalone
  33. @pytest.fixture(scope="module")
  34. def topology(request):
  35. '''
  36. This fixture is used to standalone topology for the 'module'.
  37. '''
  38. global installation_prefix
  39. if installation_prefix:
  40. args_instance[SER_DEPLOYED_DIR] = installation_prefix
  41. standalone = DirSrv(verbose=False)
  42. # Args for the standalone instance
  43. args_instance[SER_HOST] = HOST_STANDALONE
  44. args_instance[SER_PORT] = PORT_STANDALONE
  45. args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
  46. args_standalone = args_instance.copy()
  47. standalone.allocate(args_standalone)
  48. # Get the status of the instance and restart it if it exists
  49. instance_standalone = standalone.exists()
  50. # Remove the instance
  51. if instance_standalone:
  52. standalone.delete()
  53. # Create the instance
  54. standalone.create()
  55. # Used to retrieve configuration information (dbdir, confdir...)
  56. standalone.open()
  57. # clear the tmp directory
  58. standalone.clearTmpDir(__file__)
  59. # Here we have standalone instance up and running
  60. return TopologyStandalone(standalone)
  61. def _header(topology, label):
  62. topology.standalone.log.info("\n\n###############################################")
  63. topology.standalone.log.info("#######")
  64. topology.standalone.log.info("####### %s" % label)
  65. topology.standalone.log.info("#######")
  66. topology.standalone.log.info("###############################################")
  67. def test_ticket47714_init(topology):
  68. """
  69. 1. Add account policy entry to the DB
  70. 2. Add a test user to the DB
  71. """
  72. _header(topology, 'Testing Ticket 47714 - [RFE] Update lastLoginTime also in Account Policy plugin if account lockout is based on passwordExpirationTime.')
  73. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  74. log.info("\n######################### Adding Account Policy entry: %s ######################\n" % ACCT_POLICY_DN)
  75. topology.standalone.add_s(Entry((ACCT_POLICY_DN, {'objectclass': "top ldapsubentry extensibleObject accountpolicy".split(),
  76. 'accountInactivityLimit': INACTIVITY_LIMIT})))
  77. log.info("\n######################### Adding Test User entry: %s ######################\n" % TEST_USER_DN)
  78. topology.standalone.add_s(Entry((TEST_USER_DN, {'objectclass': "top person organizationalPerson inetOrgPerson".split(),
  79. 'cn': TEST_USER,
  80. 'sn': TEST_USER,
  81. 'givenname': TEST_USER,
  82. 'userPassword': TEST_USER_PW,
  83. 'acctPolicySubentry': ACCT_POLICY_DN})))
  84. def test_ticket47714_run_0(topology):
  85. """
  86. Check this change has no inpact to the existing functionality.
  87. 1. Set account policy config without the new attr alwaysRecordLoginAttr
  88. 2. Bind as a test user
  89. 3. Bind as the test user again and check the lastLoginTime is updated
  90. 4. Waint longer than the accountInactivityLimit time and bind as the test user,
  91. which should fail with CONSTANT_VIOLATION.
  92. """
  93. _header(topology, 'Account Policy - No new attr alwaysRecordLoginAttr in config')
  94. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  95. # Modify Account Policy config entry
  96. topology.standalone.modify_s(ACCT_POLICY_CONFIG_DN, [(ldap.MOD_REPLACE, 'alwaysrecordlogin', 'yes'),
  97. (ldap.MOD_REPLACE, 'stateattrname', 'lastLoginTime'),
  98. (ldap.MOD_REPLACE, 'altstateattrname', 'createTimestamp'),
  99. (ldap.MOD_REPLACE, 'specattrname', 'acctPolicySubentry'),
  100. (ldap.MOD_REPLACE, 'limitattrname', 'accountInactivityLimit')])
  101. # Enable the plugins
  102. topology.standalone.plugins.enable(name=PLUGIN_ACCT_POLICY)
  103. topology.standalone.restart(timeout=120)
  104. log.info("\n######################### Bind as %s ######################\n" % TEST_USER_DN)
  105. try:
  106. topology.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PW)
  107. except ldap.CONSTRAINT_VIOLATION as e:
  108. log.error('CONSTRAINT VIOLATION ' + e.message['desc'])
  109. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  110. entry = topology.standalone.search_s(TEST_USER_DN, ldap.SCOPE_BASE, SEARCHFILTER, ['lastLoginTime'])
  111. lastLoginTime0 = entry[0].lastLoginTime
  112. time.sleep(2)
  113. log.info("\n######################### Bind as %s again ######################\n" % TEST_USER_DN)
  114. try:
  115. topology.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PW)
  116. except ldap.CONSTRAINT_VIOLATION as e:
  117. log.error('CONSTRAINT VIOLATION ' + e.message['desc'])
  118. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  119. entry = topology.standalone.search_s(TEST_USER_DN, ldap.SCOPE_BASE, SEARCHFILTER, ['lastLoginTime'])
  120. lastLoginTime1 = entry[0].lastLoginTime
  121. log.info("First lastLoginTime: %s, Second lastLoginTime: %s" % (lastLoginTime0, lastLoginTime1))
  122. assert lastLoginTime0 < lastLoginTime1
  123. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  124. entry = topology.standalone.search_s(ACCT_POLICY_DN, ldap.SCOPE_BASE, SEARCHFILTER)
  125. log.info("\n######################### %s ######################\n" % ACCT_POLICY_CONFIG_DN)
  126. log.info("accountInactivityLimit: %s" % entry[0].accountInactivityLimit)
  127. log.info("\n######################### %s DONE ######################\n" % ACCT_POLICY_CONFIG_DN)
  128. time.sleep(10)
  129. log.info("\n######################### Bind as %s again to fail ######################\n" % TEST_USER_DN)
  130. try:
  131. topology.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PW)
  132. except ldap.CONSTRAINT_VIOLATION as e:
  133. log.info('CONSTRAINT VIOLATION ' + e.message['desc'])
  134. log.info("%s was successfully inactivated." % TEST_USER_DN)
  135. pass
  136. def test_ticket47714_run_1(topology):
  137. """
  138. Verify a new config attr alwaysRecordLoginAttr
  139. 1. Set account policy config with the new attr alwaysRecordLoginAttr: lastLoginTime
  140. Note: bogus attr is set to stateattrname.
  141. altstateattrname type value is used for checking whether the account is idle or not.
  142. 2. Bind as a test user
  143. 3. Bind as the test user again and check the alwaysRecordLoginAttr: lastLoginTime is updated
  144. """
  145. _header(topology, 'Account Policy - With new attr alwaysRecordLoginAttr in config')
  146. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  147. topology.standalone.modify_s(TEST_USER_DN, [(ldap.MOD_DELETE, 'lastLoginTime', None)])
  148. # Modify Account Policy config entry
  149. topology.standalone.modify_s(ACCT_POLICY_CONFIG_DN, [(ldap.MOD_REPLACE, 'alwaysrecordlogin', 'yes'),
  150. (ldap.MOD_REPLACE, 'stateattrname', 'bogus'),
  151. (ldap.MOD_REPLACE, 'altstateattrname', 'modifyTimestamp'),
  152. (ldap.MOD_REPLACE, 'alwaysRecordLoginAttr', 'lastLoginTime'),
  153. (ldap.MOD_REPLACE, 'specattrname', 'acctPolicySubentry'),
  154. (ldap.MOD_REPLACE, 'limitattrname', 'accountInactivityLimit')])
  155. # Enable the plugins
  156. topology.standalone.plugins.enable(name=PLUGIN_ACCT_POLICY)
  157. topology.standalone.restart(timeout=120)
  158. log.info("\n######################### Bind as %s ######################\n" % TEST_USER_DN)
  159. try:
  160. topology.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PW)
  161. except ldap.CONSTRAINT_VIOLATION as e:
  162. log.error('CONSTRAINT VIOLATION ' + e.message['desc'])
  163. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  164. entry = topology.standalone.search_s(TEST_USER_DN, ldap.SCOPE_BASE, SEARCHFILTER, ['lastLoginTime'])
  165. lastLoginTime0 = entry[0].lastLoginTime
  166. time.sleep(2)
  167. log.info("\n######################### Bind as %s again ######################\n" % TEST_USER_DN)
  168. try:
  169. topology.standalone.simple_bind_s(TEST_USER_DN, TEST_USER_PW)
  170. except ldap.CONSTRAINT_VIOLATION as e:
  171. log.error('CONSTRAINT VIOLATION ' + e.message['desc'])
  172. topology.standalone.simple_bind_s(DN_DM, PASSWORD)
  173. entry = topology.standalone.search_s(TEST_USER_DN, ldap.SCOPE_BASE, SEARCHFILTER, ['lastLoginTime'])
  174. lastLoginTime1 = entry[0].lastLoginTime
  175. log.info("First lastLoginTime: %s, Second lastLoginTime: %s" % (lastLoginTime0, lastLoginTime1))
  176. assert lastLoginTime0 < lastLoginTime1
  177. topology.standalone.log.info("ticket47714 was successfully verified.")
  178. def test_ticket47714_final(topology):
  179. topology.standalone.delete()
  180. log.info('Testcase PASSED')
  181. def run_isolated():
  182. '''
  183. run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
  184. To run isolated without py.test, you need to
  185. - edit this file and comment '@pytest.fixture' line before 'topology' function.
  186. - set the installation prefix
  187. - run this program
  188. '''
  189. global installation_prefix
  190. installation_prefix = None
  191. topo = topology(True)
  192. test_ticket47714_init(topo)
  193. test_ticket47714_run_0(topo)
  194. test_ticket47714_run_1(topo)
  195. test_ticket47714_final(topo)
  196. if __name__ == '__main__':
  197. run_isolated()