blob: 42140ae4177c417f72051e8e1dacb900b56980b9 [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.assertFalse;
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 java.util.List;
import java.util.Optional;
import java.util.UUID;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import org.apache.syncope.common.lib.Attr;
import org.apache.syncope.common.lib.SyncopeClientException;
import org.apache.syncope.common.lib.SyncopeConstants;
import org.apache.syncope.common.lib.policy.DefaultAccessPolicyConf;
import org.apache.syncope.common.lib.policy.DefaultAttrReleasePolicyConf;
import org.apache.syncope.common.lib.policy.DefaultAuthPolicyConf;
import org.apache.syncope.common.lib.policy.AccountPolicyTO;
import org.apache.syncope.common.lib.to.RealmTO;
import org.apache.syncope.common.lib.policy.DefaultAccountRuleConf;
import org.apache.syncope.common.lib.policy.AccessPolicyTO;
import org.apache.syncope.common.lib.policy.AttrReleasePolicyTO;
import org.apache.syncope.common.lib.policy.AuthPolicyTO;
import org.apache.syncope.common.lib.to.ImplementationTO;
import org.apache.syncope.common.lib.to.PagedResult;
import org.apache.syncope.common.lib.to.ProvisioningResult;
import org.apache.syncope.common.lib.types.ClientExceptionType;
import org.apache.syncope.common.lib.types.ImplementationEngine;
import org.apache.syncope.common.lib.types.PolicyType;
import org.apache.syncope.common.lib.types.ExecStatus;
import org.apache.syncope.common.lib.types.IdRepoImplementationType;
import org.apache.syncope.common.rest.api.RESTHeaders;
import org.apache.syncope.common.rest.api.beans.RealmQuery;
import org.apache.syncope.common.rest.api.service.RealmService;
import org.apache.syncope.core.provisioning.api.serialization.POJOHelper;
import org.apache.syncope.fit.AbstractITCase;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class RealmITCase extends AbstractITCase {
private static Optional<RealmTO> getRealm(final String fullPath) {
return realmService.list(fullPath).stream().filter(realm -> fullPath.equals(realm.getFullPath())).findFirst();
}
@Test
public void search() {
PagedResult<RealmTO> match = realmService.search(new RealmQuery.Builder().keyword("*o*").build());
assertTrue(match.getResult().stream().allMatch(realm -> realm.getName().contains("o")));
}
@Test
public void list() {
List<RealmTO> realms = realmService.list(SyncopeConstants.ROOT_REALM);
assertNotNull(realms);
assertFalse(realms.isEmpty());
realms.forEach(Assertions::assertNotNull);
try {
realmService.list("a name");
fail("This should not happen");
} catch (SyncopeClientException e) {
assertEquals(ClientExceptionType.InvalidPath, e.getType());
}
}
@Test
public void createUpdate() {
RealmTO realm = new RealmTO();
realm.setName("last");
// 1. create
Response response = realmService.create("/even/two", realm);
RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
assertNotNull(actuals);
assertTrue(actuals.length > 0);
RealmTO actual = actuals[0];
assertNotNull(actual.getKey());
assertEquals("last", actual.getName());
assertEquals("/even/two/last", actual.getFullPath());
assertEquals(actual.getParent(), getRealm("/even/two").get().getKey());
assertNull(realm.getAccountPolicy());
assertNull(realm.getPasswordPolicy());
// 2. update setting policies
actual.setAccountPolicy("06e2ed52-6966-44aa-a177-a0ca7434201f");
actual.setPasswordPolicy("986d1236-3ac5-4a19-810c-5ab21d79cba1");
actual.setAuthPolicy("b912a0d4-a890-416f-9ab8-84ab077eb028");
actual.setAccessPolicy("419935c7-deb3-40b3-8a9a-683037e523a2");
actual.setAttrReleasePolicy("319935c7-deb3-40b3-8a9a-683037e523a2");
realmService.update(actual);
actual = getRealm(actual.getFullPath()).get();
assertNotNull(actual.getAccountPolicy());
assertNotNull(actual.getPasswordPolicy());
assertNotNull(actual.getAuthPolicy());
assertNotNull(actual.getAccessPolicy());
assertNotNull(actual.getAttrReleasePolicy());
// 3. update changing parent
actual.setParent(getRealm("/odd").get().getKey());
realmService.update(actual);
actual = getRealm("/odd/last").get();
assertNotNull(actual);
assertEquals("/odd/last", actual.getFullPath());
assertEquals(1, realmService.list(SyncopeConstants.ROOT_REALM).stream().
filter(object -> realm.getName().equals(object.getName())).count());
// 4. create under invalid path
try {
realmService.create("a name", realm);
fail("This should not happen");
} catch (SyncopeClientException e) {
assertEquals(ClientExceptionType.InvalidPath, e.getType());
}
// 5. attempt to create duplicate
try {
realmService.create("/odd", realm);
fail("This should not happen");
} catch (SyncopeClientException e) {
assertEquals(ClientExceptionType.EntityExists, e.getType());
}
}
@Test
public void createWithTilde() {
RealmTO realm = new RealmTO();
realm.setName("73~1~19534");
Response response = realmService.create("/even/two", realm);
assertEquals(Response.Status.CREATED.getStatusCode(), response.getStatus());
List<RealmTO> realms = realmService.list("/even/two/73~1~19534");
assertEquals(1, realms.size());
assertEquals(realm.getName(), realms.get(0).getName());
}
@Test
public void deletingAccountPolicy() {
// 1. create account policy
DefaultAccountRuleConf ruleConf = new DefaultAccountRuleConf();
ruleConf.setMinLength(3);
ruleConf.setMaxLength(8);
ImplementationTO rule = new ImplementationTO();
rule.setKey("DefaultAccountRuleConf" + UUID.randomUUID().toString());
rule.setEngine(ImplementationEngine.JAVA);
rule.setType(IdRepoImplementationType.ACCOUNT_RULE);
rule.setBody(POJOHelper.serialize(ruleConf));
Response response = implementationService.create(rule);
rule.setKey(response.getHeaderString(RESTHeaders.RESOURCE_KEY));
AccountPolicyTO policy = new AccountPolicyTO();
policy.setName("deletingAccountPolicy");
policy.getRules().add(rule.getKey());
policy = createPolicy(PolicyType.ACCOUNT, policy);
assertNotNull(policy);
// 2. create realm with policy assigned
RealmTO realm = new RealmTO();
realm.setName("withPolicy");
response = realmService.create(SyncopeConstants.ROOT_REALM, realm);
RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
assertNotNull(actuals);
assertTrue(actuals.length > 0);
realm = actuals[0];
String existingAccountPolicy = realm.getAccountPolicy();
realm.setAccountPolicy(policy.getKey());
realmService.update(realm);
actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
assertNotNull(actuals);
assertTrue(actuals.length > 0);
RealmTO actual = actuals[0];
assertEquals(policy.getKey(), actual.getAccountPolicy());
// 3. remove policy
policyService.delete(PolicyType.ACCOUNT, policy.getKey());
// 4. verify
actual = getRealm(actual.getFullPath()).get();
assertEquals(existingAccountPolicy, actual.getAccountPolicy());
}
@Test
public void deletingAuthPolicy() {
// 1. create authentication policy
DefaultAuthPolicyConf ruleConf = new DefaultAuthPolicyConf();
ruleConf.getAuthModules().addAll(List.of("LdapAuthentication1"));
AuthPolicyTO policy = new AuthPolicyTO();
policy.setName("Test Authentication policy");
policy.setConf(ruleConf);
policy = createPolicy(PolicyType.AUTH, policy);
assertNotNull(policy);
// 2. create realm with policy assigned
RealmTO realm = new RealmTO();
realm.setName("withAuthPolicy");
Response response = realmService.create(SyncopeConstants.ROOT_REALM, realm);
RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
assertNotNull(actuals);
assertTrue(actuals.length > 0);
realm = actuals[0];
String existingAuthPolicy = realm.getAuthPolicy();
realm.setAuthPolicy(policy.getKey());
realmService.update(realm);
actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
assertNotNull(actuals);
assertTrue(actuals.length > 0);
RealmTO actual = actuals[0];
assertEquals(policy.getKey(), actual.getAuthPolicy());
// 3. remove policy
policyService.delete(PolicyType.AUTH, policy.getKey());
// 4. verify
actual = getRealm(actual.getFullPath()).get();
assertEquals(existingAuthPolicy, actual.getAuthPolicy());
}
@Test
public void deletingAccessPolicy() {
// 1. create access policy
DefaultAccessPolicyConf conf = new DefaultAccessPolicyConf();
conf.getRequiredAttrs().add(new Attr.Builder("cn").values("admin", "Admin", "TheAdmin").build());
AccessPolicyTO policy = new AccessPolicyTO();
policy.setName("Test Access policy");
policy.setConf(conf);
policy = createPolicy(PolicyType.ACCESS, policy);
assertNotNull(policy);
// 2. create realm with policy assigned
RealmTO realm = new RealmTO();
realm.setName("withAccessPolicy");
Response response = realmService.create(SyncopeConstants.ROOT_REALM, realm);
RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
assertNotNull(actuals);
assertTrue(actuals.length > 0);
realm = actuals[0];
String existingAccessPolicy = realm.getAccessPolicy();
realm.setAccessPolicy(policy.getKey());
realmService.update(realm);
actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
assertNotNull(actuals);
assertTrue(actuals.length > 0);
RealmTO actual = actuals[0];
assertEquals(policy.getKey(), actual.getAccessPolicy());
// 3. remove policy
policyService.delete(PolicyType.ACCESS, policy.getKey());
// 4. verify
actual = getRealm(actual.getFullPath()).get();
assertEquals(existingAccessPolicy, actual.getAccessPolicy());
}
@Test
public void deletingAttributeReleasePolicy() {
// 1. create attribute release policy
DefaultAttrReleasePolicyConf conf = new DefaultAttrReleasePolicyConf();
conf.getAllowedAttrs().addAll(List.of("cn", "givenName"));
conf.getIncludeOnlyAttrs().add("cn");
AttrReleasePolicyTO policy = new AttrReleasePolicyTO();
policy.setName("Test Attribute Release policy");
policy.setConf(conf);
policy = createPolicy(PolicyType.ATTR_RELEASE, policy);
assertNotNull(policy);
// 2. create realm with policy assigned
RealmTO realm = new RealmTO();
realm.setName("withAttrReleasePolicy");
Response response = realmService.create(SyncopeConstants.ROOT_REALM, realm);
RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
assertNotNull(actuals);
assertTrue(actuals.length > 0);
realm = actuals[0];
String existingAttrReleasePolicy = realm.getAttrReleasePolicy();
realm.setAttrReleasePolicy(policy.getKey());
realmService.update(realm);
actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
assertNotNull(actuals);
assertTrue(actuals.length > 0);
RealmTO actual = actuals[0];
assertEquals(policy.getKey(), actual.getAttrReleasePolicy());
// 3. remove policy
policyService.delete(PolicyType.ATTR_RELEASE, policy.getKey());
// 4. verify
actual = getRealm(actual.getFullPath()).get();
assertEquals(existingAttrReleasePolicy, actual.getAttrReleasePolicy());
}
@Test
public void delete() {
RealmTO realm = new RealmTO();
realm.setName("deletable3");
Response response = realmService.create("/even/two", realm);
RealmTO[] actuals = getObject(response.getLocation(), RealmService.class, RealmTO[].class);
assertNotNull(actuals);
assertTrue(actuals.length > 0);
RealmTO actual = actuals[0];
realmService.delete(actual.getFullPath());
try {
realmService.list(actual.getFullPath());
fail("This should not happen");
} catch (SyncopeClientException e) {
assertEquals(ClientExceptionType.NotFound, e.getType());
}
}
@Test
public void deleteNonEmpty() {
try {
realmService.delete("/even/two");
fail("This should not happen");
} catch (SyncopeClientException e) {
assertEquals(ClientExceptionType.AssociatedAnys, e.getType());
assertEquals(3, e.getElements().size());
}
}
@Test
public void propagate() {
// 1. create realm and add the LDAP resource
RealmTO realm = new RealmTO();
realm.setName("test");
realm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT);
RealmTO childRealm = new RealmTO();
childRealm.setName("child");
childRealm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT);
RealmTO descendantRealm = new RealmTO();
descendantRealm.setName("test");
descendantRealm.getResources().add(RESOURCE_NAME_LDAP_ORGUNIT);
// 2. check propagation
ProvisioningResult<RealmTO> result = realmService.create("/", realm).readEntity(
new GenericType<>() {
});
assertNotNull(result);
assertEquals(1, result.getPropagationStatuses().size());
assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, result.getPropagationStatuses().get(0).getResource());
assertEquals(ExecStatus.SUCCESS, result.getPropagationStatuses().get(0).getStatus());
ProvisioningResult<RealmTO> resultChild = realmService.create("/test", childRealm).readEntity(
new GenericType<>() {
});
assertNotNull(resultChild);
assertEquals(1, resultChild.getPropagationStatuses().size());
assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, resultChild.getPropagationStatuses().get(0).getResource());
assertEquals(ExecStatus.SUCCESS, resultChild.getPropagationStatuses().get(0).getStatus());
ProvisioningResult<RealmTO> resultDescendant = realmService.create("/test/child", descendantRealm).readEntity(
new GenericType<>() {
});
assertNotNull(resultDescendant);
assertEquals(1, resultDescendant.getPropagationStatuses().size());
assertEquals(RESOURCE_NAME_LDAP_ORGUNIT, resultDescendant.getPropagationStatuses().get(0).getResource());
assertEquals(ExecStatus.SUCCESS, resultDescendant.getPropagationStatuses().get(0).getStatus());
// 3. check on LDAP
assertNotNull(
getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
assertNotNull(
getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
assertNotNull(
getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,ou=child,ou=test,o=isp"));
// 4. remove realms
realmService.delete("/test/child/test");
realmService.delete("/test/child");
realmService.delete("/test");
// 5. check on LDAP: both realms should be deleted
assertNull(
getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,ou=child,ou=test,o=isp"));
assertNull(
getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=child,ou=test,o=isp"));
assertNull(
getLdapRemoteObject(RESOURCE_LDAP_ADMIN_DN, RESOURCE_LDAP_ADMIN_PWD, "ou=test,o=isp"));
}
@Test
public void issueSYNCOPE1472() {
// 1. assign twice resource-ldap-orgunit to /odd
RealmTO realmTO = realmService.list("/odd").get(0);
realmTO.getResources().clear();
realmTO.getResources().add("resource-ldap-orgunit");
realmTO.getResources().add("resource-ldap-orgunit");
realmTO = realmService.update(realmTO).readEntity(new GenericType<ProvisioningResult<RealmTO>>() {
}).getEntity();
// 2. remove resource-ldap-orgunit resource
realmTO.getResources().remove("resource-ldap-orgunit");
realmTO = realmService.update(realmTO).readEntity(new GenericType<ProvisioningResult<RealmTO>>() {
}).getEntity();
assertFalse(realmTO.getResources().contains("resource-ldap-orgunit"), "Should not contain removed resources");
}
}