syncope-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ilgro...@apache.org
Subject [4/4] syncope git commit: [SYNCOPE-753] Adding user and role migration from 1.2
Date Fri, 06 May 2016 11:56:10 GMT
[SYNCOPE-753] Adding user and role migration from 1.2


Project: http://git-wip-us.apache.org/repos/asf/syncope/repo
Commit: http://git-wip-us.apache.org/repos/asf/syncope/commit/9ef16775
Tree: http://git-wip-us.apache.org/repos/asf/syncope/tree/9ef16775
Diff: http://git-wip-us.apache.org/repos/asf/syncope/diff/9ef16775

Branch: refs/heads/master
Commit: 9ef167750a6889ab0168aea1af2b1a10a8deb68b
Parents: 44346bb
Author: Francesco Chicchiriccò <ilgrosso@apache.org>
Authored: Fri May 6 13:55:54 2016 +0200
Committer: Francesco Chicchiriccò <ilgrosso@apache.org>
Committed: Fri May 6 13:55:54 2016 +0200

----------------------------------------------------------------------
 .../console/panels/AnyDirectoryPanel.java       |    4 +-
 .../client/console/panels/TogglePanel.java      |    5 +
 .../reports/ReportletDirectoryPanel.java        |    2 -
 .../console/reports/ReportletWizardBuilder.java |    2 +-
 .../console/rest/ConfigurationRestClient.java   |    2 -
 .../console/rest/ConnectorRestClient.java       |   27 +-
 .../client/console/rest/ReportRestClient.java   |    2 -
 .../client/console/rest/ResourceRestClient.java |   45 +-
 .../client/console/rest/SchemaRestClient.java   |    2 -
 .../console/tasks/ExecutionsDirectoryPanel.java |    2 +
 .../topology/TopologyWebSocketBehavior.java     |    4 +-
 .../wicket/markup/html/form/FieldPanel.java     |   13 +-
 .../html/list/ConnConfPropertyListView.java     |    2 +-
 .../resources/ConnectorWizardBuilder.java       |    8 +-
 .../wizards/resources/ResourceMappingPanel.java |   79 +-
 .../resources/ResourceWizardBuilder.java        |    8 +-
 .../META-INF/resources/css/syncopeConsole.css   |   34 +-
 .../console/panels/ConnObjects.properties       |    2 +-
 .../console/panels/ConnObjects_it.properties    |    2 +-
 .../console/panels/ConnObjects_pt_BR.properties |    2 +-
 .../console/panels/ConnObjects_ru.properties    |    4 +-
 .../console/panels/StartAtTogglePanel.html      |   21 -
 .../console/tasks/TaskExecutionDetails.html     |   24 +
 .../console/tasks/TransformersTogglePanel.html  |   27 +-
 .../console/topology/TopologyTogglePanel.html   |   71 +-
 .../resources/AbstractConnConfPanel.properties  |    1 +
 .../AbstractConnConfPanel_it.properties         |    1 +
 .../AbstractConnConfPanel_pt_BR.properties      |    1 +
 .../AbstractConnConfPanel_ru.properties         |    1 +
 .../wizards/resources/ResourceMappingPanel.html |    2 +-
 .../common/lib/report/GroupReportletConf.java   |    6 +-
 .../syncope/common/lib/report/Schema.java       |    2 +-
 .../common/lib/report/UserReportletConf.java    |   10 +-
 .../apache/syncope/common/lib/to/MappingTO.java |    2 +-
 .../common/lib/types/ConnConfPropSchema.java    |    2 +-
 core/migration/pom.xml                          |   63 +
 .../core/migration/MigrationPullActions.java    |  149 ++
 .../main/resources/scripted/SchemaScript.groovy |  108 +
 .../main/resources/scripted/SearchScript.groovy |  165 ++
 .../main/resources/scripted/SyncScript.groovy   |  202 ++
 .../main/resources/scripted/TestScript.groovy   |   32 +
 core/pom.xml                                    |    1 +
 .../java/job/SetUMembershipsJob.java            |   92 +
 .../core/provisioning/java/job/TaskJob.java     |    3 +-
 .../AbstractPropagationTaskExecutor.java        |    4 +-
 .../java/pushpull/DBPasswordPullActions.java    |    8 +-
 .../pushpull/LDAPMembershipPullActions.java     |  202 +-
 .../java/pushpull/LDAPPasswordPullActions.java  |    4 +-
 .../java/pushpull/SchedulingPullActions.java    |   75 +
 fit/core-reference/pom.xml                      |    5 +
 .../syncope/fit/core/ConnectorITCase.java       |   20 +-
 .../syncope/fit/core/MigrationITCase.java       |  518 ++++
 .../apache/syncope/fit/core/PullTaskITCase.java |    8 +
 .../src/test/resources/migrationContext.xml     |   51 +
 fit/core-reference/src/test/resources/rebel.xml |    2 +
 .../src/test/resources/syncope12.sql            | 2265 ++++++++++++++++++
 .../src/test/resources/test.properties          |   17 +
 pom.xml                                         |    4 +-
 58 files changed, 4021 insertions(+), 399 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
index ef263fa..6bae69d 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/AnyDirectoryPanel.java
@@ -141,11 +141,9 @@ public abstract class AnyDirectoryPanel<A extends AnyTO>
 
     @Override
     protected Collection<ActionLink.ActionType> getBulkActions() {
-        final List<ActionLink.ActionType> bulkActions = new ArrayList<>();
+        List<ActionLink.ActionType> bulkActions = new ArrayList<>();
 
         bulkActions.add(ActionLink.ActionType.DELETE);
-        bulkActions.add(ActionLink.ActionType.SUSPEND);
-        bulkActions.add(ActionLink.ActionType.REACTIVATE);
 
         return bulkActions;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
index 18fd380..63343db 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/panels/TogglePanel.java
@@ -109,6 +109,11 @@ public abstract class TogglePanel<T extends Serializable> extends WizardMgtPanel
         target.add(this.header);
     }
 
+    protected void close(final AjaxRequestTarget target) {
+        status = Status.INACTIVE;
+        toggle(target, false);
+    }
+
     /**
      * Force toggle via java. To be used when the onclick has been intercepted before.
      *

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
index bc761a3..8a1bdfa 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletDirectoryPanel.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.client.console.reports;
 
-import static org.apache.wicket.Component.ENABLE;
-
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
index cf94ddf..0cf1336 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/reports/ReportletWizardBuilder.java
@@ -280,7 +280,7 @@ public class ReportletWizardBuilder extends AjaxWizardBuilder<ReportletDirectory
                             SchemaRestClient schemaRestClient = new SchemaRestClient();
 
                             List<AbstractSchemaTO> choices;
-                            switch (schemaAnnot.schema()) {
+                            switch (schemaAnnot.type()) {
                                 case UserPlainSchema:
                                     choices = schemaRestClient.getSchemas(SchemaType.PLAIN, AnyTypeKind.USER);
                                     break;

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
index f8e4863..d07827c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConfigurationRestClient.java
@@ -28,8 +28,6 @@ public class ConfigurationRestClient extends BaseRestClient {
 
     private static final long serialVersionUID = 7692363064029538722L;
 
-    private final SchemaRestClient schemaRestClient = new SchemaRestClient();
-
     public List<AttrTO> list() {
         return getService(ConfigurationService.class).list();
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
index f9e293b..519b1c0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ConnectorRestClient.java
@@ -24,6 +24,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.common.lib.SyncopeClientException;
 import org.apache.syncope.common.lib.to.BulkAction;
@@ -31,10 +32,8 @@ import org.apache.syncope.common.lib.to.BulkActionResult;
 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.ResourceTO;
 import org.apache.syncope.common.lib.types.ConnConfProperty;
 import org.apache.syncope.common.rest.api.service.ConnectorService;
-import org.apache.syncope.common.rest.api.service.ResourceService;
 import org.springframework.beans.BeanUtils;
 
 /**
@@ -132,38 +131,22 @@ public class ConnectorRestClient extends BaseRestClient {
         return newProperties;
     }
 
-    /**
-     * Test connector connection.
-     *
-     * @param connectorTO connector
-     * @return Connection status
-     */
-    public boolean check(final ConnInstanceTO connectorTO) {
+    public Pair<Boolean, String> check(final ConnInstanceTO connectorTO) {
         ConnInstanceTO toBeChecked = new ConnInstanceTO();
         BeanUtils.copyProperties(connectorTO, toBeChecked, new String[] { "configuration", "configurationMap" });
         toBeChecked.getConf().addAll(filterProperties(connectorTO.getConf()));
 
         boolean check = false;
+        String errorMessage = null;
         try {
             getService(ConnectorService.class).check(toBeChecked);
             check = true;
         } catch (Exception e) {
             LOG.error("While checking {}", toBeChecked, e);
+            errorMessage = e.getMessage();
         }
 
-        return check;
-    }
-
-    public boolean check(final ResourceTO resourceTO) {
-        boolean check = false;
-        try {
-            getService(ResourceService.class).check(resourceTO);
-            check = true;
-        } catch (Exception e) {
-            LOG.error("Connector not found {}", resourceTO.getConnector(), e);
-        }
-
-        return check;
+        return Pair.of(check, errorMessage);
     }
 
     public List<ConnIdObjectClassTO> buildObjectClassInfo(

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
index a0ccfec..c51df2c 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ReportRestClient.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.client.console.rest;
 
-import static org.apache.syncope.client.console.rest.BaseRestClient.getService;
-
 import java.io.InputStream;
 import java.util.Date;
 import java.util.List;

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
index fceef65..c70c235 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/ResourceRestClient.java
@@ -21,6 +21,7 @@ package org.apache.syncope.client.console.rest;
 import java.util.ArrayList;
 import java.util.List;
 import javax.ws.rs.core.Response;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.common.lib.patch.ResourceDeassociationPatch;
 import org.apache.syncope.common.lib.to.BulkAction;
 import org.apache.syncope.common.lib.to.BulkActionResult;
@@ -39,6 +40,20 @@ public class ResourceRestClient extends BaseRestClient {
 
     private static final long serialVersionUID = -6898907679835668987L;
 
+    public Pair<Boolean, String> check(final ResourceTO resourceTO) {
+        boolean check = false;
+        String errorMessage = null;
+        try {
+            getService(ResourceService.class).check(resourceTO);
+            check = true;
+        } catch (Exception e) {
+            LOG.error("Connector not found {}", resourceTO.getConnector(), e);
+            errorMessage = e.getMessage();
+        }
+
+        return Pair.of(check, errorMessage);
+    }
+
     public ConnObjectTO readConnObject(final String resource, final String anyTypeKey, final String anyKey) {
         return getService(ResourceService.class).readConnObject(resource, anyTypeKey, anyKey);
     }
@@ -52,19 +67,23 @@ public class ResourceRestClient extends BaseRestClient {
 
         List<ConnObjectTO> result = new ArrayList<>();
         PagedConnObjectTOResult list;
-        do {
-            list = getService(ResourceService.class).listConnObjects(resource, anyTypeKey, builder.build());
-            result.addAll(list.getResult());
-
-            // TMP - see SYNCOPE-829
-            if (result.size() >= 100) {
-                break;
-            }
-
-            if (list.getPagedResultsCookie() != null) {
-                builder.pagedResultsCookie(list.getPagedResultsCookie());
-            }
-        } while (list.getPagedResultsCookie() != null);
+        try {
+            do {
+                list = getService(ResourceService.class).listConnObjects(resource, anyTypeKey, builder.build());
+                result.addAll(list.getResult());
+
+                // TMP - see SYNCOPE-829
+                if (result.size() >= 100) {
+                    break;
+                }
+
+                if (list.getPagedResultsCookie() != null) {
+                    builder.pagedResultsCookie(list.getPagedResultsCookie());
+                }
+            } while (list.getPagedResultsCookie() != null);
+        } catch (Exception e) {
+            LOG.error("While listing objects on {} for any type {}", resource, anyTypeKey, e);
+        }
 
         return result;
     }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
index 570c969..355b974 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/rest/SchemaRestClient.java
@@ -18,8 +18,6 @@
  */
 package org.apache.syncope.client.console.rest;
 
-import static org.apache.syncope.client.console.rest.BaseRestClient.getService;
-
 import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
index 0d36759..da2cfe3 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/tasks/ExecutionsDirectoryPanel.java
@@ -45,6 +45,7 @@ import org.apache.syncope.common.lib.to.ExecTO;
 import org.apache.syncope.common.lib.types.StandardEntitlement;
 import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.extensions.markup.html.repeater.data.sort.SortOrder;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
 import org.apache.wicket.extensions.markup.html.repeater.data.table.PropertyColumn;
 import org.apache.wicket.model.AbstractReadOnlyModel;
@@ -202,6 +203,7 @@ public abstract class ExecutionsDirectoryPanel
             super(paginatorRows);
             this.taskKey = taskKey;
             comparator = new SortableDataProviderComparator<>(this);
+            setSort("end", SortOrder.DESCENDING);
         }
 
         public SortableDataProviderComparator<ExecTO> getComparator() {

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyWebSocketBehavior.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyWebSocketBehavior.java b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyWebSocketBehavior.java
index dbb30bc..6346332 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyWebSocketBehavior.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/topology/TopologyWebSocketBehavior.java
@@ -144,7 +144,7 @@ public class TopologyWebSocketBehavior extends WebSocketBehavior {
                 try {
                     final ConnInstanceTO connector = connectorRestClient.read(key);
                     res = String.format("{ \"status\": \"%s\", \"target\": \"%s\"}",
-                            connectorRestClient.check(connector)
+                            connectorRestClient.check(connector).getLeft()
                             ? TopologyNode.Status.REACHABLE : TopologyNode.Status.UNREACHABLE, key);
                 } catch (Exception e) {
                     LOG.warn("Error checking connection for {}", key, e);
@@ -185,7 +185,7 @@ public class TopologyWebSocketBehavior extends WebSocketBehavior {
                 try {
                     final ResourceTO resource = resourceRestClient.read(key);
                     res = String.format("{ \"status\": \"%s\", \"target\": \"%s\"}",
-                            connectorRestClient.check(resource)
+                            resourceRestClient.check(resource).getLeft()
                             ? TopologyNode.Status.REACHABLE : TopologyNode.Status.UNREACHABLE, key);
                 } catch (Exception e) {
                     LOG.warn("Error checking connection for {}", key, e);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/FieldPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/FieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/FieldPanel.java
index 2d51d8e..aba8aa0 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/FieldPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/FieldPanel.java
@@ -60,13 +60,20 @@ public abstract class FieldPanel<T extends Serializable> extends AbstractFieldPa
     }
 
     public FieldPanel<T> setTitle(final String title) {
+        return setTitle(title, false);
+    }
+
+    public FieldPanel<T> setTitle(final String title, final boolean html) {
         this.title = title;
         field.add(new PopoverBehavior(
                 Model.<String>of(),
                 title == null ? Model.<String>of() : Model.of(title),
-                new PopoverConfig().withHoverTrigger().withPlacement(
-                        index.getObject() != null && index.getObject() == 0
-                                ? TooltipConfig.Placement.bottom : TooltipConfig.Placement.top)));
+                new PopoverConfig().withHtml(html).withHoverTrigger().withPlacement(
+                index.getObject() != null && index.getObject() == 0
+                        ? TooltipConfig.Placement.bottom
+                        : this instanceof AjaxCheckBoxPanel
+                                ? TooltipConfig.Placement.right
+                                : TooltipConfig.Placement.top)));
         return this;
     }
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java
index e744f4e..3711054 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java
@@ -116,7 +116,7 @@ public class ConnConfPropertyListView extends ListView<ConnConfProperty> {
         }
 
         field.setIndex(item.getIndex());
-        field.setTitle(property.getSchema().getHelpMessage());
+        field.setTitle(property.getSchema().getHelpMessage(), true);
 
         final AbstractFieldPanel<? extends Serializable> fieldPanel;
         if (isArray) {

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java
index 4c41f6c..5af7da8 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ConnectorWizardBuilder.java
@@ -25,6 +25,7 @@ import java.util.List;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.IterableUtils;
 import org.apache.commons.collections4.Predicate;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
@@ -63,7 +64,7 @@ public class ConnectorWizardBuilder extends AbstractResourceWizardBuilder<ConnIn
 
     @Override
     protected WizardModel buildModelSteps(final Serializable modelObject, final WizardModel wizardModel) {
-        final ConnInstanceTO connInstanceTO = ConnInstanceTO.class.cast(modelObject);
+        ConnInstanceTO connInstanceTO = ConnInstanceTO.class.cast(modelObject);
         wizardModel.add(new ConnectorDetailsPanel(connInstanceTO, bundles));
         wizardModel.add(new ConnectorConfPanel(connInstanceTO, bundles) {
 
@@ -71,10 +72,11 @@ public class ConnectorWizardBuilder extends AbstractResourceWizardBuilder<ConnIn
 
             @Override
             protected void check(final AjaxRequestTarget target) {
-                if (connectorRestClient.check(modelObject)) {
+                Pair<Boolean, String> result = connectorRestClient.check(modelObject);
+                if (result.getLeft()) {
                     info(getString(Constants.OPERATION_SUCCEEDED));
                 } else {
-                    error(getString("error_connection"));
+                    error(getString("error_connection") + ": " + result.getRight());
                 }
                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
index 1e37df3..76fcef2 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.java
@@ -96,11 +96,6 @@ public class ResourceMappingPanel extends Panel {
      */
     private final ConnectorRestClient connRestClient = new ConnectorRestClient();
 
-    /**
-     * Resource schema name.
-     */
-    private final List<String> schemaNames;
-
     private final Label passwordLabel;
 
     /**
@@ -151,21 +146,20 @@ public class ResourceMappingPanel extends Panel {
 
         this.resourceTO = resourceTO;
         this.provisionTO = provisionTO == null ? new ProvisionTO() : provisionTO;
+        if (provisionTO == null) {
+            getMapping().getItems().clear();
+            getMapping().setConnObjectLink(null);
+        }
 
         this.mappingContainer = new WebMarkupContainer("mappingContainer");
         this.mappingContainer.setOutputMarkupId(true);
+        this.mappingContainer.setEnabled(provisionTO != null);
+        this.mappingContainer.setVisible(provisionTO != null);
         add(this.mappingContainer);
 
         transformers = new TransformersTogglePanel(this.mappingContainer);
         add(this.transformers);
 
-        if (resourceTO.getConnector() != null) {
-            schemaNames = getSchemaNames(resourceTO.getConnector(), resourceTO.getConfOverride());
-            setEnabled();
-        } else {
-            schemaNames = Collections.<String>emptyList();
-        }
-
         mappingContainer.add(Constants.getJEXLPopover(this, TooltipConfig.Placement.bottom));
 
         passwordLabel = new Label("passwordLabel", new ResourceModel("password"));
@@ -182,6 +176,14 @@ public class ResourceMappingPanel extends Panel {
                     compared = 1;
                 } else if (right == null) {
                     compared = -1;
+                } else if (left.isConnObjectKey()) {
+                    compared = -1;
+                } else if (right.isConnObjectKey()) {
+                    compared = 1;
+                } else if (left.isPassword()) {
+                    compared = -1;
+                } else if (right.isPassword()) {
+                    compared = 1;
                 } else if (left.getPurpose() == MappingPurpose.BOTH && right.getPurpose() != MappingPurpose.BOTH) {
                     compared = -1;
                 } else if (left.getPurpose() != MappingPurpose.BOTH && right.getPurpose() == MappingPurpose.BOTH) {
@@ -199,14 +201,6 @@ public class ResourceMappingPanel extends Panel {
                 } else if (left.getPurpose() == MappingPurpose.NONE
                         && right.getPurpose() != MappingPurpose.NONE) {
                     compared = 1;
-                } else if (left.isConnObjectKey()) {
-                    compared = -1;
-                } else if (right.isConnObjectKey()) {
-                    compared = 1;
-                } else if (left.isPassword()) {
-                    compared = -1;
-                } else if (right.isPassword()) {
-                    compared = 1;
                 } else {
                     compared = left.getIntAttrName().compareTo(right.getIntAttrName());
                 }
@@ -273,13 +267,13 @@ public class ResourceMappingPanel extends Panel {
                 //--------------------------------
                 // Internal attribute
                 // -------------------------------
-                final AjaxDropDownChoicePanel<String> intAttrNames = new AjaxDropDownChoicePanel<>(
+                final AjaxTextFieldPanel intAttrNames = new AjaxTextFieldPanel(
                         "intAttrNames",
                         getString("intAttrNames"),
                         new PropertyModel<String>(mapItem, "intAttrName"),
                         false);
                 intAttrNames.setChoices(Collections.<String>emptyList());
-                intAttrNames.setNullValid(true).setRequired(true).hideLabel();
+                intAttrNames.setRequired(true).hideLabel();
                 item.add(intAttrNames);
                 // -------------------------------
 
@@ -290,7 +284,7 @@ public class ResourceMappingPanel extends Panel {
                         "extAttrName",
                         new ResourceModel("extAttrNames", "extAttrNames").getObject(),
                         new PropertyModel<String>(mapItem, "extAttrName"));
-                extAttrNames.setChoices(schemaNames);
+                extAttrNames.setChoices(getExtAttrNames(resourceTO.getConnector(), resourceTO.getConfOverride()));
 
                 boolean required = !mapItem.isPassword();
                 extAttrNames.setRequired(required).hideLabel();
@@ -493,14 +487,14 @@ public class ResourceMappingPanel extends Panel {
         passwordLabel.setVisible(AnyTypeKind.USER.name().equals(this.provisionTO.getAnyType()));
     }
 
-    private List<String> getSchemaNames(final String connectorKey, final Set<ConnConfProperty> conf) {
-        final ConnInstanceTO connInstanceTO = new ConnInstanceTO();
+    private List<String> getExtAttrNames(final String connectorKey, final Set<ConnConfProperty> conf) {
+        ConnInstanceTO connInstanceTO = new ConnInstanceTO();
         connInstanceTO.setKey(connectorKey);
         connInstanceTO.getConf().addAll(conf);
 
         // SYNCOPE-156: use provided info to give schema names (and type!) by ObjectClass
-        ConnIdObjectClassTO clazz = IterableUtils.find(
-                connRestClient.buildObjectClassInfo(connInstanceTO, true), new Predicate<ConnIdObjectClassTO>() {
+        ConnIdObjectClassTO connIdObjectClass = IterableUtils.find(
+                connRestClient.buildObjectClassInfo(connInstanceTO, false), new Predicate<ConnIdObjectClassTO>() {
 
             @Override
             public boolean evaluate(final ConnIdObjectClassTO object) {
@@ -508,32 +502,9 @@ public class ResourceMappingPanel extends Panel {
             }
         });
 
-        return clazz == null ? new ArrayList<String>()
-                : IterableUtils.toList(IterableUtils.filteredIterable(clazz.getAttributes(), new Predicate<String>() {
-
-                    @Override
-                    public boolean evaluate(final String object) {
-                        return !(ConnIdSpecialAttributeName.NAME.equals(object)
-                                || ConnIdSpecialAttributeName.ENABLE.equals(object)
-                                || ConnIdSpecialAttributeName.PASSWORD.equals(object));
-                    }
-                }));
-    }
-
-    private void setEnabled() {
-        ConnInstanceTO connInstanceTO = new ConnInstanceTO();
-        connInstanceTO.setKey(resourceTO.getConnector());
-        connInstanceTO.getConf().addAll(resourceTO.getConfOverride());
-
-        boolean enabled = provisionTO != null;
-
-        this.mappingContainer.setEnabled(enabled);
-        this.mappingContainer.setVisible(enabled);
-
-        if (!enabled) {
-            getMapping().getItems().clear();
-            getMapping().setConnObjectLink(null);
-        }
+        return connIdObjectClass == null
+                ? new ArrayList<String>()
+                : connIdObjectClass.getAttributes();
     }
 
     /**
@@ -542,7 +513,7 @@ public class ResourceMappingPanel extends Panel {
      * @param type attribute type.
      * @param toBeUpdated drop down choice to be updated.
      */
-    private void setAttrNames(final IntMappingType type, final AjaxDropDownChoicePanel<String> toBeUpdated) {
+    private void setAttrNames(final IntMappingType type, final AjaxTextFieldPanel toBeUpdated) {
         toBeUpdated.setRequired(true);
         toBeUpdated.setEnabled(true);
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceWizardBuilder.java
----------------------------------------------------------------------
diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceWizardBuilder.java b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceWizardBuilder.java
index a990fd7..825f433 100644
--- a/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceWizardBuilder.java
+++ b/client/console/src/main/java/org/apache/syncope/client/console/wizards/resources/ResourceWizardBuilder.java
@@ -19,6 +19,7 @@
 package org.apache.syncope.client.console.wizards.resources;
 
 import java.io.Serializable;
+import org.apache.commons.lang3.tuple.Pair;
 import org.apache.syncope.client.console.SyncopeConsoleSession;
 import org.apache.syncope.client.console.commons.Constants;
 import org.apache.syncope.client.console.rest.ConnectorRestClient;
@@ -56,7 +57,7 @@ public class ResourceWizardBuilder extends AbstractResourceWizardBuilder<Resourc
 
     @Override
     protected WizardModel buildModelSteps(final Serializable modelObject, final WizardModel wizardModel) {
-        final ResourceTO resourceTO = ResourceTO.class.cast(modelObject);
+        ResourceTO resourceTO = ResourceTO.class.cast(modelObject);
         wizardModel.add(new ResourceDetailsPanel(resourceTO, createFlag));
         wizardModel.add(new ResourceConnConfPanel(resourceTO, createFlag) {
 
@@ -64,10 +65,11 @@ public class ResourceWizardBuilder extends AbstractResourceWizardBuilder<Resourc
 
             @Override
             protected void check(final AjaxRequestTarget target) {
-                if (connectorRestClient.check(modelObject)) {
+                Pair<Boolean, String> result = resourceRestClient.check(modelObject);
+                if (result.getLeft()) {
                     info(getString(Constants.OPERATION_SUCCEEDED));
                 } else {
-                    error(getString("error_connection"));
+                    error(getString("error_connection") + ": " + result.getRight());
                 }
                 SyncopeConsoleSession.get().getNotificationPanel().refresh(target);
             }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
index 5e3db1b..5ab7913 100644
--- a/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
+++ b/client/console/src/main/resources/META-INF/resources/css/syncopeConsole.css
@@ -419,16 +419,43 @@ div.searchResult{
   box-shadow: 0 6px 12px rgba(0, 0, 0, 0.176);
   float: left;
   font-size: 14px;
-  list-style: outside none none;
   min-width: 160px;
-  text-align: left;
   max-height: 250px;
 }
 
+div.wicket-aa ul {
+  list-style: none;
+  padding-left: 15px;
+}
+
 /**
 START - Notifications
 */
 
+/**
+START - startAt
+*/
+div#startAt {
+  background-color: rgba(98, 98, 98, 0.98) !important;
+  color: #CCC;
+  right: 5px !important;
+  top: 100px !important;
+  min-width: 450px;
+  min-height: 130px !important;
+  z-index: 6000 !important;
+}
+
+div#startAtContainer {
+  padding: 15px;
+}
+
+div#startAtContainer input {
+  background-color: rgba(200, 200, 200, 0.60) !important;
+}
+/**
+END - startAt
+*/
+
 /*Temporany fix diagonal stacking*/
 .k-popup.k-notification {
   box-shadow: none;
@@ -484,9 +511,6 @@ START - Notifications
   width:85%
 }
 
-/**
-END - Notifications
-*/
 
 /**
 START - Actions

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects.properties
index e21c540..a5641b9 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-connObject.view=Back to list
+connObject.view=Details

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_it.properties
index 7a3259d..c2bf08e 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_it.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-connObject.view=Torna alla lista
+connObject.view=Dettagli

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_pt_BR.properties
index 28ceac3..e573a86 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_pt_BR.properties
@@ -14,4 +14,4 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-connObject.view=Volte para a lista
+connObject.view=Detalhes

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_ru.properties
index cdd7b9b..c24c7f7 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/ConnObjects_ru.properties
@@ -15,5 +15,5 @@
 # specific language governing permissions and limitations
 # under the License.
 #
-# connObject.view=Вернуться к списку
-connObject.view=\u0412\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0441\u043f\u0438\u0441\u043a\u0443
+# connObject.view=\u00d0\u0092\u00d0\u00b5\u00d1\u0080\u00d0\u00bd\u00d1\u0083\u00d1\u0082\u00d1\u008c\u00d1\u0081\u00d1\u008f \u00d0\u00ba \u00d1\u0081\u00d0\u00bf\u00d0\u00b8\u00d1\u0081\u00d0\u00ba\u00d1\u0083
+connObject.view=\u0414\u0435\u0442\u0430\u043b\u0438

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/panels/StartAtTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/panels/StartAtTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/panels/StartAtTogglePanel.html
index 356e28f..c77a1ae 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/panels/StartAtTogglePanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/panels/StartAtTogglePanel.html
@@ -17,27 +17,6 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <wicket:head>
-    <style type="text/css">
-      div#startAt {
-        background-color: rgba(98, 98, 98, 0.98) !important;
-        color: #CCC;
-        right: 5px !important;
-        top: 100px !important;
-        min-width: 300px;
-        min-height: 130px !important;
-        z-index: 6000 !important;
-      }
-
-      div#startAtContainer {
-        padding: 15px;
-      }
-
-      div#startAtContainer input {
-        background-color: rgba(200, 200, 200, 0.60) !important;
-      }
-    </style>
-  </wicket:head>
   <wicket:extend>
     <div id="startAtContainer">
       <form wicket:id="startAtForm">

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails.html b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails.html
new file mode 100644
index 0000000..54ff764
--- /dev/null
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TaskExecutionDetails.html
@@ -0,0 +1,24 @@
+<!--
+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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:panel>
+    <div wicket:id="executions"></div>
+    <wicket:child/>
+  </wicket:panel>
+</html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TransformersTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TransformersTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TransformersTogglePanel.html
index 152766f..2193a6a 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TransformersTogglePanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/tasks/TransformersTogglePanel.html
@@ -17,19 +17,16 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <head><title></title></head>
-  <body>
-    <wicket:extend>
-      <div id="transformersContainer">
-        <form wicket:id="form">
-          <div id="body">
-            <span wicket:id="classes"/>
-          </div>
-          <div id="footer">
-            <input type="button" wicket:id="submit" class="btn" wicket:message="value:finish"></input>
-          </div>
-        </form>
-      </div>
-    </wicket:extend>
-  </body>
+  <wicket:extend>
+    <div id="transformersContainer">
+      <form wicket:id="form">
+        <div id="body">
+          <span wicket:id="classes"/>
+        </div>
+        <div id="footer">
+          <input type="button" wicket:id="submit" class="btn" wicket:message="value:finish"></input>
+        </div>
+      </form>
+    </div>
+  </wicket:extend>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
index d1be46a..5eb7db0 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/topology/TopologyTogglePanel.html
@@ -17,46 +17,43 @@ specific language governing permissions and limitations
 under the License.
 -->
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
-  <head><title>toggle menu</title></head>
-  <body>
-    <wicket:extend>
-      <div wicket:id="container" >
-        <wicket:container wicket:id="actions" />
-      </div>
+  <wicket:extend>
+    <div wicket:id="container" >
+      <wicket:container wicket:id="actions" />
+    </div>
 
-      <wicket:fragment wicket:id="connectorActions">
-        <ul class="menu">
-          <li><i class="fa fa-plus"></i><a href="#" wicket:id="create"><wicket:message key="resource.menu.add"/></a></li>
-          <li><i class="fa fa-minus"></i><a href="#" wicket:id="delete"><wicket:message key="connector.menu.remove"/></a></li>
-          <li><i class="fa fa-pencil"></i><a href="#" wicket:id="edit"><wicket:message key="connector.menu.edit"/></a></li>
-        </ul>
-      </wicket:fragment>
+    <wicket:fragment wicket:id="connectorActions">
+      <ul class="menu">
+        <li><i class="fa fa-plus"></i><a href="#" wicket:id="create"><wicket:message key="resource.menu.add"/></a></li>
+        <li><i class="fa fa-pencil"></i><a href="#" wicket:id="edit"><wicket:message key="connector.menu.edit"/></a></li>
+        <li><i class="fa fa-minus"></i><a href="#" wicket:id="delete"><wicket:message key="connector.menu.remove"/></a></li>
+      </ul>
+    </wicket:fragment>
 
-      <wicket:fragment wicket:id="resourceActions">
-        <ul class="menu">
-          <li><i class="fa fa-minus"></i><a href="#" wicket:id="delete"><wicket:message key="resource.menu.remove"/></a></li>
-          <li><i class="fa fa-pencil"></i><a href="#" wicket:id="edit"><wicket:message key="resource.menu.edit"/></a></li>
-          <li><i class="fa fa-exchange"></i><a href="#" wicket:id="provision"><wicket:message key="resource.menu.provision"/></a></li>
-          <li><i class="fa fa-eye"></i><a href="#" wicket:id="explore"><wicket:message key="resource.menu.explore"/></a></li>
-          <li><i class="fa fa-arrow-right"></i><a href="#" wicket:id="propagation"><wicket:message key="task.propagation.list"/></a></li>
-          <li><i class="fa fa-chevron-circle-left"></i><a href="#" wicket:id="pull"><wicket:message key="task.pull.list"/></a></li>
-          <li><i class="fa fa-chevron-circle-right"></i><a href="#" wicket:id="push"><wicket:message key="task.push.list"/></a></li>
-        </ul>
-      </wicket:fragment>
+    <wicket:fragment wicket:id="resourceActions">
+      <ul class="menu">
+        <li><i class="fa fa-pencil"></i><a href="#" wicket:id="edit"><wicket:message key="resource.menu.edit"/></a></li>
+        <li><i class="fa fa-exchange"></i><a href="#" wicket:id="provision"><wicket:message key="resource.menu.provision"/></a></li>
+        <li><i class="fa fa-eye"></i><a href="#" wicket:id="explore"><wicket:message key="resource.menu.explore"/></a></li>
+        <li><i class="fa fa-arrow-right"></i><a href="#" wicket:id="propagation"><wicket:message key="task.propagation.list"/></a></li>
+        <li><i class="fa fa-chevron-circle-left"></i><a href="#" wicket:id="pull"><wicket:message key="task.pull.list"/></a></li>
+        <li><i class="fa fa-chevron-circle-right"></i><a href="#" wicket:id="push"><wicket:message key="task.push.list"/></a></li>
+        <li><i class="fa fa-minus"></i><a href="#" wicket:id="delete"><wicket:message key="resource.menu.remove"/></a></li>
+      </ul>
+    </wicket:fragment>
 
-      <wicket:fragment wicket:id="locationActions">
-        <ul class="menu">
-          <li><i class="fa fa-plus"></i><a href="#" wicket:id="create"><wicket:message key="connector.menu.add"/></a></li>
-        </ul>
-      </wicket:fragment>
+    <wicket:fragment wicket:id="locationActions">
+      <ul class="menu">
+        <li><i class="fa fa-plus"></i><a href="#" wicket:id="create"><wicket:message key="connector.menu.add"/></a></li>
+      </ul>
+    </wicket:fragment>
 
-      <wicket:fragment wicket:id="syncopeActions">
-        <ul class="menu">
-          <li><i class="fa fa-tasks"></i><a href="#" wicket:id="tasks"><wicket:message key="task.custom.list"/></a></li>
-        </ul>
-      </wicket:fragment>
+    <wicket:fragment wicket:id="syncopeActions">
+      <ul class="menu">
+        <li><i class="fa fa-tasks"></i><a href="#" wicket:id="tasks"><wicket:message key="task.custom.list"/></a></li>
+      </ul>
+    </wicket:fragment>
 
-      <wicket:fragment wicket:id="emptyFragment"></wicket:fragment>
-    </wicket:extend>
-  </body>
+    <wicket:fragment wicket:id="emptyFragment"></wicket:fragment>
+  </wicket:extend>
 </html>

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel.properties
index abd1449..dc8013d 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel.properties
@@ -16,3 +16,4 @@
 # under the License.
 check=Check connection
 property.empty.list=No connector configuraton property available
+error_connection=Connection failure

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_it.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_it.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_it.properties
index 75979ae..6b31d94 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_it.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_it.properties
@@ -16,3 +16,4 @@
 # under the License.
 check=Verifica connessione
 property.empty.list=Nessuna propriet\u00e0 di connettore disponibile
+error_connection=Connessione non riuscita

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_pt_BR.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_pt_BR.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_pt_BR.properties
index 221a3b9..24e7b44 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_pt_BR.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_pt_BR.properties
@@ -16,3 +16,4 @@
 # under the License.
 check=Verificar a Conex\u00e3o
 property.empty.list=No connector configuraton property available
+error_connection=Falha na Conex\u00e3o

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_ru.properties
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_ru.properties b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_ru.properties
index cb72f38..1878667 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_ru.properties
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/AbstractConnConfPanel_ru.properties
@@ -19,3 +19,4 @@
 check=\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435
 # attribute.empty.list=\u00d0\u0092\u00d0\u00b8\u00d1\u0080\u00d1\u0082\u00d1\u0083\u00d0\u00b0\u00d0\u00bb\u00d1\u008c\u00d0\u00bd\u00d1\u008b\u00d0\u00b5 \u00d0\u00b0\u00d1\u0082\u00d1\u0080\u00d0\u00b8\u00d0\u00b1\u00d1\u0083\u00d1\u0082\u00d1\u008b \u00d0\u00be\u00d1\u0082\u00d1\u0081\u00d1\u0083\u00d1\u0082\u00d1\u0081\u00d1\u0082\u00d0\u00b2\u00d1\u0083\u00d1\u008e\u00d1\u0082
 property.empty.list=\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442
+error_connection=Connection failure

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.html
----------------------------------------------------------------------
diff --git a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.html b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.html
index b202b23..4214ee5 100644
--- a/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.html
+++ b/client/console/src/main/resources/org/apache/syncope/client/console/wizards/resources/ResourceMappingPanel.html
@@ -39,7 +39,7 @@ under the License.
               <th><wicket:message key="connObjectKey"/></th>
               <th><label wicket:id="passwordLabel"/></th>
               <th><wicket:message key="purpose"/></th>
-              <th><i class="fa fa-trash"></i></th>
+              <th></th>
             </tr>
             <tr wicket:id="mappings">
               <td>

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/common/lib/src/main/java/org/apache/syncope/common/lib/report/GroupReportletConf.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/GroupReportletConf.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/GroupReportletConf.java
index 68f64dd..6712b30 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/report/GroupReportletConf.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/report/GroupReportletConf.java
@@ -47,13 +47,13 @@ public class GroupReportletConf extends AbstractAnyReportletConf {
 
     }
 
-    @Schema(schema = IntMappingType.GroupPlainSchema)
+    @Schema(type = IntMappingType.GroupPlainSchema)
     private final List<String> plainAttrs = new ArrayList<>();
 
-    @Schema(schema = IntMappingType.GroupDerivedSchema)
+    @Schema(type = IntMappingType.GroupDerivedSchema)
     private final List<String> derAttrs = new ArrayList<>();
 
-    @Schema(schema = IntMappingType.GroupVirtualSchema)
+    @Schema(type = IntMappingType.GroupVirtualSchema)
     private final List<String> virAttrs = new ArrayList<>();
 
     @SearchCondition(type = "GROUP")

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/common/lib/src/main/java/org/apache/syncope/common/lib/report/Schema.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/Schema.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/Schema.java
index aea2fe9..1aad334 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/report/Schema.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/report/Schema.java
@@ -28,5 +28,5 @@ import org.apache.syncope.common.lib.types.IntMappingType;
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Schema {
 
-    IntMappingType schema() default IntMappingType.UserPlainSchema;
+    IntMappingType type() default IntMappingType.UserPlainSchema;
 }

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java b/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
index ac6f430..bcaadbb 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/report/UserReportletConf.java
@@ -32,13 +32,15 @@ import org.apache.syncope.common.lib.types.IntMappingType;
 @XmlType
 public class UserReportletConf extends AbstractAnyReportletConf {
 
-    @Schema(schema = IntMappingType.UserPlainSchema)
+    private static final long serialVersionUID = 6602717600064602764L;
+
+    @Schema(type = IntMappingType.UserPlainSchema)
     private final List<String> plainAttrs = new ArrayList<>();
 
-    @Schema(schema = IntMappingType.UserDerivedSchema)
+    @Schema(type = IntMappingType.UserDerivedSchema)
     private final List<String> derAttrs = new ArrayList<>();
 
-    @Schema(schema = IntMappingType.UserVirtualSchema)
+    @Schema(type = IntMappingType.UserVirtualSchema)
     private final List<String> virAttrs = new ArrayList<>();
 
     @XmlEnum
@@ -60,8 +62,6 @@ public class UserReportletConf extends AbstractAnyReportletConf {
 
     }
 
-    private static final long serialVersionUID = 6602717600064602764L;
-
     @SearchCondition(type = "USER")
     protected String matchingCond;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
index 89fab1e..e69cb95 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/to/MappingTO.java
@@ -72,7 +72,7 @@ public class MappingTO extends AbstractBaseBean {
             throw new IllegalArgumentException("Password attributes cannot be set as connObjectKey");
         }
 
-        connObjectItem.setExtAttrName(connObjectItem.getExtAttrName());
+        connObjectItem.setMandatoryCondition("true");
         connObjectItem.setConnObjectKey(true);
 
         return this.add(connObjectItem);

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/common/lib/src/main/java/org/apache/syncope/common/lib/types/ConnConfPropSchema.java
----------------------------------------------------------------------
diff --git a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ConnConfPropSchema.java b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ConnConfPropSchema.java
index d2e6c1f..8b0dbe6 100644
--- a/common/lib/src/main/java/org/apache/syncope/common/lib/types/ConnConfPropSchema.java
+++ b/common/lib/src/main/java/org/apache/syncope/common/lib/types/ConnConfPropSchema.java
@@ -39,7 +39,7 @@ public class ConnConfPropSchema extends AbstractBaseBean implements Comparable<C
 
     private String helpMessage;
 
-    private String type;
+    private String type = String.class.getName();
 
     private boolean required;
 

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/core/migration/pom.xml
----------------------------------------------------------------------
diff --git a/core/migration/pom.xml b/core/migration/pom.xml
new file mode 100644
index 0000000..86e75eb
--- /dev/null
+++ b/core/migration/pom.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.syncope</groupId>
+    <artifactId>syncope-core</artifactId>
+    <version>2.0.0-SNAPSHOT</version>
+  </parent>
+
+  <name>Apache Syncope Core Migration</name>
+  <description>Apache Syncope Core Migration</description>
+  <groupId>org.apache.syncope.core</groupId>
+  <artifactId>syncope-core-migration</artifactId>
+  <packaging>jar</packaging>
+  
+  <properties>
+    <rootpom.basedir>${basedir}/../..</rootpom.basedir>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.syncope.core</groupId>
+      <artifactId>syncope-core-provisioning-java</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>${basedir}/src/main/resources</directory>
+        <filtering>true</filtering>
+      </resource>
+    </resources>
+        
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+      </plugin>
+    </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/core/migration/src/main/java/org/apache/syncope/core/migration/MigrationPullActions.java
----------------------------------------------------------------------
diff --git a/core/migration/src/main/java/org/apache/syncope/core/migration/MigrationPullActions.java b/core/migration/src/main/java/org/apache/syncope/core/migration/MigrationPullActions.java
new file mode 100644
index 0000000..5119ece
--- /dev/null
+++ b/core/migration/src/main/java/org/apache/syncope/core/migration/MigrationPullActions.java
@@ -0,0 +1,149 @@
+/*
+ * 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.core.migration;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.TransformerUtils;
+import org.apache.syncope.common.lib.to.AnyTO;
+import org.apache.syncope.common.lib.to.GroupTO;
+import org.apache.syncope.common.lib.to.UserTO;
+import org.apache.syncope.common.lib.types.CipherAlgorithm;
+import org.apache.syncope.core.persistence.api.dao.UserDAO;
+import org.apache.syncope.core.persistence.api.entity.user.User;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningProfile;
+import org.apache.syncope.core.provisioning.api.pushpull.ProvisioningReport;
+import org.apache.syncope.core.provisioning.java.job.SetUMembershipsJob;
+import org.apache.syncope.core.provisioning.java.pushpull.SchedulingPullActions;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.Attribute;
+import org.identityconnectors.framework.common.objects.AttributeUtil;
+import org.identityconnectors.framework.common.objects.SyncDelta;
+import org.quartz.JobExecutionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Transactional;
+
+public class MigrationPullActions extends SchedulingPullActions {
+
+    private static final Logger LOG = LoggerFactory.getLogger(MigrationPullActions.class);
+
+    private static final String CIPHER_ALGORITHM_ATTR = "cipherAlgorithm";
+
+    private static final String RESOURCES_ATTR = "__RESOURCES__";
+
+    private static final String MEMBERSHIPS_ATTR = "__MEMBERSHIPS__";
+
+    @Autowired
+    private UserDAO userDAO;
+
+    private final Map<String, Set<String>> memberships = new HashMap<>();
+
+    @Override
+    public <A extends AnyTO> SyncDelta beforeProvision(
+            final ProvisioningProfile<?, ?> profile,
+            final SyncDelta delta,
+            final A any) throws JobExecutionException {
+
+        // handles resource assignment, for users and groups
+        Attribute resourcesAttr = delta.getObject().getAttributeByName(RESOURCES_ATTR);
+        if (resourcesAttr != null
+                && resourcesAttr.getValue() != null && !resourcesAttr.getValue().isEmpty()) {
+
+            LOG.debug("Found {} for {} {}, adding...", RESOURCES_ATTR, any.getType(), any.getKey());
+
+            any.getResources().addAll(
+                    CollectionUtils.collect(resourcesAttr.getValue(), TransformerUtils.stringValueTransformer()));
+        }
+
+        return delta;
+    }
+
+    @Transactional
+    @Override
+    public <A extends AnyTO> void after(
+            final ProvisioningProfile<?, ?> profile, final SyncDelta delta, final A any,
+            final ProvisioningReport result)
+            throws JobExecutionException {
+
+        if (any instanceof UserTO) {
+            // handles ciphered password import
+            CipherAlgorithm cipherAlgorithm = null;
+            Attribute cipherAlgorithmAttr = delta.getObject().getAttributeByName(CIPHER_ALGORITHM_ATTR);
+            if (cipherAlgorithmAttr != null
+                    && cipherAlgorithmAttr.getValue() != null && !cipherAlgorithmAttr.getValue().isEmpty()) {
+
+                cipherAlgorithm = CipherAlgorithm.valueOf(cipherAlgorithmAttr.getValue().get(0).toString());
+            }
+
+            GuardedString passwordValue = AttributeUtil.getPasswordValue(delta.getObject().getAttributes());
+
+            if (cipherAlgorithm != null && passwordValue != null) {
+                final StringBuilder password = new StringBuilder();
+                passwordValue.access(new GuardedString.Accessor() {
+
+                    @Override
+                    public void access(final char[] clearChars) {
+                        password.append(clearChars);
+                    }
+                });
+
+                User user = userDAO.find(any.getKey());
+                LOG.debug("Setting encoded password for {}", user);
+                user.setEncodedPassword(password.toString(), cipherAlgorithm);
+            }
+        } else if (any instanceof GroupTO) {
+            // handles group membership
+            Attribute membershipsAttr = delta.getObject().getAttributeByName(MEMBERSHIPS_ATTR);
+            if (membershipsAttr != null
+                    && membershipsAttr.getValue() != null && !membershipsAttr.getValue().isEmpty()) {
+
+                LOG.debug("Found {} for group {}", MEMBERSHIPS_ATTR, any.getKey());
+
+                for (Object membership : membershipsAttr.getValue()) {
+                    User member = userDAO.findByUsername(membership.toString());
+                    if (member == null) {
+                        LOG.warn("Could not find member {} for group {}", membership, any.getKey());
+                    } else {
+                        Set<String> memb = memberships.get(member.getKey());
+                        if (memb == null) {
+                            memb = new HashSet<>();
+                            memberships.put(member.getKey(), memb);
+                        }
+                        memb.add(any.getKey());
+                    }
+                }
+            }
+        } else {
+            super.after(profile, delta, any, result);
+        }
+    }
+
+    @Override
+    public void afterAll(final ProvisioningProfile<?, ?> profile) throws JobExecutionException {
+        Map<String, Object> jobMap = new HashMap<>();
+        jobMap.put(SetUMembershipsJob.MEMBERSHIPS_KEY, memberships);
+        schedule(SetUMembershipsJob.class, jobMap);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/core/migration/src/main/resources/scripted/SchemaScript.groovy
----------------------------------------------------------------------
diff --git a/core/migration/src/main/resources/scripted/SchemaScript.groovy b/core/migration/src/main/resources/scripted/SchemaScript.groovy
new file mode 100644
index 0000000..8a009a2
--- /dev/null
+++ b/core/migration/src/main/resources/scripted/SchemaScript.groovy
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+import groovy.sql.Sql;
+import org.identityconnectors.common.security.GuardedString;
+import org.identityconnectors.framework.common.objects.AttributeInfo;
+import org.identityconnectors.framework.common.objects.AttributeInfo.Flags;
+import org.identityconnectors.framework.common.objects.AttributeInfoBuilder;
+import org.identityconnectors.framework.common.objects.ObjectClassInfo;
+import org.identityconnectors.framework.common.objects.ObjectClassInfoBuilder;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// action: a string describing the action ("SCHEMA" here)
+// log: a handler to the Log facility
+// builder: SchemaBuilder instance for the connector
+//
+// The connector will make the final call to builder.build()
+// so the scipt just need to declare the different object types.
+
+def getAIB(it) {
+  aib = new AttributeInfoBuilder(it.NAME);
+    
+  switch(it.TYPE) {
+  case "String":
+  case "Date":
+  case "Enum":
+    aib.setType(String.class);
+    break;
+      
+  case "Long":
+    aib.setType(Long.class);
+    break;
+        
+  case "Double":
+    aib.setType(Double.class);
+    break;
+
+  case "Boolean":
+    aib.setType(Boolean.class);
+    break;
+  
+  case "Encrypted":
+    aib.setType(GuardedString.class);
+    
+  case "Binary":
+    aib.setType(byte[].class);
+  }
+    
+  if (it.MULTIVALUE == 1) {
+    aib.setMultiValued(true);
+  }
+    
+  if (it.MANDATORYCONDITION == "true") {
+    aib.setRequired(true);
+  }
+
+  return aib;
+}
+
+log.ok("Entering " + action + " script");
+
+// User
+idAIB = new AttributeInfoBuilder("USERNAME", String.class);
+idAIB.setRequired(true);
+
+userAI = new HashSet<AttributeInfo>();
+userAI.add(idAIB.build());
+
+def sql = new Sql(connection);
+sql.eachRow("SELECT NAME, TYPE, MULTIVALUE, MANDATORYCONDITION FROM USCHEMA", {    
+    userAI.add(getAIB(it).build());
+  });
+
+ObjectClassInfo userCI = new ObjectClassInfoBuilder().setType("__ACCOUNT__").addAllAttributeInfo(userAI).build();
+builder.defineObjectClass(userCI);
+
+// Group
+idAIB = new AttributeInfoBuilder("NAME", String.class);
+idAIB.setRequired(true);
+
+roleAI = new HashSet<AttributeInfo>();
+roleAI.add(idAIB.build());
+
+sql.eachRow("SELECT NAME, TYPE, MULTIVALUE, MANDATORYCONDITION FROM RSCHEMA", {    
+    roleAI.add(getAIB(it).build());
+  });
+
+ObjectClassInfo roleCI = new ObjectClassInfoBuilder().setType("__GROUP__").addAllAttributeInfo(roleAI).build();
+builder.defineObjectClass(roleCI);
+
+log.ok(action + " script done");

http://git-wip-us.apache.org/repos/asf/syncope/blob/9ef16775/core/migration/src/main/resources/scripted/SearchScript.groovy
----------------------------------------------------------------------
diff --git a/core/migration/src/main/resources/scripted/SearchScript.groovy b/core/migration/src/main/resources/scripted/SearchScript.groovy
new file mode 100644
index 0000000..92a640c
--- /dev/null
+++ b/core/migration/src/main/resources/scripted/SearchScript.groovy
@@ -0,0 +1,165 @@
+/*
+ * 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.
+ */
+import groovy.sql.Sql;
+import org.identityconnectors.framework.common.objects.OperationOptions;
+import org.identityconnectors.common.security.GuardedString;
+
+// Parameters:
+// The connector sends the following:
+// connection: handler to the SQL connection
+// objectClass: a String describing the Object class (__ACCOUNT__ / __GROUP__ / other)
+// action: a string describing the action ("SEARCH" here)
+// log: a handler to the Log facility
+// options: a handler to the OperationOptions Map
+// query: a handler to the Query Map
+//
+// The Query map describes the filter used.
+//
+// query = [ operation: "CONTAINS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "ENDSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "STARTSWITH", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "EQUALS", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "GREATERTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHAN", left: attribute, right: "value", not: true/false ]
+// query = [ operation: "LESSTHANOREQUAL", left: attribute, right: "value", not: true/false ]
+// query = null : then we assume we fetch everything
+//
+// AND and OR filter just embed a left/right couple of queries.
+// query = [ operation: "AND", left: query1, right: query2 ]
+// query = [ operation: "OR", left: query1, right: query2 ]
+//
+// Returns: A list of Maps. Each map describing one row.
+// !!!! Each Map must contain a '__UID__' and '__NAME__' attribute.
+// This is required to build a ConnectorObject.
+
+def addAttributes(it) {
+  value = it.stringValue;
+  if (value == null) {
+    value = it.longValue;
+  }
+  if (value == null) {
+    value = it.doubleValue;
+  }
+  if (value == null) {
+    if (it.dateValue instanceof java.sql.Timestamp) {
+      value = new Date(it.dateValue.getTime()).format("yyyy-MM-dd HH:mm:ss");
+    }
+  }
+  if (value == null) {
+    value = it.booleanValue;
+  }
+          
+  if (options[OperationOptions.OP_ATTRIBUTES_TO_GET].contains(it.schema_name)) {
+    item.put(it.schema_name, value);
+    withValues.add(it.schema_name);
+  }
+}
+
+log.ok("Entering " + action + " script");
+
+def sql = new Sql(connection);
+def result = []
+
+switch ( objectClass ) {
+case "__ACCOUNT__":
+  sql.eachRow("SELECT * FROM USER_SEARCH", {
+      item = [
+        __UID__: it.username, 
+        __NAME__: it.username, 
+        username: it.username,
+        __PASSWORD__: new GuardedString(it.password.toCharArray()),
+        cipherAlgorithm: it.cipherAlgorithm,
+        __ENABLE__: it.suspended == 0
+      ];
+      
+      withValues = ['__UID__', '__NAME__', '__PASSWORD__', 'cipherAlgorithm', '__ENABLE__', 'username'];
+      
+      sql.eachRow("SELECT * FROM USER_SEARCH_ATTR WHERE subject_id = " + it.id, {
+          addAttributes(it);
+        });
+      sql.eachRow("SELECT * FROM USER_SEARCH_UNIQUE_ATTR WHERE subject_id = " + it.id, {
+          addAttributes(it);
+        });
+      
+      for (attr in options[OperationOptions.OP_ATTRIBUTES_TO_GET]) {
+        if (!withValues.contains(attr)) {
+          item.put(attr, null);          
+        }
+      }
+      
+      resources = [];
+      sql.eachRow("SELECT DISTINCT * FROM USER_SEARCH_RESOURCE WHERE subject_id = " + it.id, {
+          resources.add(it.resource_name);
+        });      
+      item.put('__RESOURCES__', resources);
+      
+      result.add(item)
+    });
+  break
+
+case "__GROUP__":
+  sql.eachRow("SELECT * FROM ROLE_SEARCH", {
+      name = it.id + ' ' + it.name;
+      item = [
+        __UID__: name, 
+        __NAME__: name, 
+        __ENABLE__: true, 
+        name: name
+      ];
+      
+      withValues = ['__UID__', '__NAME__', '__ENABLE__', 'name'];
+      
+      sql.eachRow("SELECT * FROM ROLE_SEARCH_ATTR WHERE subject_id = " + it.id, {
+          addAttributes(it);
+        });
+      sql.eachRow("SELECT * FROM ROLE_SEARCH_UNIQUE_ATTR WHERE subject_id = " + it.id, {
+          addAttributes(it);
+        });
+      
+      for (attr in options[OperationOptions.OP_ATTRIBUTES_TO_GET]) {
+        if (!withValues.contains(attr)) {
+          item.put(attr, null);          
+        }
+      }
+
+      resources = [];
+      sql.eachRow("SELECT DISTINCT * FROM ROLE_SEARCH_RESOURCE WHERE subject_id = " + it.id, {
+          resources.add(it.resource_name);
+        });      
+      item.put('__RESOURCES__', resources);
+
+      memberships = [];
+      sql.eachRow("SELECT u.username as username FROM USER_SEARCH_MEMBERSHIP usm, USER_SEARCH u "
+        +"WHERE u.subject_id=usm.subject_id AND usm.role_id =" + it.id, {
+          memberships.add(it.username);
+        });      
+      item.put('__MEMBERSHIPS__', memberships);
+
+      result.add(item)
+    });
+  break
+  
+default:
+  result;
+}
+
+log.ok(action + " script done");
+
+return result;


Mime
View raw message