def test_pwdReset_by_user_DM(topology_st, create_user):
    """Test new password policy attribute "pwdReset"
    :id: 232bc7dc-8cb6-11eb-9791-98fa9ba19b65
    :customerscenario: True
    :setup:
        1. Standalone instance
        2. Add a new user with a password 
    :steps:
        1. Enable passwordMustChange
        2. Bind as the user and change the password
        3. Check that the pwdReset attribute is set to TRUE
        4. Bind as the Directory manager and attempt to change the pwdReset to FALSE
        5. Check that pwdReset is NOT SET to FALSE
    :expected results:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Success
    """

    # Reset user's password
    our_user = UserAccount(topology_st.standalone, TEST_USER_DN)
    log.info('Set password policy passwordMustChange on')
    topology_st.standalone.config.replace('passwordMustChange', 'on')
    our_user.replace('userpassword', PASSWORD)
    time.sleep(5)

    # Check that pwdReset is TRUE
    assert our_user.get_attr_val_utf8('pwdReset') == 'TRUE'

    log.info(
        'Binding as the Directory manager and attempt to change the pwdReset to FALSE'
    )
    topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
    with pytest.raises(ldap.UNWILLING_TO_PERFORM):
        topology_st.standalone.config.replace('pwdReset', 'FALSE')

    log.info('Check that pwdReset is NOT SET to FALSE')
    assert our_user.get_attr_val_utf8('pwdReset') == 'TRUE'

    log.info('Resetting password for {}'.format(TEST_USER_PWD))
    our_user.reset_password(TEST_USER_PWD)
def test_global_tpr_delayValidFrom_2(topology_st, test_user, request):
    """Test global TPR policy : passwordTPRDelayValidFrom
    Test that a TPR password is valid after reset time +
    passwordTPRDelayValidFrom

    :id: 8fa9f6f7-9be2-47c0-bf92-d9fe78ddbc34
    :customerscenario: False
    :setup: Standalone instance
    :steps:
        1. Enable passwordMustChange
        2. Set passwordTPRDelayValidFrom=6s
        3. Create a account user
        5. Reset the password
        6. Wait for passwordTPRDelayValidFrom=6s
        7. Bind with valid password, reset password
           to allow further searches
        8. Check bound user can search attribute ('uid')
    :expected results:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Success
        6. Success
        7. Success
        8. Success
    """

    ValidFrom = 6
    # Set password policy config, passwordMaxFailure being higher than
    # passwordTPRMaxUse so that TPR is enforced first
    topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
    topology_st.standalone.config.replace('passwordMustChange', 'on')
    topology_st.standalone.config.replace('passwordTPRDelayValidFrom',
                                          str(ValidFrom))
    time.sleep(.5)

    # Reset user's password
    our_user = UserAccount(topology_st.standalone, TEST_USER_DN)
    our_user.replace('userpassword', PASSWORD)
    # give time to update the pwp attributes in the entry
    time.sleep(.5)

    # Check that pwdReset is TRUE
    topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
    assert our_user.get_attr_val_utf8('pwdReset') == 'TRUE'

    # Check that pwdTPRReset is TRUE
    assert our_user.get_attr_val_utf8('pwdTPRReset') == 'TRUE'
    now = time.mktime(time.gmtime())
    log.info("compare pwdTPRValidFrom (%s) vs now (%s)" %
             (our_user.get_attr_val_utf8('pwdTPRValidFrom'), time.gmtime()))
    assert (gentime_to_posix_time(
        our_user.get_attr_val_utf8('pwdTPRValidFrom'))) >= (now + ValidFrom -
                                                            2)

    # wait for pwdTPRValidFrom
    time.sleep(ValidFrom + 1)

    # Bind as user with valid password, reset the password
    # and do simple search
    our_user.rebind(PASSWORD)
    our_user.reset_password(TEST_USER_PWD)
    our_user.rebind(TEST_USER_PWD)
    assert our_user.get_attr_val_utf8('uid')

    def fin():
        topology_st.standalone.restart()
        # Reset password policy config
        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
        topology_st.standalone.config.replace('passwordMustChange', 'off')

        # Reset user's password
        our_user.replace('userpassword', TEST_USER_PWD)

    request.addfinalizer(fin)
def test_global_tpr_maxuse_3(topology_st, test_user, request):
    """Test global TPR policy : passwordTPRMaxUse
    Test that after less than passwordTPRMaxUse failures to bind
    A bind with valid password is successfull but passwordMustChange
    does not allow to do a search.
    Changing the password allows to do a search

    :id: 7fd0301a-781e-4db8-a4bd-7b44e0f04bb6
    :customerscenario: False
    :setup: Standalone instance
    :steps:
        1. Enable passwordMustChange
        2. Set passwordTPRMaxUse=5
        3. Set passwordMaxFailure to a higher value to not disturb the test
        4. Bind with a wrong password less then passwordTPRMaxUse times and check INVALID_CREDENTIALS
        5. Bind with the valid password and check SRCH fail (ldap.UNWILLING_TO_PERFORM)
           because of passwordMustChange
        6. check passwordTPRRetryCount reset to 0
        7. Bindd with valid password and reset the password
        8. Check we can bind again and SRCH succeeds
        9. Reset password policy configuration
    :expected results:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Success
        6. Success
        7. Success
        8. Success
        9. Success
    """

    try_tpr_failure = 5
    # Set password policy config, passwordMaxFailure being higher than
    # passwordTPRMaxUse so that TPR is enforced first
    topology_st.standalone.config.replace('passwordMustChange', 'on')
    topology_st.standalone.config.replace('passwordMaxFailure',
                                          str(try_tpr_failure + 20))
    topology_st.standalone.config.replace('passwordTPRMaxUse',
                                          str(try_tpr_failure))
    time.sleep(.5)

    # Reset user's password
    our_user = UserAccount(topology_st.standalone, TEST_USER_DN)
    our_user.replace('userpassword', PASSWORD)
    # give time to update the pwp attributes in the entry
    time.sleep(.5)

    # Do less than passwordTPRMaxUse failing bind
    try_tpr_failure = try_tpr_failure - 2
    for i in range(try_tpr_failure):
        # Bind as user with a wrong password
        with pytest.raises(ldap.INVALID_CREDENTIALS):
            our_user.rebind('wrong password')
        time.sleep(.5)

        # Check that pwdReset is TRUE
        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
        #assert our_user.get_attr_val_utf8('pwdReset') == 'TRUE'

        # Check that pwdTPRReset is TRUE
        assert our_user.get_attr_val_utf8('pwdTPRReset') == 'TRUE'
        assert our_user.get_attr_val_utf8('pwdTPRUseCount') == str(i + 1)
        log.info(
            "%dth failing bind (INVALID_CREDENTIALS) => pwdTPRUseCount = %d" %
            (i + 1, i + 1))

    # Now the #failures has not reached passwordTPRMaxUse
    # Check that pwdReset is TRUE
    topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
    assert our_user.get_attr_val_utf8('pwdReset') == 'TRUE'

    # Check that pwdTPRReset is TRUE
    assert our_user.get_attr_val_utf8('pwdTPRReset') == 'TRUE'
    assert our_user.get_attr_val_utf8('pwdTPRUseCount') == str(try_tpr_failure)
    log.info("last failing bind (INVALID_CREDENTIALS) => pwdTPRUseCount = %d" %
             (try_tpr_failure))

    # Bind as user with valid password
    our_user.rebind(PASSWORD)
    time.sleep(.5)

    # We can not do anything else that reset password
    users = UserAccounts(topology_st.standalone, OU_PEOPLE, rdn=None)
    with pytest.raises(ldap.UNWILLING_TO_PERFORM):
        user = users.get(TEST_USER_NAME)

    # Check that pwdReset is TRUE
    topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
    assert our_user.get_attr_val_utf8('pwdReset') == 'TRUE'

    # Check that pwdTPRReset is FALSE
    assert our_user.get_attr_val_utf8('pwdTPRReset') == 'TRUE'
    assert our_user.get_attr_val_utf8('pwdTPRUseCount') == str(
        try_tpr_failure + 1)

    # Now reset the password and check we can do fully use the account
    our_user.rebind(PASSWORD)
    our_user.reset_password(TEST_USER_PWD)
    # give time to update the pwp attributes in the entry
    time.sleep(.5)
    our_user.rebind(TEST_USER_PWD)
    time.sleep(.5)
    user = users.get(TEST_USER_NAME)

    def fin():
        topology_st.standalone.restart()
        # Reset password policy config
        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
        topology_st.standalone.config.replace('passwordMustChange', 'off')

        # Reset user's password
        our_user.replace('userpassword', TEST_USER_PWD)

    request.addfinalizer(fin)
def test_global_tpr_delayExpireAt_2(topology_st, test_user, request):
    """Test global TPR policy : passwordTPRDelayExpireAt
    Test that a TPR password is valid before reset time +
    passwordTPRDelayExpireAt

    :id: 9df320de-ebf6-4ed0-a619-51b1a05a560c
    :customerscenario: False
    :setup: Standalone instance
    :steps:
        1. Enable passwordMustChange
        2. Set passwordTPRDelayExpireAt=6s
        3. Create a account user
        5. Reset the password
        6. Wait for 1s
        7. Bind with valid password should succeeds
    :expected results:
        1. Success
        2. Success
        3. Success
        4. Success
        5. Success
        6. Success
        7. Success
    """

    ExpireAt = 6
    # Set password policy config, passwordMaxFailure being higher than
    # passwordTPRMaxUse so that TPR is enforced first
    topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
    topology_st.standalone.config.replace('passwordMustChange', 'on')
    topology_st.standalone.config.replace('passwordTPRMaxUse', str(-1))
    topology_st.standalone.config.replace('passwordTPRDelayValidFrom', str(-1))
    topology_st.standalone.config.replace('passwordTPRDelayExpireAt',
                                          str(ExpireAt))
    time.sleep(.5)

    # Reset user's password
    our_user = UserAccount(topology_st.standalone, TEST_USER_DN)
    our_user.replace('userpassword', PASSWORD)
    # give time to update the pwp attributes in the entry
    time.sleep(.5)

    # Check that pwdReset is TRUE
    topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
    assert our_user.get_attr_val_utf8('pwdReset') == 'TRUE'

    # Check that pwdTPRReset is TRUE
    assert our_user.get_attr_val_utf8('pwdTPRReset') == 'TRUE'
    now = time.mktime(time.gmtime())
    log.info("compare pwdTPRExpireAt (%s) vs now (%s)" %
             (our_user.get_attr_val_utf8('pwdTPRExpireAt'), time.gmtime()))
    assert (gentime_to_posix_time(
        our_user.get_attr_val_utf8('pwdTPRExpireAt'))) >= (now + ExpireAt - 2)

    # wait for 1s
    time.sleep(1)

    # Bind as user with valid password, reset the password
    # and do simple search
    our_user.rebind(PASSWORD)
    our_user.reset_password(TEST_USER_PWD)
    time.sleep(.5)
    our_user.rebind(TEST_USER_PWD)
    assert our_user.get_attr_val_utf8('uid')

    def fin():
        topology_st.standalone.restart()
        # Reset password policy config
        topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
        topology_st.standalone.config.replace('passwordMustChange', 'off')

        # Reset user's password
        our_user.replace('userpassword', TEST_USER_PWD)

    request.addfinalizer(fin)