You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@syncope.apache.org by il...@apache.org on 2014/06/30 12:15:20 UTC

svn commit: r1606667 - in /syncope/trunk: common/src/main/java/org/apache/syncope/common/to/ common/src/main/java/org/apache/syncope/common/types/ console/src/main/java/org/apache/syncope/console/pages/ console/src/main/java/org/apache/syncope/console/...

Author: ilgrosso
Date: Mon Jun 30 10:15:19 2014
New Revision: 1606667

URL: http://svn.apache.org/r1606667
Log:
[SYNCOPE-164] implementation provided for core and console

Modified:
    syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AccountPolicyTO.java
    syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AccountPolicySpec.java
    syncope/trunk/common/src/main/java/org/apache/syncope/common/types/ConnectorCapability.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/AbstractSyncTaskModalPage.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/PolicyModalPage.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Resources.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/StatusModalPage.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AbstractSearchPanel.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/PoliciesPanel.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourcesPanel.java
    syncope/trunk/console/src/main/java/org/apache/syncope/console/rest/ResourceRestClient.java
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Configuration.html
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/DisplayAttributesModalPage.html
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.html
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage_it.properties
    syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage_pt_BR.properties
    syncope/trunk/core/pom.xml
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AccountPolicy.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/PolicyDAO.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/PolicyDAOImpl.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/ResourceDAOImpl.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncopeUserValidator.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/Connector.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AbstractPropagationTaskExecutor.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AsyncConnectorFacade.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/ConnectorFacadeProxy.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/PolicyDataBinder.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java
    syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/DBPasswordSyncActions.java
    syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java
    syncope/trunk/core/src/test/resources/content.xml

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AccountPolicyTO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AccountPolicyTO.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AccountPolicyTO.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/to/AccountPolicyTO.java Mon Jun 30 10:15:19 2014
@@ -18,6 +18,11 @@
  */
 package org.apache.syncope.common.to;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlType;
 
@@ -32,6 +37,8 @@ public class AccountPolicyTO extends Abs
 
     private AccountPolicySpec specification;
 
+    private final List<String> resources = new ArrayList<String>();
+
     public AccountPolicyTO() {
         this(false);
     }
@@ -52,4 +59,11 @@ public class AccountPolicyTO extends Abs
     public AccountPolicySpec getSpecification() {
         return specification;
     }
+
+    @XmlElementWrapper(name = "resources")
+    @XmlElement(name = "resource")
+    @JsonProperty("resources")
+    public List<String> getResources() {
+        return resources;
+    }
 }

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AccountPolicySpec.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AccountPolicySpec.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AccountPolicySpec.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/types/AccountPolicySpec.java Mon Jun 30 10:15:19 2014
@@ -80,8 +80,7 @@ public class AccountPolicySpec extends A
     private boolean allLowerCase;
 
     /**
-     * Specify if it must be propagate suspension in case of maximum subsequent
-     * failed logins reached.
+     * Specify if, when reached the maximum allowed number of subsequent login failures, user shall be suspended.
      */
     private boolean propagateSuspension;
 

Modified: syncope/trunk/common/src/main/java/org/apache/syncope/common/types/ConnectorCapability.java
URL: http://svn.apache.org/viewvc/syncope/trunk/common/src/main/java/org/apache/syncope/common/types/ConnectorCapability.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/common/src/main/java/org/apache/syncope/common/types/ConnectorCapability.java (original)
+++ syncope/trunk/common/src/main/java/org/apache/syncope/common/types/ConnectorCapability.java Mon Jun 30 10:15:19 2014
@@ -26,6 +26,7 @@ import javax.xml.bind.annotation.XmlEnum
 @XmlEnum
 public enum ConnectorCapability {
 
+    AUTHENTICATE,
     ONE_PHASE_CREATE,
     TWO_PHASES_CREATE,
     ONE_PHASE_UPDATE,

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/AbstractSyncTaskModalPage.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/AbstractSyncTaskModalPage.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/AbstractSyncTaskModalPage.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/AbstractSyncTaskModalPage.java Mon Jun 30 10:15:19 2014
@@ -70,7 +70,7 @@ public abstract class AbstractSyncTaskMo
             protected List<String> load() {
                 final List<String> resourceNames = new ArrayList<String>();
 
-                for (ResourceTO resourceTO : resourceRestClient.getAllResources()) {
+                for (ResourceTO resourceTO : resourceRestClient.getAll()) {
 
                     resourceNames.add(resourceTO.getName());
                 }

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/PolicyModalPage.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/PolicyModalPage.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/PolicyModalPage.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/PolicyModalPage.java Mon Jun 30 10:15:19 2014
@@ -23,9 +23,10 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import org.apache.syncope.common.to.AbstractPolicyTO;
 import org.apache.syncope.common.to.AccountPolicyTO;
 import org.apache.syncope.common.to.PasswordPolicyTO;
-import org.apache.syncope.common.to.AbstractPolicyTO;
+import org.apache.syncope.common.to.ResourceTO;
 import org.apache.syncope.common.to.RoleTO;
 import org.apache.syncope.common.to.SyncPolicyTO;
 import org.apache.syncope.common.types.AbstractPolicySpec;
@@ -37,13 +38,13 @@ import org.apache.syncope.console.common
 import org.apache.syncope.console.pages.panels.NotificationPanel;
 import org.apache.syncope.console.pages.panels.PolicyBeanPanel;
 import org.apache.syncope.console.rest.PolicyRestClient;
-import org.apache.syncope.console.rest.ResourceRestClient;
-import org.apache.syncope.console.rest.RoleRestClient;
 import org.apache.syncope.console.wicket.markup.html.form.ActionLink;
 import org.apache.syncope.console.wicket.markup.html.form.ActionLinksPanel;
 import org.apache.syncope.console.wicket.markup.html.form.AjaxDropDownChoicePanel;
+import org.apache.syncope.console.wicket.markup.html.form.AjaxPalettePanel;
 import org.apache.syncope.console.wicket.markup.html.form.AjaxTextFieldPanel;
 import org.apache.wicket.Page;
+import org.apache.wicket.PageReference;
 import org.apache.wicket.ajax.AjaxRequestTarget;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxButton;
@@ -58,12 +59,14 @@ import org.apache.wicket.extensions.mark
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.ChoiceRenderer;
 import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.panel.Fragment;
 import org.apache.wicket.markup.repeater.Item;
 import org.apache.wicket.model.IModel;
 import org.apache.wicket.model.Model;
 import org.apache.wicket.model.PropertyModel;
 import org.apache.wicket.model.ResourceModel;
 import org.apache.wicket.model.StringResourceModel;
+import org.apache.wicket.model.util.ListModel;
 import org.apache.wicket.spring.injection.annot.SpringBean;
 
 /**
@@ -80,16 +83,10 @@ public class PolicyModalPage<T extends A
     @SpringBean
     private PolicyRestClient policyRestClient;
 
-    @SpringBean
-    private ResourceRestClient resourceRestClient;
-
-    @SpringBean
-    private RoleRestClient roleRestClient;
-
-    public PolicyModalPage(final ModalWindow window, final T policyTO) {
+    public PolicyModalPage(final PageReference pageRef, final ModalWindow window, final T policyTO) {
         super();
 
-        final Form form = new Form(FORM);
+        final Form<?> form = new Form<Void>(FORM);
         form.setOutputMarkupId(true);
         add(form);
 
@@ -107,7 +104,6 @@ public class PolicyModalPage<T extends A
 
         final AjaxDropDownChoicePanel<PolicyType> type = new AjaxDropDownChoicePanel<PolicyType>("type", "type",
                 new PropertyModel<PolicyType>(policyTO, "type"));
-
         switch (policyTO.getType()) {
             case GLOBAL_ACCOUNT:
             case ACCOUNT:
@@ -125,12 +121,28 @@ public class PolicyModalPage<T extends A
 
             default:
         }
-
         type.setChoiceRenderer(new PolicyTypeRenderer());
-
         type.addRequiredLabel();
         form.add(type);
 
+        // Authentication resources - only for AccountPolicyTO
+        Fragment fragment;
+        if (policyTO instanceof AccountPolicyTO) {
+            fragment = new Fragment("forAccountOnly", "authResourcesFragment", form);
+
+            final List<String> resourceNames = new ArrayList<String>();
+            for (ResourceTO resource : resourceRestClient.getAll()) {
+                resourceNames.add(resource.getName());
+            }
+            fragment.add(new AjaxPalettePanel<String>("authResources",
+                    new PropertyModel<List<String>>(policyTO, "resources"),
+                    new ListModel<String>(resourceNames)));
+        } else {
+            fragment = new Fragment("forAccountOnly", "emptyFragment", form);
+        }
+        form.add(fragment);
+        //
+
         final AbstractPolicySpec policy = getPolicySpecification(policyTO);
 
         form.add(new PolicyBeanPanel("panel", policy));
@@ -220,7 +232,7 @@ public class PolicyModalPage<T extends A
             }
         };
         final AjaxFallbackDefaultDataTable<String, String> resources =
-                 new AjaxFallbackDefaultDataTable<String, String>("resources", resColumns, resDataProvider, 10);
+                new AjaxFallbackDefaultDataTable<String, String>("resources", resColumns, resDataProvider, 10);
         form.add(resources);
 
         List<IColumn<RoleTO, String>> roleColumns = new ArrayList<IColumn<RoleTO, String>>();
@@ -298,8 +310,9 @@ public class PolicyModalPage<T extends A
             }
         };
         final AjaxFallbackDefaultDataTable<RoleTO, String> roles =
-                 new AjaxFallbackDefaultDataTable<RoleTO, String>("roles", roleColumns, roleDataProvider, 10);
+                new AjaxFallbackDefaultDataTable<RoleTO, String>("roles", roleColumns, roleDataProvider, 10);
         form.add(roles);
+
         mwindow.setWindowClosedCallback(new ModalWindow.WindowClosedCallback() {
 
             private static final long serialVersionUID = 8804221891699487139L;
@@ -330,6 +343,7 @@ public class PolicyModalPage<T extends A
                     } else {
                         policyRestClient.createPolicy(policyTO);
                     }
+                    ((BasePage) pageRef.getPage()).setModalResult(true);
 
                     window.close(target);
                 } catch (Exception e) {
@@ -345,7 +359,6 @@ public class PolicyModalPage<T extends A
                 ((NotificationPanel) getPage().get(Constants.FEEDBACK)).refresh(target);
             }
         };
-
         form.add(submit);
 
         final IndicatingAjaxButton cancel = new IndicatingAjaxButton(CANCEL, new ResourceModel(CANCEL)) {
@@ -361,7 +374,6 @@ public class PolicyModalPage<T extends A
             protected void onError(final AjaxRequestTarget target, final Form<?> form) {
             }
         };
-
         cancel.setDefaultFormProcessing(false);
         form.add(cancel);
     }
@@ -400,8 +412,8 @@ public class PolicyModalPage<T extends A
             case GLOBAL_ACCOUNT:
             case ACCOUNT:
                 if (!(specification instanceof AccountPolicySpec)) {
-                    throw new ClassCastException("policy is type Account, but spec is not: " + specification.getClass().
-                            getName());
+                    throw new ClassCastException("policy is type Account, but spec is not: "
+                            + specification.getClass().getName());
                 }
                 ((AccountPolicyTO) policyTO).setSpecification((AccountPolicySpec) specification);
                 break;
@@ -418,8 +430,8 @@ public class PolicyModalPage<T extends A
             case GLOBAL_SYNC:
             case SYNC:
                 if (!(specification instanceof SyncPolicySpec)) {
-                    throw new ClassCastException("policy is type Sync, but spec is not: " + specification.getClass().
-                            getName());
+                    throw new ClassCastException("policy is type Sync, but spec is not: "
+                            + specification.getClass().getName());
                 }
                 ((SyncPolicyTO) policyTO).setSpecification((SyncPolicySpec) specification);
 

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Resources.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Resources.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Resources.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/Resources.java Mon Jun 30 10:15:19 2014
@@ -625,7 +625,7 @@ public class Resources extends BasePage 
         }
 
         public List<ResourceTO> getResourcesListDB() {
-            return resourceRestClient.getAllResources();
+            return resourceRestClient.getAll();
         }
     }
 

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/StatusModalPage.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/StatusModalPage.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/StatusModalPage.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/StatusModalPage.java Mon Jun 30 10:15:19 2014
@@ -490,7 +490,7 @@ public class StatusModalPage<T extends A
         @Override
         public List<StatusBean> getStatusBeans() {
             final List<String> resources = new ArrayList<String>();
-            for (ResourceTO resourceTO : resourceRestClient.getAllResources()) {
+            for (ResourceTO resourceTO : resourceRestClient.getAll()) {
                 resources.add(resourceTO.getName());
             }
 

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AbstractSearchPanel.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AbstractSearchPanel.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AbstractSearchPanel.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/AbstractSearchPanel.java Mon Jun 30 10:15:19 2014
@@ -179,7 +179,7 @@ public abstract class AbstractSearchPane
 
             @Override
             protected List<String> load() {
-                List<ResourceTO> resourceTOs = resourceRestClient.getAllResources();
+                List<ResourceTO> resourceTOs = resourceRestClient.getAll();
 
                 List<String> result = new ArrayList<String>(resourceTOs.size());
 

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/PoliciesPanel.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/PoliciesPanel.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/PoliciesPanel.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/PoliciesPanel.java Mon Jun 30 10:15:19 2014
@@ -32,6 +32,7 @@ import org.apache.syncope.console.common
 import org.apache.syncope.console.commons.PreferenceManager;
 import org.apache.syncope.console.commons.SortableDataProviderComparator;
 import org.apache.syncope.console.commons.XMLRolesReader;
+import org.apache.syncope.console.pages.BasePage;
 import org.apache.syncope.console.pages.PolicyModalPage;
 import org.apache.syncope.console.rest.PolicyRestClient;
 import org.apache.syncope.console.wicket.ajax.markup.html.ClearIndicatingAjaxLink;
@@ -88,6 +89,8 @@ public class PoliciesPanel extends Panel
     @SpringBean
     private PreferenceManager prefMan;
 
+    private final PageReference pageRef;
+
     private final int paginatorRows = prefMan.getPaginatorRows(getWebRequest(), Constants.PREF_POLICY_PAGINATOR_ROWS);
 
     protected boolean modalResult = false;
@@ -96,7 +99,7 @@ public class PoliciesPanel extends Panel
 
     public PoliciesPanel(final String id, final PageReference pageRef, final PolicyType policyType) {
         super(id);
-
+        this.pageRef = pageRef;
         this.policyType = policyType;
 
         // Modal window for editing user attributes
@@ -164,7 +167,7 @@ public class PoliciesPanel extends Panel
                             @SuppressWarnings({ "unchecked", "rawtypes" })
                             @Override
                             public Page createPage() {
-                                return new PolicyModalPage(mwindow, policyTO);
+                                return new PolicyModalPage(pageRef, mwindow, policyTO);
                             }
                         });
 
@@ -216,7 +219,7 @@ public class PoliciesPanel extends Panel
                     @SuppressWarnings({ "unchecked", "rawtypes" })
                     @Override
                     public Page createPage() {
-                        return new PolicyModalPage(mwindow, getPolicyTOInstance(policyType));
+                        return new PolicyModalPage(pageRef, mwindow, getPolicyTOInstance(policyType));
                     }
                 });
 
@@ -262,6 +265,12 @@ public class PoliciesPanel extends Panel
             @Override
             public void onClose(final AjaxRequestTarget target) {
                 target.add(container);
+                BasePage configuration = ((BasePage) pageRef.getPage());
+                if (configuration.isModalResult()) {
+                    info(getString(Constants.OPERATION_SUCCEEDED));
+                    configuration.getFeedbackPanel().refresh(target);
+                    configuration.setModalResult(false);
+                }
             }
         });
     }

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourcesPanel.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourcesPanel.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourcesPanel.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/pages/panels/ResourcesPanel.java Mon Jun 30 10:15:19 2014
@@ -98,7 +98,7 @@ public class ResourcesPanel extends Pane
         subjectTO = (AbstractSubjectTO) builder.to;
         previousResources = new HashSet<String>(subjectTO.getResources());
         allResources = new ArrayList<String>();
-        for (ResourceTO resourceTO : resourceRestClient.getAllResources()) {
+        for (ResourceTO resourceTO : resourceRestClient.getAll()) {
             allResources.add(resourceTO.getName());
         }
         Collections.sort(allResources);

Modified: syncope/trunk/console/src/main/java/org/apache/syncope/console/rest/ResourceRestClient.java
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/java/org/apache/syncope/console/rest/ResourceRestClient.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/java/org/apache/syncope/console/rest/ResourceRestClient.java (original)
+++ syncope/trunk/console/src/main/java/org/apache/syncope/console/rest/ResourceRestClient.java Mon Jun 30 10:15:19 2014
@@ -51,7 +51,7 @@ public class ResourceRestClient extends 
         return actions;
     }
 
-    public List<ResourceTO> getAllResources() {
+    public List<ResourceTO> getAll() {
         List<ResourceTO> resources = null;
 
         try {

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Configuration.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Configuration.html?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Configuration.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/Configuration.html Mon Jun 30 10:15:19 2014
@@ -52,17 +52,17 @@ under the License.
       <div id="policies">
         <ul>
           <li class="tabs-selected">
-            <a href="#password"><span><wicket:message key="password"/></span></a>
+            <a href="#account"><span><wicket:message key="account"/></span></a>
           </li>
-          <li><a href="#account"><span><wicket:message key="account"/></span></a></li>
+          <li><a href="#password"><span><wicket:message key="password"/></span></a></li>
           <li><a href="#sync"><span><wicket:message key="sync"/></span></a></li>
         </ul>
-        <div id="password" style="border-width: 1px;border-top-width: 0px;">
-          <span wicket:id="passwordPoliciesPanel">[password policies]</span>
-        </div>
         <div id="account" style="border-width: 1px;border-top-width: 0px;">
           <span wicket:id="accountPoliciesPanel">[account policies]</span>
         </div>
+        <div id="password" style="border-width: 1px;border-top-width: 0px;">
+          <span wicket:id="passwordPoliciesPanel">[password policies]</span>
+        </div>
         <div id="sync" style="border-width: 1px;border-top-width: 0px;">
           <span wicket:id="syncPoliciesPanel">[sync policies]</span>
         </div>

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/DisplayAttributesModalPage.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/DisplayAttributesModalPage.html?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/DisplayAttributesModalPage.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/DisplayAttributesModalPage.html Mon Jun 30 10:15:19 2014
@@ -16,115 +16,117 @@ KIND, either express or implied.  See th
 specific language governing permissions and limitations
 under the License.
 -->
-<wicket:head>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+  <wicket:head>
     <style>
-        div.group{
-            width:450px;
-        }
-
-        div.group div{
-            width:150;
-            height: 25px;
-            float:left;
-        }
-
-        div.group div input {
-            width: 30px;
-        }
-
-        div#attributes-view {
-            display:  block;
-            clear:  both;
-            float: none;
-            overflow: auto;
-            margin-top: 0px;
-            margin-bottom: 20px;
-            margin-left: 10px;
-            margin-right: 10px;
-        }
-
-        .submit{
-            display:  block;
-            clear:  both;
-            float: none;
-            margin-left: 10px;
-        }
-
-        span.grouplabel{
-            display:block;
-            clear: both;
-            margin-left: 10px;
-            margin-bottom: 10px;
-            font-weight: bold;
-        }
+      div.group{
+        width:450px;
+      }
+
+      div.group div{
+        width:150;
+        height: 25px;
+        float:left;
+      }
+
+      div.group div input {
+        width: 30px;
+      }
+
+      div#attributes-view {
+        display:  block;
+        clear:  both;
+        float: none;
+        overflow: auto;
+        margin-top: 0px;
+        margin-bottom: 20px;
+        margin-left: 10px;
+        margin-right: 10px;
+      }
+
+      .submit{
+        display:  block;
+        clear:  both;
+        float: none;
+        margin-left: 10px;
+      }
+
+      span.grouplabel{
+        display:block;
+        clear: both;
+        margin-left: 10px;
+        margin-bottom: 10px;
+        font-weight: bold;
+      }
     </style>
-</wicket:head>
-<wicket:extend>
+  </wicket:head>
+  <wicket:extend>
     <form wicket:id="form">
-        <div id="attributes-view">
-            <p class="ui-widget ui-corner-all ui-widget-header">
-            <wicket:message key="title"/>
-            </p>
-
-            <span class="grouplabel"><wicket:message key="schemas"/></span>
-            <span wicket:id="dCheckGroup">
-                <div class="group">
-                    <div wicket:id="details">
-                        <input type="checkbox" wicket:id="dcheck"/>
-                        <span wicket:id="dname">[schema name]</span>
-                    </div>
-                </div>
-            </span>
-
-            <span wicket:id="schemas">[schemas]</span>
-
-            <span wicket:id="dschemas">[derived schemas]</span>
-
-            <span wicket:id="vschemas">[virtual schemas]</span>
-
-        </div>
-
-        <wicket:fragment wicket:id="sfragment">
-            <span wicket:id="sCheckGroup">
-                <div class="group">
-                    <div wicket:id="schemas">
-                        <input type="checkbox" wicket:id="scheck"/>
-                        <span wicket:id="sname">[schema name]</span>
-                    </div>
-                </div>
-            </span>
-        </wicket:fragment>
-
-        <wicket:fragment wicket:id="dsfragment">
-            <span class="grouplabel"><wicket:message key="derSchemas"/></span>
-            <span wicket:id="dsCheckGroup">
-                <div class="group">
-                    <div wicket:id="derSchemas">
-                        <input type="checkbox" wicket:id="dscheck"/>
-                        <span wicket:id="dsname">[schema name]</span>
-                    </div>
-                </div>
-            </span>
-        </wicket:fragment>
-
-        <wicket:fragment wicket:id="vsfragment">
-            <span class="grouplabel"><wicket:message key="virSchemas"/></span>
-            <span wicket:id="vsCheckGroup">
-                <div class="group">
-                    <div wicket:id="virSchemas">
-                        <input type="checkbox" wicket:id="vscheck"/>
-                        <span wicket:id="vsname">[schema name]</span>
-                    </div>
-                </div>
-            </span>
-        </wicket:fragment>
-
-        <wicket:fragment wicket:id="emptyFragment">
-        </wicket:fragment>
-
-        <div class="submit">
-            <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="submit"/>
-            <input type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="cancel"/>
-        </div>
+      <div id="attributes-view">
+        <p class="ui-widget ui-corner-all ui-widget-header">
+          <wicket:message key="title"/>
+        </p>
+
+        <span class="grouplabel"><wicket:message key="schemas"/></span>
+        <span wicket:id="dCheckGroup">
+          <div class="group">
+            <div wicket:id="details">
+              <input type="checkbox" wicket:id="dcheck"/>
+              <span wicket:id="dname">[schema name]</span>
+            </div>
+          </div>
+        </span>
+
+        <span wicket:id="schemas">[schemas]</span>
+
+        <span wicket:id="dschemas">[derived schemas]</span>
+
+        <span wicket:id="vschemas">[virtual schemas]</span>
+
+      </div>
+
+      <wicket:fragment wicket:id="sfragment">
+        <span wicket:id="sCheckGroup">
+          <div class="group">
+            <div wicket:id="schemas">
+              <input type="checkbox" wicket:id="scheck"/>
+              <span wicket:id="sname">[schema name]</span>
+            </div>
+          </div>
+        </span>
+      </wicket:fragment>
+
+      <wicket:fragment wicket:id="dsfragment">
+        <span class="grouplabel"><wicket:message key="derSchemas"/></span>
+        <span wicket:id="dsCheckGroup">
+          <div class="group">
+            <div wicket:id="derSchemas">
+              <input type="checkbox" wicket:id="dscheck"/>
+              <span wicket:id="dsname">[schema name]</span>
+            </div>
+          </div>
+        </span>
+      </wicket:fragment>
+
+      <wicket:fragment wicket:id="vsfragment">
+        <span class="grouplabel"><wicket:message key="virSchemas"/></span>
+        <span wicket:id="vsCheckGroup">
+          <div class="group">
+            <div wicket:id="virSchemas">
+              <input type="checkbox" wicket:id="vscheck"/>
+              <span wicket:id="vsname">[schema name]</span>
+            </div>
+          </div>
+        </span>
+      </wicket:fragment>
+
+      <wicket:fragment wicket:id="emptyFragment">
+      </wicket:fragment>
+
+      <div class="submit">
+        <input type="submit" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="submit"/>
+        <input type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" wicket:id="cancel"/>
+      </div>
     </form>
-</wicket:extend>
+  </wicket:extend>
+</html>
\ No newline at end of file

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.html
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.html?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.html (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.html Mon Jun 30 10:15:19 2014
@@ -24,13 +24,13 @@ under the License.
       <form wicket:id="form">
         <div id="tabs">
           <ul>
-            <li class="tabs-selected"><a href="#description"><span><wicket:message key="policyDescription"/></span></a></li>
+            <li class="tabs-selected"><a href="#info"><span><wicket:message key="policyInfo"/></span></a></li>
             <li><a href="#specification"><span><wicket:message key="policySpecification"/></span></a></li>
             <li><a href="#resources"><span><wicket:message key="resources"/></span></a></li>
             <li><a href="#roles"><span><wicket:message key="roles"/></span></a></li>
           </ul>
 
-          <div id="description">
+          <div id="info">
             <div id="formtable">
               <div class="tablerow alt">
                 <div class="tablecolumn_label short_fixedsize">
@@ -58,9 +58,24 @@ under the License.
                   <span wicket:id="description">[description]</span>
                 </div>
               </div>
+
+              <span wicket:id="forAccountOnly"/>
             </div>
           </div>
 
+          <wicket:fragment wicket:id="authResourcesFragment">
+            <div class="tablerow">
+              <div class="tablecolumn_label short_fixedsize">
+                <label for="authResources"><wicket:message key="authResources"/></label>
+              </div>
+              <div class="tablecolumn_field medium_dynamicsize">
+                <span wicket:id="authResources">[resources]</span>
+              </div>
+            </div>
+          </wicket:fragment>
+          <wicket:fragment wicket:id="emptyFragment">
+          </wicket:fragment>                        
+
           <div id="specification">
             <span wicket:id="panel">[password policy panel]</span>
           </div>

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.properties?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage.properties Mon Jun 30 10:15:19 2014
@@ -20,7 +20,7 @@ description=Description
 type=Type
 apply=Save
 
-policyDescription = Info
+policyInfo=Info
 policySpecification = Specification
 
 #-----------------------------
@@ -84,3 +84,4 @@ GLOBAL_SYNC=Global Synchronization Polic
 #-----------------------------
 resources=Resources
 roles=Roles
+authResources=Authentication resources

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage_it.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage_it.properties?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage_it.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage_it.properties Mon Jun 30 10:15:19 2014
@@ -20,7 +20,7 @@ description=Descrizione
 type=Tipo
 apply=Salva
 
-policyDescription = Info
+policyInfo=Info
 policySpecification = Specifica
 
 #-----------------------------
@@ -84,3 +84,4 @@ userJavaRule=Regola di correlazione (ute
 roleJavaRule=Regola di correlazione (ruoli)
 resources=Risorse
 roles=Ruoli
+authResources=Risorse di autenticazione

Modified: syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage_pt_BR.properties
URL: http://svn.apache.org/viewvc/syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage_pt_BR.properties?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage_pt_BR.properties (original)
+++ syncope/trunk/console/src/main/resources/org/apache/syncope/console/pages/PolicyModalPage_pt_BR.properties Mon Jun 30 10:15:19 2014
@@ -20,7 +20,7 @@ description=Descri\u00e7\u00e3o
 type=Tipo
 apply=Salvar
 
-policyDescription = Info
+policyInfo=Info
 policySpecification = Especifica\u00e7\u00e3o
 
 #-----------------------------
@@ -83,3 +83,4 @@ SYNC=Pol\u00edtica de Sincroniza\u00e7\u
 GLOBAL_SYNC=Pol\u00edtica Global de sincroniza\u00e7\u00e3o
 resources=Recursos
 roles=Fun\u00e7\u00f5es
+authResources=Recursos de autentica\u00e7\u00e3o

Modified: syncope/trunk/core/pom.xml
URL: http://svn.apache.org/viewvc/syncope/trunk/core/pom.xml?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/pom.xml (original)
+++ syncope/trunk/core/pom.xml Mon Jun 30 10:15:19 2014
@@ -776,7 +776,7 @@ under the License.
                   <dependency>org.apache.geronimo.specs:geronimo-jpa_2.0_spec</dependency>
                   <dependency>org.apache.geronimo.specs:geronimo-jms_1.1_spec</dependency>
                   <dependency>org.apache.geronimo.specs:geronimo-jta_1.1_spec</dependency>
-                  <dependency>org.apache.geronimo.specs:geronimo-validation_1.0_spec</dependency>
+                  <dependency>javax.validation:validation-api</dependency>
                   <dependency>net.sourceforge.serp:serp</dependency>
                   <dependency>commons-pool:commons-pool</dependency>
                   <dependency>commons-dbcp:commons-dbcp</dependency>

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AccountPolicy.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AccountPolicy.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AccountPolicy.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/beans/AccountPolicy.java Mon Jun 30 10:15:19 2014
@@ -18,7 +18,15 @@
  */
 package org.apache.syncope.core.persistence.beans;
 
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
 import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
+import javax.validation.Valid;
 
 import org.apache.syncope.common.types.PolicyType;
 
@@ -27,15 +35,55 @@ public class AccountPolicy extends Polic
 
     private static final long serialVersionUID = -2767606675667839060L;
 
+    /**
+     * Resources for alternative user authentication: if empty, only internal storage will be used.
+     */
+    @ManyToMany(fetch = FetchType.EAGER)
+    @JoinTable(joinColumns =
+            @JoinColumn(name = "account_policy_id"),
+            inverseJoinColumns =
+            @JoinColumn(name = "resource_name"))
+    @Valid
+    private Set<ExternalResource> resources;
+
     public AccountPolicy() {
         this(false);
+        this.resources = new HashSet<ExternalResource>();
     }
 
-    public AccountPolicy(boolean global) {
+    public AccountPolicy(final boolean global) {
         super();
 
         this.type = global
                 ? PolicyType.GLOBAL_ACCOUNT
                 : PolicyType.ACCOUNT;
     }
+
+    public boolean addResource(final ExternalResource resource) {
+        return resources.add(resource);
+    }
+
+    public boolean removeResource(final ExternalResource resource) {
+        return resources.remove(resource);
+    }
+
+    public Set<ExternalResource> getResources() {
+        return resources;
+    }
+
+    public Set<String> getResourceNames() {
+        Set<String> result = new HashSet<String>(resources.size());
+        for (ExternalResource resource : resources) {
+            result.add(resource.getName());
+        }
+
+        return result;
+    }
+
+    public void setResources(final Collection<ExternalResource> resources) {
+        this.resources.clear();
+        if (resources != null) {
+            resources.addAll(resources);
+        }
+    }
 }

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/PolicyDAO.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/PolicyDAO.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/PolicyDAO.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/PolicyDAO.java Mon Jun 30 10:15:19 2014
@@ -22,6 +22,7 @@ import java.util.List;
 
 import org.apache.syncope.common.types.PolicyType;
 import org.apache.syncope.core.persistence.beans.AccountPolicy;
+import org.apache.syncope.core.persistence.beans.ExternalResource;
 import org.apache.syncope.core.persistence.beans.PasswordPolicy;
 import org.apache.syncope.core.persistence.beans.Policy;
 import org.apache.syncope.core.persistence.beans.PushPolicy;
@@ -33,6 +34,8 @@ public interface PolicyDAO extends DAO {
 
     List<? extends Policy> find(PolicyType type);
 
+    List<AccountPolicy> findByResource(ExternalResource resource);
+
     PasswordPolicy getGlobalPasswordPolicy();
 
     AccountPolicy getGlobalAccountPolicy();

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/PolicyDAOImpl.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/PolicyDAOImpl.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/PolicyDAOImpl.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/PolicyDAOImpl.java Mon Jun 30 10:15:19 2014
@@ -23,6 +23,7 @@ import javax.persistence.TypedQuery;
 import org.apache.syncope.common.types.EntityViolationType;
 import org.apache.syncope.common.types.PolicyType;
 import org.apache.syncope.core.persistence.beans.AccountPolicy;
+import org.apache.syncope.core.persistence.beans.ExternalResource;
 import org.apache.syncope.core.persistence.beans.PasswordPolicy;
 import org.apache.syncope.core.persistence.beans.Policy;
 import org.apache.syncope.core.persistence.beans.PushPolicy;
@@ -49,6 +50,16 @@ public class PolicyDAOImpl extends Abstr
     }
 
     @Override
+    public List<AccountPolicy> findByResource(final ExternalResource resource) {
+        TypedQuery<AccountPolicy> query = entityManager.createQuery("SELECT e FROM "
+                + AccountPolicy.class.getSimpleName() + " e "
+                + "WHERE :resource MEMBER OF e.resources", AccountPolicy.class);
+        query.setParameter("resource", resource);
+
+        return query.getResultList();
+    }
+
+    @Override
     public PasswordPolicy getGlobalPasswordPolicy() {
         List<? extends Policy> policies = find(PolicyType.GLOBAL_PASSWORD);
         return policies == null || policies.isEmpty()

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/ResourceDAOImpl.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/ResourceDAOImpl.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/ResourceDAOImpl.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/dao/impl/ResourceDAOImpl.java Mon Jun 30 10:15:19 2014
@@ -27,14 +27,17 @@ import org.apache.syncope.common.types.I
 import org.apache.syncope.common.types.PolicyType;
 import org.apache.syncope.core.persistence.beans.AbstractMapping;
 import org.apache.syncope.core.persistence.beans.AbstractMappingItem;
+import org.apache.syncope.core.persistence.beans.AccountPolicy;
 import org.apache.syncope.core.persistence.beans.ExternalResource;
 import org.apache.syncope.core.persistence.beans.Policy;
 import org.apache.syncope.core.persistence.beans.PropagationTask;
+import org.apache.syncope.core.persistence.beans.PushTask;
 import org.apache.syncope.core.persistence.beans.SyncTask;
 import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.persistence.dao.ConnectorRegistry;
 import org.apache.syncope.core.persistence.dao.NotFoundException;
+import org.apache.syncope.core.persistence.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.dao.ResourceDAO;
 import org.apache.syncope.core.persistence.dao.RoleDAO;
 import org.apache.syncope.core.persistence.dao.TaskDAO;
@@ -56,12 +59,15 @@ public class ResourceDAOImpl extends Abs
     private RoleDAO roleDAO;
 
     @Autowired
+    private PolicyDAO policyDAO;
+
+    @Autowired
     private ConnectorRegistry connRegistry;
 
     @Override
     public ExternalResource find(final String name) {
         TypedQuery<ExternalResource> query = entityManager.createQuery("SELECT e FROM "
-                + ExternalResource.class.getSimpleName() + " e " + "WHERE e.name = :name", ExternalResource.class);
+                + ExternalResource.class.getSimpleName() + " e WHERE e.name = :name", ExternalResource.class);
         query.setParameter("name", name);
 
         ExternalResource result = null;
@@ -195,6 +201,7 @@ public class ResourceDAOImpl extends Abs
 
         taskDAO.deleteAll(resource, PropagationTask.class);
         taskDAO.deleteAll(resource, SyncTask.class);
+        taskDAO.deleteAll(resource, PushTask.class);
 
         for (SyncopeUser user : userDAO.findByResource(resource)) {
             user.removeResource(resource);
@@ -202,6 +209,9 @@ public class ResourceDAOImpl extends Abs
         for (SyncopeRole role : roleDAO.findByResource(resource)) {
             role.removeResource(resource);
         }
+        for (AccountPolicy policy : policyDAO.findByResource(resource)) {
+            policy.removeResource(resource);
+        }
 
         if (resource.getConnector() != null && resource.getConnector().getResources() != null
                 && !resource.getConnector().getResources().isEmpty()) {

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncopeUserValidator.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncopeUserValidator.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncopeUserValidator.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/persistence/validation/entity/SyncopeUserValidator.java Mon Jun 30 10:15:19 2014
@@ -169,7 +169,7 @@ public class SyncopeUserValidator extend
     private List<AccountPolicy> getAccountPolicies(final SyncopeUser user) {
         final List<AccountPolicy> policies = new ArrayList<AccountPolicy>();
 
-        // Add global policy
+        // add global policy
         AccountPolicy policy = policyDAO.getGlobalAccountPolicy();
         if (policy != null) {
             policies.add(policy);

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/Connector.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/Connector.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/Connector.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/Connector.java Mon Jun 30 10:15:19 2014
@@ -40,21 +40,31 @@ import org.identityconnectors.framework.
 public interface Connector {
 
     /**
-     * Create user on a connector instance.
+     * Authenticate user on a connector instance.
+     *
+     * @param username the name based credential for authentication
+     * @param password the password based credential for authentication
+     * @param options ConnId's OperationOptions
+     * @return Uid of the account that was used to authenticate
+     */
+    Uid authenticate(String username, String password, OperationOptions options);
+
+    /**
+     * Create user / role on a connector instance.
      *
      * @param propagationMode propagation mode
      * @param objectClass ConnId's object class
      * @param attrs attributes for creation
      * @param options ConnId's OperationOptions
      * @param propagationAttempted if creation is actually performed (based on connector instance's capabilities)
-     * @return Uid for created user
+     * @return Uid for created object
      */
     Uid create(PropagationMode propagationMode, ObjectClass objectClass,
             Set<Attribute> attrs, OperationOptions options,
             Set<String> propagationAttempted);
 
     /**
-     * Update user on a connector instance.
+     * Update user / role on a connector instance.
      *
      * @param propagationMode propagation mode
      * @param objectClass ConnId's object class
@@ -62,14 +72,14 @@ public interface Connector {
      * @param attrs attributes for update
      * @param options ConnId's OperationOptions
      * @param propagationAttempted if update is actually performed (based on connector instance's capabilities)
-     * @return Uid for created user
+     * @return Uid for updated object
      */
     Uid update(PropagationMode propagationMode, ObjectClass objectClass,
             Uid uid, Set<Attribute> attrs, OperationOptions options,
             Set<String> propagationAttempted);
 
     /**
-     * Delete user on a connector instance.
+     * Delete user / role on a connector instance.
      *
      * @param propagationMode propagation mode
      * @param objectClass ConnId's object class
@@ -81,7 +91,7 @@ public interface Connector {
             Uid uid, OperationOptions options, Set<String> propagationAttempted);
 
     /**
-     * Sync users from a connector instance.
+     * Sync users / roles from a connector instance.
      *
      * @param objectClass ConnId's object class
      * @param token to be passed to the underlying connector
@@ -155,6 +165,7 @@ public interface Connector {
     Attribute getObjectAttribute(ObjectClass objectClass, Uid uid, OperationOptions options, String attributeName);
 
     /**
+     * Read attributes for a given connector object.
      *
      * @param objectClass ConnId's object class
      * @param uid ConnId's Uid
@@ -173,11 +184,11 @@ public interface Connector {
 
     /**
      * Return ConnId's object classes supported by this connector.
-     * 
+     *
      * @return supported object classes
      */
     Set<ObjectClass> getSupportedObjectClasses();
-    
+
     /**
      * Validate a connector instance.
      */

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AbstractPropagationTaskExecutor.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AbstractPropagationTaskExecutor.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AbstractPropagationTaskExecutor.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AbstractPropagationTaskExecutor.java Mon Jun 30 10:15:19 2014
@@ -75,10 +75,10 @@ public abstract class AbstractPropagatio
     protected static final Logger LOG = LoggerFactory.getLogger(AbstractPropagationTaskExecutor.class);
 
     /**
-     * Connector instance loader.
+     * Connector factory.
      */
     @Autowired
-    protected ConnectorFactory connLoader;
+    protected ConnectorFactory connFactory;
 
     /**
      * ConnObjectUtil.
@@ -342,7 +342,7 @@ public abstract class AbstractPropagatio
         Connector connector = null;
         Result result;
         try {
-            connector = connLoader.getConnector(task.getResource());
+            connector = connFactory.getConnector(task.getResource());
 
             // Try to read remote object (user / group) BEFORE any actual operation
             beforeObj = getRemoteObject(task, connector, false);

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AsyncConnectorFacade.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AsyncConnectorFacade.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AsyncConnectorFacade.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/AsyncConnectorFacade.java Mon Jun 30 10:15:19 2014
@@ -21,6 +21,7 @@ package org.apache.syncope.core.propagat
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.Future;
+import org.identityconnectors.common.security.GuardedString;
 import org.identityconnectors.framework.api.ConnectorFacade;
 import org.identityconnectors.framework.common.objects.Attribute;
 import org.identityconnectors.framework.common.objects.AttributeInfo;
@@ -49,6 +50,16 @@ public class AsyncConnectorFacade {
     private static final Logger LOG = LoggerFactory.getLogger(AsyncConnectorFacade.class);
 
     @Async
+    public Future<Uid> authenticate(
+            final ConnectorFacade connector,
+            final String username,
+            final GuardedString password,
+            final OperationOptions options) {
+
+        return new AsyncResult<Uid>(connector.authenticate(ObjectClass.ACCOUNT, username, password, options));
+    }
+
+    @Async
     public Future<Uid> create(
             final ConnectorFacade connector,
             final ObjectClass objectClass,

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/ConnectorFacadeProxy.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/ConnectorFacadeProxy.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/ConnectorFacadeProxy.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/propagation/impl/ConnectorFacadeProxy.java Mon Jun 30 10:15:19 2014
@@ -132,6 +132,34 @@ public class ConnectorFacadeProxy implem
     }
 
     @Override
+    public Uid authenticate(final String username, final String password, final OperationOptions options) {
+        Uid result = null;
+
+        if (activeConnInstance.getCapabilities().contains(ConnectorCapability.AUTHENTICATE)) {
+            final Future<Uid> future = asyncFacade.authenticate(
+                    connector, username, new GuardedString(password.toCharArray()), options);
+            try {
+                result = future.get(activeConnInstance.getConnRequestTimeout(), TimeUnit.SECONDS);
+            } catch (java.util.concurrent.TimeoutException e) {
+                future.cancel(true);
+                throw new TimeoutException("Request timeout");
+            } catch (Exception e) {
+                LOG.error("Connector request execution failure", e);
+                if (e.getCause() instanceof RuntimeException) {
+                    throw (RuntimeException) e.getCause();
+                } else {
+                    throw new IllegalArgumentException(e.getCause());
+                }
+            }
+        } else {
+            LOG.info("Authenticate was attempted, although the connector only has these capabilities: {}. No action.",
+                    activeConnInstance.getCapabilities());
+        }
+
+        return result;
+    }
+
+    @Override
     public Uid create(final PropagationMode propagationMode, final ObjectClass objectClass, final Set<Attribute> attrs,
             final OperationOptions options, final Set<String> propagationAttempted) {
 

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/PolicyDataBinder.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/PolicyDataBinder.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/PolicyDataBinder.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/rest/data/PolicyDataBinder.java Mon Jun 30 10:15:19 2014
@@ -36,12 +36,19 @@ import org.apache.syncope.core.persisten
 import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
 import org.apache.syncope.core.persistence.dao.ResourceDAO;
 import org.apache.syncope.core.persistence.dao.RoleDAO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component
 public class PolicyDataBinder {
 
+    /**
+     * Logger.
+     */
+    protected static final Logger LOG = LoggerFactory.getLogger(PolicyDataBinder.class);
+
     @Autowired
     private ResourceDAO resourceDAO;
 
@@ -95,6 +102,7 @@ public class PolicyDataBinder {
                 }
                 policyTO = (T) new AccountPolicyTO(isGlobal);
                 ((AccountPolicyTO) policyTO).setSpecification((AccountPolicySpec) policy.getSpecification());
+                ((AccountPolicyTO) policyTO).getResources().addAll(((AccountPolicy) policy).getResourceNames());
                 break;
 
             case GLOBAL_SYNC:
@@ -132,6 +140,15 @@ public class PolicyDataBinder {
         return policyTO;
     }
 
+    private ExternalResource getResource(final String resourceName) {
+        ExternalResource resource = resourceDAO.find(resourceName);
+        if (resource == null) {
+            LOG.debug("Ignoring invalid resource {} ", resourceName);
+        }
+
+        return resource;
+    }
+
     @SuppressWarnings("unchecked")
     public <T extends Policy> T getPolicy(T policy, final AbstractPolicyTO policyTO) {
         if (policy != null && policy.getType() != policyTO.getType()) {
@@ -165,6 +182,15 @@ public class PolicyDataBinder {
                     policy = (T) new AccountPolicy(isGlobal);
                 }
                 policy.setSpecification(((AccountPolicyTO) policyTO).getSpecification());
+
+                ((AccountPolicy) policy).getResources().clear();
+                for (String resourceName : ((AccountPolicyTO) policyTO).getResources()) {
+                    ExternalResource resource = getResource(resourceName);
+
+                    if (resource != null) {
+                        ((AccountPolicy) policy).addResource(resource);
+                    }
+                }
                 break;
 
             case GLOBAL_SYNC:

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/security/SyncopeAuthenticationProvider.java Mon Jun 30 10:15:19 2014
@@ -19,16 +19,27 @@
 package org.apache.syncope.core.security;
 
 import java.util.Date;
+import java.util.Iterator;
+import java.util.Set;
 import javax.annotation.Resource;
+import org.apache.syncope.common.types.AttributableType;
 import org.apache.syncope.common.types.AuditElements;
 import org.apache.syncope.common.types.AuditElements.Result;
 import org.apache.syncope.common.types.CipherAlgorithm;
 import org.apache.syncope.core.audit.AuditManager;
+import org.apache.syncope.core.persistence.beans.AccountPolicy;
+import org.apache.syncope.core.persistence.beans.ExternalResource;
 import org.apache.syncope.core.persistence.beans.conf.CAttr;
+import org.apache.syncope.core.persistence.beans.role.SyncopeRole;
 import org.apache.syncope.core.persistence.beans.user.SyncopeUser;
 import org.apache.syncope.core.persistence.dao.ConfDAO;
+import org.apache.syncope.core.persistence.dao.PolicyDAO;
 import org.apache.syncope.core.persistence.dao.UserDAO;
+import org.apache.syncope.core.propagation.ConnectorFactory;
+import org.apache.syncope.core.util.AttributableUtil;
 import org.apache.syncope.core.util.Encryptor;
+import org.apache.syncope.core.util.MappingUtil;
+import org.identityconnectors.framework.common.objects.Uid;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -58,6 +69,12 @@ public class SyncopeAuthenticationProvid
     @Autowired
     private UserDAO userDAO;
 
+    @Autowired
+    private PolicyDAO policyDAO;
+
+    @Autowired
+    private ConnectorFactory connFactory;
+
     @Resource(name = "adminUser")
     private String adminUser;
 
@@ -111,7 +128,7 @@ public class SyncopeAuthenticationProvid
         if (anonymousUser.equals(username)) {
             authenticated = authentication.getCredentials().toString().equals(anonymousKey);
         } else if (adminUser.equals(username)) {
-            authenticated = authenticate(
+            authenticated = encryptor.verify(
                     authentication.getCredentials().toString(),
                     CipherAlgorithm.valueOf(adminPasswordAlgorithm),
                     adminPassword);
@@ -130,10 +147,7 @@ public class SyncopeAuthenticationProvid
                     }
                 }
 
-                authenticated = authenticate(
-                        authentication.getCredentials().toString(),
-                        user.getCipherAlgorithm(),
-                        user.getPassword());
+                authenticated = authenticate(user, authentication.getCredentials().toString());
             }
         }
 
@@ -193,10 +207,68 @@ public class SyncopeAuthenticationProvid
         return token;
     }
 
-    protected boolean authenticate(final String password, final CipherAlgorithm cipherAlgorithm,
-            final String digestedPassword) {
+    protected Set<ExternalResource> getPassthroughResources(final SyncopeUser user) {
+        Set<ExternalResource> result = null;
+
+        // 1. look for directly assigned resources, pick the ones whose account policy has authentication resources
+        for (ExternalResource resource : user.getOwnResources()) {
+            if (resource.getAccountPolicy() != null && !resource.getAccountPolicy().getResources().isEmpty()) {
+                if (result == null) {
+                    result = resource.getAccountPolicy().getResources();
+                } else {
+                    result.retainAll(resource.getAccountPolicy().getResources());
+                }
+            }
+        }
+
+        // 2. look for owned roles, pick the ones whose account policy has authentication resources
+        for (SyncopeRole role : user.getRoles()) {
+            if (role.getAccountPolicy() != null && !role.getAccountPolicy().getResources().isEmpty()) {
+                if (result == null) {
+                    result = role.getAccountPolicy().getResources();
+                } else {
+                    result.retainAll(role.getAccountPolicy().getResources());
+                }
+            }
+        }
+
+        // 3. look for global account policy (if defined)
+        AccountPolicy global = policyDAO.getGlobalAccountPolicy();
+        if (global != null && !global.getResources().isEmpty()) {
+            if (result == null) {
+                result = global.getResources();
+            } else {
+                result.retainAll(global.getResources());
+            }
+        }
+
+        return result;
+    }
+
+    protected boolean authenticate(final SyncopeUser user, final String password) {
+        boolean authenticated = encryptor.verify(password, user.getCipherAlgorithm(), user.getPassword());
+        LOG.debug("{} authenticated on internal storage: {}", user.getUsername(), authenticated);
+
+        final AttributableUtil attrUtil = AttributableUtil.getInstance(AttributableType.USER);
+        for (Iterator<ExternalResource> itor = getPassthroughResources(user).iterator();
+                itor.hasNext() && !authenticated;) {
+            
+            ExternalResource resource = itor.next();
+            String accountId = null;
+            try {
+                accountId = MappingUtil.getAccountIdValue(user, resource, attrUtil.getAccountIdItem(resource));
+                Uid uid = connFactory.getConnector(resource).authenticate(accountId, password, null);
+                if (uid != null) {
+                    authenticated = true;
+                }
+            } catch (Exception e) {
+                LOG.debug("Could not authenticate {} on {}", user.getUsername(), resource.getName(), e);
+            }
+            LOG.debug("{} authenticated on {} as {}: {}",
+                    user.getUsername(), resource.getName(), accountId, authenticated);
+        }
 
-        return encryptor.verify(password, cipherAlgorithm, digestedPassword);
+        return authenticated;
     }
 
     @Override

Modified: syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/DBPasswordSyncActions.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/DBPasswordSyncActions.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/DBPasswordSyncActions.java (original)
+++ syncope/trunk/core/src/main/java/org/apache/syncope/core/sync/impl/DBPasswordSyncActions.java Mon Jun 30 10:15:19 2014
@@ -73,7 +73,7 @@ public class DBPasswordSyncActions exten
 
         return delta;
     }
-    
+
     @Transactional(readOnly = true)
     @Override
     public <T extends AbstractAttributableTO, K extends AbstractAttributableMod> SyncDelta beforeUpdate(
@@ -81,16 +81,16 @@ public class DBPasswordSyncActions exten
             final SyncDelta delta,
             final T subject,
             final K subjectMod) throws JobExecutionException {
-        
+
         if (subjectMod instanceof UserMod) {
-            String modPassword = ((UserMod)subjectMod).getPassword();
+            String modPassword = ((UserMod) subjectMod).getPassword();
             parseEncodedPassword(modPassword, profile.getConnector());
         }
-        
+
         return delta;
     }
-    
-    private void parseEncodedPassword(String password, Connector connector) {
+
+    private void parseEncodedPassword(final String password, final Connector connector) {
         if (password != null) {
             ConnInstance connInstance = connector.getActiveConnInstance();
 
@@ -107,7 +107,7 @@ public class DBPasswordSyncActions exten
         }
     }
 
-    private String getCipherAlgorithm(ConnInstance connInstance) {
+    private String getCipherAlgorithm(final ConnInstance connInstance) {
         String cipherAlgorithm = CLEARTEXT;
         for (Iterator<ConnConfProperty> propertyIterator = connInstance.getConfiguration().iterator();
                 propertyIterator.hasNext();) {

Modified: syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java (original)
+++ syncope/trunk/core/src/test/java/org/apache/syncope/core/rest/AuthenticationTestITCase.java Mon Jun 30 10:15:19 2014
@@ -18,6 +18,7 @@
  */
 package org.apache.syncope.core.rest;
 
+import static org.apache.syncope.core.rest.AbstractTest.userService;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -52,11 +53,19 @@ import org.apache.syncope.common.types.S
 import org.apache.syncope.common.types.ClientExceptionType;
 import org.apache.syncope.common.util.CollectionWrapper;
 import org.apache.syncope.common.SyncopeClientException;
+import org.apache.syncope.common.mod.UserMod;
+import org.apache.syncope.common.reqres.BulkActionResult;
+import org.apache.syncope.common.services.UserSelfService;
+import org.apache.syncope.common.types.CipherAlgorithm;
+import org.apache.syncope.common.types.ResourceDeassociationActionType;
+import org.apache.syncope.common.wrap.ResourceName;
+import org.apache.syncope.core.util.Encryptor;
 import org.apache.syncope.core.workflow.ActivitiDetector;
 import org.junit.Assume;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runners.MethodSorters;
+import org.springframework.jdbc.core.JdbcTemplate;
 
 @FixMethodOrder(MethodSorters.JVM)
 public class AuthenticationTestITCase extends AbstractTest {
@@ -250,7 +259,8 @@ public class AuthenticationTestITCase ex
         assertEquals(0, getFailedLogins(userService2, userId));
 
         // authentications failed ...
-        UserService userService3 = clientFactory.create(userTO.getUsername(), "wrongpwd1").getService(UserService.class);
+        UserService userService3 = clientFactory.create(userTO.getUsername(), "wrongpwd1").getService(
+                UserService.class);
         assertReadFails(userService3, userId);
         assertReadFails(userService3, userId);
 
@@ -394,4 +404,39 @@ public class AuthenticationTestITCase ex
         // 4. try to authenticate again: success
         assertNotNull(myEntitlementService.getOwnEntitlements());
     }
+
+    @Test
+    public void issueSYNCOPE164() throws Exception {
+        // 1. create user with db resource
+        UserTO user = UserTestITCase.getUniqueSampleTO("syncope164@syncope.apache.org");
+        user.setPassword("password1");
+        user.getResources().add(RESOURCE_NAME_TESTDB);
+        user = createUser(user);
+        assertNotNull(user);
+
+        // 2. unlink the resource from the created user
+        assertNotNull(userService.bulkDeassociation(user.getId(),
+                ResourceDeassociationActionType.UNLINK,
+                CollectionWrapper.wrap(RESOURCE_NAME_TESTDB, ResourceName.class)).
+                readEntity(BulkActionResult.class));
+
+        // 3. change password on Syncope
+        UserMod userMod = new UserMod();
+        userMod.setId(user.getId());
+        userMod.setPassword("password2");
+        user = updateUser(userMod);
+        assertNotNull(user);
+
+        // 4. check that the db resource has still the initial password value
+        final JdbcTemplate jdbcTemplate = new JdbcTemplate(testDataSource);
+        String value = jdbcTemplate.queryForObject(
+                "SELECT PASSWORD FROM test WHERE ID=?", String.class, user.getUsername());
+        assertEquals(Encryptor.getInstance().encode("password1", CipherAlgorithm.SHA1), value.toUpperCase());
+
+        // 5. successfully authenticate with old (on db resource) and new (on internal storage) password values
+        user = clientFactory.create(user.getUsername(), "password1").getService(UserSelfService.class).read();
+        assertNotNull(user);
+        user = clientFactory.create(user.getUsername(), "password2").getService(UserSelfService.class).read();
+        assertNotNull(user);
+    }
 }

Modified: syncope/trunk/core/src/test/resources/content.xml
URL: http://svn.apache.org/viewvc/syncope/trunk/core/src/test/resources/content.xml?rev=1606667&r1=1606666&r2=1606667&view=diff
==============================================================================
--- syncope/trunk/core/src/test/resources/content.xml (original)
+++ syncope/trunk/core/src/test/resources/content.xml Mon Jun 30 10:15:19 2014
@@ -429,6 +429,7 @@ under the License.
                 connectorName="org.connid.bundles.db.table.DatabaseTableConnector"
                 version="${connid.db.table.version}"
                 xmlConfiguration="%3Cset%3E%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3Euser%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Efalse%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Esa%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EenabledStatusValue%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Efalse%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etrue%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A
 %20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EstatusColumn%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Efalse%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Estatus%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EdisabledStatusValue%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Efalse%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Efalse%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverr
 idable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EkeyColumn%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Etrue%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Eid%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EjdbcUrlTemplate%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Efalse%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3E${testdb.url}%3C%2Fjava.lang.String%3E%0A%3C%2Fva
 lues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EpasswordColumn%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Efalse%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Epassword%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EdefaultStatusValue%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Efalse%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Et
 rue%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3Etable%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Etrue%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Etest%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3Epassword%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Eorg.identityconnectors.common.security.GuardedString%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Efalse%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fsc
 hema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Esa%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EjdbcDriver%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Efalse%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3Eorg.h2.Driver%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EcipherAlgorithm%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Etrue%3C%2F
 required%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3ESHA1%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EcipherAlgorithm%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Ejava.lang.String%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Crequired%3Etrue%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cjava.lang.String%3ESHA1%3C%2Fjava.lang.String%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%3Corg.apache.syncope.common.types.ConnConfProperty%3E%0A%20%20%20%20%3Cschema%3E%0A%20%20%20%20%20%20%3Cname%3EretrievePassword%3C%2Fname%3E%0A%20%20%20%20%20%20%3Ctype%3Eboolean%3C%2Ftype%3E%0A%20%20%20%20%20%20%3Cr
 equired%3Efalse%3C%2Frequired%3E%0A%20%20%20%20%3C%2Fschema%3E%0A%0A%3Cvalues%3E%0A%3Cstring%3Etrue%3C%2Fstring%3E%0A%3C%2Fvalues%3E%0A%0A%20%20%20%20%3Coverridable%3Efalse%3C%2Foverridable%3E%0A%20%20%3C%2Forg.apache.syncope.common.types.ConnConfProperty%3E%0A%3C%2Fset%3E"/>
+  <ConnInstance_capabilities ConnInstance_id="101" capabilities="AUTHENTICATE"/>
   <ConnInstance_capabilities ConnInstance_id="101" capabilities="ONE_PHASE_CREATE"/>
   <ConnInstance_capabilities ConnInstance_id="101" capabilities="ONE_PHASE_UPDATE"/>
   <ConnInstance_capabilities ConnInstance_id="101" capabilities="ONE_PHASE_DELETE"/>
@@ -613,7 +614,10 @@ under the License.
                     propagationMode="TWO_PHASES" propagationPrimary="0" propagationPriority="0"
                     creator="admin" lastModifier="admin" 
                     creationDate="2010-10-20 11:00:00" lastChangeDate="2010-10-20 11:00:00"/>
-  
+
+  <!-- Use resource-testdb for passthrough authentication (SYNCOPE-164) in the global account policy -->
+  <Policy_ExternalResource account_policy_id="5" resource_name="resource-testdb"/>
+    
   <SyncopeUser_ExternalResource user_id="3" resource_name="ws-target-resource-delete"/>
   <SyncopeUser_ExternalResource user_id="3" resource_name="ws-target-resource-2"/>
   <SyncopeUser_ExternalResource user_id="3" resource_name="ws-target-resource-1"/>