/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 * 
 */
package org.apache.directory.server.operations.extended;


import static org.apache.directory.server.core.integ.IntegrationUtils.getAdminNetworkConnection;
import static org.apache.directory.server.core.integ.IntegrationUtils.getAnonymousNetworkConnection;
import static org.apache.directory.server.core.integ.IntegrationUtils.getNetworkConnectionAs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import org.apache.directory.api.ldap.extras.extended.pwdModify.PasswordModifyRequest;
import org.apache.directory.api.ldap.extras.extended.pwdModify.PasswordModifyRequestImpl;
import org.apache.directory.api.ldap.extras.extended.pwdModify.PasswordModifyResponse;
import org.apache.directory.api.ldap.model.constants.SchemaConstants;
import org.apache.directory.api.ldap.model.entry.Attribute;
import org.apache.directory.api.ldap.model.entry.DefaultEntry;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.exception.LdapAuthenticationException;
import org.apache.directory.api.ldap.model.exception.LdapException;
import org.apache.directory.api.ldap.model.message.AddRequest;
import org.apache.directory.api.ldap.model.message.AddRequestImpl;
import org.apache.directory.api.ldap.model.message.AddResponse;
import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
import org.apache.directory.api.ldap.model.password.PasswordUtil;
import org.apache.directory.api.util.Strings;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.server.annotations.CreateLdapServer;
import org.apache.directory.server.annotations.CreateTransport;
import org.apache.directory.server.core.annotations.CreateDS;
import org.apache.directory.server.core.api.InterceptorEnum;
import org.apache.directory.server.core.authn.AuthenticationInterceptor;
import org.apache.directory.server.core.authn.ppolicy.PpolicyConfigContainer;
import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
import org.apache.directory.server.core.integ.FrameworkRunner;
import org.apache.directory.server.ldap.handlers.extended.PwdModifyHandler;
import org.junit.Test;
import org.junit.runner.RunWith;


/**
 * Test the PwdModify extended operation
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
@RunWith(FrameworkRunner.class)
@CreateLdapServer(
    transports =
        { @CreateTransport(protocol = "LDAP") },
    extendedOpHandlers =
        { PwdModifyHandler.class },
    allowAnonymousAccess = true)
@CreateDS(name = "PasswordPolicyTest")
public class PwdModifyNoPPNoPasswordHashingIT extends AbstractLdapTestUnit
{
    /**
     * Add a user with a password
     */
    private void addUser( LdapConnection adminConnection, String user, Object password ) throws Exception
    {
        Entry userEntry = new DefaultEntry(
            "cn=" + user + ",ou=system",
            "ObjectClass: top",
            "ObjectClass: person",
            "cn", user,
            "sn", user + "_sn",
            "userPassword", password );

        AddRequest addRequest = new AddRequestImpl();
        addRequest.setEntry( userEntry );

        AddResponse addResp = adminConnection.add( addRequest );
        assertEquals( ResultCodeEnum.SUCCESS, addResp.getLdapResult().getResultCode() );
    }
    
    
    /**
     * Add a user with no password
     */
    private void addUserNoPassword( LdapConnection adminConnection, String user ) throws Exception
    {
        Entry userEntry = new DefaultEntry(
            "cn=" + user + ",ou=system",
            "ObjectClass: top",
            "ObjectClass: person",
            "cn", user,
            "sn", user + "_sn" );

        AddRequest addRequest = new AddRequestImpl();
        addRequest.setEntry( userEntry );

        AddResponse addResp = adminConnection.add( addRequest );
        assertEquals( ResultCodeEnum.SUCCESS, addResp.getLdapResult().getResultCode() );
    }


    /**
     * Add a user with 2 passwords
     */
    private void addUser2Passwords( LdapConnection adminConnection, String user, Object password1, Object password2 ) throws Exception
    {
        Entry userEntry = new DefaultEntry(
            "cn=" + user + ",ou=system",
            "ObjectClass: top",
            "ObjectClass: person",
            "cn", user,
            "sn", user + "_sn",
            "userPassword", password1, 
            "userPassword", password2 );

        AddRequest addRequest = new AddRequestImpl();
        addRequest.setEntry( userEntry );

        AddResponse addResp = adminConnection.add( addRequest );
        assertEquals( ResultCodeEnum.SUCCESS, addResp.getLdapResult().getResultCode() );
    }


    //-----------------------------------------------------------------------------------
    // Self password modification  with one password
    //-----------------------------------------------------------------------------------
    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is not provided
     * o the new password is new
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwnPasswordNoOldNew() throws Exception
    {
        // Create a user
        try ( LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() ) )
        {        
            addUser( adminConnection, "User1", "secret1" );
    
            // Bind as the user
            try ( LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" ) )
            {
                Entry user = userConnection.lookup( "cn=user1,ou=system", "modifyTimestamp" );
                
                // Now change the password
                PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
                pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1Bis" ) );
        
                // Send the request
                PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );
        
                assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );
        
                // Now try to bind with the new password
                try ( LdapConnection newUserConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1Bis" ) )
                {
                    Entry entry = newUserConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );
            
                    assertNotNull( entry );
                    assertTrue( entry.containsAttribute( "userPassword" ) );
                    Attribute userPassword = entry.get( "userPassword" );
                    
                    assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );
            
                    assertEquals( 1, userPassword.size() );
                    assertEquals( "secret1Bis", userPassword.getString() );
                    assertNull( user.get( "modifyTimestamp" ) );
                    assertNotNull( entry.get( "modifyTimestamp" ).getString() );
                }
            }
        }
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is not provided
     * o the new password exists
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwnPasswordNoOldNewExists() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User1", "secret1" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        Entry user = userConnection.lookup( "cn=user1,ou=system", "modifyTimestamp" );
        
        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Now try to bind with the new password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 1, userPassword.size() );
        assertEquals( "secret1", userPassword.getString() );
        assertNull( user.get( "modifyTimestamp" ) );
        assertNull( entry.get( "modifyTimestamp" ) );

        userConnection.close();
        adminConnection.close();
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is provided
     * o the new password is new
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwnPasswordOldNew() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User1", "secret1" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret1" ) );
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1Bis" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Now try to bind with the new password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1Bis" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 1, userPassword.size() );
        assertEquals( "secret1Bis", userPassword.getString() );

        userConnection.close();
        adminConnection.close();
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is provided, but it's the wrong one
     * o the new password is new
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwnPasswordInvalidOldNew() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User1", "secret1" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), 
            "cn=user1,ou=system", "secret1" );
        
        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret2" ) );
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1Bis" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Now try to bind with the new password. Should fail
        try
        {
            userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1Bis" );
            fail();
        }
        catch ( LdapAuthenticationException lae )
        {
            // We are fine
        }

        // Rebind with the original password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 1, userPassword.size() );
        assertEquals( "secret1", userPassword.getString() );
        
        // The entry should not have been modified
        assertFalse( entry.containsAttribute( "modifyTimestamp" ) );

        userConnection.close();
        adminConnection.close();
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is provided
     * o the new password is not provided 
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwnPasswordOldNoNew() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User1", "secret1" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret1" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, pwdModifyResponse.getLdapResult().getResultCode() );

        // Rebind with the original password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 1, userPassword.size() );
        assertEquals( "secret1", userPassword.getString() );
        assertFalse( entry.containsAttribute( "modifyTimestamp" ) );

        userConnection.close();
        adminConnection.close();
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is provided
     * o the new password is already existing
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwnPasswordOldNewExists() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User1", "secret1" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret1" ) );
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Rebind with the original password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 1, userPassword.size() );
        assertEquals( "secret1", userPassword.getString() );
        assertFalse( entry.containsAttribute( "modifyTimestamp" ) );

        userConnection.close();
        adminConnection.close();
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is not provided
     * o the new password is not provided
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwnPasswordNoOldNoNew() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User1", "secret1" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, pwdModifyResponse.getLdapResult().getResultCode() );

        // Rebind with the original password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 1, userPassword.size() );
        assertEquals( "secret1", userPassword.getString() );

        userConnection.close();
        adminConnection.close();
    }


    //-----------------------------------------------------------------------------------
    // Self password modification with two passwords
    //-----------------------------------------------------------------------------------
    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is not provided
     * o the new password is not provided
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains two values
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwn2PasswordsNoOldNoNew() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser2Passwords( adminConnection, "User1", "secret1", "other" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, pwdModifyResponse.getLdapResult().getResultCode() );

        // Rebind with the original password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 2, userPassword.size() );
        assertTrue( userPassword.contains( "secret1", "other" ) );

        userConnection.close();
        adminConnection.close();
    }

    
    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is not provided
     * o the new password is new
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains two values
     * 
     * At the end, we will have only one password remaining
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwn2PassworsdNoOldNew() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser2Passwords( adminConnection, "User1", "secret1", "other" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        Entry user = userConnection.lookup( "cn=user1,ou=system", "modifyTimestamp" );
        
        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1Bis" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Now try to bind with the new password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1Bis" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 1, userPassword.size() );
        assertEquals( "secret1Bis", userPassword.getString() );
        assertNull( user.get( "modifyTimestamp" ) );
        assertNotNull( entry.get( "modifyTimestamp" ).getString() );

        userConnection.close();
        adminConnection.close();
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is not provided
     * o the new password exists
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains two values
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwn2PasswordsNoOldNewExists() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser2Passwords( adminConnection, "User1", "secret1", "other" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        Entry user = userConnection.lookup( "cn=user1,ou=system", "modifyTimestamp" );
        
        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Now try to bind with the new password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 2, userPassword.size() );
        assertTrue( userPassword.contains( "secret1", "other" ) );
        assertNull( user.get( "modifyTimestamp" ) );
        assertNull( entry.get( "modifyTimestamp" ) );

        userConnection.close();
        adminConnection.close();
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is provided
     * o the new password is new
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains two values
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwn2PasswordsOldNew() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser2Passwords( adminConnection, "User1", "secret1", "other" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret1" ) );
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1Bis" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Now try to bind with the new password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1Bis" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 1, userPassword.size() );
        assertEquals( "secret1Bis", userPassword.getString() );

        userConnection.close();
        adminConnection.close();
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is provided, but it's the wrong one
     * o the new password is new
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains two values
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwn2PasswordsInvalidOldNew() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser2Passwords( adminConnection, "User1", "secret1", "other" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), 
            "cn=user1,ou=system", "secret1" );
        
        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret2" ) );
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1Bis" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Now try to bind with the new password. Should fail
        try
        {
            userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1Bis" );
            fail();
        }
        catch ( LdapAuthenticationException lae )
        {
            // We are fine
        }

        // Rebind with the original password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 2, userPassword.size() );
        assertTrue( userPassword.contains( "secret1", "other" ) );
        
        // The entry should not have been modified
        assertFalse( entry.containsAttribute( "modifyTimestamp" ) );

        userConnection.close();
        adminConnection.close();
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is provided
     * o the new password is not provided 
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains two values
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwn2PasswordsOldNoNew() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser2Passwords( adminConnection, "User1", "secret1", "other" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret1" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, pwdModifyResponse.getLdapResult().getResultCode() );

        // Rebind with the original password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 2, userPassword.size() );
        assertTrue( userPassword.contains( "secret1", "other" ) );
        assertFalse( entry.containsAttribute( "modifyTimestamp" ) );

        userConnection.close();
        adminConnection.close();
    }


    /**
     * Modify an existing user password while the user is connected:
     * o the userIdentity is not provided
     * o the old password is provided
     * o the new password is already existing
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains two values
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testModifyOwn2PasswordsOldNewExists() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser2Passwords( adminConnection, "User1", "secret1", "other" );

        // Bind as the user
        LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), "cn=user1,ou=system", "secret1" );

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret1" ) );
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Rebind with the original password
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User1,ou=system", "secret1" );

        Entry entry = userConnection.lookup( "cn=User1,ou=system" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 2, userPassword.size() );
        assertTrue( userPassword.contains( "secret1", "other" ) );
        assertFalse( entry.containsAttribute( "modifyTimestamp" ) );

        userConnection.close();
        adminConnection.close();
    }
    
    
    //-----------------------------------------------------------------------------------
    // Non connected user
    //-----------------------------------------------------------------------------------
    /**
     * Modify an existing user password while the user is not connected
     */
    @Test
    public void testModifyUserPasswordAnonymous() throws Exception
    {
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User2", "secret2" );

        LdapConnection userConnection = getNetworkConnectionAs( ldapServer, "cn=User2,ou=system", "secret2" );

        Entry entry = userConnection.lookup( "cn=User2,ou=system" );

        assertNotNull( entry );

        userConnection.close();

        // Anonymous Bind
        LdapConnection anonymousConnection = getAnonymousNetworkConnection( getLdapServer() );

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User2,ou=system" ) );
        pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret2" ) );
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret2Bis" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) anonymousConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Check that we can now bind using the new credentials
        userConnection = getNetworkConnectionAs( ldapServer, "cn=User2,ou=system", "secret2Bis" );

        entry = userConnection.lookup( "cn=User2,ou=system" );

        assertNotNull( entry );

        userConnection.close();
        anonymousConnection.close();
        adminConnection.close();
    }
    
    
    /**
     * Test that the server refuse to generate a password
     */
    @Test
    public void testOwnGenPassword() throws Exception
    {
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User6", "secret6" );

        // Modify the user with the user account
        LdapConnection userConnection = getNetworkConnectionAs( ldapServer, "cn=User6,ou=system", "secret6" );

        // Now request a new password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User6,ou=system" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) userConnection.extended( pwdModifyRequest );

        // We should not be allowed to do that, as the operation is not yet implemented
        assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, pwdModifyResponse.getLdapResult().getResultCode() );

        userConnection.close();
        adminConnection.close();
    }


    //-----------------------------------------------------------------------------------
    // With admin
    //-----------------------------------------------------------------------------------
    /**
     * Modify an existing user password with an admin account
     */
    @Test
    public void testAdminModifyPassword() throws Exception
    {
        try ( LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() ) )
        {
            addUserNoPassword( adminConnection, "User4" );
    
            // Modify the user with the admin account
            Entry entry = adminConnection.lookup( "cn=User4,ou=system" );
    
            assertNotNull( entry );
    
            // Now change the password
            PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
            pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User4,ou=system" ) );
            pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret4" ) );
    
            // Send the request
            PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );
    
            assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, pwdModifyResponse.getLdapResult().getResultCode() );
    
            // Now try to bind with the new password
            try( LdapConnection userConnection = getNetworkConnectionAs( ldapServer, "cn=User4,ou=system", "secret4" ))
            {
                fail();
            }
            catch ( LdapException le )
            {
                // expected
            }
    
            entry = adminConnection.lookup( "cn=User4,ou=system", SchemaConstants.ALL_ATTRIBUTES_ARRAY );
    
            assertNotNull( entry );
            assertFalse( entry.containsAttribute( "userPassword" ) );
            assertFalse( entry.containsAttribute( "modifyTimestamp" ) );
        }
    }


    /**
     * Modify an existing user password with admin
     * o the userIdentity is provided
     * o the old password is not provided
     * o the new password is not provided
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testAdminModifyPasswordNoOldNoNew() throws Exception
    {
        // Create a user
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User1", "secret1" );

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User1,ou=system" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, pwdModifyResponse.getLdapResult().getResultCode() );

        Entry entry = adminConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );

        assertNotNull( entry );
        assertTrue( entry.containsAttribute( "userPassword" ) );
        Attribute userPassword = entry.get( "userPassword" );
        
        assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );

        assertEquals( 1, userPassword.size() );
        assertEquals( "secret1", userPassword.getString() );
        assertFalse( entry.containsAttribute( "modifyTimestamp" ) );

        adminConnection.close();
    }


    /**
     * Modify an existing user password with admin
     * o the userIdentity is provided
     * o the old password is not provided
     * o the new password is provided
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testAdminModifyPasswordNoOldNew() throws Exception
    {
        // Create a user
        try ( LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() ) )
        {
            addUser( adminConnection, "User1", "secret1" );
    
            // Now change the password
            PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
            pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User1,ou=system" ) );
            pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1Bis" ) );
    
            // Send the request
            PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );
    
            assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );
    
            try ( LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), 
                "cn=user1,ou=system", "secret1Bis" ) )
            {
                Entry entry = userConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );
            
                assertNotNull( entry );
                assertTrue( entry.containsAttribute( "userPassword" ) );
                Attribute userPassword = entry.get( "userPassword" );
                
                assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );
            
                assertEquals( 1, userPassword.size() );
                assertEquals( "secret1Bis", userPassword.getString() );
                assertTrue( entry.containsAttribute( "modifyTimestamp" ) );
            }
        }
    }


    /**
     * Modify an existing user with no password with admin
     * o the userIdentity is provided
     * o the old password is not provided
     * o the new password is provided
     * o the entry does not have a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testAdminAddPasswordNoOldNew() throws Exception
    {
        // Create a user
        try ( LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() ) )
        {
            addUserNoPassword( adminConnection, "User1" );
    
            // Now change the password
            PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
            pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User1,ou=system" ) );
            pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1" ) );
    
            // Send the request
            PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );
    
            assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, pwdModifyResponse.getLdapResult().getResultCode() );
    
            try ( LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), 
                "cn=user1,ou=system", "secret1" ) )
            {
                fail();
            }
            catch ( LdapException le )
            {
                // expected
            }

            Entry entry = adminConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );
        
            assertNotNull( entry );
            assertFalse( entry.containsAttribute( "userPassword" ) );
            assertFalse( entry.containsAttribute( "modifyTimestamp" ) );
        }
    }
    

    /**
     * Modify an existing user password with admin
     * o the userIdentity is provided
     * o the old password is provided but is invalid
     * o the new password is provided
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testAdminModifyPasswordInvalidOldNew() throws Exception
    {
        // Create a user
        try ( LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() ) )
        {
            addUser( adminConnection, "User1", "secret1" );
        
            // Now change the password
            PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
            pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User1,ou=system" ) );
            pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret2" ) );
            pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret2" ) ); 
        
            // Send the request
            PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );
        
            assertEquals( ResultCodeEnum.INVALID_CREDENTIALS, pwdModifyResponse.getLdapResult().getResultCode() );
        
            Entry entry = adminConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );
        
            assertNotNull( entry );
            assertTrue( entry.containsAttribute( "userPassword" ) );
            Attribute userPassword = entry.get( "userPassword" );
            
            assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );
        
            assertEquals( 1, userPassword.size() );
            assertEquals( "secret1", userPassword.getString() );
            assertFalse( entry.containsAttribute( "modifyTimestamp" ) );
        }
    }


    /**
     * Modify an existing user password with admin
     * o the userIdentity is provided
     * o the old password is not provided
     * o the new password is provided but already exist
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testAdminModifyPasswordNoOldNewExists() throws Exception
    {
        // Create a user
        try ( LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() ) )
        {
            addUser( adminConnection, "User1", "secret1" );
    
            // Now change the password
            PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
            pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User1,ou=system" ) );
            pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1" ) );
    
            // Send the request
            PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );
    
            assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );
    
            try ( LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), 
                "cn=user1,ou=system", "secret1" ) )
            {
                Entry entry = userConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );
            
                assertNotNull( entry );
                assertTrue( entry.containsAttribute( "userPassword" ) );
                Attribute userPassword = entry.get( "userPassword" );
                
                assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );
            
                assertEquals( 1, userPassword.size() );
                assertEquals( "secret1", userPassword.getString() );
                assertFalse( entry.containsAttribute( "modifyTimestamp" ) );
            }
        }
    }


    /**
     * Modify an existing user password with admin
     * o the userIdentity is provided
     * o the old password is provided
     * o the new password is provided
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disable
     */
    @Test
    public void testAdminModifyPasswordOldNew() throws Exception
    {
        // Create a user
        try ( LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() ) )
        {
            addUser( adminConnection, "User1", "secret1" );
    
            // Now change the password
            PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
            pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User1,ou=system" ) );
            pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret1" ) );
            pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1Bis" ) );
    
            // Send the request
            PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );
    
            assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );
    
            try ( LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), 
                "cn=user1,ou=system", "secret1Bis" ) )
            {
                Entry entry = userConnection.lookup( "cn=User1,ou=system", SchemaConstants.ALL_ATTRIBUTES_ARRAY );
            
                System.out.println( entry );
                assertNotNull( entry );
                assertTrue( entry.containsAttribute( "userPassword" ) );
                Attribute userPassword = entry.get( "userPassword" );
                
                assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );
            
                assertEquals( 1, userPassword.size() );
                assertEquals( "secret1Bis", userPassword.getString() );
                assertTrue( entry.containsAttribute( "modifyTimestamp" ) );
            }
        }
    }


    /**
     * Modify an existing user password with admin
     * o the userIdentity is provided
     * o the old password is provided
     * o the new password is not provided
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disable
     */
    @Test
    public void testAdminModifyPasswordOldNoNew() throws Exception
    {
        // Create a user
        try ( LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() ) )
        {
            addUser( adminConnection, "User1", "secret1" );
    
            // Now change the password
            PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
            pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User1,ou=system" ) );
            pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret1" ) );
    
            // Send the request
            PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );
    
            assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, pwdModifyResponse.getLdapResult().getResultCode() );
    
            try ( LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), 
                "cn=user1,ou=system", "secret1" ) )
            {
                Entry entry = userConnection.lookup( "cn=User1,ou=system", SchemaConstants.ALL_ATTRIBUTES_ARRAY );
            
                assertNotNull( entry );
                assertTrue( entry.containsAttribute( "userPassword" ) );
                Attribute userPassword = entry.get( "userPassword" );
                
                assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );
            
                assertEquals( 1, userPassword.size() );
                assertEquals( "secret1", userPassword.getString() );
                assertFalse( entry.containsAttribute( "modifyTimestamp" ) );
            }
        }
    }


    /**
     * Modify an existing user password with admin
     * o the userIdentity is provided
     * o the old password is provided
     * o the new password is provided
     * o the entry has a userPassword attribute
     * o the userPassword attribute contains only one value
     * 
     * At the same time, PP and passwordHashing interceptor are disabled
     */
    @Test
    public void testAdminModifyPasswordOldNewExists() throws Exception
    {
        // Create a user
        try ( LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() ) )
        {
            addUser( adminConnection, "User1", "secret1" );
    
            // Now change the password
            PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
            pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User1,ou=system" ) );
            pwdModifyRequest.setOldPassword( Strings.getBytesUtf8( "secret1" ) );
            pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret1" ) );
    
            // Send the request
            PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );
    
            assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );
    
            try ( LdapConnection userConnection = getNetworkConnectionAs( getLdapServer(), 
                "cn=user1,ou=system", "secret1" ) )
            {
                Entry entry = userConnection.lookup( "cn=User1,ou=system", "userPassword", "modifyTimestamp" );
            
                assertNotNull( entry );
                assertTrue( entry.containsAttribute( "userPassword" ) );
                Attribute userPassword = entry.get( "userPassword" );
                
                assertNull( PasswordUtil.findAlgorithm( userPassword.getBytes() ) );
            
                assertEquals( 1, userPassword.size() );
                assertEquals( "secret1", userPassword.getString() );
                assertFalse( entry.containsAttribute( "modifyTimestamp" ) );
            }
        }
    }


    /**
     * Modify an existing user password with an admin account
     */
    @Test
    public void testAdminModifyMultiplePassword() throws Exception
    {
        AuthenticationInterceptor authenticationInterceptor = ( AuthenticationInterceptor ) getService()
            .getInterceptor( InterceptorEnum.AUTHENTICATION_INTERCEPTOR.getName() );

        PpolicyConfigContainer policyContainer = authenticationInterceptor.getPwdPolicyContainer();
        authenticationInterceptor.setPwdPolicies( null );
        
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser2Passwords( adminConnection, "User5", "secret51", "secret52" );

        // Modify the user with the admin account

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User5,ou=system" ) );
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret5Bis" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.SUCCESS, pwdModifyResponse.getLdapResult().getResultCode() );

        // Now try to bind with the new password
        LdapConnection userConnection = getNetworkConnectionAs( ldapServer, "cn=User5,ou=system", "secret5Bis" );

        Entry entry = userConnection.lookup( "cn=User5,ou=system" );

        assertNotNull( entry );

        userConnection.close();
        adminConnection.close();
        authenticationInterceptor.setPwdPolicies( policyContainer );
    }


    /**
     * Modify an existing user password with a bad account
     */
    @Test
    public void testAdminModifyPasswordBadUser() throws Exception
    {
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User5", "secret5" );

        // Modify the user with the admin account

        // Now change the password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=baduser,ou=system" ) );
        pwdModifyRequest.setNewPassword( Strings.getBytesUtf8( "secret5Bis" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );

        assertEquals( ResultCodeEnum.NO_SUCH_OBJECT, pwdModifyResponse.getLdapResult().getResultCode() );

        adminConnection.close();
    }


    /**
     * Test that the server refuse to generate a password
     */
    @Test
    public void testAdminGenPassword() throws Exception
    {
        LdapConnection adminConnection = getAdminNetworkConnection( getLdapServer() );

        addUser( adminConnection, "User6", "secret6" );

        // Modify the user with the admin account

        // Now request a new password
        PasswordModifyRequest pwdModifyRequest = new PasswordModifyRequestImpl();
        pwdModifyRequest.setUserIdentity( Strings.getBytesUtf8( "cn=User6,ou=system" ) );

        // Send the request
        PasswordModifyResponse pwdModifyResponse = ( PasswordModifyResponse ) adminConnection.extended( pwdModifyRequest );

        // We should not be allowed to do that, as the operation is not yet implemented
        assertEquals( ResultCodeEnum.UNWILLING_TO_PERFORM, pwdModifyResponse.getLdapResult().getResultCode() );

        adminConnection.close();
    }
}
