You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2015/02/12 10:14:11 UTC

[06/54] [abbrv] [partial] syncope git commit: [SYNCOPE-620] Renaming 'server' after 'core', to provide continuity with older releases (especially for archetype)

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
new file mode 100644
index 0000000..4623f25
--- /dev/null
+++ b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/AuthenticationITCase.java
@@ -0,0 +1,440 @@
+/*
+ * 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.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.security.AccessControlException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.core.Response;
+import org.apache.syncope.client.lib.SyncopeClient;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.mod.StatusMod;
+import org.apache.syncope.common.lib.mod.UserMod;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.BulkActionResult;
+import org.apache.syncope.common.lib.to.MembershipTO;
+import org.apache.syncope.common.lib.to.PagedResult;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.to.WorkflowFormPropertyTO;
+import org.apache.syncope.common.lib.to.WorkflowFormTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.wrap.EntitlementTO;
+import org.apache.syncope.common.lib.wrap.ResourceName;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.common.rest.api.service.EntitlementService;
+import org.apache.syncope.common.rest.api.service.SchemaService;
+import org.apache.syncope.common.rest.api.service.UserSelfService;
+import org.apache.syncope.common.rest.api.service.UserService;
+import org.apache.syncope.core.misc.security.Encryptor;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class AuthenticationITCase extends AbstractITCase {
+
+    private int getFailedLogins(UserService testUserService, long userId) {
+        UserTO readUserTO = testUserService.read(userId);
+        assertNotNull(readUserTO);
+        assertNotNull(readUserTO.getFailedLogins());
+        return readUserTO.getFailedLogins();
+    }
+
+    private void assertReadFails(UserService userService, long id) {
+        try {
+            userService.read(id);
+            fail("access should not work");
+        } catch (Exception e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void testAdminEntitlements() {
+        // 1. as anonymous, read all available entitlements
+        List<EntitlementTO> allEntitlements = entitlementService.getAllEntitlements();
+        assertNotNull(allEntitlements);
+        assertFalse(allEntitlements.isEmpty());
+
+        // 2. as admin, read own entitlements
+        List<EntitlementTO> adminEntitlements = entitlementService.getOwnEntitlements();
+
+        assertEquals(new HashSet<String>(CollectionWrapper.unwrap(allEntitlements)),
+                new HashSet<String>(CollectionWrapper.unwrap(adminEntitlements)));
+    }
+
+    @Test
+    public void testUserSchemaAuthorization() {
+        // 0. create a role that can only read schemas
+        RoleTO authRoleTO = new RoleTO();
+        authRoleTO.setName("authRole" + getUUIDString());
+        authRoleTO.setParent(8L);
+        authRoleTO.getEntitlements().add("SCHEMA_READ");
+
+        authRoleTO = createRole(authRoleTO);
+        assertNotNull(authRoleTO);
+
+        String schemaName = "authTestSchema" + getUUIDString();
+
+        // 1. create a schema (as admin)
+        PlainSchemaTO schemaTO = new PlainSchemaTO();
+        schemaTO.setKey(schemaName);
+        schemaTO.setMandatoryCondition("false");
+        schemaTO.setType(AttrSchemaType.String);
+
+        PlainSchemaTO newPlainSchemaTO = createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+        assertEquals(schemaTO, newPlainSchemaTO);
+
+        // 2. create an user with the role created above (as admin)
+        UserTO userTO = UserITCase.getUniqueSampleTO("auth@test.org");
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(authRoleTO.getKey());
+        AttrTO testAttrTO = new AttrTO();
+        testAttrTO.setSchema("testAttribute");
+        testAttrTO.getValues().add("a value");
+        membershipTO.getPlainAttrs().add(testAttrTO);
+        userTO.getMemberships().add(membershipTO);
+
+        userTO = createUser(userTO);
+        assertNotNull(userTO);
+
+        // 3. read the schema created above (as admin) - success
+        schemaTO = schemaService.read(AttributableType.USER, SchemaType.PLAIN, schemaName);
+        assertNotNull(schemaTO);
+
+        // 4. read the schema created above (as user) - success
+        SchemaService schemaService2 = clientFactory.create(userTO.getUsername(), "password123").getService(
+                SchemaService.class);
+
+        schemaTO = schemaService2.read(AttributableType.USER, SchemaType.PLAIN, schemaName);
+        assertNotNull(schemaTO);
+
+        // 5. update the schema create above (as user) - failure
+        try {
+            schemaService2.update(AttributableType.ROLE, SchemaType.PLAIN, schemaName, schemaTO);
+            fail("Schemaupdate as user schould not work");
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+            assertEquals(Response.Status.UNAUTHORIZED, e.getType().getResponseStatus());
+        } catch (AccessControlException e) {
+            // CXF Service will throw this exception
+            assertNotNull(e);
+        }
+
+        assertEquals(0, getFailedLogins(userService, userTO.getKey()));
+    }
+
+    @Test
+    public void testUserRead() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("testuserread@test.org");
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(7L);
+        AttrTO testAttrTO = new AttrTO();
+        testAttrTO.setSchema("testAttribute");
+        testAttrTO.getValues().add("a value");
+        membershipTO.getPlainAttrs().add(testAttrTO);
+        userTO.getMemberships().add(membershipTO);
+
+        userTO = createUser(userTO);
+        assertNotNull(userTO);
+
+        UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
+                getService(UserService.class);
+
+        UserTO readUserTO = userService2.read(1L);
+        assertNotNull(readUserTO);
+
+        UserService userService3 = clientFactory.create("verdi", ADMIN_PWD).getService(UserService.class);
+
+        SyncopeClientException exception = null;
+        try {
+            userService3.read(1L);
+            fail();
+        } catch (SyncopeClientException e) {
+            exception = e;
+        }
+        assertNotNull(exception);
+        assertEquals(ClientExceptionType.UnauthorizedRole, exception.getType());
+    }
+
+    @Test
+    public void testUserSearch() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("testusersearch@test.org");
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(7L);
+        AttrTO testAttrTO = new AttrTO();
+        testAttrTO.setSchema("testAttribute");
+        testAttrTO.getValues().add("a value");
+        membershipTO.getPlainAttrs().add(testAttrTO);
+        userTO.getMemberships().add(membershipTO);
+
+        userTO = createUser(userTO);
+        assertNotNull(userTO);
+
+        UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
+                getService(UserService.class);
+
+        PagedResult<UserTO> matchedUsers = userService2.search(
+                SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query());
+        assertNotNull(matchedUsers);
+        assertFalse(matchedUsers.getResult().isEmpty());
+        Set<Long> userIds = new HashSet<Long>(matchedUsers.getResult().size());
+        for (UserTO user : matchedUsers.getResult()) {
+            userIds.add(user.getKey());
+        }
+        assertTrue(userIds.contains(1L));
+
+        UserService userService3 = clientFactory.create("verdi", "password").getService(UserService.class);
+
+        matchedUsers = userService3.search(
+                SyncopeClient.getUserSearchConditionBuilder().isNotNull("loginDate").query());
+        assertNotNull(matchedUsers);
+
+        userIds = new HashSet<>(matchedUsers.getResult().size());
+
+        for (UserTO user : matchedUsers.getResult()) {
+            userIds.add(user.getKey());
+        }
+        assertFalse(userIds.contains(1L));
+    }
+
+    @Test
+    public void checkFailedLogins() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("checkFailedLogin@syncope.apache.org");
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(7L);
+        AttrTO testAttrTO = new AttrTO();
+        testAttrTO.setSchema("testAttribute");
+        testAttrTO.getValues().add("a value");
+        membershipTO.getPlainAttrs().add(testAttrTO);
+        userTO.getMemberships().add(membershipTO);
+
+        userTO = createUser(userTO);
+        assertNotNull(userTO);
+        long userId = userTO.getKey();
+
+        UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").getService(
+                UserService.class);
+        assertEquals(0, getFailedLogins(userService2, userId));
+
+        // authentications failed ...
+        UserService userService3 = clientFactory.create(userTO.getUsername(), "wrongpwd1").getService(
+                UserService.class);
+        assertReadFails(userService3, userId);
+        assertReadFails(userService3, userId);
+
+        assertEquals(2, getFailedLogins(userService, userId));
+
+        UserService userService4 = clientFactory.create(userTO.getUsername(), "password123").getService(
+                UserService.class);
+        assertEquals(0, getFailedLogins(userService4, userId));
+    }
+
+    @Test
+    public void checkUserSuspension() {
+        UserTO userTO = UserITCase.getUniqueSampleTO("checkSuspension@syncope.apache.org");
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(7L);
+        AttrTO testAttrTO = new AttrTO();
+        testAttrTO.setSchema("testAttribute");
+        testAttrTO.getValues().add("a value");
+        membershipTO.getPlainAttrs().add(testAttrTO);
+        userTO.getMemberships().add(membershipTO);
+
+        userTO = createUser(userTO);
+        long userId = userTO.getKey();
+        assertNotNull(userTO);
+
+        UserService userService2 = clientFactory.create(userTO.getUsername(), "password123").
+                getService(UserService.class);
+        assertEquals(0, getFailedLogins(userService2, userId));
+
+        // authentications failed ...
+        UserService userService3 = clientFactory.create(userTO.getUsername(), "wrongpwd1").
+                getService(UserService.class);
+        assertReadFails(userService3, userId);
+        assertReadFails(userService3, userId);
+        assertReadFails(userService3, userId);
+
+        assertEquals(3, getFailedLogins(userService, userId));
+
+        // last authentication before suspension
+        assertReadFails(userService3, userId);
+
+        userTO = userService.read(userTO.getKey());
+        assertNotNull(userTO);
+        assertNotNull(userTO.getFailedLogins());
+        assertEquals(3, userTO.getFailedLogins(), 0);
+        assertEquals("suspended", userTO.getStatus());
+
+        // Access with correct credentials should fail as user is suspended
+        userService2 = clientFactory.create(userTO.getUsername(), "password123").getService(UserService.class);
+        assertReadFails(userService2, userId);
+
+        StatusMod reactivate = new StatusMod();
+        reactivate.setType(StatusMod.ModType.REACTIVATE);
+        userTO = userService.status(userTO.getKey(), reactivate).readEntity(UserTO.class);
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+
+        userService2 = clientFactory.create(userTO.getUsername(), "password123").getService(UserService.class);
+        assertEquals(0, getFailedLogins(userService2, userId));
+    }
+
+    @Test
+    public void issueSYNCOPE48() {
+        // Parent role, able to create users with role 1
+        RoleTO parentRole = new RoleTO();
+        parentRole.setName("parentAdminRole" + getUUIDString());
+        parentRole.getEntitlements().add("USER_CREATE");
+        parentRole.getEntitlements().add("ROLE_1");
+        parentRole.setParent(1L);
+        parentRole = createRole(parentRole);
+        assertNotNull(parentRole);
+
+        // Child role, with no entitlements
+        RoleTO childRole = new RoleTO();
+        childRole.setName("childAdminRole");
+        childRole.setParent(parentRole.getKey());
+
+        childRole = createRole(childRole);
+        assertNotNull(childRole);
+
+        // User with child role, created by admin
+        UserTO role1Admin = UserITCase.getUniqueSampleTO("syncope48admin@apache.org");
+        role1Admin.setPassword("password");
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(childRole.getKey());
+        role1Admin.getMemberships().add(membershipTO);
+
+        role1Admin = createUser(role1Admin);
+        assertNotNull(role1Admin);
+
+        UserService userService2 = clientFactory.create(role1Admin.getUsername(), "password").getService(
+                UserService.class);
+
+        // User with role 1, created by user with child role created above
+        UserTO role1User = UserITCase.getUniqueSampleTO("syncope48user@apache.org");
+        membershipTO = new MembershipTO();
+        membershipTO.setRoleId(1L);
+        role1User.getMemberships().add(membershipTO);
+
+        Response response = userService2.create(role1User, true);
+        assertNotNull(response);
+        role1User = response.readEntity(UserTO.class);
+        assertNotNull(role1User);
+    }
+
+    @Test
+    public void issueSYNCOPE434() {
+        Assume.assumeTrue(ActivitiDetector.isActivitiEnabledForUsers(syncopeService));
+
+        // 1. create user with role 9 (users with role 9 are defined in workflow as subject to approval)
+        UserTO userTO = UserITCase.getUniqueSampleTO("createWithReject@syncope.apache.org");
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(9L);
+        userTO.getMemberships().add(membershipTO);
+
+        userTO = createUser(userTO);
+        assertNotNull(userTO);
+        assertEquals("createApproval", userTO.getStatus());
+
+        // 2. try to authenticate: fail
+        EntitlementService myEntitlementService = clientFactory.create(userTO.getUsername(), "password123").
+                getService(EntitlementService.class);
+        try {
+            myEntitlementService.getOwnEntitlements();
+            fail();
+        } catch (AccessControlException e) {
+            assertNotNull(e);
+        }
+
+        // 3. approve user
+        WorkflowFormTO form = userWorkflowService.getFormForUser(userTO.getKey());
+        form = userWorkflowService.claimForm(form.getTaskId());
+        Map<String, WorkflowFormPropertyTO> props = form.getPropertyMap();
+        props.get("approve").setValue(Boolean.TRUE.toString());
+        form.getProperties().clear();
+        form.getProperties().addAll(props.values());
+        userTO = userWorkflowService.submitForm(form);
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+
+        // 4. try to authenticate again: success
+        assertNotNull(myEntitlementService.getOwnEntitlements());
+    }
+
+    @Test
+    public void issueSYNCOPE164() throws Exception {
+        // 1. create user with db resource
+        UserTO user = UserITCase.getUniqueSampleTO("syncope164@syncope.apache.org");
+        user.setPassword("password1");
+        user.getResources().add(RESOURCE_NAME_TESTDB);
+        user = createUser(user);
+        assertNotNull(user);
+
+        // 2. unlink the resource from the created user
+        assertNotNull(userService.bulkDeassociation(user.getKey(),
+                ResourceDeassociationActionType.UNLINK,
+                CollectionWrapper.wrap(RESOURCE_NAME_TESTDB, ResourceName.class)).
+                readEntity(BulkActionResult.class));
+
+        // 3. change password on Syncope
+        UserMod userMod = new UserMod();
+        userMod.setKey(user.getKey());
+        userMod.setPassword("password2");
+        user = updateUser(userMod);
+        assertNotNull(user);
+
+        // 4. check that the db resource has still the initial password value
+        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        String value = jdbcTemplate.queryForObject(
+                "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
+        assertEquals(Encryptor.getInstance().encode("password1", CipherAlgorithm.SHA1), value.toUpperCase());
+
+        // 5. successfully authenticate with old (on db resource) and new (on internal storage) password values
+        user = clientFactory.create(user.getUsername(), "password1").getService(UserSelfService.class).read();
+        assertNotNull(user);
+        user = clientFactory.create(user.getUsername(), "password2").getService(UserSelfService.class).read();
+        assertNotNull(user);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java
new file mode 100644
index 0000000..47cad19
--- /dev/null
+++ b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelDetector.java
@@ -0,0 +1,32 @@
+/*
+ * 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.reference;
+
+import org.apache.syncope.common.rest.api.service.SyncopeService;
+
+public class CamelDetector {
+
+    public static boolean isCamelEnabledForUsers(final SyncopeService syncopeService) {
+        return syncopeService.info().getUserProvisioningManager().indexOf("Camel") != -1;
+    }
+
+    public static boolean isCamelEnabledForRoles(final SyncopeService syncopeService) {
+        return syncopeService.info().getRoleProvisioningManager().indexOf("Camel") != -1;
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
new file mode 100644
index 0000000..1b3e91d
--- /dev/null
+++ b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/CamelRouteITCase.java
@@ -0,0 +1,163 @@
+/*
+ * 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.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.List;
+import org.apache.syncope.common.lib.to.CamelRouteTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.apache.syncope.common.lib.types.SubjectType;
+import org.junit.Assume;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class CamelRouteITCase extends AbstractITCase {
+
+    @Test
+    public void userRoutes() {
+        Assume.assumeTrue(CamelDetector.isCamelEnabledForUsers(syncopeService));
+
+        List<CamelRouteTO> userRoutes = camelRouteService.list(SubjectType.USER);
+        assertNotNull(userRoutes);
+        assertEquals(15, userRoutes.size());
+        for (CamelRouteTO route : userRoutes) {
+            assertNotNull(route.getContent());
+        }
+    }
+
+    @Test
+    public void roleRoutes() {
+        Assume.assumeTrue(CamelDetector.isCamelEnabledForRoles(syncopeService));
+
+        List<CamelRouteTO> roleRoutes = camelRouteService.list(SubjectType.ROLE);
+        assertNotNull(roleRoutes);
+        assertEquals(7, roleRoutes.size());
+        for (CamelRouteTO route : roleRoutes) {
+            assertNotNull(route.getContent());
+        }
+    }
+
+    private CamelRouteTO doUpdate(final String key, String content) {
+        CamelRouteTO route = camelRouteService.read(key);
+        route.setContent(content);
+        camelRouteService.update(route.getKey(), route);
+        //getting new route definition
+        return camelRouteService.read(key);
+    }
+
+    @Test
+    public void update() {
+        Assume.assumeTrue(CamelDetector.isCamelEnabledForUsers(syncopeService));
+
+        CamelRouteTO oldRoute = camelRouteService.read("createUser");
+        assertNotNull(oldRoute);
+        String routeContent = "<route id=\"createUser\">\n"
+                + "  <from uri=\"direct:createUser\"/>\n"
+                + "  <setProperty propertyName=\"actual\">\n"
+                + "    <simple>${body}</simple>\n"
+                + "  </setProperty>\n"
+                + "  <doTry>\n"
+                + "    <bean ref=\"uwfAdapter\" method=\"create(${body},${property.disablePwdPolicyCheck},\n"
+                + "                             ${property.enabled},${property.storePassword})\"/>\n"
+                + "    <process ref=\"userCreateProcessor\" />\n"
+                + "    <to uri=\"direct:createPort\"/>\n"
+                + "    <to uri=\"log:myLog\"/>\n"
+                + "    <doCatch>        \n"
+                + "      <exception>java.lang.RuntimeException</exception>\n"
+                + "      <handled>\n"
+                + "        <constant>false</constant>\n"
+                + "      </handled>\n"
+                + "      <to uri=\"direct:createPort\"/>\n"
+                + "    </doCatch>\n"
+                + "  </doTry>\n"
+                + "</route>";
+        try {
+            CamelRouteTO route = doUpdate("createUser", routeContent);
+            assertEquals(routeContent, route.getContent());
+        } finally {
+            doUpdate(oldRoute.getKey(), oldRoute.getContent());
+        }
+    }
+
+    @Test
+    public void scriptingUpdate() {
+        Assume.assumeTrue(CamelDetector.isCamelEnabledForUsers(syncopeService));
+
+        CamelRouteTO oldRoute = camelRouteService.read("createUser");
+        //updating route content including new attribute management
+        String routeContent = "<route id=\"createUser\">\n"
+                + "  <from uri=\"direct:createUser\"/>\n"
+                + "  <setProperty propertyName=\"actual\">\n"
+                + "    <simple>${body}</simple>\n"
+                + "  </setProperty>\n"
+                + "  <setBody>\n"
+                + "   <groovy>\n"
+                + "       request.body.getPlainAttrs().get(3).getValues().set(0,\"true\")\n"
+                + "       return request.body\n"
+                + "   </groovy>\n"
+                + "  </setBody>\n"
+                + "  <doTry>\n"
+                + "      <bean ref=\"uwfAdapter\" method=\"create(${body},${property.disablePwdPolicyCheck},\n"
+                + "                            ${property.enabled},${property.storePassword})\"/>\n"
+                + "      <process ref=\"userCreateProcessor\" />\n"
+                + "      <to uri=\"direct:createPort\"/>\n"
+                + "      <doCatch>        \n"
+                + "      <exception>java.lang.RuntimeException</exception>\n"
+                + "          <handled>\n"
+                + "           <constant>false</constant>\n"
+                + "          </handled>\n"
+                + "      <to uri=\"direct:createPort\"/>\n"
+                + "      </doCatch>\n"
+                + "   </doTry>\n"
+                + "</route>";
+        try {
+            doUpdate("createUser", routeContent);
+
+            //creating new schema attribute for user
+            PlainSchemaTO schemaTO = new PlainSchemaTO();
+            schemaTO.setKey("camelAttribute");
+            schemaTO.setType(AttrSchemaType.String);
+            createSchema(AttributableType.USER, SchemaType.PLAIN, schemaTO);
+
+            UserTO userTO = new UserTO();
+            String userId = getUUIDString() + "camelUser@syncope.apache.org";
+            userTO.setUsername(userId);
+            userTO.setPassword("password");
+            userTO.getPlainAttrs().add(attrTO("userId", userId));
+            userTO.getPlainAttrs().add(attrTO("fullname", userId));
+            userTO.getPlainAttrs().add(attrTO("surname", userId));
+            userTO.getPlainAttrs().add(attrTO("camelAttribute", "false"));
+
+            userTO = createUser(userTO);
+            assertNotNull(userTO);
+            assertEquals("true", userTO.getPlainAttrs().get(3).getValues().get(0));
+        } finally {
+            doUpdate(oldRoute.getKey(), oldRoute.getContent());
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java
new file mode 100644
index 0000000..27fb19b
--- /dev/null
+++ b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConfigurationITCase.java
@@ -0,0 +1,245 @@
+/*
+ * 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.reference;
+
+import static org.apache.commons.lang3.StringUtils.isEmpty;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.SyncopeConstants;
+import org.apache.syncope.common.lib.to.AttrTO;
+import org.apache.syncope.common.lib.to.ConfTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.RoleTO;
+import org.apache.syncope.common.lib.types.AttrSchemaType;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ConfigurationITCase extends AbstractITCase {
+
+    @Test
+    public void create() {
+        PlainSchemaTO testKey = new PlainSchemaTO();
+        testKey.setKey("testKey");
+        testKey.setType(AttrSchemaType.String);
+        createSchema(AttributableType.CONFIGURATION, SchemaType.PLAIN, testKey);
+
+        AttrTO conf = new AttrTO();
+        conf.setSchema("testKey");
+        conf.getValues().add("testValue");
+
+        configurationService.set(conf.getSchema(), conf);
+
+        AttrTO actual = configurationService.read(conf.getSchema());
+        assertEquals(actual, conf);
+    }
+
+    @Test
+    public void delete() throws UnsupportedEncodingException {
+        try {
+            configurationService.delete("nonExistent");
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+
+        AttrTO tokenLength = configurationService.read("token.length");
+
+        configurationService.delete("token.length");
+        try {
+            configurationService.read("token.length");
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+
+        configurationService.set(tokenLength.getSchema(), tokenLength);
+
+        AttrTO actual = configurationService.read(tokenLength.getSchema());
+        assertEquals(actual, tokenLength);
+    }
+
+    @Test
+    public void list() {
+        ConfTO wholeConf = configurationService.list();
+        assertNotNull(wholeConf);
+        for (AttrTO conf : wholeConf.getPlainAttrs()) {
+            assertNotNull(conf);
+        }
+    }
+
+    @Test
+    public void read() {
+        AttrTO conf = configurationService.read("token.expireTime");
+        assertNotNull(conf);
+    }
+
+    @Test
+    public void update() {
+        AttrTO expireTime = configurationService.read("token.expireTime");
+        int value = Integer.parseInt(expireTime.getValues().get(0));
+        value++;
+        expireTime.getValues().set(0, value + "");
+
+        configurationService.set(expireTime.getSchema(), expireTime);
+
+        AttrTO newConfigurationTO = configurationService.read(expireTime.getSchema());
+        assertEquals(expireTime, newConfigurationTO);
+    }
+
+    @Test
+    public void dbExport() throws IOException {
+        Response response = configurationService.export();
+        assertNotNull(response);
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+        assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML));
+        String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+        assertNotNull(contentDisposition);
+
+        Object entity = response.getEntity();
+        assertTrue(entity instanceof InputStream);
+        String configExport = IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING);
+        assertFalse(configExport.isEmpty());
+        assertTrue(configExport.length() > 1000);
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        PlainSchemaTO failing = new PlainSchemaTO();
+        failing.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+        failing.setType(AttrSchemaType.String);
+
+        try {
+            createSchema(AttributableType.CONFIGURATION, SchemaType.PLAIN, failing);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidPlainSchema, e.getType());
+
+            assertNotNull(e.getElements());
+            assertEquals(1, e.getElements().size());
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+
+    private static String[] substringsBetween(final String str, final String open, final String close) {
+        if (str == null || isEmpty(open) || isEmpty(close)) {
+            return null;
+        }
+        final int strLen = str.length();
+        if (strLen == 0) {
+            return ArrayUtils.EMPTY_STRING_ARRAY;
+        }
+        final int closeLen = close.length();
+        final int openLen = open.length();
+        final List<String> list = new ArrayList<>();
+        int pos = 0;
+        while (pos < strLen - closeLen) {
+            int start = StringUtils.indexOfIgnoreCase(str, open, pos);
+            if (start < 0) {
+                break;
+            }
+            start += openLen;
+            final int end = StringUtils.indexOfIgnoreCase(str, close, start);
+            if (end < 0) {
+                break;
+            }
+            list.add(str.substring(start, end));
+            pos = end + closeLen;
+        }
+        if (list.isEmpty()) {
+            return null;
+        }
+        return list.toArray(new String[list.size()]);
+    }
+
+    @Test
+    public void issueSYNCOPE629() throws IOException {
+        PlainSchemaTO membershipKey = new PlainSchemaTO();
+        membershipKey.setKey("membershipKey" + getUUIDString());
+        membershipKey.setType(AttrSchemaType.String);
+        createSchema(AttributableType.MEMBERSHIP, SchemaType.PLAIN, membershipKey);
+
+        PlainSchemaTO roleKey = new PlainSchemaTO();
+        roleKey.setKey("roleKey" + getUUIDString());
+        roleKey.setType(AttrSchemaType.String);
+        createSchema(AttributableType.ROLE, SchemaType.PLAIN, roleKey);
+
+        RoleTO roleTO = new RoleTO();
+        roleTO.setName("aRole" + getUUIDString());
+        roleTO.getMPlainAttrTemplates().add(membershipKey.getKey());
+        roleTO.getRPlainAttrTemplates().add(roleKey.getKey());
+        roleTO = createRole(roleTO);
+
+        try {
+            Response response = configurationService.export();
+            assertNotNull(response);
+            assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+            assertTrue(response.getMediaType().toString().startsWith(MediaType.TEXT_XML));
+            String contentDisposition = response.getHeaderString(HttpHeaders.CONTENT_DISPOSITION);
+            assertNotNull(contentDisposition);
+
+            Object entity = response.getEntity();
+            assertTrue(entity instanceof InputStream);
+            String configExport = IOUtils.toString((InputStream) entity, SyncopeConstants.DEFAULT_ENCODING);
+            assertFalse(configExport.isEmpty());
+            assertTrue(configExport.length() > 1000);
+
+            String[] result = substringsBetween(configExport, "<RPLAINATTRTEMPLATE", "/>");
+            assertNotNull(result);
+            boolean rattrExists = false;
+            for (String entry : result) {
+                if (entry.contains(roleKey.getKey())) {
+                    rattrExists = true;
+                }
+            }
+            assertTrue(rattrExists);
+
+            result = substringsBetween(configExport, "<MPLAINATTRTEMPLATE", "/>");
+            assertNotNull(result);
+            boolean mattrExists = false;
+            for (String entry : result) {
+                if (entry.contains(membershipKey.getKey())) {
+                    mattrExists = true;
+                }
+            }
+            assertTrue(mattrExists);
+        } finally {
+            deleteRole(roleTO.getKey());
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
new file mode 100644
index 0000000..de54fd5
--- /dev/null
+++ b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/ConnectorITCase.java
@@ -0,0 +1,730 @@
+/*
+ * 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.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import javax.ws.rs.core.Response;
+import org.apache.commons.io.IOUtils;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.BulkAction;
+import org.apache.syncope.common.lib.to.ConnBundleTO;
+import org.apache.syncope.common.lib.to.ConnIdObjectClassTO;
+import org.apache.syncope.common.lib.to.ConnInstanceTO;
+import org.apache.syncope.common.lib.to.ConnPoolConfTO;
+import org.apache.syncope.common.lib.to.MappingItemTO;
+import org.apache.syncope.common.lib.to.MappingTO;
+import org.apache.syncope.common.lib.to.PlainSchemaTO;
+import org.apache.syncope.common.lib.to.ResourceTO;
+import org.apache.syncope.common.lib.types.ConnConfPropSchema;
+import org.apache.syncope.common.lib.types.ConnConfProperty;
+import org.apache.syncope.common.lib.types.ConnectorCapability;
+import org.apache.syncope.common.lib.types.IntMappingType;
+import org.apache.syncope.common.rest.api.service.ConnectorService;
+import org.apache.syncope.common.rest.api.service.ResourceService;
+import org.identityconnectors.common.security.GuardedString;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class ConnectorITCase extends AbstractITCase {
+
+    private static String connectorServerLocation;
+
+    private static String connidSoapVersion;
+
+    private static String connidDbTableVersion;
+
+    private static String testJDBCURL;
+
+    @BeforeClass
+    public static void setUpConnIdBundles() throws IOException {
+        InputStream propStream = null;
+        try {
+            Properties props = new Properties();
+            propStream = ConnectorITCase.class.getResourceAsStream("/connid.properties");
+            props.load(propStream);
+
+            for (String location : props.getProperty("connid.locations").split(",")) {
+                if (!location.startsWith("file")) {
+                    connectorServerLocation = location;
+                }
+            }
+
+            connidSoapVersion = props.getProperty("connid.soap.version");
+            connidDbTableVersion = props.getProperty("connid.db.table.version");
+
+            testJDBCURL = props.getProperty("testdb.url");
+        } catch (Exception e) {
+            LOG.error("Could not load /connid.properties", e);
+        } finally {
+            IOUtils.closeQuietly(propStream);
+        }
+        assertNotNull(connectorServerLocation);
+        assertNotNull(connidSoapVersion);
+        assertNotNull(connidDbTableVersion);
+        assertNotNull(testJDBCURL);
+    }
+
+    @Test(expected = SyncopeClientException.class)
+    public void createWithException() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+        Response response = connectorService.create(connectorTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+        }
+    }
+
+    @Test
+    public void create() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+        connectorTO.setLocation(connectorService.read(100L).getLocation());
+        connectorTO.setVersion(connidSoapVersion);
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+        connectorTO.setDisplayName("Display name");
+        connectorTO.setConnRequestTimeout(15);
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<>();
+
+        ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
+        endpointSchema.setName("endpoint");
+        endpointSchema.setType(String.class.getName());
+        endpointSchema.setRequired(true);
+        ConnConfProperty endpoint = new ConnConfProperty();
+        endpoint.setSchema(endpointSchema);
+        endpoint.getValues().add("http://localhost:8888/wssample/services");
+        endpoint.getValues().add("Provisioning");
+        conf.add(endpoint);
+
+        ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
+        servicenameSchema.setName("servicename");
+        servicenameSchema.setType(String.class.getName());
+        servicenameSchema.setRequired(true);
+        ConnConfProperty servicename = new ConnConfProperty();
+        servicename.setSchema(servicenameSchema);
+        conf.add(servicename);
+
+        // set connector configuration
+        connectorTO.getConfiguration().addAll(conf);
+
+        // set connector capabilities
+        connectorTO.getCapabilities().add(ConnectorCapability.TWO_PHASES_CREATE);
+        connectorTO.getCapabilities().add(ConnectorCapability.ONE_PHASE_CREATE);
+        connectorTO.getCapabilities().add(ConnectorCapability.TWO_PHASES_UPDATE);
+
+        // set connector pool conf
+        ConnPoolConfTO cpc = new ConnPoolConfTO();
+        cpc.setMaxObjects(1534);
+        connectorTO.setPoolConf(cpc);
+
+        Response response = connectorService.create(connectorTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+        }
+
+        ConnInstanceTO actual = getObject(
+                response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+        assertNotNull(actual);
+
+        assertEquals(actual.getBundleName(), connectorTO.getBundleName());
+        assertEquals(actual.getConnectorName(), connectorTO.getConnectorName());
+        assertEquals(actual.getVersion(), connectorTO.getVersion());
+        assertEquals("Display name", actual.getDisplayName());
+        assertEquals(Integer.valueOf(15), actual.getConnRequestTimeout());
+        assertEquals(connectorTO.getCapabilities(), actual.getCapabilities());
+        assertNotNull(actual.getPoolConf());
+        assertEquals(1534, actual.getPoolConf().getMaxObjects().intValue());
+        assertEquals(10, actual.getPoolConf().getMaxIdle().intValue());
+
+        Throwable t = null;
+
+        // check update
+        actual.getCapabilities().remove(ConnectorCapability.TWO_PHASES_UPDATE);
+        actual.getPoolConf().setMaxObjects(null);
+
+        try {
+            connectorService.update(actual.getKey(), actual);
+            actual = connectorService.read(actual.getKey());
+        } catch (SyncopeClientException e) {
+            LOG.error("update failed", e);
+            t = e;
+        }
+
+        assertNull(t);
+        assertNotNull(actual);
+        assertEquals(EnumSet.of(ConnectorCapability.ONE_PHASE_CREATE, ConnectorCapability.TWO_PHASES_CREATE),
+                actual.getCapabilities());
+        assertEquals(10, actual.getPoolConf().getMaxObjects().intValue());
+
+        // check also for the deletion of the created object
+        try {
+            connectorService.delete(actual.getKey());
+        } catch (SyncopeClientException e) {
+            LOG.error("delete failed", e);
+            t = e;
+        }
+
+        assertNull(t);
+
+        // check the non existence
+        try {
+            connectorService.read(actual.getKey());
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void update() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+        // set connector instance id
+        connectorTO.setKey(103L);
+
+        // set connector version
+        connectorTO.setVersion(connidSoapVersion);
+
+        // set connector name
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+
+        // set bundle name
+        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+
+        connectorTO.setConnRequestTimeout(20);
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+
+        ConnConfPropSchema endpointSchema = new ConnConfPropSchema();
+        endpointSchema.setName("endpoint");
+        endpointSchema.setType(String.class.getName());
+        endpointSchema.setRequired(true);
+        ConnConfProperty endpoint = new ConnConfProperty();
+        endpoint.setSchema(endpointSchema);
+        endpoint.getValues().add("http://localhost:8888/wssample/services");
+        conf.add(endpoint);
+
+        ConnConfPropSchema servicenameSchema = new ConnConfPropSchema();
+        servicenameSchema.setName("servicename");
+        servicenameSchema.setType(String.class.getName());
+        servicenameSchema.setRequired(true);
+        ConnConfProperty servicename = new ConnConfProperty();
+        servicename.setSchema(servicenameSchema);
+        servicename.getValues().add("Provisioning");
+        conf.add(servicename);
+
+        // set connector configuration
+        connectorTO.getConfiguration().addAll(conf);
+
+        connectorService.update(connectorTO.getKey(), connectorTO);
+        ConnInstanceTO actual = connectorService.read(connectorTO.getKey());
+
+        assertNotNull(actual);
+
+        actual = connectorService.read(actual.getKey());
+
+        assertNotNull(actual);
+        assertEquals(actual.getBundleName(), connectorTO.getBundleName());
+        assertEquals(actual.getConnectorName(), connectorTO.getConnectorName());
+        assertEquals(actual.getVersion(), connectorTO.getVersion());
+        assertEquals(Integer.valueOf(20), actual.getConnRequestTimeout());
+    }
+
+    private List<ResourceTO> filter(final List<ResourceTO> input, final Long connectorKey) {
+        List<ResourceTO> result = new ArrayList<>();
+
+        for (ResourceTO resource : input) {
+            if (connectorKey.equals(resource.getConnectorId())) {
+                result.add(resource);
+            }
+        }
+
+        return result;
+    }
+
+    @Test
+    public void issueSYNCOPE10() {
+        // ----------------------------------
+        // Copy resource and connector in order to create new objects.
+        // ----------------------------------
+        // Retrieve a connector instance template.
+        ConnInstanceTO connInstanceTO = connectorService.read(103L);
+        assertNotNull(connInstanceTO);
+
+        // check for resource
+        List<ResourceTO> resources = filter(resourceService.list(), 103L);
+        assertEquals(4, resources.size());
+
+        // Retrieve a resource TO template.
+        ResourceTO resourceTO = resources.get(0);
+
+        // Make it new.
+        resourceTO.setKey("newAbout103");
+
+        // Make it new.
+        connInstanceTO.setKey(0);
+        connInstanceTO.setDisplayName("newDisplayName" + getUUIDString());
+        // ----------------------------------
+
+        // ----------------------------------
+        // Create a new connector instance.
+        // ----------------------------------
+        Response response = connectorService.create(connInstanceTO);
+        if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+            throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+        }
+
+        connInstanceTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+        assertNotNull(connInstanceTO);
+        assertFalse(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+
+        long connId = connInstanceTO.getKey();
+
+        // Link resourceTO to the new connector instance.
+        resourceTO.setConnectorId(connId);
+        // ----------------------------------
+
+        // ----------------------------------
+        // Check for connector instance update after resource creation.
+        // ----------------------------------
+        response = resourceService.create(resourceTO);
+        resourceTO = getObject(response.getLocation(), ResourceService.class, ResourceTO.class);
+
+        assertNotNull(resourceTO);
+
+        resources = filter(resourceService.list(), connId);
+        assertEquals(1, resources.size());
+        // ----------------------------------
+
+        // ----------------------------------
+        // Check for spring bean.
+        // ----------------------------------
+        ConnInstanceTO connInstanceBean = connectorService.readByResource(resourceTO.getKey());
+        assertNotNull(connInstanceBean);
+        assertFalse(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+        // ----------------------------------
+
+        // ----------------------------------
+        // Check for spring bean update after connector instance update.
+        // ----------------------------------
+        connInstanceTO.getCapabilities().add(ConnectorCapability.AUTHENTICATE);
+
+        connectorService.update(connInstanceTO.getKey(), connInstanceTO);
+        ConnInstanceTO actual = connectorService.read(connInstanceTO.getKey());
+        assertNotNull(actual);
+        assertTrue(connInstanceTO.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+
+        // check for spring bean update
+        connInstanceBean = connectorService.readByResource(resourceTO.getKey());
+        assertTrue(connInstanceBean.getCapabilities().contains(ConnectorCapability.AUTHENTICATE));
+        // ----------------------------------
+    }
+
+    @Test
+    public void deleteWithException() {
+        try {
+            connectorService.delete(0L);
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.NOT_FOUND, e.getType().getResponseStatus());
+        }
+    }
+
+    @Test
+    public void list() {
+        List<ConnInstanceTO> connectorInstanceTOs = connectorService.list(null);
+        assertNotNull(connectorInstanceTOs);
+        assertFalse(connectorInstanceTOs.isEmpty());
+        for (ConnInstanceTO instance : connectorInstanceTOs) {
+            assertNotNull(instance);
+        }
+    }
+
+    @Test
+    public void read() {
+        ConnInstanceTO connectorInstanceTO = connectorService.read(100L);
+        assertNotNull(connectorInstanceTO);
+    }
+
+    @Test
+    public void getBundles() {
+        List<ConnBundleTO> bundles = connectorService.getBundles(null);
+        assertNotNull(bundles);
+        assertFalse(bundles.isEmpty());
+        for (ConnBundleTO bundle : bundles) {
+            assertNotNull(bundle);
+        }
+    }
+
+    @Test
+    public void getConnectorConfiguration() {
+        List<ConnConfProperty> props = connectorService.getConfigurationProperties(104L);
+        assertNotNull(props);
+        assertFalse(props.isEmpty());
+    }
+
+    @Test
+    public void checkHiddenProperty() {
+        ConnInstanceTO connInstanceTO = connectorService.read(100L);
+
+        boolean check = false;
+
+        for (ConnConfProperty prop : connInstanceTO.getConfiguration()) {
+            if ("receiveTimeout".equals(prop.getSchema().getName())) {
+                check = true;
+            }
+        }
+        assertTrue(check);
+    }
+
+    @Test
+    public void checkSelectedLanguage() {
+        // 1. Check Italian
+        List<ConnInstanceTO> connectorInstanceTOs = connectorService.list("it");
+
+        Map<String, ConnConfProperty> instanceConfMap;
+        for (ConnInstanceTO instance : connectorInstanceTOs) {
+            if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
+                instanceConfMap = instance.getConfigurationMap();
+                assertEquals("Utente", instanceConfMap.get("user").getSchema().getDisplayName());
+            }
+        }
+
+        // 2. Check English (default)
+        connectorInstanceTOs = connectorService.list(null);
+
+        for (ConnInstanceTO instance : connectorInstanceTOs) {
+            if ("net.tirasa.connid.bundles.db.table".equals(instance.getBundleName())) {
+                instanceConfMap = instance.getConfigurationMap();
+                assertEquals("User", instanceConfMap.get("user").getSchema().getDisplayName());
+            }
+        }
+    }
+
+    @Test
+    public void validate() {
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+        connectorTO.setLocation(connectorServerLocation);
+        connectorTO.setVersion(connidDbTableVersion);
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.db.table.DatabaseTableConnector");
+        connectorTO.setBundleName("net.tirasa.connid.bundles.db.table");
+        connectorTO.setDisplayName("H2Test");
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+
+        ConnConfPropSchema jdbcDriverSchema = new ConnConfPropSchema();
+        jdbcDriverSchema.setName("jdbcDriver");
+        jdbcDriverSchema.setType(String.class.getName());
+        jdbcDriverSchema.setRequired(true);
+        ConnConfProperty jdbcDriver = new ConnConfProperty();
+        jdbcDriver.setSchema(jdbcDriverSchema);
+        jdbcDriver.getValues().add("org.h2.Driver");
+        conf.add(jdbcDriver);
+
+        ConnConfPropSchema jdbcUrlTemplateSchema = new ConnConfPropSchema();
+        jdbcUrlTemplateSchema.setName("jdbcUrlTemplate");
+        jdbcUrlTemplateSchema.setType(String.class.getName());
+        jdbcUrlTemplateSchema.setRequired(true);
+        ConnConfProperty jdbcUrlTemplate = new ConnConfProperty();
+        jdbcUrlTemplate.setSchema(jdbcUrlTemplateSchema);
+        jdbcUrlTemplate.getValues().add(testJDBCURL);
+        conf.add(jdbcUrlTemplate);
+
+        ConnConfPropSchema userSchema = new ConnConfPropSchema();
+        userSchema.setName("user");
+        userSchema.setType(String.class.getName());
+        userSchema.setRequired(false);
+        ConnConfProperty user = new ConnConfProperty();
+        user.setSchema(userSchema);
+        user.getValues().add("sa");
+        conf.add(user);
+
+        ConnConfPropSchema passwordSchema = new ConnConfPropSchema();
+        passwordSchema.setName("password");
+        passwordSchema.setType(GuardedString.class.getName());
+        passwordSchema.setRequired(true);
+        ConnConfProperty password = new ConnConfProperty();
+        password.setSchema(passwordSchema);
+        password.getValues().add("sa");
+        conf.add(password);
+
+        ConnConfPropSchema tableSchema = new ConnConfPropSchema();
+        tableSchema.setName("table");
+        tableSchema.setType(String.class.getName());
+        tableSchema.setRequired(true);
+        ConnConfProperty table = new ConnConfProperty();
+        table.setSchema(tableSchema);
+        table.getValues().add("test");
+        conf.add(table);
+
+        ConnConfPropSchema keyColumnSchema = new ConnConfPropSchema();
+        keyColumnSchema.setName("keyColumn");
+        keyColumnSchema.setType(String.class.getName());
+        keyColumnSchema.setRequired(true);
+        ConnConfProperty keyColumn = new ConnConfProperty();
+        keyColumn.setSchema(keyColumnSchema);
+        keyColumn.getValues().add("id");
+        conf.add(keyColumn);
+
+        ConnConfPropSchema passwordColumnSchema = new ConnConfPropSchema();
+        passwordColumnSchema.setName("passwordColumn");
+        passwordColumnSchema.setType(String.class.getName());
+        passwordColumnSchema.setRequired(true);
+        ConnConfProperty passwordColumn = new ConnConfProperty();
+        passwordColumn.setSchema(passwordColumnSchema);
+        passwordColumn.getValues().add("password");
+        conf.add(passwordColumn);
+
+        // set connector configuration
+        connectorTO.getConfiguration().addAll(conf);
+
+        assertTrue(connectorService.check(connectorTO));
+
+        conf.remove(password);
+        password.getValues().clear();
+        password.getValues().add("password");
+        conf.add(password);
+
+        assertFalse(connectorService.check(connectorTO));
+    }
+
+    @Test
+    public void getSchemaNames() {
+        ConnInstanceTO conn = connectorService.read(101L);
+
+        List<PlainSchemaTO> schemaNames = connectorService.getSchemaNames(conn.getKey(), conn, true);
+        assertNotNull(schemaNames);
+        assertFalse(schemaNames.isEmpty());
+        assertNotNull(schemaNames.get(0).getKey());
+        assertNull(schemaNames.get(0).getEnumerationValues());
+
+        schemaNames = connectorService.getSchemaNames(conn.getKey(), conn, false);
+
+        assertNotNull(schemaNames);
+        assertEquals(0, schemaNames.size());
+
+        conn = connectorService.read(104L);
+
+        // to be used with overridden properties
+        conn.getConfiguration().clear();
+
+        schemaNames = connectorService.getSchemaNames(conn.getKey(), conn, true);
+        assertNotNull(schemaNames);
+        assertFalse(schemaNames.isEmpty());
+    }
+
+    @Test
+    public void getSupportedObjectClasses() {
+        ConnInstanceTO ldap = connectorService.read(105L);
+        assertNotNull(ldap);
+
+        List<ConnIdObjectClassTO> objectClasses = connectorService.getSupportedObjectClasses(ldap.getKey(), ldap);
+        assertNotNull(objectClasses);
+        assertEquals(2, objectClasses.size());
+        assertTrue(objectClasses.contains(ConnIdObjectClassTO.ACCOUNT));
+        assertTrue(objectClasses.contains(ConnIdObjectClassTO.GROUP));
+
+        ConnInstanceTO csv = connectorService.read(104L);
+        assertNotNull(csv);
+
+        objectClasses = connectorService.getSupportedObjectClasses(csv.getKey(), csv);
+        assertNotNull(objectClasses);
+        assertEquals(1, objectClasses.size());
+        assertTrue(objectClasses.contains(ConnIdObjectClassTO.ACCOUNT));
+    }
+
+    @Test
+    public void issueSYNCOPE112() {
+        // ----------------------------------------
+        // Create a new connector
+        // ----------------------------------------
+        ConnInstanceTO connectorTO = new ConnInstanceTO();
+
+        connectorTO.setLocation(connectorService.read(100L).getLocation());
+
+        // set connector version
+        connectorTO.setVersion(connidSoapVersion);
+
+        // set connector name
+        connectorTO.setConnectorName("net.tirasa.connid.bundles.soap.WebServiceConnector");
+
+        // set bundle name
+        connectorTO.setBundleName("net.tirasa.connid.bundles.soap");
+
+        // set display name
+        connectorTO.setDisplayName("WSSoap");
+
+        // set the connector configuration using PropertyTO
+        Set<ConnConfProperty> conf = new HashSet<ConnConfProperty>();
+
+        ConnConfPropSchema userSchema = new ConnConfPropSchema();
+        userSchema.setName("endpoint");
+        userSchema.setType(String.class.getName());
+        userSchema.setRequired(true);
+        ConnConfProperty endpoint = new ConnConfProperty();
+        endpoint.setSchema(userSchema);
+        endpoint.getValues().add("http://localhost:9080/does_not_work");
+        endpoint.setOverridable(true);
+
+        ConnConfPropSchema keyColumnSchema = new ConnConfPropSchema();
+        keyColumnSchema.setName("servicename");
+        keyColumnSchema.setType(String.class.getName());
+        keyColumnSchema.setRequired(true);
+        ConnConfProperty servicename = new ConnConfProperty();
+        servicename.setSchema(keyColumnSchema);
+        servicename.getValues().add("net.tirasa.connid.bundles.soap.provisioning.interfaces.Provisioning");
+        servicename.setOverridable(false);
+
+        conf.add(endpoint);
+        conf.add(servicename);
+
+        // set connector configuration
+        connectorTO.getConfiguration().addAll(conf);
+
+        try {
+            assertFalse(connectorService.check(connectorTO));
+
+            Response response = connectorService.create(connectorTO);
+            if (response.getStatusInfo().getStatusCode() != Response.Status.CREATED.getStatusCode()) {
+                throw (RuntimeException) clientFactory.getExceptionMapper().fromResponse(response);
+            }
+
+            connectorTO = getObject(response.getLocation(), ConnectorService.class, ConnInstanceTO.class);
+            assertNotNull(connectorTO);
+            // ----------------------------------------
+
+            // ----------------------------------------
+            // create a resourceTO
+            // ----------------------------------------
+            String resourceName = "checkForPropOverriding";
+            ResourceTO resourceTO = new ResourceTO();
+
+            resourceTO.setKey(resourceName);
+            resourceTO.setConnectorId(connectorTO.getKey());
+
+            conf = new HashSet<ConnConfProperty>();
+            endpoint.getValues().clear();
+            endpoint.getValues().add("http://localhost:9080/wssample/services/provisioning");
+            conf.add(endpoint);
+
+            resourceTO.getConnConfProperties().addAll(conf);
+
+            MappingTO mapping = new MappingTO();
+            resourceTO.setUmapping(mapping);
+
+            MappingItemTO mapItem = new MappingItemTO();
+            mapItem.setExtAttrName("uid");
+            mapItem.setIntAttrName("userId");
+            mapItem.setIntMappingType(IntMappingType.UserPlainSchema);
+            mapItem.setAccountid(true);
+            mapping.setAccountIdItem(mapItem);
+            // ----------------------------------------
+
+            // ----------------------------------------
+            // Check connection without saving the resource ....
+            // ----------------------------------------
+            assertTrue(resourceService.check(resourceTO));
+            // ----------------------------------------
+        } finally {
+            // Remove connector from db to make test re-runnable
+            connectorService.delete(connectorTO.getKey());
+        }
+    }
+
+    @Test
+    public void reload() {
+        connectorService.reload();
+    }
+
+    @Test
+    public void bulkAction() {
+        final BulkAction bulkAction = new BulkAction();
+        bulkAction.setOperation(BulkAction.Type.DELETE);
+
+        ConnInstanceTO conn = connectorService.read(101L);
+
+        conn.setKey(0);
+        conn.setDisplayName("forBulk1");
+
+        bulkAction.getTargets().add(String.valueOf(getObject(
+                connectorService.create(conn).getLocation(), ConnectorService.class, ConnInstanceTO.class).getKey()));
+
+        conn.setDisplayName("forBulk2");
+
+        bulkAction.getTargets().add(String.valueOf(getObject(
+                connectorService.create(conn).getLocation(), ConnectorService.class, ConnInstanceTO.class).getKey()));
+
+        Iterator<String> iter = bulkAction.getTargets().iterator();
+
+        assertNotNull(connectorService.read(Long.valueOf(iter.next())));
+        assertNotNull(connectorService.read(Long.valueOf(iter.next())));
+
+        connectorService.bulk(bulkAction);
+
+        iter = bulkAction.getTargets().iterator();
+
+        try {
+            connectorService.read(Long.valueOf(iter.next()));
+            fail();
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+
+        try {
+            connectorService.read(Long.valueOf(iter.next()));
+            fail();
+        } catch (SyncopeClientException e) {
+            assertNotNull(e);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE605() {
+
+        ConnInstanceTO connectorInstanceTO = connectorService.read(103L);
+        assertTrue(connectorInstanceTO.getCapabilities().isEmpty());
+
+        connectorInstanceTO.getCapabilities().add(ConnectorCapability.SEARCH);
+        connectorService.update(connectorInstanceTO.getKey(), connectorInstanceTO);
+
+        ConnInstanceTO updatedCapabilities = connectorService.read(connectorInstanceTO.getKey());
+        assertNotNull(updatedCapabilities.getCapabilities());
+        assertTrue(updatedCapabilities.getCapabilities().size() == 1);
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java
new file mode 100644
index 0000000..a5c14ad
--- /dev/null
+++ b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/DerSchemaITCase.java
@@ -0,0 +1,151 @@
+/*
+ * 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.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.util.List;
+import javax.ws.rs.core.Response;
+import org.apache.syncope.common.lib.SyncopeClientException;
+import org.apache.syncope.common.lib.to.DerSchemaTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.ClientExceptionType;
+import org.apache.syncope.common.lib.types.EntityViolationType;
+import org.apache.syncope.common.lib.types.SchemaType;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class DerSchemaITCase extends AbstractITCase {
+
+    @Test
+    public void list() {
+        List<DerSchemaTO> derivedSchemas = schemaService.list(AttributableType.USER, SchemaType.DERIVED);
+        assertFalse(derivedSchemas.isEmpty());
+        for (DerSchemaTO derivedSchemaTO : derivedSchemas) {
+            assertNotNull(derivedSchemaTO);
+        }
+    }
+
+    @Test
+    public void read() {
+        DerSchemaTO derivedSchemaTO = schemaService.read(AttributableType.USER, SchemaType.DERIVED,
+                "cn");
+        assertNotNull(derivedSchemaTO);
+    }
+
+    @Test
+    public void create() {
+        DerSchemaTO schema = new DerSchemaTO();
+        schema.setKey("derived");
+        schema.setExpression("derived_sx + '_' + derived_dx");
+
+        DerSchemaTO actual = createSchema(AttributableType.USER, SchemaType.DERIVED, schema);
+        assertNotNull(actual);
+
+        actual = schemaService.read(AttributableType.USER, SchemaType.DERIVED, actual.getKey());
+        assertNotNull(actual);
+        assertEquals(actual.getExpression(), "derived_sx + '_' + derived_dx");
+    }
+
+    @Test
+    public void delete() {
+        DerSchemaTO schema = schemaService.read(AttributableType.ROLE, SchemaType.DERIVED, "rderiveddata");
+        assertNotNull(schema);
+
+        schemaService.delete(AttributableType.ROLE, SchemaType.DERIVED, schema.getKey());
+
+        try {
+            schemaService.read(AttributableType.ROLE, SchemaType.DERIVED, "rderiveddata");
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.NotFound, e.getType());
+        } finally {
+            // Recreate schema to make test re-runnable
+            schema = createSchema(AttributableType.ROLE, SchemaType.DERIVED, schema);
+            assertNotNull(schema);
+        }
+    }
+
+    @Test
+    public void update() {
+        DerSchemaTO schema = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+                "mderiveddata");
+        assertNotNull(schema);
+        assertEquals("mderived_sx + '-' + mderived_dx", schema.getExpression());
+        try {
+            schema.setExpression("mderived_sx + '.' + mderived_dx");
+
+            schemaService.update(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+                    schema.getKey(), schema);
+
+            schema = schemaService.read(AttributableType.MEMBERSHIP, SchemaType.DERIVED, "mderiveddata");
+            assertNotNull(schema);
+            assertEquals("mderived_sx + '.' + mderived_dx", schema.getExpression());
+        } finally {
+            // Set updated back to make test re-runnable
+            schema.setExpression("mderived_sx + '-' + mderived_dx");
+            schemaService.update(AttributableType.MEMBERSHIP, SchemaType.DERIVED,
+                    schema.getKey(), schema);
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE323() {
+        DerSchemaTO actual = schemaService.read(AttributableType.ROLE, SchemaType.DERIVED, "rderiveddata");
+        assertNotNull(actual);
+
+        try {
+            createSchema(AttributableType.ROLE, SchemaType.DERIVED, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.CONFLICT, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.EntityExists, e.getType());
+        }
+
+        actual.setKey(null);
+        try {
+            createSchema(AttributableType.ROLE, SchemaType.DERIVED, actual);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(Response.Status.BAD_REQUEST, e.getType().getResponseStatus());
+            assertEquals(ClientExceptionType.RequiredValuesMissing, e.getType());
+        }
+    }
+
+    @Test
+    public void issueSYNCOPE418() {
+        DerSchemaTO schema = new DerSchemaTO();
+        schema.setKey("http://schemas.examples.org/security/authorization/organizationUnit");
+        schema.setExpression("derived_sx + '_' + derived_dx");
+
+        try {
+            createSchema(AttributableType.ROLE, SchemaType.DERIVED, schema);
+            fail();
+        } catch (SyncopeClientException e) {
+            assertEquals(ClientExceptionType.InvalidDerSchema, e.getType());
+            assertTrue(e.getElements().iterator().next().contains(EntityViolationType.InvalidName.name()));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/d30c8526/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
----------------------------------------------------------------------
diff --git a/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
new file mode 100644
index 0000000..7b5e845
--- /dev/null
+++ b/syncope620/fit/core-reference/src/test/java/org/apache/syncope/fit/core/reference/LoggerITCase.java
@@ -0,0 +1,215 @@
+/*
+ * 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.reference;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.text.ParseException;
+import java.util.List;
+import org.apache.syncope.common.lib.to.EventCategoryTO;
+import org.apache.syncope.common.lib.to.LoggerTO;
+import org.apache.syncope.common.lib.types.AttributableType;
+import org.apache.syncope.common.lib.types.AuditElements;
+import org.apache.syncope.common.lib.types.AuditElements.EventCategoryType;
+import org.apache.syncope.common.lib.types.AuditLoggerName;
+import org.apache.syncope.common.lib.types.LoggerLevel;
+import org.apache.syncope.common.lib.types.LoggerType;
+import org.apache.syncope.common.lib.types.ResourceOperation;
+import org.apache.syncope.common.rest.api.CollectionWrapper;
+import org.apache.syncope.core.logic.ReportLogic;
+import org.apache.syncope.core.logic.ResourceLogic;
+import org.apache.syncope.core.logic.RoleLogic;
+import org.apache.syncope.core.logic.UserLogic;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+@FixMethodOrder(MethodSorters.JVM)
+public class LoggerITCase extends AbstractITCase {
+
+    @Test
+    public void listLogs() {
+        List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        assertFalse(loggers.isEmpty());
+        for (LoggerTO logger : loggers) {
+            assertNotNull(logger);
+        }
+    }
+
+    @Test
+    public void listAudits() throws ParseException {
+        List<LoggerTO> audits = loggerService.list(LoggerType.AUDIT);
+
+        assertNotNull(audits);
+        assertFalse(audits.isEmpty());
+        for (LoggerTO audit : audits) {
+            assertNotNull(AuditLoggerName.fromLoggerName(audit.getKey()));
+        }
+    }
+
+    @Test
+    public void setLevel() {
+        List<LoggerTO> loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        int startSize = loggers.size();
+
+        LoggerTO logger = new LoggerTO();
+        logger.setKey("TEST");
+        logger.setLevel(LoggerLevel.INFO);
+        loggerService.update(LoggerType.LOG, logger.getKey(), logger);
+        logger = loggerService.read(LoggerType.LOG, logger.getKey());
+        assertNotNull(logger);
+        assertEquals(LoggerLevel.INFO, logger.getLevel());
+
+        loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        assertEquals(startSize + 1, loggers.size());
+
+        // TEST Delete
+        loggerService.delete(LoggerType.LOG, "TEST");
+        loggers = loggerService.list(LoggerType.LOG);
+        assertNotNull(loggers);
+        assertEquals(startSize, loggers.size());
+    }
+
+    @Test
+    public void enableDisableAudit() {
+        AuditLoggerName auditLoggerName = new AuditLoggerName(
+                EventCategoryType.REST,
+                ReportLogic.class.getSimpleName(),
+                null,
+                "deleteExecution",
+                AuditElements.Result.FAILURE);
+
+        List<AuditLoggerName> audits = CollectionWrapper.wrapLogger(loggerService.list(LoggerType.AUDIT));
+        assertNotNull(audits);
+        assertFalse(audits.contains(auditLoggerName));
+
+        LoggerTO loggerTO = new LoggerTO();
+        String name = auditLoggerName.toLoggerName();
+        loggerTO.setKey(name);
+        loggerTO.setLevel(LoggerLevel.DEBUG);
+        loggerService.update(LoggerType.AUDIT, name, loggerTO);
+
+        audits = CollectionWrapper.wrapLogger(loggerService.list(LoggerType.AUDIT));
+        assertNotNull(audits);
+        assertTrue(audits.contains(auditLoggerName));
+
+        loggerService.delete(LoggerType.AUDIT, auditLoggerName.toLoggerName());
+
+        audits = CollectionWrapper.wrapLogger(loggerService.list(LoggerType.AUDIT));
+        assertNotNull(audits);
+        assertFalse(audits.contains(auditLoggerName));
+    }
+
+    @Test
+    public void listAuditEvents() {
+        final List<EventCategoryTO> events = loggerService.events();
+
+        boolean found = false;
+
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (UserLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+                assertTrue(eventCategoryTO.getEvents().contains("create"));
+                assertTrue(eventCategoryTO.getEvents().contains("list"));
+                assertFalse(eventCategoryTO.getEvents().contains("doCreate"));
+                assertFalse(eventCategoryTO.getEvents().contains("setStatusOnWfAdapter"));
+                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (RoleLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+                assertTrue(eventCategoryTO.getEvents().contains("create"));
+                assertTrue(eventCategoryTO.getEvents().contains("list"));
+                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (ResourceLogic.class.getSimpleName().equals(eventCategoryTO.getCategory())) {
+                assertEquals(EventCategoryType.REST, eventCategoryTO.getType());
+                assertTrue(eventCategoryTO.getEvents().contains("create"));
+                assertTrue(eventCategoryTO.getEvents().contains("read"));
+                assertTrue(eventCategoryTO.getEvents().contains("delete"));
+                assertFalse(eventCategoryTO.getEvents().contains("resolveReference"));
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (AttributableType.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
+                if (RESOURCE_NAME_LDAP.equals(eventCategoryTO.getSubcategory())
+                        && EventCategoryType.SYNCHRONIZATION == eventCategoryTO.getType()) {
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
+                    found = true;
+                }
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (AttributableType.USER.name().toLowerCase().equals(eventCategoryTO.getCategory())) {
+                if (RESOURCE_NAME_CSV.equals(eventCategoryTO.getSubcategory())
+                        && EventCategoryType.PROPAGATION == eventCategoryTO.getType()) {
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.CREATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.UPDATE.name().toLowerCase()));
+                    assertTrue(eventCategoryTO.getEvents().contains(ResourceOperation.DELETE.name().toLowerCase()));
+                    found = true;
+                }
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (EventCategoryType.TASK == eventCategoryTO.getType()
+                    && "SampleJob".equals(eventCategoryTO.getCategory())) {
+                found = true;
+            }
+        }
+        assertTrue(found);
+
+        found = false;
+        for (EventCategoryTO eventCategoryTO : events) {
+            if (EventCategoryType.TASK == eventCategoryTO.getType()
+                    && "SyncJob".equals(eventCategoryTO.getCategory())) {
+                found = true;
+            }
+        }
+        assertTrue(found);
+    }
+}