From c32620b71802dc8bca9fc14ebeda7750b89e00d3 Mon Sep 17 00:00:00 2001 From: mposolda Date: Mon, 9 Jan 2017 21:29:06 +0100 Subject: [PATCH] KEYCLOAK-4175 Provide a way to set the connect and read timeout for ldap connections --- .../org/keycloak/storage/ldap/LDAPConfig.java | 8 ++++++ .../ldap/LDAPStorageProviderFactory.java | 25 +++++++++++++++++++ .../idm/store/ldap/LDAPOperationManager.java | 10 ++++++++ .../admin/client/resource/RealmResource.java | 2 +- .../org/keycloak/models/LDAPConstants.java | 2 ++ .../managers/LDAPConnectionTestManager.java | 6 ++++- .../resources/admin/RealmAdminResource.java | 5 ++-- .../testsuite/admin/PermissionsTest.java | 2 +- .../UserFederationLdapConnectionTest.java | 18 ++++++------- .../messages/admin-messages_en.properties | 4 +++ .../admin/messages/messages_en.properties | 2 ++ .../admin/resources/js/controllers/users.js | 1 + .../resources/partials/user-storage-ldap.html | 14 +++++++++++ 13 files changed, 85 insertions(+), 14 deletions(-) diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPConfig.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPConfig.java index ee2a89f6703..d6640357b42 100644 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPConfig.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPConfig.java @@ -109,6 +109,14 @@ public class LDAPConfig { return config.getFirst(LDAPConstants.CONNECTION_POOLING); } + public String getConnectionTimeout() { + return config.getFirst(LDAPConstants.CONNECTION_TIMEOUT); + } + + public String getReadTimeout() { + return config.getFirst(LDAPConstants.READ_TIMEOUT); + } + public Properties getAdditionalConnectionProperties() { // not supported for now return null; diff --git a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java index d8d04977b7a..524f2501c00 100755 --- a/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java +++ b/federation/ldap/src/main/java/org/keycloak/storage/ldap/LDAPStorageProviderFactory.java @@ -145,6 +145,12 @@ public class LDAPStorageProviderFactory implements UserStorageProviderFactory response) { - response.set(realm.testLDAPConnection("nosuch", "nosuch", "nosuch", "nosuch", "nosuch")); + response.set(realm.testLDAPConnection("nosuch", "nosuch", "nosuch", "nosuch", "nosuch", "nosuch")); } }, Resource.REALM, true); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java index 52bfc69b086..6ee926d6532 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/UserFederationLdapConnectionTest.java @@ -36,23 +36,23 @@ public class UserFederationLdapConnectionTest extends AbstractAdminTest { @Test public void testLdapConnections1() { // Unknown action - Response response = realm.testLDAPConnection("unknown", "ldap://localhost:10389", "foo", "bar", "false"); + Response response = realm.testLDAPConnection("unknown", "ldap://localhost:10389", "foo", "bar", "false", null); assertStatus(response, 400); // Bad host - response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldap://localhostt:10389", "foo", "bar", "false"); + response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldap://localhostt:10389", "foo", "bar", "false", null); assertStatus(response, 400); // Connection success - response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldap://localhost:10389", "foo", "bar", "false"); + response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldap://localhost:10389", "foo", "bar", "false", null); assertStatus(response, 204); // Bad authentication - response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldap://localhost:10389", "foo", "bar", "false"); + response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldap://localhost:10389", "foo", "bar", "false", "10000"); assertStatus(response, 400); // Authentication success - response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldap://localhost:10389", "uid=admin,ou=system", "secret", "false"); + response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldap://localhost:10389", "uid=admin,ou=system", "secret", "false", null); assertStatus(response, 204); } @@ -60,16 +60,16 @@ public class UserFederationLdapConnectionTest extends AbstractAdminTest { @Test public void testLdapConnectionsSsl() { - Response response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldaps://localhost:10636", "foo", "bar", "false"); + Response response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldaps://localhost:10636", "foo", "bar", "false", null); assertStatus(response, 204); - response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldaps://localhostt:10636", "foo", "bar", "false"); + response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_CONNECTION, "ldaps://localhostt:10636", "foo", "bar", "false", null); assertStatus(response, 400); - response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldaps://localhost:10636", "foo", "bar", "false"); + response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldaps://localhost:10636", "foo", "bar", "false", null); assertStatus(response, 400); - response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldaps://localhost:10636", "uid=admin,ou=system", "secret", "true"); + response = realm.testLDAPConnection(LDAPConnectionTestManager.TEST_AUTHENTICATION, "ldaps://localhost:10636", "uid=admin,ou=system", "secret", "true", null); assertStatus(response, 204); } diff --git a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties index 7480ef8baa8..e6a9a63b1f5 100644 --- a/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties +++ b/themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties @@ -744,6 +744,10 @@ ldap.search-scope.tooltip=For one level, we search for users just in DNs specifi use-truststore-spi=Use Truststore SPI ldap.use-truststore-spi.tooltip=Specifies whether LDAP connection will use the truststore SPI with the truststore configured in standalone.xml/domain.xml. 'Always' means that it will always use it. 'Never' means that it won't use it. 'Only for ldaps' means that it will use if your connection URL use ldaps. Note even if standalone.xml/domain.xml is not configured, the default Java cacerts or certificate specified by 'javax.net.ssl.trustStore' property will be used. connection-pooling=Connection Pooling +ldap-connection-timeout=Connection Timeout +ldap.connection-timeout.tooltip=LDAP Connection Timeout in milliseconds +ldap-read-timeout=Read Timeout +ldap.read-timeout.tooltip=LDAP Read Timeout in milliseconds. This timeout applies for LDAP read operations ldap.connection-pooling.tooltip=Does Keycloak should use connection pooling for accessing LDAP server ldap.pagination.tooltip=Does the LDAP server support pagination. kerberos-integration=Kerberos Integration diff --git a/themes/src/main/resources/theme/base/admin/messages/messages_en.properties b/themes/src/main/resources/theme/base/admin/messages/messages_en.properties index f4044ab7df6..e734c06d732 100644 --- a/themes/src/main/resources/theme/base/admin/messages/messages_en.properties +++ b/themes/src/main/resources/theme/base/admin/messages/messages_en.properties @@ -8,6 +8,8 @@ invalidPasswordRegexPatternMessage=Invalid password: fails to match regex patter invalidPasswordHistoryMessage=Invalid password: must not be equal to any of last {0} passwords. ldapErrorInvalidCustomFilter=Custom configured LDAP filter does not start with "(" or does not end with ")". +ldapErrorConnectionTimeoutNotNumber=Connection Timeout must be a number +ldapErrorReadTimeoutNotNumber=Read Timeout must be a number ldapErrorMissingClientId=Client ID needs to be provided in config when Realm Roles Mapping is not used. ldapErrorCantPreserveGroupInheritanceWithUIDMembershipType=Not possible to preserve group inheritance and use UID membership type together. ldapErrorCantWriteOnlyForReadOnlyLdap=Can't set write only when LDAP provider mode is not WRITABLE diff --git a/themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js b/themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js index e99b03e1a8d..4f968910eae 100755 --- a/themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js +++ b/themes/src/main/resources/theme/base/admin/resources/js/controllers/users.js @@ -1262,6 +1262,7 @@ module.controller('LDAPUserStorageCtrl', function($scope, $location, Notificatio bindDn: ldapConfig.bindDn, bindCredential: ldapConfig.bindCredential, useTruststoreSpi: ldapConfig.useTruststoreSpi, + connectionTimeout: ldapConfig.connectionTimeout, componentId: instance.id }; }; diff --git a/themes/src/main/resources/theme/base/admin/resources/partials/user-storage-ldap.html b/themes/src/main/resources/theme/base/admin/resources/partials/user-storage-ldap.html index 060d7d70ac2..02a3464c516 100755 --- a/themes/src/main/resources/theme/base/admin/resources/partials/user-storage-ldap.html +++ b/themes/src/main/resources/theme/base/admin/resources/partials/user-storage-ldap.html @@ -186,6 +186,20 @@ {{:: 'ldap.connection-pooling.tooltip' | translate}} +
+ +
+ +
+ {{:: 'ldap.connection-timeout.tooltip' | translate}} +
+
+ +
+ +
+ {{:: 'ldap.read-timeout.tooltip' | translate}} +