/* * Copyright (c) 2013-2015 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.testing.wstest; import static org.testng.AssertJUnit.assertNotNull; import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertTrue; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; import org.apache.cxf.binding.soap.SoapFault; import org.apache.cxf.frontend.ClientProxy; import org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor; import org.apache.wss4j.common.ext.WSPasswordCallback; import org.apache.wss4j.dom.WSConstants; import org.apache.wss4j.dom.handler.WSHandlerConstants; import org.opends.server.types.Entry; import org.opends.server.types.SearchResultEntry; 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.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import org.w3c.dom.Element; import com.evolveum.midpoint.model.client.ModelClientUtil; import com.evolveum.midpoint.test.ldap.OpenDJController; import com.evolveum.midpoint.test.util.LogfileTestTailer; import com.evolveum.midpoint.test.util.TestUtil; import com.evolveum.midpoint.util.DOMUtil; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectDeltaListType; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectDeltaOperationListType; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectListType; import com.evolveum.midpoint.xml.ns._public.common.api_types_3.ObjectModificationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ActivationStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ConnectorType; import com.evolveum.midpoint.xml.ns._public.common.common_3.MetadataType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ModelExecuteOptionsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectReferenceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ObjectType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultStatusType; import com.evolveum.midpoint.xml.ns._public.common.common_3.OperationResultType; import com.evolveum.midpoint.xml.ns._public.common.common_3.PasswordType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ResourceType; import com.evolveum.midpoint.xml.ns._public.common.common_3.RoleType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowAttributesType; import com.evolveum.midpoint.xml.ns._public.common.common_3.ShadowType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemConfigurationType; import com.evolveum.midpoint.xml.ns._public.common.common_3.SystemObjectsType; import com.evolveum.midpoint.xml.ns._public.common.common_3.UserType; import com.evolveum.midpoint.xml.ns._public.common.fault_3.FaultMessage; import com.evolveum.midpoint.xml.ns._public.common.fault_3.FaultType; import com.evolveum.midpoint.xml.ns._public.common.fault_3.ObjectNotFoundFaultType; import com.evolveum.midpoint.xml.ns._public.common.fault_3.PolicyViolationFaultType; import com.evolveum.midpoint.xml.ns._public.model.model_3.ModelPortType; import com.evolveum.midpoint.xml.ns._public.model.model_3.ModelService; import com.evolveum.prism.xml.ns._public.query_3.QueryType; import com.evolveum.prism.xml.ns._public.types_3.ChangeTypeType; import com.evolveum.prism.xml.ns._public.types_3.ModificationTypeType; import com.evolveum.prism.xml.ns._public.types_3.ObjectDeltaType; import com.evolveum.prism.xml.ns._public.types_3.PolyStringType; import com.evolveum.prism.xml.ns._public.types_3.ProtectedStringType; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; import javax.xml.soap.SOAPFault; import javax.xml.ws.BindingProvider; import javax.xml.ws.Holder; import javax.xml.ws.soap.SOAPFaultException; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Testing basic web service operations * * @author Radovan Semancik * */ @ContextConfiguration(locations = {"classpath:ctx-wstest-main.xml"}) @DirtiesContext(classMode = ClassMode.AFTER_CLASS) public class TestWSSanity extends AbstractWebserviceTest { protected static OpenDJController openDJController = new OpenDJController(); private String connectorLdapOid = null; private String accountJackOid; @Override protected void startResources() throws Exception { super.startResources(); openDJController.startCleanServer(); } @Override protected void stopResources() throws Exception { super.stopResources(); openDJController.stop(); } // TODO: fetch&parse schema http://..?WSDL @Test public void test015SearchLdapConnector() throws Exception { final String TEST_NAME = "test015SearchLdapConnector"; displayTestTitle(TEST_NAME); QueryType query = new QueryType(); query.setFilter(ModelClientUtil.parseSearchFilterType( "<equal xmlns='http://prism.evolveum.com/xml/ns/public/query-3' xmlns:c='http://midpoint.evolveum.com/xml/ns/public/common/common-3' >" + "<path>c:connectorType</path>" + "<value>" + CONNECTOR_LDAP_TYPE + "</value>" + "</equal>" )); Holder<ObjectListType> objectListHolder = new Holder<>(); Holder<OperationResultType> resultHolder = new Holder<>(); // WHEN modelPort.searchObjects(ModelClientUtil.getTypeQName(ConnectorType.class), query, null, objectListHolder, resultHolder); // THEN assertSuccess(resultHolder); ObjectListType objectList = objectListHolder.value; assertEquals("Unexpected number of LDAP connectors", 1, objectList.getObject().size()); ConnectorType ldapConnector = (ConnectorType) objectList.getObject().get(0); assertNotNull("Null LDAP connector", ldapConnector); connectorLdapOid = ldapConnector.getOid(); assertNotNull("Null LDAP connector OID", connectorLdapOid); } @Test public void test020AddResourceOpenDj() throws Exception { final String TEST_NAME = "test020AddResourceOpenDj"; displayTestTitle(TEST_NAME); LogfileTestTailer tailer = createLogTailer(); ResourceType resource = ModelClientUtil.unmarshallFile(RESOURCE_OPENDJ_FILE); ObjectDeltaListType deltaList = new ObjectDeltaListType(); ObjectDeltaType delta = new ObjectDeltaType(); delta.setObjectType(getTypeQName(ResourceType.class)); delta.setChangeType(ChangeTypeType.ADD); delta.setObjectToAdd(resource); deltaList.getDelta().add(delta); ModelExecuteOptionsType options = new ModelExecuteOptionsType(); options.setIsImport(Boolean.TRUE); XMLGregorianCalendar startTs = TestUtil.currentTime(); // WHEN ObjectDeltaOperationListType deltaOpList = modelPort.executeChanges(deltaList, options); // THEN assertSuccess(deltaOpList); String oid = deltaOpList.getDeltaOperation().get(0).getObjectDelta().getOid(); XMLGregorianCalendar endTs = TestUtil.currentTime(); tailer.tail(); displayAudit(tailer); assertAuditLoginLogout(tailer); assertAuditIds(tailer); assertAuditOperation(tailer, "ADD_OBJECT"); tailer.assertAudit(4); assertEquals("Wrong OID", RESOURCE_OPENDJ_OID, oid); ResourceType resourceAfter = getObject(ResourceType.class, RESOURCE_OPENDJ_OID); display(resourceAfter); assertEquals("Wrong connector OID", connectorLdapOid, resourceAfter.getConnectorRef().getOid()); assertCreateMetadata(resourceAfter, USER_ADMINISTRATOR_OID, startTs, endTs); } @Test public void test030ResourceOpenDjTestConnection() throws Exception { final String TEST_NAME = "test030ResourceOpenDjTestConnection"; displayTestTitle(TEST_NAME); ResourceType resource = ModelClientUtil.unmarshallFile(RESOURCE_OPENDJ_FILE); // WHEN OperationResultType testResult = modelPort.testResource(RESOURCE_OPENDJ_OID); // THEN display(testResult); assertSuccess(testResult); } @Test public void test032ResourceNonexistingTestConnection() throws Exception { final String TEST_NAME = "test032ResourceNonexistingTestConnection"; displayTestTitle(TEST_NAME); try { // WHEN OperationResultType testResult = modelPort.testResource("56b53914-df90-11e4-8c8c-001e8c717e5b"); AssertJUnit.fail("Unexpected success"); } catch (FaultMessage f) { assertFaultMessage(f, ObjectNotFoundFaultType.class, "was not found"); } } // TODO: test unreachable resource @Test public void test100AddUserJack() throws Exception { final String TEST_NAME = "test100AddUserJack"; displayTestTitle(TEST_NAME); LogfileTestTailer tailer = createLogTailer(); UserType userNobody = ModelClientUtil.unmarshallFile(USER_JACK_FILE); XMLGregorianCalendar startTs = TestUtil.currentTime(); // WHEN String oid = addObject(userNobody); // THEN XMLGregorianCalendar endTs = TestUtil.currentTime(); tailer.tail(); displayAudit(tailer); assertAuditLoginLogout(tailer); assertAuditIds(tailer); assertAuditOperation(tailer, "ADD_OBJECT"); tailer.assertAudit(4); // GET user UserType userAfter = getObject(UserType.class, USER_JACK_OID); display(userAfter); assertUser(userAfter, oid, USER_JACK_USERNAME, USER_JACK_GIVEN_NAME, USER_JACK_FAMILY_NAME); assertCreateMetadata(userAfter, USER_ADMINISTRATOR_OID, startTs, endTs); assertPasswordCreateMetadata(userAfter, USER_ADMINISTRATOR_OID, startTs, endTs); } @Test public void test110AssignOpenDJAccountToJack() throws Exception { final String TEST_NAME = "test110AssignOpenDJAccountToJack"; displayTestTitle(TEST_NAME); LogfileTestTailer tailer = createLogTailer(); XMLGregorianCalendar startTs = TestUtil.currentTime(); ObjectDeltaType delta = ModelClientUtil.createConstructionAssignDelta(UserType.class, USER_JACK_OID, RESOURCE_OPENDJ_OID); // WHEN ObjectDeltaOperationListType executedDeltas = modelPort.executeChanges(ModelClientUtil.createDeltaList(delta), null); // THEN XMLGregorianCalendar endTs = TestUtil.currentTime(); assertSuccess(executedDeltas); tailer.tail(); displayAudit(tailer); assertAuditLoginLogout(tailer); assertAuditIds(tailer); assertAuditOperation(tailer, "MODIFY_OBJECT"); tailer.assertAudit(4); // GET user UserType userAfter = getObject(UserType.class, USER_JACK_OID); display(userAfter); assertUser(userAfter, USER_JACK_OID, USER_JACK_USERNAME, USER_JACK_GIVEN_NAME, USER_JACK_FAMILY_NAME); assertModifyMetadata(userAfter, USER_ADMINISTRATOR_OID, startTs, endTs); accountJackOid = getSingleLinkOid(userAfter); assertNotNull(accountJackOid); Entry ldapEntry = openDJController.fetchEntry("uid="+USER_JACK_USERNAME+","+openDJController.getSuffixPeople()); display(ldapEntry.toLDIFString()); OpenDJController.assertAttribute(ldapEntry, "uid", "jack"); OpenDJController.assertAttribute(ldapEntry, "givenName", "Jack"); OpenDJController.assertAttribute(ldapEntry, "sn", "Sparrow"); OpenDJController.assertAttribute(ldapEntry, "cn", "Jack Sparrow"); OpenDJController.assertAttribute(ldapEntry, "displayName", "Jack Sparrow"); } @Test public void test111CheckJackAccountShadow() throws Exception { final String TEST_NAME = "test111CheckJackAccountShadow"; displayTestTitle(TEST_NAME); Holder<ObjectType> objectHolder = new Holder<>(); Holder<OperationResultType> resultHolder = new Holder<>(); // WHEN modelPort.getObject(ModelClientUtil.getTypeQName(ShadowType.class), accountJackOid, null, objectHolder, resultHolder); // THEN assertSuccess(resultHolder); ShadowType shadow = (ShadowType) objectHolder.value; display(shadow); assertAttribute(shadow, ATTR_ICF_NAME_NAME, "uid="+USER_JACK_USERNAME+","+openDJController.getSuffixPeople()); assertAttribute(shadow, "uid", "jack"); assertAttribute(shadow, "givenName", "Jack"); assertAttribute(shadow, "sn", "Sparrow"); assertAttribute(shadow, "cn", "Jack Sparrow"); assertAttribute(shadow, "displayName", "Jack Sparrow"); } @Test public void test112CheckJackAccountShadowRaw() throws Exception { final String TEST_NAME = "test112CheckJackAccountShadowRaw"; displayTestTitle(TEST_NAME); Holder<ObjectType> objectHolder = new Holder<>(); Holder<OperationResultType> resultHolder = new Holder<>(); // WHEN modelPort.getObject(ModelClientUtil.getTypeQName(ShadowType.class), accountJackOid, ModelClientUtil.createRootGetOptions(ModelClientUtil.createRawGetOption()), objectHolder, resultHolder); // THEN assertSuccess(resultHolder); ShadowType shadow = (ShadowType) objectHolder.value; display(shadow); assertAttribute(shadow, ATTR_ICF_NAME_NAME, "uid="+USER_JACK_USERNAME+","+openDJController.getSuffixPeople()); assertNoAttribute(shadow, "uid"); assertNoAttribute(shadow, "givenName"); assertNoAttribute(shadow, "sn"); assertNoAttribute(shadow, "cn"); assertNoAttribute(shadow, "displayName"); } }