keycloak-uncached

Merge pull request #585 from mposolda/master Upgrade to

8/4/2014 9:58:29 AM

Changes

federation/ldap/src/main/java/org/keycloak/federation/ldap/KeycloakLDAPIdentityStore.java 89(+0 -89)

federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPKeycloakCredentialHandler.java 168(+0 -168)

picketlink/keycloak-picketlink-api/src/main/java/org/keycloak/picketlink/AbstractIdentityManagerProvider.java 32(+0 -32)

picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/idm/KeycloakLDAPIdentityStore.java 92(+0 -92)

picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java 169(+0 -169)

picketlink/keycloak-picketlink-realm/src/main/java/org/keycloak/picketlink/realm/PartitionManagerRegistry.java 168(+0 -168)

picketlink/keycloak-picketlink-realm/src/main/resources/META-INF/services/org.keycloak.picketlink.IdentityManagerProviderFactory 1(+0 -1)

pom.xml 2(+1 -1)

Details

diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
index 70135fb..e644c7a 100644
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
@@ -24,16 +24,14 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
             "org.keycloak.models.mongo.keycloak.entities.MongoUserEntity",
             "org.keycloak.models.mongo.keycloak.entities.MongoRoleEntity",
             "org.keycloak.models.entities.RequiredCredentialEntity",
-            "org.keycloak.models.entities.AuthenticationProviderEntity",
             "org.keycloak.models.entities.CredentialEntity",
             "org.keycloak.models.entities.SocialLinkEntity",
-            "org.keycloak.models.entities.AuthenticationLinkEntity",
             "org.keycloak.models.mongo.keycloak.entities.MongoApplicationEntity",
             "org.keycloak.models.mongo.keycloak.entities.MongoOAuthClientEntity",
             "org.keycloak.models.sessions.mongo.entities.MongoUsernameLoginFailureEntity",
             "org.keycloak.models.sessions.mongo.entities.MongoUserSessionEntity",
             "org.keycloak.models.sessions.mongo.entities.MongoClientSessionEntity",
-            "org.keycloak.models.entities.FederationProviderEntity"
+            "org.keycloak.models.entities.UserFederationProviderEntity"
     };
 
     private static final Logger logger = Logger.getLogger(DefaultMongoConnectionFactoryProvider.class);
diff --git a/dependencies/server-all/pom.xml b/dependencies/server-all/pom.xml
index d36543d..92f6df0 100755
--- a/dependencies/server-all/pom.xml
+++ b/dependencies/server-all/pom.xml
@@ -112,6 +112,11 @@
             <artifactId>keycloak-picketlink-api</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-picketlink-ldap</artifactId>
+            <version>${project.version}</version>
+        </dependency>
 
         <!-- mongo -->
         <dependency>
diff --git a/federation/ldap/pom.xml b/federation/ldap/pom.xml
index 0ce4c2e..a156a54 100755
--- a/federation/ldap/pom.xml
+++ b/federation/ldap/pom.xml
@@ -26,6 +26,12 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-picketlink-api</artifactId>
+            <version>${project.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.jboss.resteasy</groupId>
             <artifactId>resteasy-jaxrs</artifactId>
             <scope>provided</scope>
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java
index 27a6dd2..562e247 100755
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java
@@ -16,6 +16,7 @@ import org.picketlink.idm.PartitionManager;
 import org.picketlink.idm.credential.Credentials;
 import org.picketlink.idm.credential.Password;
 import org.picketlink.idm.credential.UsernamePasswordCredentials;
+import org.picketlink.idm.model.Attribute;
 import org.picketlink.idm.model.basic.BasicModel;
 import org.picketlink.idm.model.basic.User;
 import org.picketlink.idm.query.IdentityQuery;
@@ -123,6 +124,7 @@ public class LDAPFederationProvider implements UserFederationProvider {
             picketlinkUser.setFirstName(user.getFirstName());
             picketlinkUser.setLastName(user.getLastName());
             picketlinkUser.setEmail(user.getEmail());
+            picketlinkUser.setAttribute(new Attribute("fullName", getFullName(user)));
             identityManager.add(picketlinkUser);
             user.setAttribute(LDAP_ID, picketlinkUser.getId());
             return proxy(user);
@@ -321,4 +323,23 @@ public class LDAPFederationProvider implements UserFederationProvider {
     public void close() {
         //To change body of implemented methods use File | Settings | File Templates.
     }
+
+    // Needed for ActiveDirectory updates
+    protected String getFullName(UserModel user) {
+        String fullName;
+        if (user.getFirstName() != null && user.getLastName() != null) {
+            fullName = user.getFirstName() + " " + user.getLastName();
+        } else if (user.getFirstName() != null && user.getFirstName().trim().length() > 0) {
+            fullName = user.getFirstName();
+        } else {
+            fullName = user.getLastName();
+        }
+
+        // Fallback to loginName
+        if (fullName == null || fullName.trim().length() == 0) {
+            fullName = user.getUsername();
+        }
+
+        return fullName;
+    }
 }
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java
index 8da274e..ad6d185 100755
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProviderFactory.java
@@ -5,10 +5,10 @@ import org.keycloak.models.UserFederationProvider;
 import org.keycloak.models.UserFederationProviderFactory;
 import org.keycloak.models.UserFederationProviderModel;
 import org.keycloak.models.KeycloakSession;
+import org.keycloak.picketlink.PartitionManagerProvider;
 import org.picketlink.idm.PartitionManager;
 
 import java.util.Collections;
-import java.util.List;
 import java.util.Set;
 
 /**
@@ -18,7 +18,6 @@ import java.util.Set;
  */
 public class LDAPFederationProviderFactory implements UserFederationProviderFactory {
     public static final String PROVIDER_NAME = "ldap";
-    PartitionManagerRegistry registry;
 
     @Override
     public UserFederationProvider create(KeycloakSession session) {
@@ -27,13 +26,13 @@ public class LDAPFederationProviderFactory implements UserFederationProviderFact
 
     @Override
     public UserFederationProvider getInstance(KeycloakSession session, UserFederationProviderModel model) {
-        PartitionManager partition = registry.getPartitionManager(model);
+        PartitionManagerProvider idmProvider = session.getProvider(PartitionManagerProvider.class);
+        PartitionManager partition = idmProvider.getPartitionManager(model);
         return new LDAPFederationProvider(session, model, partition);
     }
 
     @Override
     public void init(Config.Scope config) {
-        registry = new PartitionManagerRegistry();
     }
 
     @Override
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 3b6ac1c..ba29870 100644
--- a/model/api/src/main/java/org/keycloak/models/LDAPConstants.java
+++ b/model/api/src/main/java/org/keycloak/models/LDAPConstants.java
@@ -18,4 +18,6 @@ public class LDAPConstants {
     public static final String USER_DN_SUFFIX = "userDnSuffix";
     public static final String BIND_DN = "bindDn";
     public static final String BIND_CREDENTIAL = "bindCredential";
+
+    public static final String USER_ACCOUNT_CONTROLS_AFTER_PASSWORD_UPDATE = "userAccountControlsAfterPasswordUpdate";
 }
diff --git a/picketlink/keycloak-picketlink-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/picketlink/keycloak-picketlink-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index ffcb6e5..88b1bcc 100644
--- a/picketlink/keycloak-picketlink-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/picketlink/keycloak-picketlink-api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -1 +1 @@
-org.keycloak.picketlink.IdentityManagerSpi
\ No newline at end of file
+org.keycloak.picketlink.PartitionManagerSpi
\ No newline at end of file
diff --git a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/KeycloakEventBridge.java b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/KeycloakEventBridge.java
new file mode 100644
index 0000000..90a221e
--- /dev/null
+++ b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/KeycloakEventBridge.java
@@ -0,0 +1,57 @@
+package org.keycloak.picketlink.idm;
+
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+
+import org.jboss.logging.Logger;
+import org.picketlink.idm.PartitionManager;
+import org.picketlink.idm.event.CredentialUpdatedEvent;
+import org.picketlink.idm.event.EventBridge;
+import org.picketlink.idm.ldap.internal.LDAPIdentityStore;
+import org.picketlink.idm.ldap.internal.LDAPOperationManager;
+import org.picketlink.idm.model.basic.User;
+import org.picketlink.idm.spi.CredentialStore;
+import org.picketlink.idm.spi.IdentityContext;
+import org.picketlink.idm.spi.StoreSelector;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class KeycloakEventBridge implements EventBridge {
+
+    private static final Logger logger = Logger.getLogger(KeycloakEventBridge.class);
+
+    private final boolean updateUserAccountAfterPasswordUpdate;
+
+    public KeycloakEventBridge(boolean updateUserAccountAfterPasswordUpdate) {
+        this.updateUserAccountAfterPasswordUpdate = updateUserAccountAfterPasswordUpdate;
+    }
+
+    @Override
+    public void raiseEvent(Object event) {
+        // Used in ActiveDirectory to put account into "enabled" state (aka userAccountControl=512, see http://support.microsoft.com/kb/305144/en ) after password update. If value is -1, it's ignored
+        if (updateUserAccountAfterPasswordUpdate && event instanceof CredentialUpdatedEvent) {
+            CredentialUpdatedEvent credEvent = ((CredentialUpdatedEvent) event);
+            PartitionManager partitionManager = credEvent.getPartitionMananger();
+            IdentityContext identityCtx = (IdentityContext)partitionManager.createIdentityManager();
+
+            CredentialStore store = ((StoreSelector)partitionManager).getStoreForCredentialOperation(identityCtx, credEvent.getCredential().getClass());
+            if (store instanceof LDAPIdentityStore) {
+                LDAPIdentityStore ldapStore = (LDAPIdentityStore)store;
+                LDAPOperationManager operationManager = ldapStore.getOperationManager();
+                User picketlinkUser = (User) credEvent.getAccount();
+                String userDN = ldapStore.getBindingDN(picketlinkUser, true);
+
+                ModificationItem[] mods = new ModificationItem[1];
+                BasicAttribute mod0 = new BasicAttribute("userAccountControl", "512");
+                mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, mod0);
+                operationManager.modifyAttribute(userDN, mod0);
+                logger.debug("Attribute userAccountControls switched to 512 after password update of user " + picketlinkUser.getLoginName());
+            } else {
+                logger.debug("Store for credential updates is not LDAPIdentityStore. Ignored");
+            }
+
+        }
+    }
+}
diff --git a/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java
new file mode 100644
index 0000000..7844e8e
--- /dev/null
+++ b/picketlink/keycloak-picketlink-ldap/src/main/java/org/keycloak/picketlink/idm/LDAPKeycloakCredentialHandler.java
@@ -0,0 +1,27 @@
+package org.keycloak.picketlink.idm;
+
+import org.picketlink.idm.IdentityManager;
+import org.picketlink.idm.ldap.internal.LDAPPlainTextPasswordCredentialHandler;
+import org.picketlink.idm.model.basic.BasicModel;
+import org.picketlink.idm.model.basic.User;
+import org.picketlink.idm.spi.IdentityContext;
+
+import static org.picketlink.idm.IDMLog.CREDENTIAL_LOGGER;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class LDAPKeycloakCredentialHandler extends LDAPPlainTextPasswordCredentialHandler {
+
+    // Overridden as in Keycloak, we don't have Agents
+    @Override
+    protected User getAccount(IdentityContext context, String loginName) {
+        IdentityManager identityManager = getIdentityManager(context);
+
+        if (CREDENTIAL_LOGGER.isDebugEnabled()) {
+            CREDENTIAL_LOGGER.debugf("Trying to find account [%s] using default account type [%s]", loginName, User.class);
+        }
+
+        return BasicModel.getUser(identityManager, loginName);
+    }
+}
diff --git a/picketlink/keycloak-picketlink-ldap/src/main/resources/META-INF/services/org.keycloak.picketlink.PartitionManagerProviderFactory b/picketlink/keycloak-picketlink-ldap/src/main/resources/META-INF/services/org.keycloak.picketlink.PartitionManagerProviderFactory
new file mode 100644
index 0000000..5bfaf9d
--- /dev/null
+++ b/picketlink/keycloak-picketlink-ldap/src/main/resources/META-INF/services/org.keycloak.picketlink.PartitionManagerProviderFactory
@@ -0,0 +1 @@
+org.keycloak.picketlink.ldap.LDAPPartitionManagerProviderFactory
\ No newline at end of file
diff --git a/picketlink/pom.xml b/picketlink/pom.xml
index 30d9b06..4cefc46 100755
--- a/picketlink/pom.xml
+++ b/picketlink/pom.xml
@@ -17,6 +17,7 @@
 
     <modules>
         <module>keycloak-picketlink-api</module>
+        <module>keycloak-picketlink-ldap</module>
     </modules>
 
 

pom.xml 2(+1 -1)

diff --git a/pom.xml b/pom.xml
index 6e8c88d..dcecacf 100755
--- a/pom.xml
+++ b/pom.xml
@@ -18,7 +18,7 @@
         <resteasy.version>2.3.7.Final</resteasy.version>
         <resteasy.version.latest>3.0.8.Final</resteasy.version.latest>
         <undertow.version>1.0.15.Final</undertow.version>
-        <picketlink.version>2.6.0.CR5</picketlink.version>
+        <picketlink.version>2.7.0.Beta1-20140731</picketlink.version>
         <picketbox.ldap.version>1.0.2.Final</picketbox.ldap.version>
         <mongo.driver.version>2.11.3</mongo.driver.version>
         <jboss.logging.version>3.1.4.GA</jboss.logging.version>
diff --git a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
index 6f7b21e..7101a8f 100755
--- a/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
+++ b/testsuite/integration/src/main/resources/META-INF/keycloak-server.json
@@ -78,7 +78,7 @@
             "host": "${keycloak.connectionsMongo.host:127.0.0.1}",
             "port": "${keycloak.connectionsMongo.port:27017}",
             "db": "${keycloak.connectionsMongo.db:keycloak}",
-            "clearOnStartup": "${keycloak.connectionsMongo.clearOnStartup:true}"
+            "clearOnStartup": "${keycloak.connectionsMongo.clearOnStartup:false}"
         }
     }
 }
\ No newline at end of file
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/LDAPTestUtils.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/LDAPTestUtils.java
index fa9f703..cf1ab61 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/LDAPTestUtils.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/LDAPTestUtils.java
@@ -1,9 +1,6 @@
 package org.keycloak.testsuite;
 
-import org.keycloak.federation.ldap.PartitionManagerRegistry;
-import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.RealmModel;
-import org.keycloak.picketlink.IdentityManagerProvider;
+import org.keycloak.picketlink.ldap.PartitionManagerRegistry;
 import org.picketlink.idm.IdentityManager;
 import org.picketlink.idm.PartitionManager;
 import org.picketlink.idm.credential.Password;