keycloak-aplcache

Details

diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js
index 7d84ce8..706cd0e 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/js/controllers/users.js
@@ -445,11 +445,20 @@ module.controller('LDAPCtrl', function($scope, $location, Notifications, Dialog,
         $scope.instance.config = {};
         $scope.instance.priority = 0;
         $scope.syncRegistrations = false;
+
         $scope.userAccountControlsAfterPasswordUpdate = true;
-        $scope.instance.config.userAccountControlsAfterPasswordUpdate = true;
+        $scope.instance.config.userAccountControlsAfterPasswordUpdate = "true";
+
+        $scope.connectionPooling = true;
+        $scope.instance.config.connectionPooling = "true";
+
+        $scope.pagination = true;
+        $scope.instance.config.pagination = "true";
     } else {
         $scope.syncRegistrations = instance.config.syncRegistrations && instance.config.syncRegistrations == "true";
         $scope.userAccountControlsAfterPasswordUpdate = instance.config.userAccountControlsAfterPasswordUpdate && instance.config.userAccountControlsAfterPasswordUpdate == "true";
+        $scope.connectionPooling = instance.config.connectionPooling && instance.config.connectionPooling == "true";
+        $scope.pagination = instance.config.pagination && instance.config.pagination == "true";
     }
 
     $scope.ldapVendors = [
@@ -469,21 +478,20 @@ module.controller('LDAPCtrl', function($scope, $location, Notifications, Dialog,
 
     $scope.lastVendor = $scope.instance.config.vendor;
 
-    $scope.$watch('syncRegistrations', function() {
-        if ($scope.syncRegistrations) {
-            $scope.instance.config.syncRegistrations = "true";
-        } else {
-            $scope.instance.config.syncRegistrations = "false";
-        }
-    })
+    function watchBooleanProperty(propertyName) {
+        $scope.$watch(propertyName, function() {
+            if ($scope[propertyName]) {
+                $scope.instance.config[propertyName] = "true";
+            } else {
+                $scope.instance.config[propertyName] = "false";
+            }
+        })
+    }
 
-    $scope.$watch('userAccountControlsAfterPasswordUpdate', function() {
-        if ($scope.userAccountControlsAfterPasswordUpdate) {
-            $scope.instance.config.userAccountControlsAfterPasswordUpdate = "true";
-        } else {
-            $scope.instance.config.userAccountControlsAfterPasswordUpdate = "false";
-        }
-    })
+    watchBooleanProperty('syncRegistrations');
+    watchBooleanProperty('userAccountControlsAfterPasswordUpdate');
+    watchBooleanProperty('connectionPooling');
+    watchBooleanProperty('pagination');
 
     $scope.$watch('instance', function() {
         if (!angular.equals($scope.instance, instance)) {
diff --git a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/federated-ldap.html b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/federated-ldap.html
index 3d5bc52..4a77776 100755
--- a/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/federated-ldap.html
+++ b/forms/common-themes/src/main/resources/theme/admin/base/resources/partials/federated-ldap.html
@@ -116,6 +116,18 @@
                         <a class="btn btn-primary" data-ng-click="testAuthentication()">Test authentication</a>
                     </div>
                 </div>
+                <div class="form-group clearfix">
+                    <label class="col-sm-2 control-label" for="connectionPooling">Connection pooling</label>
+                    <div class="col-sm-4">
+                        <input ng-model="connectionPooling" name="connectionPooling" id="connectionPooling" onoffswitch />
+                    </div>
+                </div>
+                <div class="form-group clearfix">
+                    <label class="col-sm-2 control-label" for="pagination">Pagination</label>
+                    <div class="col-sm-4">
+                        <input ng-model="pagination" name="pagination" id="pagination" onoffswitch />
+                    </div>
+                </div>
                 <div class="form-group clearfix" data-ng-show="instance.config.vendor === 'ad' ">
                     <label class="col-sm-2 control-label" for="userAccountControlsAfterPasswordUpdate">Enable Account After Password Update</label>
                     <div class="col-sm-4">
diff --git a/model/api/src/main/java/org/keycloak/models/LDAPConstants.java b/model/api/src/main/java/org/keycloak/models/LDAPConstants.java
index ba29870..1328c01 100644
--- a/model/api/src/main/java/org/keycloak/models/LDAPConstants.java
+++ b/model/api/src/main/java/org/keycloak/models/LDAPConstants.java
@@ -19,5 +19,8 @@ public class LDAPConstants {
     public static final String BIND_DN = "bindDn";
     public static final String BIND_CREDENTIAL = "bindCredential";
 
+    public static final String CONNECTION_POOLING = "connectionPooling";
+    public static final String PAGINATION = "pagination";
+
     public static final String USER_ACCOUNT_CONTROLS_AFTER_PASSWORD_UPDATE = "userAccountControlsAfterPasswordUpdate";
 }
diff --git a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/PartitionManagerRegistry.java b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/PartitionManagerRegistry.java
index 53e4cbe..03fcf5b 100644
--- a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/PartitionManagerRegistry.java
+++ b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/ldap/PartitionManagerRegistry.java
@@ -61,7 +61,9 @@ public class PartitionManagerRegistry {
         IdentityConfigurationBuilder builder = new IdentityConfigurationBuilder();
 
         Properties connectionProps = new Properties();
-        connectionProps.put("com.sun.jndi.ldap.connect.pool", "true");
+        if (ldapConfig.containsKey(LDAPConstants.CONNECTION_POOLING)) {
+            connectionProps.put("com.sun.jndi.ldap.connect.pool", ldapConfig.get(LDAPConstants.CONNECTION_POOLING));
+        }
 
         checkSystemProperty("com.sun.jndi.ldap.connect.pool.authentication", "none simple");
         checkSystemProperty("com.sun.jndi.ldap.connect.pool.initsize", "1");
@@ -83,6 +85,8 @@ public class PartitionManagerRegistry {
         String ldapFirstNameMapping = activeDirectory ?  "givenName" : CN;
         String[] userObjectClasses = getUserObjectClasses(ldapConfig);
 
+        boolean pagination = ldapConfig.containsKey(LDAPConstants.PAGINATION) ? Boolean.parseBoolean(ldapConfig.get(LDAPConstants.PAGINATION)) : false;
+
         // Use same mapping for User and Agent for now
         LDAPStoreConfigurationBuilder ldapStoreBuilder =
         builder
@@ -96,7 +100,8 @@ public class PartitionManagerRegistry {
                         .bindCredential(ldapConfig.get(LDAPConstants.BIND_CREDENTIAL))
                         .url(ldapConfig.get(LDAPConstants.CONNECTION_URL))
                         .activeDirectory(activeDirectory)
-                        .supportAllFeatures();
+                        .supportAllFeatures()
+                        .pagination(pagination);
 
         // RHDS is using "nsuniqueid" as unique identifier instead of "entryUUID"
         if (vendor != null && vendor.equals(LDAPConstants.VENDOR_RHDS)) {
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/LDAPEmbeddedServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/LDAPEmbeddedServer.java
index 1ac63d8..5debd5e 100755
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/LDAPEmbeddedServer.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/LDAPEmbeddedServer.java
@@ -41,6 +41,8 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
     protected String bindDn = "uid=admin,ou=system";
     protected String bindCredential = "secret";
     protected String vendor = LDAPConstants.VENDOR_OTHER;
+    protected boolean connectionPooling = true;
+    protected boolean pagination = true;
 
     public static String IDM_TEST_LDAP_CONNECTION_URL = "idm.test.ldap.connection.url";
     public static String IDM_TEST_LDAP_BASE_DN = "idm.test.ldap.base.dn";
@@ -52,6 +54,8 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
     public static String IDM_TEST_LDAP_BIND_DN = "idm.test.ldap.bind.dn";
     public static String IDM_TEST_LDAP_BIND_CREDENTIAL = "idm.test.ldap.bind.credential";
     public static String IDM_TEST_LDAP_VENDOR = "idm.test.ldap.vendor";
+    public static String IDM_TEST_LDAP_CONNECTION_POOLING = "idm.test.ldap.connection.pooling";
+    public static String IDM_TEST_LDAP_PAGINATION = "idm.test.ldap.pagination";
 
 
     public LDAPEmbeddedServer() {
@@ -79,6 +83,8 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
         bindDn = p.getProperty(IDM_TEST_LDAP_BIND_DN, bindDn);
         bindCredential = p.getProperty(IDM_TEST_LDAP_BIND_CREDENTIAL, bindCredential);
         vendor = p.getProperty(IDM_TEST_LDAP_VENDOR);
+        connectionPooling = Boolean.parseBoolean(p.getProperty(IDM_TEST_LDAP_CONNECTION_POOLING, "true"));
+        pagination = Boolean.parseBoolean(p.getProperty(IDM_TEST_LDAP_PAGINATION, "true"));
     }
 
     @Override
@@ -127,6 +133,8 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
         ldapConfig.put(LDAPConstants.BIND_CREDENTIAL, getBindCredential());
         ldapConfig.put(LDAPConstants.USER_DN_SUFFIX, getUserDnSuffix());
         ldapConfig.put(LDAPConstants.VENDOR, getVendor());
+        ldapConfig.put(LDAPConstants.CONNECTION_POOLING, String.valueOf(isConnectionPooling()));
+        ldapConfig.put(LDAPConstants.PAGINATION, String.valueOf(isPagination()));
         return ldapConfig;
     }
 
@@ -201,6 +209,14 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
         return vendor;
     }
 
+    public boolean isConnectionPooling() {
+        return connectionPooling;
+    }
+
+    public boolean isPagination() {
+        return pagination;
+    }
+
     @Override
     public void importLDIF(String fileName) throws Exception {
         // import LDIF only in case we are running against embedded LDAP server
diff --git a/testsuite/integration/src/main/resources/ldap/ldap-connection.properties b/testsuite/integration/src/main/resources/ldap/ldap-connection.properties
index 5ccc6ad..6119852 100644
--- a/testsuite/integration/src/main/resources/ldap/ldap-connection.properties
+++ b/testsuite/integration/src/main/resources/ldap/ldap-connection.properties
@@ -6,4 +6,6 @@ idm.test.ldap.user.dn.suffix=ou\=People,dc\=keycloak,dc\=org
 idm.test.ldap.agent.dn.suffix=ou\=Agent,dc\=keycloak,dc\=org
 idm.test.ldap.start.embedded.ldap.server=true
 idm.test.ldap.bind.dn=uid\=admin,ou\=system
-idm.test.ldap.bind.credential=secret
\ No newline at end of file
+idm.test.ldap.bind.credential=secret
+idm.test.ldap.connection.pooling=true
+idm.test.ldap.pagination=true
\ No newline at end of file
diff --git a/testsuite/integration/src/main/resources/ldap/users.ldif b/testsuite/integration/src/main/resources/ldap/users.ldif
index 386a9d6..b41d9f5 100644
--- a/testsuite/integration/src/main/resources/ldap/users.ldif
+++ b/testsuite/integration/src/main/resources/ldap/users.ldif
@@ -19,22 +19,3 @@ objectclass: top
 objectclass: organizationalUnit
 ou: Groups
 
-dn: uid=johnkeycloak,ou=People,dc=keycloak,dc=org
-objectclass: top
-objectclass: uidObject
-objectclass: person
-objectclass: inetOrgPerson
-uid: johnkeycloak
-cn: John
-sn: Doe
-mail: john@email.org
-
-dn: uid=existing,ou=People,dc=keycloak,dc=org
-objectclass: top
-objectclass: uidObject
-objectclass: person
-objectclass: inetOrgPerson
-uid: existing
-cn: Existing
-sn: Foo
-mail: existing@email.org