keycloak-uncached

KEYCLOAK-1116 KEYCLOAK-1117 JSON migration and removal of

3/26/2015 4:09:50 AM

Changes

services/src/main/java/org/keycloak/services/resources/admin/ClaimResource.java 54(+0 -54)

Details

diff --git a/connections/jpa-liquibase/pom.xml b/connections/jpa-liquibase/pom.xml
index d541d2a..659e611 100755
--- a/connections/jpa-liquibase/pom.xml
+++ b/connections/jpa-liquibase/pom.xml
@@ -21,7 +21,7 @@
         </dependency>
         <dependency>
             <groupId>org.keycloak</groupId>
-            <artifactId>keycloak-services</artifactId>
+            <artifactId>keycloak-model-api</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
diff --git a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java
index b28dce5..89e7885 100644
--- a/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java
+++ b/connections/jpa-liquibase/src/main/java/org/keycloak/connections/jpa/updater/liquibase/custom/JpaUpdate1_2_0_Beta1.java
@@ -2,7 +2,6 @@ package org.keycloak.connections.jpa.updater.liquibase.custom;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -12,11 +11,11 @@ import liquibase.statement.core.InsertStatement;
 import liquibase.statement.core.UpdateStatement;
 import liquibase.structure.core.Table;
 import org.keycloak.Config;
+import org.keycloak.migration.MigrationProvider;
 import org.keycloak.models.AdminRoles;
 import org.keycloak.models.ClaimMask;
-import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.services.util.MigrationUtils;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -296,8 +295,10 @@ public class JpaUpdate1_2_0_Beta1 extends CustomKeycloakTask {
                     Object acmObj = resultSet.getObject("ALLOWED_CLAIMS_MASK");
                     long mask = (acmObj != null) ? (Long) acmObj : ClaimMask.ALL;
 
-                    Collection<ProtocolMapperModel> protocolMappers = MigrationUtils.getMappersForClaimMask(this.kcSession, mask);
-                    for (ProtocolMapperModel protocolMapper : protocolMappers) {
+                    MigrationProvider migrationProvider = this.kcSession.getProvider(MigrationProvider.class);
+                    List<ProtocolMapperRepresentation> protocolMappers = migrationProvider.getMappersForClaimMask(mask);
+
+                    for (ProtocolMapperRepresentation protocolMapper : protocolMappers) {
                         String mapperId = KeycloakModelUtils.generateId();
 
                         InsertStatement insert = new InsertStatement(null, null, protocolMapperTableName)
diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
index 079bee8..d9d1a2e 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.2.0.Beta1.xml
@@ -152,11 +152,12 @@
 
         <customChange class="org.keycloak.connections.jpa.updater.liquibase.custom.JpaUpdate1_2_0_Beta1"/>
 
-        <!-- Remove obsolete 'social' stuff -->
+        <!-- Remove obsolete 'social' and 'claims' stuff -->
         <dropForeignKeyConstraint baseTableName="USER_SOCIAL_LINK" constraintName="FK_68CJYS5UWM55UY823Y75XG4OM" />
         <dropTable tableName="USER_SOCIAL_LINK" cascadeConstraints="true" />
         <dropForeignKeyConstraint baseTableName="REALM_SOCIAL_CONFIG" constraintName="FK_SV5I3C2TI7G0G922FGE683SOV" />
         <dropTable tableName="REALM_SOCIAL_CONFIG" cascadeConstraints="true" />
+        <dropColumn tableName="CLIENT" columnName="ALLOWED_CLAIMS_MASK" />
 
     </changeSet>
 </databaseChangeLog>
diff --git a/connections/mongo-update/pom.xml b/connections/mongo-update/pom.xml
index 658df45..0c67e8b 100644
--- a/connections/mongo-update/pom.xml
+++ b/connections/mongo-update/pom.xml
@@ -30,11 +30,6 @@
             <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>
diff --git a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java
index 5dcb1e7..65cf97f 100644
--- a/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java
+++ b/connections/mongo-update/src/main/java/org/keycloak/connections/mongo/updater/impl/updates/Update1_2_0_Beta1.java
@@ -1,6 +1,5 @@
 package org.keycloak.connections.mongo.updater.impl.updates;
 
-import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -12,14 +11,11 @@ import com.mongodb.DBCursor;
 import com.mongodb.DBObject;
 import org.keycloak.Config;
 import org.keycloak.connections.mongo.impl.types.MapMapper;
+import org.keycloak.migration.MigrationProvider;
 import org.keycloak.models.AdminRoles;
 import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.ProtocolMapperModel;
 import org.keycloak.models.utils.KeycloakModelUtils;
-import org.keycloak.protocol.LoginProtocol;
-import org.keycloak.protocol.LoginProtocolFactory;
-import org.keycloak.provider.ProviderFactory;
-import org.keycloak.services.util.MigrationUtils;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 
 /**
  * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
@@ -74,8 +70,7 @@ public class Update1_2_0_Beta1 extends Update {
                             DBObject identityProvider = new BasicDBObjectBuilder()
                                     .add("internalId", KeycloakModelUtils.generateId())
                                     .add("providerId", socialProviderId)
-                                    .add("name", socialProviderId)
-                                    .add("id", socialProviderId)
+                                    .add("alias", socialProviderId.substring(0, 1).toUpperCase() + socialProviderId.substring(1))
                                     .add("updateProfileFirstLogin", updateProfileOnInitialSocialLogin)
                                     .add("enabled", true)
                                     .add("storeToken", false)
@@ -241,9 +236,10 @@ public class Update1_2_0_Beta1 extends Update {
                 currentClient.put("protocolMappers", dbProtocolMappers);
 
                 Object claimMask = currentClient.get("allowedClaimsMask");
-                Collection<ProtocolMapperModel> clientProtocolMappers = MigrationUtils.getMappersForClaimMask(session, (Long) claimMask);
+                MigrationProvider migrationProvider = session.getProvider(MigrationProvider.class);
+                List<ProtocolMapperRepresentation> protocolMappers = migrationProvider.getMappersForClaimMask((Long) claimMask);
 
-                for (ProtocolMapperModel protocolMapper : clientProtocolMappers) {
+                for (ProtocolMapperRepresentation protocolMapper : protocolMappers) {
                     BasicDBObject dbMapper = new BasicDBObject();
                     dbMapper.put("id", KeycloakModelUtils.generateId());
                     dbMapper.put("protocol", protocolMapper.getProtocol());
@@ -259,6 +255,7 @@ public class Update1_2_0_Beta1 extends Update {
                     dbProtocolMappers.add(dbMapper);
                 }
 
+                // Remove obsolete keys from client
                 currentClient.remove("allowedClaimsMask");
 
                 log.debugv("Added default mappers to application {1}", currentClient.get("name"));
diff --git a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
index 88c8cff..e407049 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ApplicationRepresentation.java
@@ -18,6 +18,7 @@ public class ApplicationRepresentation {
     protected String[] defaultRoles;
     protected List<String> redirectUris;
     protected List<String> webOrigins;
+    @Deprecated
     protected ClaimRepresentation claims;
     protected Integer notBefore;
     protected Boolean bearerOnly;
diff --git a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
index e477be0..5f0ed4e 100755
--- a/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/OAuthClientRepresentation.java
@@ -14,6 +14,7 @@ public class OAuthClientRepresentation {
     protected List<String> webOrigins;
     protected Boolean enabled;
     protected String secret;
+    @Deprecated
     protected ClaimRepresentation claims;
     protected Integer notBefore;
     protected Boolean publicClient;
diff --git a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml
index c5b7d85..f52bc84 100755
--- a/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml
+++ b/distribution/modules/src/main/resources/modules/org/keycloak/keycloak-connections-jpa-liquibase/main/module.xml
@@ -10,7 +10,6 @@
         <module name="org.keycloak.keycloak-core"/>
         <module name="org.keycloak.keycloak-model-api"/>
         <module name="org.keycloak.keycloak-connections-jpa"/>
-        <module name="org.keycloak.keycloak-services"/>
         <module name="org.liquibase"/>
         <module name="javax.persistence.api"/>
         <module name="org.jboss.logging"/>
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
index efc0102..c14a061 100644
--- 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
@@ -10,7 +10,6 @@
         <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"/>
diff --git a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
index 8e5d445..9e68367 100755
--- a/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
+++ b/export-import/export-import-api/src/main/java/org/keycloak/exportimport/util/ExportUtils.java
@@ -169,8 +169,6 @@ public class ExportUtils {
         ApplicationRepresentation appRep = ModelToRepresentation.toRepresentation(app);
 
         appRep.setSecret(app.getSecret());
-        ClaimRepresentation claimRep = ModelToRepresentation.toRepresentation((ClientModel)app);
-        appRep.setClaims(claimRep);
         return appRep;
     }
 
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java
index 458135c..2601d53 100755
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ApplicationResource.java
@@ -1,8 +1,6 @@
 package org.keycloak.admin.client.resource;
 
-import org.jboss.resteasy.annotations.cache.NoCache;
 import org.keycloak.representations.idm.ApplicationRepresentation;
-import org.keycloak.representations.idm.ClaimRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.UserSessionRepresentation;
 
@@ -25,6 +23,9 @@ import java.util.Set;
  */
 public interface ApplicationResource {
 
+    @Path("protocol-mappers")
+    public ProtocolMappersResource getProtocolMappers();
+
     @GET
     @Produces(MediaType.APPLICATION_JSON)
     public ApplicationRepresentation toRepresentation();
@@ -51,16 +52,6 @@ public interface ApplicationResource {
     @Consumes(MediaType.APPLICATION_JSON)
     public void removeAllowedOrigins(Set<String> originsToRemove);
 
-    @GET
-    @Path("claims")
-    @Produces(MediaType.APPLICATION_JSON)
-    public ClaimRepresentation getClaims();
-
-    @PUT
-    @Path("claims")
-    @Consumes(MediaType.APPLICATION_JSON)
-    public void updateClaims(ClaimRepresentation claimRepresentation);
-
     @POST
     @Path("client-secret")
     @Produces(MediaType.APPLICATION_JSON)
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java
index 5d08748..a2effee 100755
--- a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/OAuthClientResource.java
@@ -1,6 +1,5 @@
 package org.keycloak.admin.client.resource;
 
-import org.keycloak.representations.idm.ClaimRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
 
@@ -16,37 +15,40 @@ import javax.ws.rs.core.MediaType;
 /**
  * @author rodrigo.sasaki@icarros.com.br
  */
-@Consumes(MediaType.APPLICATION_JSON)
-@Produces(MediaType.APPLICATION_JSON)
 public interface OAuthClientResource {
 
+    @Path("protocol-mappers")
+    public ProtocolMappersResource getProtocolMappers();
+
+    // TODO
+    // @Path("certificates/{attr}")
+    // public ClientAttributeCertificateResource getCertficateResource(@PathParam("attr") String attributePrefix);
+
     @GET
+    @Produces(MediaType.APPLICATION_JSON)
     public OAuthClientRepresentation toRepresentation();
 
     @PUT
+    @Consumes(MediaType.APPLICATION_JSON)
     public void update(OAuthClientRepresentation oAuthClientRepresentation);
 
     @DELETE
     public void remove();
 
-    @GET
-    @Path("claims")
-    public ClaimRepresentation getClaims();
-
-    @PUT
-    @Path("claims")
-    public ClaimRepresentation updateClaims(ClaimRepresentation claimRepresentation);
-
     @POST
     @Path("client-secret")
+    @Consumes("application/json")
+    @Produces(MediaType.APPLICATION_JSON)
     public CredentialRepresentation generateNewSecret();
 
     @GET
     @Path("client-secret")
+    @Produces(MediaType.APPLICATION_JSON)
     public CredentialRepresentation getSecret();
 
     @GET
     @Path("installation")
+    @Produces(MediaType.APPLICATION_JSON)
     public String getInstallationJson();
 
     @Path("/scope-mappings")
diff --git a/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ProtocolMappersResource.java b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ProtocolMappersResource.java
new file mode 100644
index 0000000..40e505f
--- /dev/null
+++ b/integration/admin-client/src/main/java/org/keycloak/admin/client/resource/ProtocolMappersResource.java
@@ -0,0 +1,55 @@
+package org.keycloak.admin.client.resource;
+
+import java.util.List;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Response;
+
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public interface ProtocolMappersResource {
+
+    @GET
+    @Path("protocol/{protocol}")
+    @Produces("application/json")
+    public List<ProtocolMapperRepresentation> getMappersPerProtocol(@PathParam("protocol") String protocol);
+
+    @Path("models")
+    @POST
+    @Consumes("application/json")
+    public Response createMapper(ProtocolMapperRepresentation rep);
+
+    @Path("add-models")
+    @POST
+    @Consumes("application/json")
+    public void createMapper(List<ProtocolMapperRepresentation> reps);
+
+    @GET
+    @Path("models")
+    @Produces("application/json")
+    public List<ProtocolMapperRepresentation> getMappers();
+
+    @GET
+    @Path("models/{id}")
+    @Produces("application/json")
+    public ProtocolMapperRepresentation getMapperById(@PathParam("id") String id);
+
+    @PUT
+    @Path("models/{id}")
+    @Consumes("application/json")
+    public void update(@PathParam("id") String id, ProtocolMapperRepresentation rep);
+
+    @DELETE
+    @Path("models/{id}")
+    public void delete(@PathParam("id") String id);
+}
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationProvider.java b/model/api/src/main/java/org/keycloak/migration/MigrationProvider.java
new file mode 100644
index 0000000..784ba8e
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationProvider.java
@@ -0,0 +1,20 @@
+package org.keycloak.migration;
+
+import java.util.List;
+import org.keycloak.provider.Provider;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
+
+/**
+ * Various common utils needed for migration from older version to newer
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public interface MigrationProvider extends Provider {
+
+    /**
+     * @param claimMask mask used on ClientModel in 1.1.0
+     * @return set of 1.2.0.Beta1 protocol mappers corresponding to given claimMask
+     */
+    List<ProtocolMapperRepresentation> getMappersForClaimMask(Long claimMask);
+
+}
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationProviderFactory.java b/model/api/src/main/java/org/keycloak/migration/MigrationProviderFactory.java
new file mode 100644
index 0000000..a147ef7
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationProviderFactory.java
@@ -0,0 +1,9 @@
+package org.keycloak.migration;
+
+import org.keycloak.provider.ProviderFactory;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public interface MigrationProviderFactory extends ProviderFactory<MigrationProvider> {
+}
diff --git a/model/api/src/main/java/org/keycloak/migration/MigrationSpi.java b/model/api/src/main/java/org/keycloak/migration/MigrationSpi.java
new file mode 100644
index 0000000..f6b768c
--- /dev/null
+++ b/model/api/src/main/java/org/keycloak/migration/MigrationSpi.java
@@ -0,0 +1,26 @@
+package org.keycloak.migration;
+
+import org.keycloak.provider.Provider;
+import org.keycloak.provider.ProviderFactory;
+import org.keycloak.provider.Spi;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class MigrationSpi implements Spi {
+
+    @Override
+    public String getName() {
+        return "migration";
+    }
+
+    @Override
+    public Class<? extends Provider> getProviderClass() {
+        return MigrationProvider.class;
+    }
+
+    @Override
+    public Class<? extends ProviderFactory> getProviderFactoryClass() {
+        return MigrationProviderFactory.class;
+    }
+}
diff --git a/model/api/src/main/java/org/keycloak/models/ClientModel.java b/model/api/src/main/java/org/keycloak/models/ClientModel.java
index 39e4d17..e9de509 100755
--- a/model/api/src/main/java/org/keycloak/models/ClientModel.java
+++ b/model/api/src/main/java/org/keycloak/models/ClientModel.java
@@ -30,10 +30,6 @@ public interface ClientModel {
      */
     String getClientId();
 
-    long getAllowedClaimsMask();
-
-    void setAllowedClaimsMask(long mask);
-
     Set<String> getWebOrigins();
 
     void setWebOrigins(Set<String> webOrigins);
diff --git a/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
index 8ba2ef0..9c24072 100755
--- a/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/ClientEntity.java
@@ -56,14 +56,6 @@ public class ClientEntity extends AbstractIdentifiableEntity {
         this.secret = secret;
     }
 
-    public long getAllowedClaimsMask() {
-        return allowedClaimsMask;
-    }
-
-    public void setAllowedClaimsMask(long allowedClaimsMask) {
-        this.allowedClaimsMask = allowedClaimsMask;
-    }
-
     public int getNotBefore() {
         return notBefore;
     }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
index 30157e0..af0b92d 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/KeycloakModelUtils.java
@@ -178,7 +178,6 @@ public final class KeycloakModelUtils {
         ApplicationModel app = realm.addApplication(name);
         generateSecret(app);
         app.setFullScopeAllowed(true);
-        app.setAllowedClaimsMask(ClaimMask.ALL);
 
         return app;
     }
diff --git a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
index 7e88c9a..1ff0b01 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/ModelToRepresentation.java
@@ -192,21 +192,6 @@ public class ModelToRepresentation {
         return rep;
     }
 
-    public static ClaimRepresentation toRepresentation(ClientModel model) {
-        ClaimRepresentation rep = new ClaimRepresentation();
-        rep.setAddress(ClaimMask.hasAddress(model.getAllowedClaimsMask()));
-        rep.setEmail(ClaimMask.hasEmail(model.getAllowedClaimsMask()));
-        rep.setGender(ClaimMask.hasGender(model.getAllowedClaimsMask()));
-        rep.setLocale(ClaimMask.hasLocale(model.getAllowedClaimsMask()));
-        rep.setName(ClaimMask.hasName(model.getAllowedClaimsMask()));
-        rep.setPhone(ClaimMask.hasPhone(model.getAllowedClaimsMask()));
-        rep.setPicture(ClaimMask.hasPicture(model.getAllowedClaimsMask()));
-        rep.setProfile(ClaimMask.hasProfile(model.getAllowedClaimsMask()));
-        rep.setWebsite(ClaimMask.hasWebsite(model.getAllowedClaimsMask()));
-        rep.setUsername(ClaimMask.hasUsername(model.getAllowedClaimsMask()));
-        return rep;
-    }
-
     public static FederatedIdentityRepresentation toRepresentation(FederatedIdentityModel socialLink) {
         FederatedIdentityRepresentation rep = new FederatedIdentityRepresentation();
         rep.setUserName(socialLink.getUserName());
diff --git a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
index b23a367..85e724c 100755
--- a/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
+++ b/model/api/src/main/java/org/keycloak/models/utils/RepresentationToModel.java
@@ -3,6 +3,7 @@ package org.keycloak.models.utils;
 import net.iharder.Base64;
 import org.jboss.logging.Logger;
 import org.keycloak.enums.SslRequired;
+import org.keycloak.migration.MigrationProvider;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.BrowserSecurityHeaders;
 import org.keycloak.models.ClaimMask;
@@ -129,7 +130,7 @@ public class RepresentationToModel {
         importIdentityProviders(rep, newRealm);
 
         if (rep.getApplications() != null) {
-            Map<String, ApplicationModel> appMap = createApplications(rep, newRealm);
+            Map<String, ApplicationModel> appMap = createApplications(session, rep, newRealm);
         }
 
         if (rep.getRoles() != null) {
@@ -189,7 +190,7 @@ public class RepresentationToModel {
         }
 
         if (rep.getOauthClients() != null) {
-            createOAuthClients(rep, newRealm);
+            createOAuthClients(session, rep, newRealm);
         }
 
 
@@ -302,6 +303,7 @@ public class RepresentationToModel {
                 federatedIdentity.setIdentityProvider(social.getSocialProvider());
                 federatedIdentity.setUserId(social.getSocialUserId());
                 federatedIdentity.setUserName(social.getSocialUsername());
+                federatedIdentities.add(federatedIdentity);
             }
             user.setFederatedIdentities(federatedIdentities);
         }
@@ -309,6 +311,16 @@ public class RepresentationToModel {
         user.setSocialLinks(null);
     }
 
+    private static List<ProtocolMapperRepresentation> convertDeprecatedClaimsMask(KeycloakSession session, ClaimRepresentation claimRep) {
+        if (claimRep == null) {
+            return null;
+        }
+
+        long mask = getClaimsMask(claimRep);
+        MigrationProvider migrationProvider = session.getProvider(MigrationProvider.class);
+        return migrationProvider.getMappersForClaimMask(mask);
+    }
+
     public static void updateRealm(RealmRepresentation rep, RealmModel realm) {
         if (rep.getRealm() != null) {
             realm.setName(rep.getRealm());
@@ -435,10 +447,10 @@ public class RepresentationToModel {
 
     // APPLICATIONS
 
-    private static Map<String, ApplicationModel> createApplications(RealmRepresentation rep, RealmModel realm) {
+    private static Map<String, ApplicationModel> createApplications(KeycloakSession session, RealmRepresentation rep, RealmModel realm) {
         Map<String, ApplicationModel> appMap = new HashMap<String, ApplicationModel>();
         for (ApplicationRepresentation resourceRep : rep.getApplications()) {
-            ApplicationModel app = createApplication(realm, resourceRep, false);
+            ApplicationModel app = createApplication(session, realm, resourceRep, false);
             appMap.put(app.getName(), app);
         }
         return appMap;
@@ -451,8 +463,16 @@ public class RepresentationToModel {
      * @param resourceRep
      * @return
      */
-    public static ApplicationModel createApplication(RealmModel realm, ApplicationRepresentation resourceRep, boolean addDefaultRoles) {
+    public static ApplicationModel createApplication(KeycloakSession session, RealmModel realm, ApplicationRepresentation resourceRep, boolean addDefaultRoles) {
         logger.debug("************ CREATE APPLICATION: {0}" + resourceRep.getName());
+
+        if (resourceRep.getProtocolMappers() == null) {
+            List<ProtocolMapperRepresentation> convertedProtocolMappers = convertDeprecatedClaimsMask(session, resourceRep.getClaims());
+            if (convertedProtocolMappers != null) {
+                resourceRep.setProtocolMappers(convertedProtocolMappers);
+            }
+        }
+
         ApplicationModel applicationModel = resourceRep.getId()!=null ? realm.addApplication(resourceRep.getId(), resourceRep.getName()) : realm.addApplication(resourceRep.getName());
         if (resourceRep.isEnabled() != null) applicationModel.setEnabled(resourceRep.isEnabled());
         applicationModel.setManagementUrl(resourceRep.getAdminUrl());
@@ -595,8 +615,9 @@ public class RepresentationToModel {
         updateClientIdentityProviders(rep.getIdentityProviders(), resource);
     }
 
-    public static void setClaims(ClientModel model, ClaimRepresentation rep) {
-        long mask = model.getAllowedClaimsMask();
+    public static long getClaimsMask(ClaimRepresentation rep) {
+        long mask = ClaimMask.ALL;
+
         if (rep.getAddress()) {
             mask |= ClaimMask.ADDRESS;
         } else {
@@ -647,14 +668,14 @@ public class RepresentationToModel {
         } else {
             mask &= ~ClaimMask.WEBSITE;
         }
-        model.setAllowedClaimsMask(mask);
+        return mask;
     }
 
     // OAuth clients
 
-    private static void createOAuthClients(RealmRepresentation realmRep, RealmModel realm) {
+    private static void createOAuthClients(KeycloakSession session, RealmRepresentation realmRep, RealmModel realm) {
         for (OAuthClientRepresentation rep : realmRep.getOauthClients()) {
-            createOAuthClient(rep, realm);
+            createOAuthClient(session, rep, realm);
         }
     }
 
@@ -664,25 +685,29 @@ public class RepresentationToModel {
         return model;
     }
 
-    public static OAuthClientModel createOAuthClient(OAuthClientRepresentation rep, RealmModel realm) {
+    public static OAuthClientModel createOAuthClient(KeycloakSession session, OAuthClientRepresentation rep, RealmModel realm) {
         OAuthClientModel model = createOAuthClient(rep.getId(), rep.getName(), realm);
 
         model.updateIdentityProviders(toModel(rep.getIdentityProviders(), realm));
 
-        updateOAuthClient(rep, model);
+        updateOAuthClient(session, rep, model);
         return model;
     }
 
-    public static void updateOAuthClient(OAuthClientRepresentation rep, OAuthClientModel model) {
+    public static void updateOAuthClient(KeycloakSession session, OAuthClientRepresentation rep, OAuthClientModel model) {
+        if (rep.getProtocolMappers() == null) {
+            List<ProtocolMapperRepresentation> convertedProtocolMappers = convertDeprecatedClaimsMask(session, rep.getClaims());
+            if (convertedProtocolMappers != null) {
+                rep.setProtocolMappers(convertedProtocolMappers);
+            }
+        }
+
         if (rep.getName() != null) model.setClientId(rep.getName());
         if (rep.isEnabled() != null) model.setEnabled(rep.isEnabled());
         if (rep.isPublicClient() != null) model.setPublicClient(rep.isPublicClient());
         if (rep.isFrontchannelLogout() != null) model.setFrontchannelLogout(rep.isFrontchannelLogout());
         if (rep.isFullScopeAllowed() != null) model.setFullScopeAllowed(rep.isFullScopeAllowed());
         if (rep.isDirectGrantsOnly() != null) model.setDirectGrantsOnly(rep.isDirectGrantsOnly());
-        if (rep.getClaims() != null) {
-            setClaims(model, rep.getClaims());
-        }
         if (rep.getNotBefore() != null) {
             model.setNotBefore(rep.getNotBefore());
         }
diff --git a/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi b/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
index e071894..64dd861 100755
--- a/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
+++ b/model/api/src/main/resources/META-INF/services/org.keycloak.provider.Spi
@@ -1,4 +1,5 @@
 org.keycloak.models.UserFederationSpi
 org.keycloak.models.RealmSpi
 org.keycloak.models.UserSessionSpi
-org.keycloak.models.UserSpi
\ No newline at end of file
+org.keycloak.models.UserSpi
+org.keycloak.migration.MigrationSpi
\ No newline at end of file
diff --git a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
index c7ef8ad..6c47bdf 100755
--- a/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
+++ b/model/file/src/main/java/org/keycloak/models/file/adapter/ClientAdapter.java
@@ -70,16 +70,6 @@ public abstract class ClientAdapter implements ClientModel {
     }
 
     @Override
-    public long getAllowedClaimsMask() {
-        return clientEntity.getAllowedClaimsMask();
-    }
-
-    @Override
-    public void setAllowedClaimsMask(long mask) {
-        clientEntity.setAllowedClaimsMask(mask);
-    }
-
-    @Override
     public Set<String> getWebOrigins() {
         Set<String> result = new HashSet<String>();
         if (clientEntity.getWebOrigins() != null) {
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
index 202be7b..12e89e1 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/ClientAdapter.java
@@ -44,16 +44,6 @@ public abstract class ClientAdapter implements ClientModel {
     @Override
     public abstract String getClientId();
 
-    public long getAllowedClaimsMask() {
-        if (updatedClient != null) return updatedClient.getAllowedClaimsMask();
-        return cachedClient.getAllowedClaimsMask();
-    }
-
-    public void setAllowedClaimsMask(long mask) {
-        getDelegateForUpdate();
-        updatedClient.setAllowedClaimsMask(mask);
-    }
-
     public Set<String> getWebOrigins() {
         if (updatedClient != null) return updatedClient.getWebOrigins();
         return cachedClient.getWebOrigins();
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
index 859e593..f1f5ef1 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/entities/CachedClient.java
@@ -23,7 +23,6 @@ public class CachedClient {
     protected String id;
     protected String name;
     protected String realm;
-    protected long allowedClaimsMask;
     protected Set<String> redirectUris = new HashSet<String>();
     protected boolean enabled;
     protected String secret;
@@ -51,7 +50,6 @@ public class CachedClient {
         directGrantsOnly = model.isDirectGrantsOnly();
         frontchannelLogout = model.isFrontchannelLogout();
         publicClient = model.isPublicClient();
-        allowedClaimsMask = model.getAllowedClaimsMask();
         fullScopeAllowed = model.isFullScopeAllowed();
         redirectUris.addAll(model.getRedirectUris());
         webOrigins.addAll(model.getWebOrigins());
@@ -76,10 +74,6 @@ public class CachedClient {
         return realm;
     }
 
-    public long getAllowedClaimsMask() {
-        return allowedClaimsMask;
-    }
-
     public Set<String> getRedirectUris() {
         return redirectUris;
     }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
index bf0fefc..bd44308 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/ClientAdapter.java
@@ -73,16 +73,6 @@ public abstract class ClientAdapter implements ClientModel {
     }
 
     @Override
-    public long getAllowedClaimsMask() {
-        return entity.getAllowedClaimsMask();
-    }
-
-    @Override
-    public void setAllowedClaimsMask(long mask) {
-        entity.setAllowedClaimsMask(mask);
-    }
-
-    @Override
     public boolean isPublicClient() {
         return entity.isPublicClient();
     }
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
index f61f7bf..e3c8bfd 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/ClientEntity.java
@@ -40,8 +40,6 @@ public abstract class ClientEntity {
     private boolean enabled;
     @Column(name="SECRET")
     private String secret;
-    @Column(name="ALLOWED_CLAIMS_MASK")
-    private long allowedClaimsMask;
     @Column(name="NOT_BEFORE")
     private int notBefore;
     @Column(name="PUBLIC_CLIENT")
@@ -111,14 +109,6 @@ public abstract class ClientEntity {
         this.name = name;
     }
 
-    public long getAllowedClaimsMask() {
-        return allowedClaimsMask;
-    }
-
-    public void setAllowedClaimsMask(long allowedClaimsMask) {
-        this.allowedClaimsMask = allowedClaimsMask;
-    }
-
     public Set<String> getWebOrigins() {
         return webOrigins;
     }
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
index ea97d65..38c40f8 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/ClientAdapter.java
@@ -60,17 +60,6 @@ public abstract class ClientAdapter<T extends MongoIdentifiableEntity> extends A
     }
 
     @Override
-    public long getAllowedClaimsMask() {
-        return getMongoEntityAsClient().getAllowedClaimsMask();
-    }
-
-    @Override
-    public void setAllowedClaimsMask(long mask) {
-        getMongoEntityAsClient().setAllowedClaimsMask(mask);
-        updateMongoEntity();
-    }
-
-    @Override
     public Set<String> getWebOrigins() {
         Set<String> result = new HashSet<String>();
         if (getMongoEntityAsClient().getWebOrigins() != null) {
diff --git a/services/src/main/java/org/keycloak/services/migration/DefaultMigrationProviderFactory.java b/services/src/main/java/org/keycloak/services/migration/DefaultMigrationProviderFactory.java
new file mode 100644
index 0000000..cdc9f93
--- /dev/null
+++ b/services/src/main/java/org/keycloak/services/migration/DefaultMigrationProviderFactory.java
@@ -0,0 +1,38 @@
+package org.keycloak.services.migration;
+
+import org.keycloak.Config;
+import org.keycloak.migration.MigrationProvider;
+import org.keycloak.migration.MigrationProviderFactory;
+import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.KeycloakSessionFactory;
+
+/**
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class DefaultMigrationProviderFactory implements MigrationProviderFactory {
+
+    @Override
+    public MigrationProvider create(KeycloakSession session) {
+        return new DefaultMigrationProvider(session);
+    }
+
+    @Override
+    public void init(Config.Scope config) {
+
+    }
+
+    @Override
+    public void postInit(KeycloakSessionFactory factory) {
+
+    }
+
+    @Override
+    public void close() {
+
+    }
+
+    @Override
+    public String getId() {
+        return "default";
+    }
+}
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
index cc996cd..7df7b1e 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationResource.java
@@ -78,16 +78,6 @@ public class ApplicationResource {
         auth.init(RealmAuth.Resource.APPLICATION);
     }
 
-    /**
-     * base path for managing allowed application claims
-     *
-     * @return
-     */
-    @Path("claims")
-    public ClaimResource getClaimResource() {
-        return new ClaimResource(application, auth);
-    }
-
     @Path("protocol-mappers")
     public ProtocolMappersResource getProtocolMappers() {
         ProtocolMappersResource mappers = new ProtocolMappersResource(application, auth);
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
index e47e002..c74a8f0 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/ApplicationsResource.java
@@ -87,7 +87,7 @@ public class ApplicationsResource {
         auth.requireManage();
 
         try {
-            ApplicationModel applicationModel = RepresentationToModel.createApplication(realm, rep, true);
+            ApplicationModel applicationModel = RepresentationToModel.createApplication(session, realm, rep, true);
             return Response.created(uriInfo.getAbsolutePathBuilder().path(getApplicationPath(applicationModel)).build()).build();
         } catch (ModelDuplicateException e) {
             return Flows.errors().exists("Application " + rep.getName() + " already exists");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
index 10b20b8..b69fb83 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientResource.java
@@ -65,16 +65,6 @@ public class OAuthClientResource  {
     }
 
     /**
-     * Base path for managing allowed oauth client claims
-     *
-     * @return
-     */
-    @Path("claims")
-    public ClaimResource getClaimResource() {
-        return new ClaimResource(oauthClient, auth);
-    }
-
-    /**
      * interface for updating attached ProtocolMappers
      *
      * @return
@@ -111,7 +101,7 @@ public class OAuthClientResource  {
         auth.requireManage();
 
         try {
-            RepresentationToModel.updateOAuthClient(rep, oauthClient);
+            RepresentationToModel.updateOAuthClient(session, rep, oauthClient);
             return Response.noContent().build();
         } catch (ModelDuplicateException e) {
             return Flows.errors().exists("Client " + rep.getName() + " already exists");
diff --git a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
index 3d57d42..a2c387c 100755
--- a/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/admin/OAuthClientsResource.java
@@ -89,7 +89,7 @@ public class OAuthClientsResource {
         auth.requireManage();
 
         try {
-            OAuthClientModel oauth = RepresentationToModel.createOAuthClient(rep, realm);
+            OAuthClientModel oauth = RepresentationToModel.createOAuthClient(session, rep, realm);
             return Response.created(uriInfo.getAbsolutePathBuilder().path(getClientPath(oauth)).build()).build();
         } catch (ModelDuplicateException e) {
             return Flows.errors().exists("Client " + rep.getName() + " already exists");
diff --git a/services/src/main/resources/META-INF/services/org.keycloak.migration.MigrationProviderFactory b/services/src/main/resources/META-INF/services/org.keycloak.migration.MigrationProviderFactory
new file mode 100644
index 0000000..d928feb
--- /dev/null
+++ b/services/src/main/resources/META-INF/services/org.keycloak.migration.MigrationProviderFactory
@@ -0,0 +1 @@
+org.keycloak.services.migration.DefaultMigrationProviderFactory
\ No newline at end of file
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java
index 3c07797..e1902f9 100644
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/ApplicationTest.java
@@ -3,9 +3,12 @@ package org.keycloak.testsuite.admin;
 import org.junit.Rule;
 import org.junit.Test;
 import org.keycloak.admin.client.resource.ApplicationResource;
+import org.keycloak.admin.client.resource.ProtocolMappersResource;
 import org.keycloak.models.ApplicationModel;
 import org.keycloak.models.RealmModel;
+import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
 import org.keycloak.representations.idm.ApplicationRepresentation;
+import org.keycloak.representations.idm.ProtocolMapperRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
 import org.keycloak.representations.idm.UserSessionRepresentation;
@@ -17,6 +20,8 @@ import org.keycloak.testsuite.rule.WebRule;
 import org.openqa.selenium.WebDriver;
 
 import javax.ws.rs.NotFoundException;
+import javax.ws.rs.core.Response;
+
 import java.util.LinkedList;
 import java.util.List;
 
@@ -113,4 +118,63 @@ public class ApplicationTest extends AbstractClientTest {
         assertNull(realm.applications().get("my-app").toRepresentation().getDefaultRoles());
     }
 
+    @Test
+    public void testProtocolMappers() {
+        createApplication();
+        ProtocolMappersResource mappersResource = realm.applications().get("my-app").getProtocolMappers();
+
+        protocolMappersTest(mappersResource);
+    }
+
+
+    public static void protocolMappersTest(ProtocolMappersResource mappersResource) {
+        // assert default mappers found
+        List<ProtocolMapperRepresentation> protocolMappers = mappersResource.getMappers();
+
+        String emailMapperId = null;
+        String usernameMapperId = null;
+        String fooMapperId = null;
+        for (ProtocolMapperRepresentation mapper : protocolMappers) {
+            if (mapper.getName().equals(OIDCLoginProtocolFactory.EMAIL)) {
+                emailMapperId = mapper.getId();
+            } else if (mapper.getName().equals(OIDCLoginProtocolFactory.USERNAME)) {
+                usernameMapperId = mapper.getId();
+            } else if (mapper.getName().equals("foo")) {
+                fooMapperId = mapper.getId();
+            }
+        }
+
+        assertNotNull(emailMapperId);
+        assertNotNull(usernameMapperId);
+        assertNull(fooMapperId);
+
+        // Create foo mapper
+        ProtocolMapperRepresentation fooMapper = new ProtocolMapperRepresentation();
+        fooMapper.setName("foo");
+        fooMapper.setProtocol("fooProtocol");
+        fooMapper.setProtocolMapper("fooMapper");
+        fooMapper.setConsentRequired(true);
+        Response response = mappersResource.createMapper(fooMapper);
+        String location = response.getLocation().toString();
+        fooMapperId = location.substring(location.lastIndexOf("/") + 1);
+        response.close();
+
+        fooMapper = mappersResource.getMapperById(fooMapperId);
+        assertEquals(fooMapper.getName(), "foo");
+
+        // Update foo mapper
+        fooMapper.setProtocolMapper("foo-mapper-updated");
+        mappersResource.update(fooMapperId, fooMapper);
+
+        fooMapper = mappersResource.getMapperById(fooMapperId);
+        assertEquals(fooMapper.getProtocolMapper(), "foo-mapper-updated");
+
+        // Remove foo mapper
+        mappersResource.delete(fooMapperId);
+        try {
+            mappersResource.getMapperById(fooMapperId);
+            fail("Not expected to find deleted mapper");
+        } catch (NotFoundException nfe) {
+        }
+    }
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/OAuthClientTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/OAuthClientTest.java
index 44cf762..f064136 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/OAuthClientTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/OAuthClientTest.java
@@ -1,6 +1,7 @@
 package org.keycloak.testsuite.admin;
 
 import org.junit.Test;
+import org.keycloak.admin.client.resource.ProtocolMappersResource;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
 
 import static org.junit.Assert.assertEquals;
@@ -34,6 +35,14 @@ public class OAuthClientTest extends AbstractClientTest {
     }
 
     @Test
+    public void testProtocolMappers() {
+        createOAuthClient();
+        ProtocolMappersResource mappersResource = realm.oAuthClients().get("my-client").getProtocolMappers();
+
+        ApplicationTest.protocolMappersTest(mappersResource);
+    }
+
+    @Test
     public void getOAuthClientRepresentation() {
         createOAuthClient();
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ApplicationModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ApplicationModelTest.java
index bb8c651..e55a325 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ApplicationModelTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/ApplicationModelTest.java
@@ -65,7 +65,7 @@ public class ApplicationModelTest extends AbstractModelTest {
         representation.setId(null);
 
         RealmModel realm = realmManager.createRealm("copy");
-        ApplicationModel copy = RepresentationToModel.createApplication(realm, representation, true);
+        ApplicationModel copy = RepresentationToModel.createApplication(session, realm, representation, true);
 
         assertEquals(application, copy);
     }
diff --git a/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json b/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
index 7174420..b419196 100755
--- a/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
+++ b/testsuite/integration/src/test/resources/broker-test/test-realm-with-broker.json
@@ -165,18 +165,6 @@
                 "userInfoUrl": "http://localhost:8082/auth/realms/realm-with-oidc-identity-provider/protocol/openid-connect/userinfo",
                 "defaultScope": "email profile"
             }
-        },
-        {
-            "alias" : "model-kerberos",
-            "providerId" : "kerberos",
-            "enabled": true,
-            "updateProfileFirstLogin" : "true",
-            "authenticateByDefault" : "false",
-            "config": {
-                "serverPrincipal": "HTTP/server.domain.org@DOMAIN.ORG",
-                "keyTab": "/etc/http.keytab",
-                "debug": "true"
-            }
         }
     ],
     "users": [
@@ -242,4 +230,4 @@
             }
         ]
     }
-}
+}