/* * Copyright (c) 2010-2017 Evolveum * * Licensed 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 com.evolveum.midpoint.model.impl.lens; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.fail; import static com.evolveum.midpoint.test.IntegrationTestTools.display; import java.io.File; import java.util.List; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.annotation.DirtiesContext.ClassMode; import org.springframework.test.context.ContextConfiguration; import org.testng.AssertJUnit; import org.testng.annotations.Test; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.path.ItemPath; import com.evolveum.midpoint.schema.constants.ObjectTypes; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.schema.util.ObjectTypeUtil; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.exception.ObjectNotFoundException; import com.evolveum.midpoint.util.exception.PolicyViolationException; import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsPolicyType; import com.evolveum.midpoint.xml.ns._public.common.common_3.CredentialsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordCredentialsPolicyType; import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordHistoryEntryType; import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SecurityPolicyType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; @ContextConfiguration(locations = { "classpath:ctx-model-test-main.xml" }) @DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class TestPasswordPolicyProcessor extends AbstractLensTest { private static final String BASE_PATH = "src/test/resources/lens"; private static final String PASSWORD_HISTORY_POLICY_OID = "policy00-0000-0000-0000-000000000003"; private static final String PASSWORD_HISTORY_POLICY_NAME = "password-policy-history.xml"; private static final File PASSWORD_HISTORY_POLICY_FILE = new File(BASE_PATH, PASSWORD_HISTORY_POLICY_NAME); private static final String PASSWORD_NO_HISTORY_POLICY_OID = "policy00-0000-0000-0000-000000000004"; private static final String PASSWORD_NO_HISTORY_POLICY_NAME = "password-policy-no-history.xml"; private static final File PASSWORD_NO_HISTORY_POLICY_FILE = new File(BASE_PATH, PASSWORD_NO_HISTORY_POLICY_NAME); private static final String PASSWORD1 = "ch4nGedPa33word1"; private static final String PASSWORD2 = "ch4nGedPa33word2"; private static final String PASSWORD3 = "ch4nGedPa33word3"; @Override public void initSystem(Task initTask, OperationResult initResult) throws Exception { super.initSystem(initTask, initResult); repoAddObjectFromFile(PASSWORD_HISTORY_POLICY_FILE, initResult); repoAddObjectFromFile(PASSWORD_NO_HISTORY_POLICY_FILE, initResult); deleteObject(UserType.class, USER_JACK_OID); } @Test public void test000initPasswordPolicyForHistory() throws Exception { final String TEST_NAME = "test000initPasswordPolicyForHistory"; initPasswordPolicy(TEST_NAME, PASSWORD_HISTORY_POLICY_OID); } @Test public void test100CreateUserWithPassword() throws Exception { final String TEST_NAME = "test100CreateUserWithPassword"; TestUtil.displayTestTile(TEST_NAME); // WHEN addObject(USER_JACK_FILE); // THEN PrismObject<UserType> jack = getObject(UserType.class, USER_JACK_OID); assertNotNull("User Jack was not found.", jack); assertPasswordHistoryEntries(jack); } @Test public void test101ModifyUserPassword() throws Exception { final String TEST_NAME = "test101ModifyUserPassword"; TestUtil.displayTestTile(TEST_NAME); Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN modifyUserChangePassword(USER_JACK_OID, PASSWORD1, task, result); // THEN PrismObject<UserType> jack = getObject(UserType.class, USER_JACK_OID); assertNotNull("User Jack was not found.", jack); UserType jackType = jack.asObjectable(); CredentialsType credentialsType = jackType.getCredentials(); assertNotNull("No credentials set for user Jack", credentialsType); PasswordType passwordType = credentialsType.getPassword(); assertNotNull("No password set for user Jack", passwordType); ProtectedStringType passwordAfterChange = passwordType.getValue(); assertNotNull("Password musn't be null", passwordAfterChange); assertEquals("Password doesn't match", PASSWORD1, protector.decryptString(passwordAfterChange)); assertPasswordHistoryEntries(passwordType, USER_JACK_PASSWORD); } @Test public void test102ModifyUserPassword() throws Exception { final String TEST_NAME = "test102ModifyUserPassword"; TestUtil.displayTestTile(TEST_NAME); Task task = taskManager.createTaskInstance(TEST_NAME); OperationResult result = task.getResult(); // WHEN modifyUserChangePassword(USER_JACK_OID, PASSWORD2, task, result); // THEN PrismObject<UserType> jack = getObject(UserType.class, USER_JACK_OID); assertNotNull("User Jack was not found.", jack); UserType jackType = jack.asObjectable(); CredentialsType credentialsType = jackType.getCredentials(); assertNotNull("No credentials set for user Jack", credentialsType); PasswordType passwordType = credentialsType.getPassword(); assertNotNull("No password set for user Jack", passwordType); ProtectedStringType passwordAfterChange = passwordType.getValue(); assertNotNull("Password musn't be null", passwordAfterChange); assertEquals("Password doesn't match", PASSWORD2, protector.decryptString(passwordAfterChange)); assertPasswordHistoryEntries(passwordType, USER_JACK_PASSWORD, PASSWORD1); } @Test public void test103ModifyUserPasswordAgain() throws Exception { final String TEST_NAME = "test103ModifyUserPasswordAgain"; TestUtil.displayTestTile(TEST_NAME); Task task = createTask(TEST_NAME); OperationResult result = task.getResult(); // WHEN modifyUserChangePassword(USER_JACK_OID, PASSWORD3, task, result); // THEN PrismObject<UserType> jackAfterSecondChange = getObject(UserType.class, USER_JACK_OID); assertNotNull("User Jack was not found.", jackAfterSecondChange); UserType jackTypeAfterSecondChange = jackAfterSecondChange.asObjectable(); CredentialsType credentialsTypeAfterSecondChange = jackTypeAfterSecondChange.getCredentials(); assertNotNull("No credentials set for user Jack", credentialsTypeAfterSecondChange); PasswordType passwordTypeAfterSecondChnage = credentialsTypeAfterSecondChange.getPassword(); assertNotNull("No password set for user Jack", passwordTypeAfterSecondChnage); ProtectedStringType passwordAfterSecondChange = passwordTypeAfterSecondChnage.getValue(); assertNotNull("Password musn't be null", passwordAfterSecondChange); assertEquals("Password doesn't match", PASSWORD3, protector.decryptString(passwordAfterSecondChange)); assertPasswordHistoryEntries(passwordTypeAfterSecondChnage, PASSWORD1, PASSWORD2); } @Test public void test111ModifyUserPasswordOldPassword1() throws Exception { doTestModifyUserPasswordExpectFailure("test111ModifyUserPasswordOldPassword1", PASSWORD1); } @Test public void test112ModifyUserPasswordOldPassword2() throws Exception { doTestModifyUserPasswordExpectFailure("test112ModifyUserPasswordOldPassword2", PASSWORD2); } @Test public void test113ModifyUserPasswordSamePassword3() throws Exception { doTestModifyUserPasswordExpectFailure("test113ModifyUserPasswordSamePassword3", PASSWORD3); } public void doTestModifyUserPasswordExpectFailure(final String TEST_NAME, String password) throws Exception { Task task = taskManager.createTaskInstance(TEST_NAME); TestUtil.displayTestTile(TEST_NAME); OperationResult result = task.getResult(); try { // WHEN modifyUserChangePassword(USER_JACK_OID, password, task, result); fail("Expected PolicyViolationException but didn't get one."); } catch (PolicyViolationException ex) { // this is expected display("expected exception", ex); result.computeStatus(); TestUtil.assertFailure(result); } } @Test public void test200initNoHistoryPasswordPolicy() throws Exception { String title = "test200initNoHistoryPasswordPolicy"; initPasswordPolicy(title, PASSWORD_NO_HISTORY_POLICY_OID); } @Test public void test201deleteUserJack() throws Exception { final String TEST_NAME = "test201deleteUserJack"; TestUtil.displayTestTile(TEST_NAME); // WHEN deleteObject(UserType.class, USER_JACK_OID); try { getObject(UserType.class, USER_JACK_OID); fail("Unexpected user Jack, should be deleted."); } catch (ObjectNotFoundException ex) { // this is OK; } } @Test public void test202createUserJackNoPasswordHistory() throws Exception { final String TEST_NAME = "test202createUserJackNoPasswordHistory"; TestUtil.displayTestTile(TEST_NAME); // WHEN addObject(USER_JACK_FILE); // THEN PrismObject<UserType> userJack = getObject(UserType.class, USER_JACK_OID); assertNotNull("Expected to find user Jack, but no one exists here", userJack); UserType userJackType = userJack.asObjectable(); CredentialsType credentials = userJackType.getCredentials(); assertNotNull("User Jack has no credentials", credentials); PasswordType password = credentials.getPassword(); assertNotNull("User Jack has no password", password); List<PasswordHistoryEntryType> historyEntries = password.getHistoryEntry(); assertEquals("Expected no history entries, but found: " + historyEntries.size(), 0, historyEntries.size()); } @Test public void test203modifyUserJackPasswordNoPasswordHistory() throws Exception { final String TEST_NAME = "test203modifyUserJackPasswordNoPasswordHistory"; TestUtil.displayTestTile(TEST_NAME); Task task = taskManager.createTaskInstance(TEST_NAME); OperationResult result = task.getResult(); // WHEN ProtectedStringType newValue = new ProtectedStringType(); newValue.setClearValue("n0Hist0ryEntr7"); modifyObjectReplaceProperty(UserType.class, USER_JACK_OID, new ItemPath(UserType.F_CREDENTIALS, CredentialsType.F_PASSWORD, PasswordType.F_VALUE), task, result, newValue); // THEN PrismObject<UserType> userJack = getObject(UserType.class, USER_JACK_OID); assertNotNull("Expected to find user Jack, but no one exists here", userJack); UserType userJackType = userJack.asObjectable(); CredentialsType credentials = userJackType.getCredentials(); assertNotNull("User Jack has no credentials", credentials); PasswordType password = credentials.getPassword(); assertNotNull("User Jack has no password", password); List<PasswordHistoryEntryType> historyEntries = password.getHistoryEntry(); assertEquals("Expected no history entries, but found: " + historyEntries.size(), 0, historyEntries.size()); } private void initPasswordPolicy(String title, String passwordPolicyOid) throws Exception { display(title); Task task = createTask(title); OperationResult result = task.getResult(); ObjectReferenceType passwordPolicyRef = ObjectTypeUtil.createObjectRef(passwordPolicyOid, ObjectTypes.PASSWORD_POLICY); modifyObjectReplaceReference(SecurityPolicyType.class, SECURITY_POLICY_OID, new ItemPath(SecurityPolicyType.F_CREDENTIALS, CredentialsPolicyType.F_PASSWORD, PasswordCredentialsPolicyType.F_PASSWORD_POLICY_REF), task, result, passwordPolicyRef.asReferenceValue()); } }