keycloak-aplcache

Changes

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 649ad7e..464dcca 100755
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/DefaultMongoConnectionFactoryProvider.java
@@ -10,7 +10,7 @@ import org.keycloak.Config;
 import org.keycloak.connections.mongo.api.MongoStore;
 import org.keycloak.connections.mongo.impl.MongoStoreImpl;
 import org.keycloak.connections.mongo.impl.context.TransactionMongoStoreInvocationContext;
-import org.keycloak.connections.mongo.updater.DefaultMongoUpdaterProvider;
+import org.keycloak.connections.mongo.updater.MongoUpdaterProvider;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.KeycloakSessionFactory;
 
@@ -51,7 +51,7 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
 
     @Override
     public MongoConnectionProvider create(KeycloakSession session) {
-        lazyInit();
+        lazyInit(session);
 
         TransactionMongoStoreInvocationContext invocationContext = new TransactionMongoStoreInvocationContext(mongoStore);
         session.getTransaction().enlist(new MongoKeycloakTransaction(invocationContext));
@@ -69,7 +69,7 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
     }
 
 
-    private void lazyInit() {
+    private void lazyInit(KeycloakSession session) {
         if (client == null) {
             synchronized (this) {
                 if (client == null) {
@@ -94,7 +94,13 @@ public class DefaultMongoConnectionFactoryProvider implements MongoConnectionPro
                         String databaseSchema = config.get("databaseSchema");
                         if (databaseSchema != null) {
                             if (databaseSchema.equals("update")) {
-                                new DefaultMongoUpdaterProvider().update(db);
+                                MongoUpdaterProvider mongoUpdater = session.getProvider(MongoUpdaterProvider.class);
+
+                                if (mongoUpdater == null) {
+                                    throw new RuntimeException("Can't update database: Mongo updater provider not found");
+                                }
+
+                                mongoUpdater.update(session, db);
                             } else {
                                 throw new RuntimeException("Invalid value for databaseSchema: " + databaseSchema);
                             }
diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/MapMapper.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/MapMapper.java
index 988ce34..d4f0d29 100644
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/MapMapper.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/impl/types/MapMapper.java
@@ -25,10 +25,13 @@ public class MapMapper<T extends Map> implements Mapper<T, BasicDBObject> {
 
     @Override
     public BasicDBObject convertObject(MapperContext<T, BasicDBObject> context) {
-        T objectToConvert = context.getObjectToConvert();
+        T mapToConvert = context.getObjectToConvert();
+        return convertMap(mapToConvert);
+    }
 
+    public static BasicDBObject convertMap(Map mapToConvert) {
         BasicDBObject dbObject = new BasicDBObject();
-        Set<Map.Entry> entries = objectToConvert.entrySet();
+        Set<Map.Entry> entries = mapToConvert.entrySet();
         for (Map.Entry entry : entries) {
             String key = (String)entry.getKey();
             Object value = entry.getValue();
diff --git a/connections/mongo/src/main/java/org/keycloak/connections/mongo/updater/MongoUpdaterProvider.java b/connections/mongo/src/main/java/org/keycloak/connections/mongo/updater/MongoUpdaterProvider.java
index 7192f1d..3147100 100644
--- a/connections/mongo/src/main/java/org/keycloak/connections/mongo/updater/MongoUpdaterProvider.java
+++ b/connections/mongo/src/main/java/org/keycloak/connections/mongo/updater/MongoUpdaterProvider.java
@@ -1,6 +1,7 @@
 package org.keycloak.connections.mongo.updater;
 
 import com.mongodb.DB;
+import org.keycloak.models.KeycloakSession;
 import org.keycloak.provider.Provider;
 
 /**
@@ -8,6 +9,6 @@ import org.keycloak.provider.Provider;
  */
 public interface MongoUpdaterProvider extends Provider {
 
-    public void update(DB db);
+    public void update(KeycloakSession session, DB db);
 
 }
diff --git a/connections/mongo/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/connections/mongo/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index 90eedc3..fdf7660 100644
--- a/connections/mongo/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/connections/mongo/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -1 +1,2 @@
-org.keycloak.connections.mongo.MongoConnectionSpi
\ No newline at end of file
+org.keycloak.connections.mongo.MongoConnectionSpi
+org.keycloak.connections.mongo.updater.MongoUpdaterSpi
\ No newline at end of file
diff --git a/connections/mongo-update/pom.xml b/connections/mongo-update/pom.xml
new file mode 100644
index 0000000..658df45
--- /dev/null
+++ b/connections/mongo-update/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <artifactId>keycloak-parent</artifactId>
+        <groupId>org.keycloak</groupId>
+        <version>1.2.0.Beta1-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>keycloak-connections-mongo-update</artifactId>
+    <name>Keycloak Connections Mongo Update</name>
+    <description/>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-model-api</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-connections-mongo</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-services</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mongodb</groupId>
+            <artifactId>mongo-java-driver</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.logging</groupId>
+            <artifactId>jboss-logging</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/connections/mongo-update/src/main/resources/META-INF/services/org.keycloak.connections.mongo.updater.MongoUpdaterProviderFactory b/connections/mongo-update/src/main/resources/META-INF/services/org.keycloak.connections.mongo.updater.MongoUpdaterProviderFactory
new file mode 100644
index 0000000..6565597
--- /dev/null
+++ b/connections/mongo-update/src/main/resources/META-INF/services/org.keycloak.connections.mongo.updater.MongoUpdaterProviderFactory
@@ -0,0 +1 @@
+org.keycloak.connections.mongo.updater.impl.DefaultMongoUpdaterProviderFactory
\ No newline at end of file
diff --git a/connections/pom.xml b/connections/pom.xml
index 58918f5..d43d861 100755
--- a/connections/pom.xml
+++ b/connections/pom.xml
@@ -18,6 +18,7 @@
         <module>infinispan</module>
         <module>mongo</module>
         <module>file</module>
+        <module>mongo-update</module>
     </modules>
 
     <build>
diff --git a/dependencies/server-all/pom.xml b/dependencies/server-all/pom.xml
index 25b33d0..fe6d5cc 100755
--- a/dependencies/server-all/pom.xml
+++ b/dependencies/server-all/pom.xml
@@ -182,6 +182,11 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-connections-mongo-update</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
             <artifactId>keycloak-model-mongo</artifactId>
             <version>${project.version}</version>
         </dependency>
diff --git a/distribution/modules/build.xml b/distribution/modules/build.xml
index 52b97ef..9199165 100755
--- a/distribution/modules/build.xml
+++ b/distribution/modules/build.xml
@@ -269,6 +269,10 @@
             <maven-resource group="org.keycloak" artifact="keycloak-connections-mongo"/>
         </module-def>
 
+        <module-def name="org.keycloak.keycloak-connections-mongo-update">
+            <maven-resource group="org.keycloak" artifact="keycloak-connections-mongo-update"/>
+        </module-def>
+
         <module-def name="org.keycloak.keycloak-model-mongo">
             <maven-resource group="org.keycloak" artifact="keycloak-model-mongo"/>
         </module-def>
diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-mongo-update/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-mongo-update/main/module.xml
new file mode 100644
index 0000000..efc0102
--- /dev/null
+++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-mongo-update/main/module.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+
+
+<module xmlns="urn:jboss:module:1.1" name="org.keycloak.keycloak-connections-mongo-update">
+    <resources>
+        <!-- Insert resources here -->
+    </resources>
+    <dependencies>
+        <module name="org.keycloak.keycloak-core"/>
+        <module name="org.keycloak.keycloak-model-api"/>
+        <module name="org.keycloak.keycloak-connections-mongo"/>
+        <module name="org.keycloak.keycloak-services"/>
+        <module name="org.mongodb.mongo-java-driver"/>
+        <module name="org.jboss.logging"/>
+        <module name="javax.api"/>
+    </dependencies>
+
+</module>
\ No newline at end of file
diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml
index 2772582..c757599 100755
--- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml
+++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-server/main/module.xml
@@ -16,6 +16,7 @@
         <module name="org.keycloak.keycloak-connections-jpa" services="import"/>
         <module name="org.keycloak.keycloak-connections-jpa-liquibase" services="import"/>
         <module name="org.keycloak.keycloak-connections-mongo" services="import"/>
+        <module name="org.keycloak.keycloak-connections-mongo-update" services="import"/>
         <module name="org.keycloak.keycloak-connections-file" services="import"/>
         <module name="org.keycloak.keycloak-core" services="import"/>
         <module name="org.keycloak.keycloak-core-jaxrs" services="import"/>
diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-services/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-services/main/module.xml
index 341e44b..bafc53f 100755
--- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-services/main/module.xml
+++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-services/main/module.xml
@@ -16,6 +16,7 @@
         <module name="org.keycloak.keycloak-connections-jpa" services="import"/>
         <module name="org.keycloak.keycloak-connections-jpa-liquibase" services="import"/>
         <module name="org.keycloak.keycloak-connections-mongo" services="import"/>
+        <module name="org.keycloak.keycloak-connections-mongo-update" services="import"/>
         <module name="org.keycloak.keycloak-connections-file" services="import"/>
         <module name="org.keycloak.keycloak-core" services="import"/>
         <module name="org.keycloak.keycloak-core-jaxrs" services="import"/>
diff --git a/distribution/subsystem-war/src/main/webapp/WEB-INF/jboss-deployment-structure.xml b/distribution/subsystem-war/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
index 1da88be..29de32e 100755
--- a/distribution/subsystem-war/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
+++ b/distribution/subsystem-war/src/main/webapp/WEB-INF/jboss-deployment-structure.xml
@@ -7,6 +7,7 @@
             <module name="org.keycloak.keycloak-connections-jpa" services="import" meta-inf="import"/>
             <module name="org.keycloak.keycloak-connections-jpa-liquibase" services="import"/>
             <module name="org.keycloak.keycloak-connections-mongo" services="import"/>
+            <module name="org.keycloak.keycloak-connections-mongo-update" services="import"/>
             <module name="org.keycloak.keycloak-connections-file" services="import"/>
             <module name="org.keycloak.keycloak-core" services="import"/>
             <module name="org.keycloak.keycloak-core-jaxrs" services="import"/>
diff --git a/model/api/src/main/java/org/keycloak/models/ClaimMask.java b/model/api/src/main/java/org/keycloak/models/ClaimMask.java
index 3a65034..da8063f 100755
--- a/model/api/src/main/java/org/keycloak/models/ClaimMask.java
+++ b/model/api/src/main/java/org/keycloak/models/ClaimMask.java
@@ -49,4 +49,6 @@ public class ClaimMask {
         return (mask & PHONE) > 0;
     }
 
+
+
 }
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
index 34b688c..4423686 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocol.java
@@ -5,14 +5,11 @@ import org.jboss.resteasy.client.ClientRequest;
 import org.jboss.resteasy.client.ClientResponse;
 import org.jboss.resteasy.client.core.executors.ApacheHttpClient4Executor;
 import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.ClaimMask;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.ClientSessionModel;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.KeycloakSessionFactory;
 import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.RealmModel;
-import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
 import org.keycloak.protocol.LoginProtocol;
diff --git a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolFactory.java b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolFactory.java
index 8ef3c80..83afe93 100755
--- a/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolFactory.java
+++ b/saml/saml-protocol/src/main/java/org/keycloak/protocol/saml/SamlProtocolFactory.java
@@ -51,6 +51,11 @@ public class SamlProtocolFactory extends AbstractLoginProtocolFactory {
         return builtins;
     }
 
+    @Override
+    public List<ProtocolMapperModel> getDefaultBuiltinMappers() {
+        return defaultBuiltins;
+    }
+
     static List<ProtocolMapperModel> builtins = new ArrayList<>();
     static List<ProtocolMapperModel> defaultBuiltins = new ArrayList<>();
 
diff --git a/services/src/main/java/org/keycloak/protocol/LoginProtocolFactory.java b/services/src/main/java/org/keycloak/protocol/LoginProtocolFactory.java
index f634161..5e5bf0b 100755
--- a/services/src/main/java/org/keycloak/protocol/LoginProtocolFactory.java
+++ b/services/src/main/java/org/keycloak/protocol/LoginProtocolFactory.java
@@ -19,5 +19,12 @@ public interface LoginProtocolFactory extends ProviderFactory<LoginProtocol> {
      * @return
      */
     List<ProtocolMapperModel> getBuiltinMappers();
+
+    /**
+     * List of mappers, which are added to new clients by default
+     * @return
+     */
+    List<ProtocolMapperModel> getDefaultBuiltinMappers();
+
     Object createProtocolEndpoint(RealmModel realm, EventBuilder event, AuthenticationManager authManager);
 }
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
index 120446f..c039929 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolFactory.java
@@ -25,6 +25,14 @@ import java.util.Map;
  * @version $Revision: 1 $
  */
 public class OIDCLoginProtocolFactory extends AbstractLoginProtocolFactory {
+
+    public static final String USERNAME = "username";
+    public static final String EMAIL = "email";
+    public static final String EMAIL_VERIFIED = "email verified";
+    public static final String GIVEN_NAME = "given name";
+    public static final String FAMILY_NAME = "family name";
+    public static final String FULL_NAME = "full name";
+
     @Override
     public LoginProtocol create(KeycloakSession session) {
         return new OIDCLoginProtocol().setSession(session);
@@ -35,41 +43,46 @@ public class OIDCLoginProtocolFactory extends AbstractLoginProtocolFactory {
         return builtins;
     }
 
+    @Override
+    public List<ProtocolMapperModel> getDefaultBuiltinMappers() {
+        return defaultBuiltins;
+    }
+
     static List<ProtocolMapperModel> builtins = new ArrayList<>();
     static List<ProtocolMapperModel> defaultBuiltins = new ArrayList<>();
 
     static {
 
         ProtocolMapperModel model;
-        model = UserPropertyMapper.createClaimMapper("username",
+        model = UserPropertyMapper.createClaimMapper(USERNAME,
                 "username",
                 "preferred_username", "String",
-                true, "username",
+                true, USERNAME,
                 true, true);
         builtins.add(model);
         defaultBuiltins.add(model);
-        model = UserPropertyMapper.createClaimMapper("email",
+        model = UserPropertyMapper.createClaimMapper(EMAIL,
                 "email",
                 "email", "String",
-                true, "email",
+                true, EMAIL,
                 true, true);
         builtins.add(model);
         defaultBuiltins.add(model);
-        model = UserPropertyMapper.createClaimMapper("given name",
+        model = UserPropertyMapper.createClaimMapper(GIVEN_NAME,
                 "firstName",
                 "given_name", "String",
-                true, "given name",
+                true, GIVEN_NAME,
                 true, true);
         builtins.add(model);
         defaultBuiltins.add(model);
-        model = UserPropertyMapper.createClaimMapper("family name",
+        model = UserPropertyMapper.createClaimMapper(FAMILY_NAME,
                 "lastName",
                 "family_name", "String",
-                true, "family name",
+                true, FAMILY_NAME,
                 true, true);
         builtins.add(model);
         defaultBuiltins.add(model);
-        model = UserPropertyMapper.createClaimMapper("email verified",
+        model = UserPropertyMapper.createClaimMapper(EMAIL_VERIFIED,
                 "emailVerified",
                 "email_verified", "boolean",
                 false, null,
@@ -77,11 +90,11 @@ public class OIDCLoginProtocolFactory extends AbstractLoginProtocolFactory {
         builtins.add(model);
 
         ProtocolMapperModel fullName = new ProtocolMapperModel();
-        fullName.setName("full name");
+        fullName.setName(FULL_NAME);
         fullName.setProtocolMapper(FullNameMapper.PROVIDER_ID);
         fullName.setProtocol(OIDCLoginProtocol.LOGIN_PROTOCOL);
         fullName.setConsentRequired(true);
-        fullName.setConsentText("full name");
+        fullName.setConsentText(FULL_NAME);
         Map<String, String> config = new HashMap<String, String>();
         config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ACCESS_TOKEN, "true");
         config.put(OIDCAttributeMapperHelper.INCLUDE_IN_ID_TOKEN, "true");
diff --git a/services/src/main/java/org/keycloak/services/util/MigrationUtils.java b/services/src/main/java/org/keycloak/services/util/MigrationUtils.java
new file mode 100644
index 0000000..f2a1676
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/util/MigrationUtils.java
@@ -0,0 +1,70 @@
+package org.keycloak.services.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.keycloak.models.ClaimMask;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.ProtocolMapperModel;
+import org.keycloak.protocol.LoginProtocol;
+import org.keycloak.protocol.LoginProtocolFactory;
+import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
+import org.keycloak.provider.ProviderFactory;
+
+/**
+ * Various common utils needed for migration from older version to newer
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MigrationUtils {
+
+    private MigrationUtils() {}
+
+    /**
+     *
+     * @param session
+     * @param claimMask mask used on ClientModel in 1.1.0
+     * @return set of 1.2.0.Beta1 protocol mappers corresponding to given claimMask
+     */
+    public static Collection<ProtocolMapperModel> getMappersForClaimMask(KeycloakSession session, Long claimMask) {
+        Map<String, ProtocolMapperModel> allMappers = getAllDefaultMappers(session);
+
+        if (claimMask == null) {
+            return allMappers.values();
+        }
+
+        if (!ClaimMask.hasUsername(claimMask)) {
+            allMappers.remove(OIDCLoginProtocolFactory.USERNAME);
+        }
+        if (!ClaimMask.hasEmail(claimMask)) {
+            allMappers.remove(OIDCLoginProtocolFactory.EMAIL);
+        }
+        if (!ClaimMask.hasName(claimMask)) {
+            allMappers.remove(OIDCLoginProtocolFactory.FAMILY_NAME);
+            allMappers.remove(OIDCLoginProtocolFactory.FULL_NAME);
+            allMappers.remove(OIDCLoginProtocolFactory.GIVEN_NAME);
+        }
+
+        return allMappers.values();
+    }
+
+    private static Map<String, ProtocolMapperModel> getAllDefaultMappers(KeycloakSession session) {
+        Map<String, ProtocolMapperModel> allMappers = new HashMap<String, ProtocolMapperModel>();
+
+        List<ProviderFactory> loginProtocolFactories = session.getKeycloakSessionFactory().getProviderFactories(LoginProtocol.class);
+
+        for (ProviderFactory factory : loginProtocolFactories) {
+            LoginProtocolFactory loginProtocolFactory = (LoginProtocolFactory) factory;
+            List<ProtocolMapperModel> currentMappers = loginProtocolFactory.getDefaultBuiltinMappers();
+
+            for (ProtocolMapperModel protocolMapper : currentMappers) {
+                allMappers.put(protocolMapper.getName(), protocolMapper);
+            }
+        }
+
+        return allMappers;
+    }
+}