Added a test for password modify
diff --git a/server-integ/src/test/java/org/apache/directory/server/operations/extended/PwdModifyNoPPNoPasswordHashingIT.java b/server-integ/src/test/java/org/apache/directory/server/operations/extended/PwdModifyNoPPNoPasswordHashingIT.java
new file mode 100644
index 0000000..1dd8a77
--- /dev/null
+++ b/server-integ/src/test/java/org/apache/directory/server/operations/extended/PwdModifyNoPPNoPasswordHashingIT.java
@@ -0,0 +1,1474 @@
+/*
+ * 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();
+ }
+}