blob: 256ea7f597c8a21b627f4407fde305f40053c160 [file] [log] [blame]
/*
* 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.syncope.fit.core;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import java.util.List;
import java.util.Locale;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.syncope.client.lib.SyncopeClient;
import org.apache.syncope.client.lib.SyncopeClientFactoryBean;
import org.apache.syncope.common.keymaster.client.api.model.Domain;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.request.UserCR;
import org.apache.syncope.common.lib.to.ConnInstanceTO;
import org.apache.syncope.common.lib.to.ExecTO;
import org.apache.syncope.common.lib.to.ItemTO;
import org.apache.syncope.common.lib.to.MappingTO;
import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.lib.to.ProvisionTO;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.to.PullTaskTO;
import org.apache.syncope.common.lib.to.PushTaskTO;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.to.ResourceTO;
import org.apache.syncope.common.lib.to.UserTO;
import org.apache.syncope.common.lib.types.AnyTypeKind;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.ExecStatus;
import org.apache.syncope.common.lib.types.MappingPurpose;
import org.apache.syncope.common.lib.types.MatchingRule;
import org.apache.syncope.common.lib.types.PullMode;
import org.apache.syncope.common.lib.types.SchemaType;
import org.apache.syncope.common.lib.types.TaskType;
import org.apache.syncope.common.rest.api.beans.AnyQuery;
import org.apache.syncope.common.rest.api.beans.RealmQuery;
import org.apache.syncope.common.rest.api.beans.ReconQuery;
import org.apache.syncope.common.rest.api.beans.SchemaQuery;
import org.apache.syncope.common.rest.api.beans.TaskQuery;
import org.apache.syncope.common.rest.api.service.ConnectorService;
import org.apache.syncope.common.rest.api.service.RealmService;
import org.apache.syncope.common.rest.api.service.ReconciliationService;
import org.apache.syncope.common.rest.api.service.ResourceService;
import org.apache.syncope.common.rest.api.service.SchemaService;
import org.apache.syncope.common.rest.api.service.TaskService;
import org.apache.syncope.common.rest.api.service.UserSelfService;
import org.apache.syncope.common.rest.api.service.UserService;
import org.apache.syncope.fit.AbstractITCase;
import org.apache.syncope.fit.ElasticsearchDetector;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class MultitenancyITCase extends AbstractITCase {
@BeforeEach
public void multitenancyCheck() {
List<Domain> initial = domainOps.list();
assertNotNull(initial);
assumeTrue(initial.stream().anyMatch(domain -> "Two".equals(domain.getKey())));
CLIENT_FACTORY = new SyncopeClientFactoryBean().setAddress(ADDRESS).setDomain("Two");
String envContentType = System.getProperty(ENV_KEY_CONTENT_TYPE);
if (StringUtils.isNotBlank(envContentType)) {
CLIENT_FACTORY.setContentType(envContentType);
}
LOG.info("Performing IT with content type {}", CLIENT_FACTORY.getContentType().getMediaType());
ADMIN_CLIENT = CLIENT_FACTORY.create(ADMIN_UNAME, "password2");
}
@Test
public void readPlainSchemas() {
assertEquals(1, ADMIN_CLIENT.getService(SchemaService.class).
search(new SchemaQuery.Builder().type(SchemaType.PLAIN).build()).size());
}
@Test
public void readRealm() {
PagedResult<RealmTO> realms = ADMIN_CLIENT.getService(RealmService.class).
search(new RealmQuery.Builder().keyword("*").build());
assertEquals(1, realms.getTotalCount());
assertEquals(1, realms.getResult().size());
assertEquals(SyncopeConstants.ROOT_REALM, realms.getResult().get(0).getName());
}
@Test
public void createUser() {
assertNull(ADMIN_CLIENT.getService(RealmService.class).
search(new RealmQuery.Builder().keyword("*").build()).getResult().get(0).getPasswordPolicy());
UserCR userCR = new UserCR();
userCR.setRealm(SyncopeConstants.ROOT_REALM);
userCR.setUsername(getUUIDString());
userCR.setPassword("password");
Response response = ADMIN_CLIENT.getService(UserService.class).create(userCR);
assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
UserTO user = response.readEntity(new GenericType<ProvisioningResult<UserTO>>() {
}).getEntity();
assertNotNull(user);
}
@Test
public void createResourceAndPull() {
// read connector
ConnInstanceTO conn = ADMIN_CLIENT.getService(ConnectorService.class).
read("b7ea96c3-c633-488b-98a0-b52ac35850f7", Locale.ENGLISH.getLanguage());
assertNotNull(conn);
assertEquals("LDAP", conn.getDisplayName());
// prepare resource
ResourceTO resource = new ResourceTO();
resource.setKey("new-ldap-resource");
resource.setConnector(conn.getKey());
try {
ProvisionTO provisionTO = new ProvisionTO();
provisionTO.setAnyType(AnyTypeKind.USER.name());
provisionTO.setObjectClass(ObjectClass.ACCOUNT_NAME);
resource.getProvisions().add(provisionTO);
MappingTO mapping = new MappingTO();
mapping.setConnObjectLink("'uid=' + username + ',ou=people,o=isp'");
provisionTO.setMapping(mapping);
ItemTO item = new ItemTO();
item.setIntAttrName("username");
item.setExtAttrName("cn");
item.setPurpose(MappingPurpose.BOTH);
mapping.setConnObjectKeyItem(item);
item = new ItemTO();
item.setPassword(true);
item.setIntAttrName("password");
item.setExtAttrName("userPassword");
item.setPurpose(MappingPurpose.BOTH);
item.setMandatoryCondition("true");
mapping.add(item);
item = new ItemTO();
item.setIntAttrName("key");
item.setPurpose(MappingPurpose.BOTH);
item.setExtAttrName("sn");
item.setMandatoryCondition("true");
mapping.add(item);
item = new ItemTO();
item.setIntAttrName("email");
item.setPurpose(MappingPurpose.BOTH);
item.setExtAttrName("mail");
mapping.add(item);
// create resource
Response response = ADMIN_CLIENT.getService(ResourceService.class).create(resource);
assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
resource = ADMIN_CLIENT.getService(ResourceService.class).read(resource.getKey());
assertNotNull(resource);
// create pull task
PullTaskTO task = new PullTaskTO();
task.setName("LDAP Pull Task");
task.setActive(true);
task.setDestinationRealm(SyncopeConstants.ROOT_REALM);
task.setResource(resource.getKey());
task.setPullMode(PullMode.FULL_RECONCILIATION);
task.setPerformCreate(true);
response = ADMIN_CLIENT.getService(TaskService.class).create(TaskType.PULL, task);
assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
task = ADMIN_CLIENT.getService(TaskService.class).read(TaskType.PULL,
StringUtils.substringAfterLast(response.getLocation().toASCIIString(), "/"), true);
assertNotNull(resource);
// pull
ExecTO execution = AbstractTaskITCase.execProvisioningTask(
ADMIN_CLIENT.getService(TaskService.class), TaskType.PULL, task.getKey(), MAX_WAIT_SECONDS, false);
// verify execution status
String status = execution.getStatus();
assertNotNull(status);
assertEquals(ExecStatus.SUCCESS, ExecStatus.valueOf(status));
// verify that pulled user is found
if (ElasticsearchDetector.isElasticSearchEnabled(ANONYMOUS_CLIENT.platform())) {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
// ignore
}
}
PagedResult<UserTO> matchingUsers = ADMIN_CLIENT.getService(UserService.class).
search(new AnyQuery.Builder().
realm(SyncopeConstants.ROOT_REALM).
fiql(SyncopeClient.getUserSearchConditionBuilder().
is("username").equalTo("pullFromLDAP").query()).
build());
assertNotNull(matchingUsers);
assertEquals(1, matchingUsers.getResult().size());
// SYNCOPE-1374
String pullFromLDAPKey = matchingUsers.getResult().get(0).getKey();
assertEquals(0, ADMIN_CLIENT.getService(TaskService.class).
search(new TaskQuery.Builder(TaskType.PROPAGATION).
anyTypeKind(AnyTypeKind.USER).entityKey(pullFromLDAPKey).build()).getSize());
PushTaskTO pushTask = new PushTaskTO();
pushTask.setPerformUpdate(true);
pushTask.setMatchingRule(MatchingRule.UPDATE);
ADMIN_CLIENT.getService(ReconciliationService.class).
push(new ReconQuery.Builder(AnyTypeKind.USER.name(), resource.getKey()).
anyKey(pullFromLDAPKey).build(), pushTask);
assertEquals(1, ADMIN_CLIENT.getService(TaskService.class).
search(new TaskQuery.Builder(TaskType.PROPAGATION).
anyTypeKind(AnyTypeKind.USER).entityKey(pullFromLDAPKey).build()).getSize());
} finally {
ADMIN_CLIENT.getService(ResourceService.class).delete(resource.getKey());
}
}
@Test
public void issueSYNCOPE1377() {
try {
new SyncopeClientFactoryBean().setAddress(ADDRESS).setDomain("NotExisting").create().
getService(UserSelfService.class).
create(UserITCase.getUniqueSample("syncope1377@syncope.apache.org"));
fail("This should not happen");
} catch (SyncopeClientException e) {
assertEquals(ClientExceptionType.NotFound, e.getType());
assertTrue(e.getMessage().contains("NotExisting"));
}
}
}