You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by fm...@apache.org on 2012/06/06 14:00:53 UTC

svn commit: r1346839 - in /incubator/syncope/trunk/core/src: main/java/org/apache/syncope/core/rest/controller/ main/resources/ test/java/org/apache/syncope/core/persistence/dao/ test/java/org/apache/syncope/core/rest/ test/resources/

Author: fmartelli
Date: Wed Jun  6 12:00:53 2012
New Revision: 1346839

URL: http://svn.apache.org/viewvc?rev=1346839&view=rev
Log:
SYNCOPE-91 #comment added alternative wf path and activation test

Modified:
    incubator/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java
    incubator/syncope/trunk/core/src/main/resources/userWorkflow.bpmn20.xml
    incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java
    incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/RoleTest.java
    incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java
    incubator/syncope/trunk/core/src/test/resources/content.xml

Modified: incubator/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java?rev=1346839&r1=1346838&r2=1346839&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java (original)
+++ incubator/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/controller/UserController.java Wed Jun  6 12:00:53 2012
@@ -112,7 +112,8 @@ public class UserController {
     @RequestMapping(method = RequestMethod.GET, value = "/verifyPassword/{username}")
     @Transactional(readOnly = true)
     public ModelAndView verifyPassword(@PathVariable("username") String username,
-            @RequestParam("password") final String password) throws NotFoundException, UnauthorizedRoleException {
+            @RequestParam("password") final String password)
+            throws NotFoundException, UnauthorizedRoleException {
 
         auditManager.audit(Category.user, UserSubCategory.create, Result.success,
                 "Verified password for: " + username);
@@ -132,7 +133,8 @@ public class UserController {
     @PreAuthorize("hasRole('USER_READ')")
     @RequestMapping(method = RequestMethod.POST, value = "/search/count")
     @Transactional(readOnly = true, rollbackFor = {Throwable.class})
-    public ModelAndView searchCount(@RequestBody final NodeCond searchCondition) throws InvalidSearchConditionException {
+    public ModelAndView searchCount(@RequestBody final NodeCond searchCondition)
+            throws InvalidSearchConditionException {
 
         if (!searchCondition.checkValidity()) {
             LOG.error("Invalid search condition: {}", searchCondition);
@@ -185,7 +187,8 @@ public class UserController {
     @PreAuthorize("hasRole('USER_READ')")
     @RequestMapping(method = RequestMethod.GET, value = "/read/{userId}")
     @Transactional(readOnly = true, rollbackFor = {Throwable.class})
-    public UserTO read(@PathVariable("userId") final Long userId) throws NotFoundException, UnauthorizedRoleException {
+    public UserTO read(@PathVariable("userId") final Long userId)
+            throws NotFoundException, UnauthorizedRoleException {
 
         UserTO result = userDataBinder.getUserTO(userId);
 
@@ -212,7 +215,8 @@ public class UserController {
     @PreAuthorize("hasRole('USER_READ')")
     @RequestMapping(method = RequestMethod.POST, value = "/search")
     @Transactional(readOnly = true, rollbackFor = {Throwable.class})
-    public List<UserTO> search(@RequestBody final NodeCond searchCondition) throws InvalidSearchConditionException {
+    public List<UserTO> search(@RequestBody final NodeCond searchCondition)
+            throws InvalidSearchConditionException {
 
         LOG.debug("User search called with condition {}", searchCondition);
 
@@ -238,7 +242,8 @@ public class UserController {
     @RequestMapping(method = RequestMethod.POST, value = "/search/{page}/{size}")
     @Transactional(readOnly = true, rollbackFor = {Throwable.class})
     public List<UserTO> search(@RequestBody final NodeCond searchCondition, @PathVariable("page") final int page,
-            @PathVariable("size") final int size) throws InvalidSearchConditionException {
+            @PathVariable("size") final int size)
+            throws InvalidSearchConditionException {
 
         LOG.debug("User search called with condition {}", searchCondition);
 
@@ -374,22 +379,65 @@ public class UserController {
     }
 
     @PreAuthorize("hasRole('USER_UPDATE')")
-    @RequestMapping(method = RequestMethod.POST, value = "/activate")
+    @RequestMapping(method = RequestMethod.GET, value = "/activate/{userId}")
     @Transactional(readOnly = true, rollbackFor = {Throwable.class})
-    public UserTO activate(@RequestBody final UserTO userTO,
+    public UserTO activate(
+            @PathVariable("userId") final Long userId,
+            @RequestParam(required = true) final String token,
             @RequestParam(required = false) final Set<String> resourceNames,
             @RequestParam(required = false, defaultValue = "true") final Boolean performLocally,
             @RequestParam(required = false, defaultValue = "true") final Boolean performRemotely)
             throws WorkflowException, NotFoundException, UnauthorizedRoleException, PropagationException {
 
-        LOG.debug("About to activate " + userTO.getId());
+        LOG.debug("About to activate " + userId);
+
+        SyncopeUser user = userDAO.find(userId);
+        if (user == null) {
+            throw new NotFoundException("User " + userId);
+        }
+
+        return setStatus(user, token, resourceNames, performLocally, performRemotely, true, "activate");
+    }
+
+    @PreAuthorize("hasRole('USER_UPDATE')")
+    @RequestMapping(method = RequestMethod.GET, value = "/activateByUsername/{username}")
+    @Transactional(readOnly = true, rollbackFor = {Throwable.class})
+    public UserTO activate(
+            @PathVariable("username") final String username,
+            @RequestParam(required = true) final String token,
+            @RequestParam(required = false) final Set<String> resourceNames,
+            @RequestParam(required = false, defaultValue = "true") final Boolean performLocally,
+            @RequestParam(required = false, defaultValue = "true") final Boolean performRemotely)
+            throws WorkflowException, NotFoundException, UnauthorizedRoleException, PropagationException {
+
+        LOG.debug("About to activate " + username);
+
+        SyncopeUser user = userDAO.find(username);
+        if (user == null) {
+            throw new NotFoundException("User " + username);
+        }
+
+        return setStatus(user, token, resourceNames, performLocally, performRemotely, true, "activate");
+    }
+
+    @PreAuthorize("hasRole('USER_UPDATE')")
+    @RequestMapping(method = RequestMethod.GET, value = "/suspendByUsername/{username}")
+    @Transactional(rollbackFor = {Throwable.class})
+    public UserTO suspend(@PathVariable("username") final String username,
+            @RequestParam(required = false) final Set<String> resourceNames,
+            @RequestParam(required = false, defaultValue = "true") final Boolean performLocally,
+            @RequestParam(required = false, defaultValue = "true") final Boolean performRemotely)
+            throws NotFoundException, WorkflowException, UnauthorizedRoleException, PropagationException {
+
+        LOG.debug("About to suspend " + username);
+
+        SyncopeUser user = userDAO.find(username);
 
-        SyncopeUser user = userDAO.find(userTO.getId());
         if (user == null) {
-            throw new NotFoundException("User " + userTO.getId());
+            throw new NotFoundException("User " + username);
         }
 
-        return setStatus(user, userTO.getToken(), resourceNames, performLocally, performRemotely, true, "activate");
+        return setStatus(user, null, resourceNames, performLocally, performRemotely, false, "suspend");
     }
 
     @PreAuthorize("hasRole('USER_UPDATE')")
@@ -430,6 +478,25 @@ public class UserController {
         return setStatus(user, null, resourceNames, performLocally, performRemotely, true, "reactivate");
     }
 
+    @PreAuthorize("hasRole('USER_UPDATE')")
+    @RequestMapping(method = RequestMethod.GET, value = "/reactivateByUsername/{username}")
+    @Transactional(rollbackFor = {Throwable.class})
+    public UserTO reactivate(final @PathVariable("username") String username,
+            @RequestParam(required = false) final Set<String> resourceNames,
+            @RequestParam(required = false, defaultValue = "true") final Boolean performLocally,
+            @RequestParam(required = false, defaultValue = "true") final Boolean performRemotely)
+            throws NotFoundException, WorkflowException, UnauthorizedRoleException, PropagationException {
+
+        LOG.debug("About to reactivate " + username);
+
+        SyncopeUser user = userDAO.find(username);
+        if (user == null) {
+            throw new NotFoundException("User " + username);
+        }
+
+        return setStatus(user, null, resourceNames, performLocally, performRemotely, true, "reactivate");
+    }
+
     @PreAuthorize("hasRole('USER_DELETE')")
     @RequestMapping(method = RequestMethod.GET, value = "/delete/{userId}")
     public UserTO delete(@PathVariable("userId") final Long userId)

Modified: incubator/syncope/trunk/core/src/main/resources/userWorkflow.bpmn20.xml
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/main/resources/userWorkflow.bpmn20.xml?rev=1346839&r1=1346838&r2=1346839&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/main/resources/userWorkflow.bpmn20.xml (original)
+++ incubator/syncope/trunk/core/src/main/resources/userWorkflow.bpmn20.xml Wed Jun  6 12:00:53 2012
@@ -64,9 +64,13 @@ under the License.
     <sequenceFlow id="createApproval2Reject" sourceRef="createApprovalGW" targetRef="reject">
       <conditionExpression xsi:type="tFormalExpression">${!approve}</conditionExpression>
     </sequenceFlow>
-        
-    <!-- activate user if suspension is not required -->
+    
     <exclusiveGateway id="enableGW"/>
+    <!-- opt-in required -->
+    <sequenceFlow id="createApprovalGW2OptIn" sourceRef="enableGW" targetRef="generateToken">
+      <conditionExpression xsi:type="tFormalExpression">${syncopeUser.getRoleIds().contains(11)}</conditionExpression>
+    </sequenceFlow>
+    <!-- activate user if suspension is not required -->
     <sequenceFlow id="createApprovalGW2Activate" sourceRef="enableGW" targetRef="activate">
       <conditionExpression xsi:type="tFormalExpression">${enabled==null}</conditionExpression>
     </sequenceFlow>
@@ -76,45 +80,39 @@ under the License.
     <sequenceFlow id="createApprovalGW2Suspended" sourceRef="enableGW" targetRef="suspend">
       <conditionExpression xsi:type="tFormalExpression">${!enabled}</conditionExpression>
     </sequenceFlow>
-        
-    <!-- Comment the following two lines, uncomment the lines below and change
-         createApprovalGW2Activate.targetRef to "generateToken" in order to enable opt-in. -->
+    
     <serviceTask id="activate" name="Activate" activiti:class="org.apache.syncope.core.workflow.activiti.AutoActivate"/>
     <sequenceFlow id="flow4" sourceRef="activate" targetRef="active"/>
 
-    <!--<serviceTask id="generateToken" name="Generate token" activiti:class="org.apache.syncope.core.workflow.activiti.GenerateToken"/>
+    <!-- Double opt-in required -->
+    <serviceTask id="generateToken" name="Generate token" 
+                 activiti:class="org.apache.syncope.core.workflow.activiti.GenerateToken"/>
         
-    <sequenceFlow id="flow5" sourceRef="generateToken" targetRef="createdGw"/>
+    <sequenceFlow id="flow5" sourceRef="generateToken" targetRef="created"/>
 
     <userTask id="created" name="Created"/>
 
-    <sequenceFlow id="flow6" sourceRef="created" targetRef="createdGw"/>
+    <sequenceFlow id="flow6" sourceRef="created" targetRef="optinGW"/>
 
-    NOTE: this gateway makes sense when the token to be checked (i.e. the 'token' variable below) is provided as input
-    from external to this workflow instance (a link provided in an notification e-mail, for example)
-    <exclusiveGateway id="createdGw"/>
-    <sequenceFlow id="created2Activate" sourceRef="createdGw" targetRef="activate">
-      <conditionExpression xsi:type="tFormalExpression">
-        <![CDATA[${syncopeUser.checkToken(token)}]]>
-      </conditionExpression>
+    <exclusiveGateway id="optinGW"/>
+    <sequenceFlow id="created2Activate" sourceRef="optinGW" targetRef="removeToken">
+      <conditionExpression xsi:type="tFormalExpression">${syncopeUser.checkToken(token)}</conditionExpression>
     </sequenceFlow>  
-    <sequenceFlow id="created2Created" sourceRef="createdGw" targetRef="created">
-      <conditionExpression xsi:type="tFormalExpression">
-        <![CDATA[${!syncopeUser.checkToken(token)}]]>
-      </conditionExpression>
+    <sequenceFlow id="created2Created" sourceRef="optinGW" targetRef="created">
+      <conditionExpression xsi:type="tFormalExpression">${!syncopeUser.checkToken(token)}</conditionExpression>
     </sequenceFlow>
         
-    <scriptTask id="activate" name="Activate" scriptFormat="juel">
+    <scriptTask id="removeToken" name="Remove Token and Activate" scriptFormat="groovy">
       <script>
         syncopeUser.removeToken()    
       </script>
     </scriptTask>
 
-    <sequenceFlow id="flow62" sourceRef="activate" targetRef="active"/>-->
-
+    <sequenceFlow id="flow7" sourceRef="removeToken" targetRef="active"/>
+    
     <userTask id="active" name="Active"/>
         
-    <sequenceFlow id="flow7" sourceRef="active" targetRef="activeGw"/>
+    <sequenceFlow id="flow8" sourceRef="active" targetRef="activeGw"/>
 
     <exclusiveGateway id="activeGw"/>
     <sequenceFlow id="active2Update" sourceRef="activeGw" targetRef="update">
@@ -130,16 +128,16 @@ under the License.
     <!-- Update an active user -->
     <serviceTask id="update" name="Update" activiti:class="org.apache.syncope.core.workflow.activiti.Update"/>
 
-    <sequenceFlow id="flow8" sourceRef="update" targetRef="active"/>
+    <sequenceFlow id="flow9" sourceRef="update" targetRef="active"/>
 
     <!-- Suspend an active user -->
     <serviceTask id="suspend" name="Suspend" activiti:class="org.apache.syncope.core.workflow.activiti.Suspend"/>
 
-    <sequenceFlow id="flow9" sourceRef="suspend" targetRef="suspended"/>
+    <sequenceFlow id="flow10" sourceRef="suspend" targetRef="suspended"/>
 
     <userTask id="suspended" name="Suspended"/>
         
-    <sequenceFlow id="flow10" sourceRef="suspended" targetRef="suspendedGw"/>
+    <sequenceFlow id="flow11" sourceRef="suspended" targetRef="suspendedGw"/>
 
     <exclusiveGateway id="suspendedGw"/>
     <sequenceFlow id="suspended2Reactivate" sourceRef="suspendedGw" targetRef="reactivate">
@@ -152,7 +150,7 @@ under the License.
     <!-- Reactivate a suspended user -->
     <serviceTask id="reactivate" name ="Reactivate" activiti:class="org.apache.syncope.core.workflow.activiti.Reactivate"/>
 
-    <sequenceFlow id="flow11" sourceRef="reactivate" targetRef="active"/>
+    <sequenceFlow id="flow12" sourceRef="reactivate" targetRef="active"/>
         
     <!-- Reject an user -->
     <scriptTask id="reject" name="Reject" scriptFormat="groovy">
@@ -162,11 +160,11 @@ under the License.
       </script>
     </scriptTask>
         
-    <sequenceFlow id="flow12" sourceRef="reject" targetRef="rejected"/>
+    <sequenceFlow id="flow13" sourceRef="reject" targetRef="rejected"/>
 
     <userTask id="rejected" name="Rejected"/>
         
-    <sequenceFlow id="flow13" sourceRef="rejected" targetRef="delete"/>
+    <sequenceFlow id="flow14" sourceRef="rejected" targetRef="delete"/>
 
     <!-- Delete an user (created, active or suspended) -->
     <serviceTask id="delete" name="Delete" activiti:class="org.apache.syncope.core.workflow.activiti.Delete"/>

Modified: incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java?rev=1346839&r1=1346838&r2=1346839&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/EntitlementTest.java Wed Jun  6 12:00:53 2012
@@ -43,7 +43,7 @@ public class EntitlementTest extends Abs
     public void findAll() {
         List<Entitlement> list = entitlementDAO.findAll();
         // 69 real entitlements + 9 role entitlements
-        assertEquals("did not get expected number of entitlements ", 79, list.size());
+        assertEquals("did not get expected number of entitlements ", 80, list.size());
     }
 
     @Test

Modified: incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/RoleTest.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/RoleTest.java?rev=1346839&r1=1346838&r2=1346839&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/RoleTest.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/persistence/dao/RoleTest.java Wed Jun  6 12:00:53 2012
@@ -43,7 +43,7 @@ public class RoleTest extends AbstractTe
     @Test
     public void findAll() {
         List<SyncopeRole> list = roleDAO.findAll();
-        assertEquals("did not get expected number of roles ", 10, list.size());
+        assertEquals("did not get expected number of roles ", 11, list.size());
     }
 
     @Test

Modified: incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java?rev=1346839&r1=1346838&r2=1346839&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java (original)
+++ incubator/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/UserTestITCase.java Wed Jun  6 12:00:53 2012
@@ -434,8 +434,8 @@ public class UserTestITCase extends Abst
     @Test
     public void create() {
         // get task list
-        List<PropagationTaskTO> tasks = Arrays.asList(restTemplate.getForObject(BASE_URL + "task/propagation/list",
-                PropagationTaskTO[].class));
+        List<PropagationTaskTO> tasks =
+                Arrays.asList(restTemplate.getForObject(BASE_URL + "task/propagation/list", PropagationTaskTO[].class));
 
         assertNotNull(tasks);
         assertFalse(tasks.isEmpty());
@@ -447,8 +447,8 @@ public class UserTestITCase extends Abst
                 maxId = task.getId();
             }
         }
-        PropagationTaskTO taskTO = restTemplate.getForObject(BASE_URL + "task/read/{taskId}", PropagationTaskTO.class,
-                maxId);
+        PropagationTaskTO taskTO =
+                restTemplate.getForObject(BASE_URL + "task/read/{taskId}", PropagationTaskTO.class, maxId);
 
         assertNotNull(taskTO);
         int maxTaskExecutions = taskTO.getExecutions().size();
@@ -1265,6 +1265,59 @@ public class UserTestITCase extends Abst
     }
 
     @Test
+    public void createActivate() {
+        UserTO userTO = getSampleTO("createActivate@syncope.apache.org");
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(11L);
+        userTO.addMembership(membershipTO);
+
+        userTO = restTemplate.postForObject(BASE_URL + "user/create", userTO, UserTO.class);
+
+        assertNotNull(userTO);
+        assertNotNull(userTO.getToken());
+        assertNotNull(userTO.getTokenExpireTime());
+
+        assertEquals("created", userTO.getStatus());
+
+        userTO = restTemplate.getForObject(
+                BASE_URL + "user/activate/{userId}?token=" + userTO.getToken(), UserTO.class, userTO.getId());
+
+        assertNotNull(userTO);
+        assertNull(userTO.getToken());
+        assertNull(userTO.getTokenExpireTime());
+
+        assertEquals("active", userTO.getStatus());
+    }
+
+    @Test
+    public void createActivateByUsername() {
+        UserTO userTO = getSampleTO("createActivateByUsername@syncope.apache.org");
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(11L);
+        userTO.addMembership(membershipTO);
+
+        userTO = restTemplate.postForObject(BASE_URL + "user/create", userTO, UserTO.class);
+
+        assertNotNull(userTO);
+        assertNotNull(userTO.getToken());
+        assertNotNull(userTO.getTokenExpireTime());
+
+        assertEquals("created", userTO.getStatus());
+
+        userTO = restTemplate.getForObject(
+                BASE_URL + "user/activateByUsername/{username}.json?token=" + userTO.getToken(),
+                UserTO.class, userTO.getUsername());
+
+        assertNotNull(userTO);
+        assertNull(userTO.getToken());
+        assertNull(userTO.getTokenExpireTime());
+
+        assertEquals("active", userTO.getStatus());
+    }
+
+    @Test
     public void suspendReactivate() {
         UserTO userTO = getSampleTO("suspendReactivate@syncope.apache.org");
 
@@ -1289,6 +1342,32 @@ public class UserTestITCase extends Abst
     }
 
     @Test
+    public void suspendReactivateByUsername() {
+        UserTO userTO = getSampleTO("suspendReactivateByUsername@syncope.apache.org");
+
+        MembershipTO membershipTO = new MembershipTO();
+        membershipTO.setRoleId(7L);
+        userTO.addMembership(membershipTO);
+
+        userTO = restTemplate.postForObject(BASE_URL + "user/create", userTO, UserTO.class);
+
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+
+        userTO = restTemplate.getForObject(
+                BASE_URL + "user/suspendByUsername/{username}.json", UserTO.class, userTO.getUsername());
+
+        assertNotNull(userTO);
+        assertEquals("suspended", userTO.getStatus());
+
+        userTO = restTemplate.getForObject(
+                BASE_URL + "user/reactivateByUsername/{username}.json", UserTO.class, userTO.getUsername());
+
+        assertNotNull(userTO);
+        assertEquals("active", userTO.getStatus());
+    }
+
+    @Test
     public void suspendReactivateOnResource() {
         UserTO userTO = getSampleTO("suspreactonresource@syncope.apache.org");
 

Modified: incubator/syncope/trunk/core/src/test/resources/content.xml
URL: http://svn.apache.org/viewvc/incubator/syncope/trunk/core/src/test/resources/content.xml?rev=1346839&r1=1346838&r2=1346839&view=diff
==============================================================================
--- incubator/syncope/trunk/core/src/test/resources/content.xml (original)
+++ incubator/syncope/trunk/core/src/test/resources/content.xml Wed Jun  6 12:00:53 2012
@@ -69,6 +69,7 @@ under the License.
                name="managingConsultant" parent_id="6"
                inheritAttributes="1" inheritDerivedAttributes="1" inheritVirtualAttributes="1"
                inheritPasswordPolicy="1" inheritAccountPolicy="1"/>
+  <SyncopeRole id="11" name="roleForWorkflowOptIn" parent_id="1"/>
 
   <Membership id="1" syncopeUser_id="1" syncopeRole_id="1"/>
   <Membership id="2" syncopeUser_id="2" syncopeRole_id="1"/>
@@ -287,10 +288,10 @@ under the License.
   <ConnInstance_capabilities ConnInstance_id="105" capabilities="ONE_PHASE_CREATE"/>
   
   <ConnInstance id="106" displayName="H2-test2"
-                  bundleName="org.connid.bundles.db.table"
-                  connectorName="org.identityconnectors.databasetable.DatabaseTableConnector"
-                  version="${connid.db.table.version}"
-                  xmlConfiguration="%3Cset%3E%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Euser%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Esa%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EenabledStatusValue%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etrue%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EstatusColumn%3C/name%3E%0A++++
 ++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Estatus%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EdisabledStatusValue%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Efalse%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EkeyColumn%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Eid%3C/java
 .lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EjdbcUrlTemplate%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Ejdbc%3Ah2%3Atcp%3A//localhost%3A9092/testdb%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EpasswordColumn%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Epassword%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.type
 s.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EdefaultStatusValue%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etrue%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Etable%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etest2%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Epassword%3C/name%3E%0A++++++%3Ctype%3Eorg.identi
 tyconnectors.common.security.GuardedString%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Esa%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EjdbcDriver%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Eorg.h2.Driver%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EcipherAlgorithm%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.Stri
 ng%3EMD5%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EretrievePassword%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.Boolean%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etrue%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%3C/set%3E%0A"/>
+                bundleName="org.connid.bundles.db.table"
+                connectorName="org.identityconnectors.databasetable.DatabaseTableConnector"
+                version="${connid.db.table.version}"
+                xmlConfiguration="%3Cset%3E%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Euser%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Esa%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EenabledStatusValue%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etrue%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EstatusColumn%3C/name%3E%0A++++++
 %3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Estatus%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EdisabledStatusValue%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Efalse%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EkeyColumn%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Eid%3C/java.l
 ang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EjdbcUrlTemplate%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Ejdbc%3Ah2%3Atcp%3A//localhost%3A9092/testdb%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EpasswordColumn%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Epassword%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.
 ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EdefaultStatusValue%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etrue%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Etable%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etest2%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3Epassword%3C/name%3E%0A++++++%3Ctype%3Eorg.identity
 connectors.common.security.GuardedString%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Esa%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EjdbcDriver%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Eorg.h2.Driver%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EcipherAlgorithm%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.String%3C/type%3E%0A++++++%3Crequired%3Etrue%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String
 %3EMD5%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%0A++%3Corg.apache.syncope.types.ConnConfProperty%3E%0A++++%3Cschema%3E%0A++++++%3Cname%3EretrievePassword%3C/name%3E%0A++++++%3Ctype%3Ejava.lang.Boolean%3C/type%3E%0A++++++%3Crequired%3Efalse%3C/required%3E%0A++++%3C/schema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etrue%3C/java.lang.String%3E%0A%3C/values%3E%0A%0A++++%3Coverridable%3Efalse%3C/overridable%3E%0A++%3C/org.apache.syncope.types.ConnConfProperty%3E%0A%3C/set%3E%0A"/>
   <ConnInstance_capabilities ConnInstance_id="106" capabilities="SEARCH"/>
   <ConnInstance_capabilities ConnInstance_id="106" capabilities="SYNC"/>
     
@@ -629,6 +630,7 @@ under the License.
   <Entitlement name="ROLE_8"/>
   <Entitlement name="ROLE_9"/>
   <Entitlement name="ROLE_10"/>
+  <Entitlement name="ROLE_11"/>
 
   <SyncopeRole_Entitlement entitlement_name="base" role_id="1"/>
   <SyncopeRole_Entitlement entitlement_name="advanced" role_id="1"/>