keycloak-uncached

Details

diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LDAPQuery.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LDAPQuery.java
index e9f30f8..be4ddcd 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LDAPQuery.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/query/internal/LDAPQuery.java
@@ -47,6 +47,8 @@ public class LDAPQuery {
     private final List<UserFederationMapperModel> mappers = new ArrayList<UserFederationMapperModel>();
 
     private int searchScope = SearchControls.SUBTREE_SCOPE;
+    
+    private String ldapFilter = null;
 
     public LDAPQuery(LDAPFederationProvider ldapProvider) {
         this.ldapFedProvider = ldapProvider;
@@ -189,4 +191,12 @@ public class LDAPQuery {
         return this.conditions;
     }
 
+    public String getLdapFilter() {
+        return ldapFilter;
+    }
+
+    public void setLdapFilter(String ldapFilter) {
+        this.ldapFilter = ldapFilter;
+    }
+
 }
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java
index dc93742..9bc51f3 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/idm/store/ldap/LDAPIdentityStore.java
@@ -255,7 +255,9 @@ public class LDAPIdentityStore implements IdentityStore {
         for (Condition condition : identityQuery.getConditions()) {
             applyCondition(filter, condition);
         }
-
+        if (!(identityQuery.getLdapFilter() == null || identityQuery.getLdapFilter().isEmpty())) {
+            filter.append(identityQuery.getLdapFilter());
+        }
 
         filter.insert(0, "(&");
         filter.append(getObjectClassesFilter(identityQuery.getObjectClasses()));
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapper.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapper.java
index 09375fc..76d2df9 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapper.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapper.java
@@ -54,6 +54,9 @@ public class RoleLDAPFederationMapper extends AbstractLDAPFederationMapper {
 
     // See docs for Mode enum
     public static final String MODE = "mode";
+    
+    // Customized LDAP filter which is added to the whole LDAP query
+    public static final String ROLES_LDAP_FILTER = "roles.ldap.filter";
 
 
     // List of IDs of UserFederationMapperModels where syncRolesFromLDAP was already called in this KeycloakSession. This is to improve performance
@@ -128,6 +131,7 @@ public class RoleLDAPFederationMapper extends AbstractLDAPFederationMapper {
         ldapQuery.addObjectClasses(roleObjectClasses);
 
         String rolesRdnAttr = getRoleNameLdapAttribute(mapperModel);
+        ldapQuery.setLdapFilter(mapperModel.getConfig().get(RoleLDAPFederationMapper.ROLES_LDAP_FILTER));
         String membershipAttr = getMembershipLdapAttribute(mapperModel);
         ldapQuery.addReturningLdapAttribute(rolesRdnAttr);
         ldapQuery.addReturningLdapAttribute(membershipAttr);
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapperFactory.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapperFactory.java
index 2d6d24c..07b4635 100644
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapperFactory.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/mappers/RoleLDAPFederationMapperFactory.java
@@ -51,6 +51,12 @@ public class RoleLDAPFederationMapperFactory extends AbstractLDAPFederationMappe
                 "Object class (or classes) of the role object. It's divided by comma if more classes needed. In typical LDAP deployment it could be 'groupOfNames' . In Active Directory it's usually 'group' ",
                 ProviderConfigProperty.STRING_TYPE, null);
         configProperties.add(roleObjectClasses);
+        
+        ProviderConfigProperty ldapFilter = createConfigProperty(RoleLDAPFederationMapper.ROLES_LDAP_FILTER,
+                "LDAP Filter",
+                "LDAP Filter adds additional custom filter to the whole query.",
+                ProviderConfigProperty.STRING_TYPE, null);
+        configProperties.add(ldapFilter);
 
         List<String> modes = new LinkedList<String>();
         for (RoleLDAPFederationMapper.Mode mode : RoleLDAPFederationMapper.Mode.values()) {