keycloak-aplcache

[KEYCLOAK-883] - Model tests.

1/27/2015 11:53:56 PM

Changes

testsuite/integration/src/test/resources/META-INF/services/org.keycloak.social.SocialProvider 1(+0 -1)

Details

diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java
index a34438e..652a109 100644
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/AbstractOAuth2IdentityProvider.java
@@ -105,6 +105,11 @@ public abstract class AbstractOAuth2IdentityProvider<C extends OAuth2IdentityPro
         }
     }
 
+    @Override
+    public C getConfig() {
+        return super.getConfig();
+    }
+
     protected AuthenticationResponse doHandleResponse(String response) throws IOException {
         String token = extractTokenFromResponse(response, OAUTH2_PARAMETER_ACCESS_TOKEN);
 
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OAuth2IdentityProviderConfig.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OAuth2IdentityProviderConfig.java
index 52be1cd..45aae22 100644
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OAuth2IdentityProviderConfig.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OAuth2IdentityProviderConfig.java
@@ -19,15 +19,13 @@ package org.keycloak.broker.oidc;
 
 import org.keycloak.models.IdentityProviderModel;
 
-import java.util.Map;
-
 /**
  * @author Pedro Igor
  */
 public class OAuth2IdentityProviderConfig extends IdentityProviderModel {
 
-    public OAuth2IdentityProviderConfig(String providerId, String id, String name, Map<String, String> config) {
-        super(providerId, id, name, config);
+    public OAuth2IdentityProviderConfig(IdentityProviderModel model) {
+        super(model);
     }
 
     public String getAuthorizationUrl() {
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderConfig.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderConfig.java
index 302221a..ba2dceb 100644
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderConfig.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderConfig.java
@@ -17,15 +17,15 @@
  */
 package org.keycloak.broker.oidc;
 
-import java.util.Map;
+import org.keycloak.models.IdentityProviderModel;
 
 /**
  * @author Pedro Igor
  */
 public class OIDCIdentityProviderConfig extends OAuth2IdentityProviderConfig {
 
-    public OIDCIdentityProviderConfig(String providerId, String id, String name, Map<String, String> config) {
-        super(providerId, id, name, config);
+    public OIDCIdentityProviderConfig(IdentityProviderModel identityProviderModel) {
+        super(identityProviderModel);
     }
 
     public String getPrompt() {
diff --git a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderFactory.java b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderFactory.java
index 10316d9..65bfedd 100644
--- a/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderFactory.java
+++ b/broker/oidc/src/main/java/org/keycloak/broker/oidc/OIDCIdentityProviderFactory.java
@@ -25,6 +25,8 @@ import org.keycloak.models.IdentityProviderModel;
  */
 public class OIDCIdentityProviderFactory extends AbstractIdentityProviderFactory<OIDCIdentityProvider> {
 
+    public static final String PROVIDER_ID = "oidc";
+
     @Override
     public String getName() {
         return "OpenID Connect v1.0";
@@ -32,11 +34,11 @@ public class OIDCIdentityProviderFactory extends AbstractIdentityProviderFactory
 
     @Override
     public OIDCIdentityProvider create(IdentityProviderModel model) {
-        return new OIDCIdentityProvider(new OIDCIdentityProviderConfig(getId(), model.getId(), model.getName(), model.getConfig()));
+        return new OIDCIdentityProvider(new OIDCIdentityProviderConfig(model));
     }
 
     @Override
     public String getId() {
-        return "oidc";
+        return PROVIDER_ID;
     }
 }
diff --git a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java
index 6ce34fc..c389b1d 100644
--- a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java
+++ b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProvider.java
@@ -69,7 +69,6 @@ import java.util.List;
  */
 public class SAMLIdentityProvider extends AbstractIdentityProvider<SAMLIdentityProviderConfig> {
 
-    private static final String SAML_REQUEST_PARAMETER = "SAMLRequest";
     private static final String SAML_RESPONSE_PARAMETER = "SAMLResponse";
     private static final String RELAY_STATE_PARAMETER = "RelayState";
 
diff --git a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderConfig.java b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderConfig.java
index e6efe16..e4be0eb 100644
--- a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderConfig.java
+++ b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderConfig.java
@@ -19,19 +19,16 @@ package org.keycloak.broker.saml;
 
 import org.keycloak.models.IdentityProviderModel;
 
-import java.util.Map;
-
 /**
  * @author Pedro Igor
  */
 public class SAMLIdentityProviderConfig extends IdentityProviderModel {
 
     public SAMLIdentityProviderConfig() {
-        super();
     }
 
-    public SAMLIdentityProviderConfig(String providerId, String id, String name, Map<String, String> config) {
-        super(providerId, id, name, config);
+    public SAMLIdentityProviderConfig(IdentityProviderModel identityProviderModel) {
+        super(identityProviderModel);
     }
 
     public String getSingleSignOnServiceUrl() {
diff --git a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java
index ce5faba..9b1e551 100644
--- a/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java
+++ b/broker/saml/src/main/java/org/keycloak/broker/saml/SAMLIdentityProviderFactory.java
@@ -40,6 +40,8 @@ import java.util.Map;
  */
 public class SAMLIdentityProviderFactory extends AbstractIdentityProviderFactory<SAMLIdentityProvider> {
 
+    public static final String PROVIDER_ID = "saml";
+
     @Override
     public String getName() {
         return "SAML v2.0";
@@ -47,7 +49,7 @@ public class SAMLIdentityProviderFactory extends AbstractIdentityProviderFactory
 
     @Override
     public SAMLIdentityProvider create(IdentityProviderModel model) {
-        return new SAMLIdentityProvider(new SAMLIdentityProviderConfig(getId(), model.getId(), model.getName(), model.getConfig()));
+        return new SAMLIdentityProvider(new SAMLIdentityProviderConfig(model));
     }
 
     @Override
@@ -121,6 +123,6 @@ public class SAMLIdentityProviderFactory extends AbstractIdentityProviderFactory
 
     @Override
     public String getId() {
-        return "saml";
+        return PROVIDER_ID;
     }
 }
diff --git a/model/api/src/main/java/org/keycloak/models/IdentityProviderModel.java b/model/api/src/main/java/org/keycloak/models/IdentityProviderModel.java
index 457ba35..12501bb 100644
--- a/model/api/src/main/java/org/keycloak/models/IdentityProviderModel.java
+++ b/model/api/src/main/java/org/keycloak/models/IdentityProviderModel.java
@@ -55,17 +55,15 @@ public class IdentityProviderModel {
     private Map<String, String> config = new HashMap<String, String>();
 
     public IdentityProviderModel() {
-        this(null, null, null, null);
     }
 
-    public IdentityProviderModel(String providerId, String id, String name, Map<String, String> config) {
-        this.providerId = providerId;
-        this.id = id;
-        this.name = name;
-
-        if (config != null) {
-            this.config.putAll(config);
-        }
+    public IdentityProviderModel(IdentityProviderModel model) {
+        this.providerId = model.getProviderId();
+        this.id = model.getId();
+        this.name = model.getName();
+        this.config = new HashMap<String, String>(model.getConfig());
+        this.enabled = model.isEnabled();
+        this.updateProfileFirstLogin = model.isUpdateProfileFirstLogin();
     }
 
     public String getId() {
diff --git a/model/api/src/main/java/org/keycloak/models/RealmModel.java b/model/api/src/main/java/org/keycloak/models/RealmModel.java
index 454179e..4ce7d61 100755
--- a/model/api/src/main/java/org/keycloak/models/RealmModel.java
+++ b/model/api/src/main/java/org/keycloak/models/RealmModel.java
@@ -164,6 +164,7 @@ public interface RealmModel extends RoleContainerModel {
     void setSmtpConfig(Map<String, String> smtpConfig);
 
     List<IdentityProviderModel> getIdentityProviders();
+    IdentityProviderModel getIdentityProviderById(String identityProviderId);
     void addIdentityProvider(IdentityProviderModel identityProvider);
     void removeIdentityProviderById(String providerId);
     void updateIdentityProvider(IdentityProviderModel identityProvider);
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 2ab0afe..50907bc 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
@@ -8,6 +8,7 @@ import org.keycloak.models.BrowserSecurityHeaders;
 import org.keycloak.models.ClaimMask;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.FederatedIdentityModel;
+import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.OAuthClientModel;
 import org.keycloak.models.PasswordPolicy;
@@ -21,6 +22,7 @@ import org.keycloak.representations.idm.ApplicationRepresentation;
 import org.keycloak.representations.idm.ClaimRepresentation;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.representations.idm.FederatedIdentityRepresentation;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.representations.idm.OAuthClientRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.representations.idm.RoleRepresentation;
@@ -229,6 +231,21 @@ public class RepresentationToModel {
                 UserModel user = createUser(session, newRealm, userRep, appMap);
             }
         }
+
+        if (rep.getIdentityProviders() != null) {
+            for (IdentityProviderRepresentation identityProviderRepresentation : rep.getIdentityProviders()) {
+                IdentityProviderModel identityProviderModel = new IdentityProviderModel();
+
+                identityProviderModel.setId(identityProviderRepresentation.getId());
+                identityProviderModel.setProviderId(identityProviderRepresentation.getProviderId());
+                identityProviderModel.setName(identityProviderRepresentation.getName());
+                identityProviderModel.setEnabled(identityProviderRepresentation.isEnabled());
+                identityProviderModel.setUpdateProfileFirstLogin(identityProviderRepresentation.isUpdateProfileFirstLogin());
+                identityProviderModel.setConfig(identityProviderRepresentation.getConfig());
+
+                newRealm.addIdentityProvider(identityProviderModel);
+            }
+        }
     }
 
     public static void updateRealm(RealmRepresentation rep, RealmModel realm) {
@@ -727,5 +744,4 @@ public class RepresentationToModel {
 
         }
     }
-
 }
diff --git a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
index 98e120c..dc4ede4 100755
--- a/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
+++ b/model/invalidation-cache/model-adapters/src/main/java/org/keycloak/models/cache/RealmAdapter.java
@@ -616,6 +616,17 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
+    public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
+        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
+            if (identityProviderModel.getId().equals(identityProviderId)) {
+                return identityProviderModel;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
     public void addIdentityProvider(IdentityProviderModel identityProvider) {
         getDelegateForUpdate();
         updated.addIdentityProvider(identityProvider);
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
index b8d864c..af73db6 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/RealmAdapter.java
@@ -1111,9 +1111,12 @@ public class RealmAdapter implements RealmModel {
         List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
 
         for (IdentityProviderEntity entity: realm.getIdentityProviders()) {
-            IdentityProviderModel identityProviderModel = new IdentityProviderModel(entity.getProviderId(), entity.getId(), entity.getName(),
-                    entity.getConfig());
+            IdentityProviderModel identityProviderModel = new IdentityProviderModel();
 
+            identityProviderModel.setProviderId(entity.getProviderId());
+            identityProviderModel.setId(entity.getId());
+            identityProviderModel.setName(entity.getName());
+            identityProviderModel.setConfig(entity.getConfig());
             identityProviderModel.setEnabled(entity.isEnabled());
             identityProviderModel.setUpdateProfileFirstLogin(entity.isUpdateProfileFirstLogin());
 
@@ -1124,6 +1127,17 @@ public class RealmAdapter implements RealmModel {
     }
 
     @Override
+    public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
+        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
+            if (identityProviderModel.getId().equals(identityProviderId)) {
+                return identityProviderModel;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
     public void addIdentityProvider(IdentityProviderModel identityProvider) {
         IdentityProviderEntity entity = new IdentityProviderEntity();
 
diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
index 8c32349..3bb7113 100755
--- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
+++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/RealmAdapter.java
@@ -787,9 +787,12 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
         List<IdentityProviderModel> identityProviders = new ArrayList<IdentityProviderModel>();
 
         for (IdentityProviderEntity entity: realm.getIdentityProviders()) {
-            IdentityProviderModel identityProviderModel = new IdentityProviderModel(entity.getProviderId(), entity.getId(), entity.getName(),
-                    entity.getConfig());
+            IdentityProviderModel identityProviderModel = new IdentityProviderModel();
 
+            identityProviderModel.setProviderId(entity.getProviderId());
+            identityProviderModel.setId(entity.getId());
+            identityProviderModel.setName(entity.getName());
+            identityProviderModel.setConfig(entity.getConfig());
             identityProviderModel.setEnabled(entity.isEnabled());
             identityProviderModel.setUpdateProfileFirstLogin(entity.isUpdateProfileFirstLogin());
 
@@ -800,6 +803,17 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
     }
 
     @Override
+    public IdentityProviderModel getIdentityProviderById(String identityProviderId) {
+        for (IdentityProviderModel identityProviderModel : getIdentityProviders()) {
+            if (identityProviderModel.getId().equals(identityProviderId)) {
+                return identityProviderModel;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
     public void addIdentityProvider(IdentityProviderModel identityProvider) {
         IdentityProviderEntity entity = new IdentityProviderEntity();
 
diff --git a/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java b/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java
index 19ff363..0f14b30 100644
--- a/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java
+++ b/services/src/main/java/org/keycloak/services/resources/AuthenticationBrokerResource.java
@@ -314,16 +314,16 @@ public class AuthenticationBrokerResource {
     }
 
     private IdentityProvider getIdentityProvider(RealmModel realm, String providerId) {
-        for (IdentityProviderModel model : realm.getIdentityProviders()) {
-            if (model.getId().equals(providerId)) {
-                IdentityProviderFactory providerFactory = getIdentityProviderFactory(model);
+        IdentityProviderModel identityProviderModel = realm.getIdentityProviderById(providerId);
 
-                if (providerFactory == null) {
-                    throw new RuntimeException("Could not find provider factory for identity provider [" + providerId + "].");
-                }
+        if (identityProviderModel != null) {
+            IdentityProviderFactory providerFactory = getIdentityProviderFactory(identityProviderModel);
 
-                return providerFactory.create(model);
+            if (providerFactory == null) {
+                throw new RuntimeException("Could not find provider factory for identity provider [" + providerId + "].");
             }
+
+            return providerFactory.create(identityProviderModel);
         }
 
         return null;
diff --git a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java
index 518b1e1..774f306 100755
--- a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java
+++ b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProvider.java
@@ -12,11 +12,10 @@ import org.keycloak.social.SocialIdentityProvider;
  */
 public class FacebookIdentityProvider extends AbstractOAuth2IdentityProvider implements SocialIdentityProvider {
 
-    private static final String ID = "facebook";
-    private static final String AUTH_URL = "https://graph.facebook.com/oauth/authorize";
-    private static final String TOKEN_URL = "https://graph.facebook.com/oauth/access_token";
-    private static final String PROFILE_URL = "https://graph.facebook.com/me";
-    private static final String DEFAULT_SCOPE = "email";
+    public static final String AUTH_URL = "https://graph.facebook.com/oauth/authorize";
+    public static final String TOKEN_URL = "https://graph.facebook.com/oauth/access_token";
+    public static final String PROFILE_URL = "https://graph.facebook.com/me";
+    public static final String DEFAULT_SCOPE = "email";
 
     public FacebookIdentityProvider(OAuth2IdentityProviderConfig config) {
         super(config);
diff --git a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProviderFactory.java b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProviderFactory.java
index c5bdad3..57f484e 100644
--- a/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProviderFactory.java
+++ b/social/facebook/src/main/java/org/keycloak/social/facebook/FacebookIdentityProviderFactory.java
@@ -27,6 +27,8 @@ import org.keycloak.social.SocialIdentityProviderFactory;
  */
 public class FacebookIdentityProviderFactory extends AbstractIdentityProviderFactory<FacebookIdentityProvider> implements SocialIdentityProviderFactory<FacebookIdentityProvider> {
 
+    public static final String PROVIDER_ID = "facebook";
+
     @Override
     public String getName() {
         return "Facebook";
@@ -34,11 +36,11 @@ public class FacebookIdentityProviderFactory extends AbstractIdentityProviderFac
 
     @Override
     public FacebookIdentityProvider create(IdentityProviderModel model) {
-        return new FacebookIdentityProvider(new OAuth2IdentityProviderConfig(getId(), model.getId(), model.getName(), model.getConfig()));
+        return new FacebookIdentityProvider(new OAuth2IdentityProviderConfig(model));
     }
 
     @Override
     public String getId() {
-        return "facebook";
+        return PROVIDER_ID;
     }
 }
diff --git a/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java b/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java
index b48b825..b24d3ea 100755
--- a/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java
+++ b/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProvider.java
@@ -12,11 +12,10 @@ import org.keycloak.social.SocialIdentityProvider;
  */
 public class GitHubIdentityProvider extends AbstractOAuth2IdentityProvider implements SocialIdentityProvider {
 
-    private static final String ID = "github";
-    private static final String AUTH_URL = "https://github.com/login/oauth/authorize";
-    private static final String TOKEN_URL = "https://github.com/login/oauth/access_token";
-    private static final String PROFILE_URL = "https://api.github.com/user";
-    private static final String DEFAULT_SCOPE = "user:email";
+    public static final String AUTH_URL = "https://github.com/login/oauth/authorize";
+    public static final String TOKEN_URL = "https://github.com/login/oauth/access_token";
+    public static final String PROFILE_URL = "https://api.github.com/user";
+    public static final String DEFAULT_SCOPE = "user:email";
 
     public GitHubIdentityProvider(OAuth2IdentityProviderConfig config) {
         super(config);
diff --git a/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProviderFactory.java b/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProviderFactory.java
index 43cea68..ed06598 100644
--- a/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProviderFactory.java
+++ b/social/github/src/main/java/org/keycloak/social/github/GitHubIdentityProviderFactory.java
@@ -27,6 +27,8 @@ import org.keycloak.social.SocialIdentityProviderFactory;
  */
 public class GitHubIdentityProviderFactory extends AbstractIdentityProviderFactory<GitHubIdentityProvider> implements SocialIdentityProviderFactory<GitHubIdentityProvider> {
 
+    public static final String PROVIDER_ID = "github";
+
     @Override
     public String getName() {
         return "GitHub";
@@ -34,11 +36,11 @@ public class GitHubIdentityProviderFactory extends AbstractIdentityProviderFacto
 
     @Override
     public GitHubIdentityProvider create(IdentityProviderModel model) {
-        return new GitHubIdentityProvider(new OAuth2IdentityProviderConfig(getId(), model.getId(), model.getName(), model.getConfig()));
+        return new GitHubIdentityProvider(new OAuth2IdentityProviderConfig(model));
     }
 
     @Override
     public String getId() {
-        return "github";
+        return PROVIDER_ID;
     }
 }
diff --git a/social/google/src/main/java/org/keycloak/social/google/GoogleIdentityProvider.java b/social/google/src/main/java/org/keycloak/social/google/GoogleIdentityProvider.java
index f6f28b5..65a6b12 100755
--- a/social/google/src/main/java/org/keycloak/social/google/GoogleIdentityProvider.java
+++ b/social/google/src/main/java/org/keycloak/social/google/GoogleIdentityProvider.java
@@ -30,11 +30,10 @@ import org.keycloak.social.SocialIdentityProvider;
  */
 public class GoogleIdentityProvider extends OIDCIdentityProvider implements SocialIdentityProvider<OIDCIdentityProviderConfig> {
 
-    private static final String ID = "google";
-    private static final String AUTH_URL = "https://accounts.google.com/o/oauth2/auth";
-    private static final String TOKEN_URL = "https://accounts.google.com/o/oauth2/token";
-    private static final String PROFILE_URL = "https://www.googleapis.com/plus/v1/people/me/openIdConnect";
-    private static final String DEFAULT_SCOPE = "openid profile email";
+    public static final String AUTH_URL = "https://accounts.google.com/o/oauth2/auth";
+    public static final String TOKEN_URL = "https://accounts.google.com/o/oauth2/token";
+    public static final String PROFILE_URL = "https://www.googleapis.com/plus/v1/people/me/openIdConnect";
+    public static final String DEFAULT_SCOPE = "openid profile email";
 
     public GoogleIdentityProvider(OIDCIdentityProviderConfig config) {
         super(config);
diff --git a/social/google/src/main/java/org/keycloak/social/google/GoogleIdentityProviderFactory.java b/social/google/src/main/java/org/keycloak/social/google/GoogleIdentityProviderFactory.java
index df5d45e..5171c4f 100644
--- a/social/google/src/main/java/org/keycloak/social/google/GoogleIdentityProviderFactory.java
+++ b/social/google/src/main/java/org/keycloak/social/google/GoogleIdentityProviderFactory.java
@@ -27,6 +27,8 @@ import org.keycloak.social.SocialIdentityProviderFactory;
  */
 public class GoogleIdentityProviderFactory extends AbstractIdentityProviderFactory<GoogleIdentityProvider> implements SocialIdentityProviderFactory<GoogleIdentityProvider> {
 
+    public static final String PROVIDER_ID = "google";
+
     @Override
     public String getName() {
         return "Google";
@@ -34,11 +36,11 @@ public class GoogleIdentityProviderFactory extends AbstractIdentityProviderFacto
 
     @Override
     public GoogleIdentityProvider create(IdentityProviderModel model) {
-        return new GoogleIdentityProvider(new OIDCIdentityProviderConfig(getId(), model.getId(), model.getName(), model.getConfig()));
+        return new GoogleIdentityProvider(new OIDCIdentityProviderConfig(model));
     }
 
     @Override
     public String getId() {
-        return "google";
+        return PROVIDER_ID;
     }
 }
diff --git a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterIdentityProviderFactory.java b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterIdentityProviderFactory.java
index 382ecf9..21730c5 100644
--- a/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterIdentityProviderFactory.java
+++ b/social/twitter/src/main/java/org/keycloak/social/twitter/TwitterIdentityProviderFactory.java
@@ -27,6 +27,8 @@ import org.keycloak.social.SocialIdentityProviderFactory;
  */
 public class TwitterIdentityProviderFactory extends AbstractIdentityProviderFactory<TwitterIdentityProvider> implements SocialIdentityProviderFactory<TwitterIdentityProvider> {
 
+    public static final String PROVIDER_ID = "twitter";
+
     @Override
     public String getName() {
         return "Twitter";
@@ -34,11 +36,11 @@ public class TwitterIdentityProviderFactory extends AbstractIdentityProviderFact
 
     @Override
     public TwitterIdentityProvider create(IdentityProviderModel model) {
-        return new TwitterIdentityProvider(new OAuth2IdentityProviderConfig(getId(), model.getId(), model.getName(), model.getConfig()));
+        return new TwitterIdentityProvider(new OAuth2IdentityProviderConfig(model));
     }
 
     @Override
     public String getId() {
-        return "twitter";
+        return PROVIDER_ID;
     }
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderModelTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderModelTest.java
new file mode 100644
index 0000000..2dd3164
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderModelTest.java
@@ -0,0 +1,57 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.broker;
+
+import org.junit.Before;
+import org.keycloak.broker.oidc.OIDCIdentityProviderFactory;
+import org.keycloak.broker.saml.SAMLIdentityProviderFactory;
+import org.keycloak.social.facebook.FacebookIdentityProviderFactory;
+import org.keycloak.social.github.GitHubIdentityProviderFactory;
+import org.keycloak.social.google.GoogleIdentityProviderFactory;
+import org.keycloak.social.twitter.TwitterIdentityProviderFactory;
+import org.keycloak.testsuite.model.AbstractModelTest;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author pedroigor
+ */
+public abstract class AbstractIdentityProviderModelTest extends AbstractModelTest {
+
+    private Set<String> expectedProviders;
+
+    @Before
+    public void onBefore() {
+        this.expectedProviders = new HashSet<String>();
+
+        this.expectedProviders.add(SAMLIdentityProviderFactory.PROVIDER_ID);
+        this.expectedProviders.add(OIDCIdentityProviderFactory.PROVIDER_ID);
+        this.expectedProviders.add(GoogleIdentityProviderFactory.PROVIDER_ID);
+        this.expectedProviders.add(FacebookIdentityProviderFactory.PROVIDER_ID);
+        this.expectedProviders.add(GitHubIdentityProviderFactory.PROVIDER_ID);
+        this.expectedProviders.add(TwitterIdentityProviderFactory.PROVIDER_ID);
+
+        this.expectedProviders = Collections.unmodifiableSet(this.expectedProviders);
+    }
+
+    protected Set<String> getExpectedProviders() {
+        return this.expectedProviders;
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderRegistrationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderRegistrationTest.java
new file mode 100644
index 0000000..0320a0a
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/IdentityProviderRegistrationTest.java
@@ -0,0 +1,105 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.broker;
+
+import org.junit.Test;
+import org.keycloak.broker.provider.IdentityProvider;
+import org.keycloak.broker.provider.IdentityProviderFactory;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.social.SocialIdentityProvider;
+import org.keycloak.social.SocialIdentityProviderFactory;
+import org.keycloak.testsuite.broker.provider.CustomIdentityProvider;
+import org.keycloak.testsuite.broker.social.CustomSocialProvider;
+
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author pedroigor
+ */
+public class IdentityProviderRegistrationTest extends AbstractIdentityProviderModelTest {
+
+    @Test
+    public void testIdentityProviderRegistration() {
+        Set<String> installedProviders = getInstalledProviders();
+
+        for (String providerId : getExpectedProviders()) {
+            if (!installedProviders.contains(providerId)) {
+                fail("Provider [" + providerId + "] not installed ");
+            }
+        }
+    }
+
+    @Test
+    public void testCustomSocialProviderRegistration() {
+        String providerId = "custom-social-provider";
+
+        assertTrue(getInstalledProviders().contains(providerId));
+
+        SocialIdentityProviderFactory<CustomSocialProvider> providerFactory = (SocialIdentityProviderFactory) this.session.getKeycloakSessionFactory().getProviderFactory(SocialIdentityProvider.class, providerId);
+
+        assertNotNull(providerFactory);
+
+        IdentityProviderModel identityProviderModel = new IdentityProviderModel();
+
+        identityProviderModel.setId("custom-provider");
+
+        CustomSocialProvider customSocialProvider = providerFactory.create(identityProviderModel);
+
+        assertNotNull(customSocialProvider);
+        IdentityProviderModel config = customSocialProvider.getConfig();
+
+        assertNotNull(config);
+        assertEquals("custom-provider", config.getId());
+    }
+
+    @Test
+    public void testCustomIdentityProviderRegistration() {
+        String providerId = "custom-identity-provider";
+
+        assertTrue(getInstalledProviders().contains(providerId));
+
+        IdentityProviderFactory<CustomIdentityProvider> providerFactory = (IdentityProviderFactory) this.session.getKeycloakSessionFactory().getProviderFactory(IdentityProvider.class, providerId);
+
+        assertNotNull(providerFactory);
+
+        IdentityProviderModel identityProviderModel = new IdentityProviderModel();
+
+        identityProviderModel.setId("custom-provider");
+
+        CustomIdentityProvider provider = providerFactory.create(identityProviderModel);
+
+        assertNotNull(provider);
+        IdentityProviderModel config = provider.getConfig();
+
+        assertNotNull(config);
+        assertEquals("custom-provider", config.getId());
+    }
+
+    private Set<String> getInstalledProviders() {
+        Set<String> installedProviders = this.session.listProviderIds(IdentityProvider.class);
+
+        installedProviders.addAll(this.session.listProviderIds(SocialIdentityProvider.class));
+
+        return installedProviders;
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java
new file mode 100644
index 0000000..3b011cc
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java
@@ -0,0 +1,276 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.broker;
+
+import org.junit.Test;
+import org.keycloak.broker.oidc.OAuth2IdentityProviderConfig;
+import org.keycloak.broker.oidc.OIDCIdentityProvider;
+import org.keycloak.broker.oidc.OIDCIdentityProviderConfig;
+import org.keycloak.broker.oidc.OIDCIdentityProviderFactory;
+import org.keycloak.broker.saml.SAMLIdentityProvider;
+import org.keycloak.broker.saml.SAMLIdentityProviderConfig;
+import org.keycloak.broker.saml.SAMLIdentityProviderFactory;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.models.RealmModel;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.keycloak.social.facebook.FacebookIdentityProvider;
+import org.keycloak.social.facebook.FacebookIdentityProviderFactory;
+import org.keycloak.social.github.GitHubIdentityProvider;
+import org.keycloak.social.github.GitHubIdentityProviderFactory;
+import org.keycloak.social.google.GoogleIdentityProvider;
+import org.keycloak.social.google.GoogleIdentityProviderFactory;
+import org.keycloak.social.twitter.TwitterIdentityProvider;
+import org.keycloak.social.twitter.TwitterIdentityProviderFactory;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author pedroigor
+ */
+public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTest {
+
+    @Test
+    public void testInstallation() throws Exception {
+        RealmModel realm = installTestRealm();
+
+        assertIdentityProviderConfig(realm.getIdentityProviders());
+
+        assertTrue(realm.isIdentityFederationEnabled());
+
+        this.realmManager.removeRealm(realm);
+
+        commit();
+
+        realm = this.realmManager.getRealm(realm.getId());
+
+        assertNull(realm);
+    }
+
+    @Test
+    public void testUpdateIdentityProvider() throws Exception {
+        RealmModel realm = installTestRealm();
+        List<IdentityProviderModel> identityProviders = realm.getIdentityProviders();
+
+        assertFalse(identityProviders.isEmpty());
+
+        IdentityProviderModel identityProviderModel = identityProviders.get(0);
+        String identityProviderId = identityProviderModel.getId();
+
+        identityProviderModel.setName("Changed Name");
+        identityProviderModel.getConfig().put("config-added", "value-added");
+        identityProviderModel.setEnabled(false);
+        identityProviderModel.setUpdateProfileFirstLogin(false);
+
+        realm.updateIdentityProvider(identityProviderModel);
+
+        commit();
+
+        realm = this.realmManager.getRealm(realm.getId());
+
+        identityProviderModel = realm.getIdentityProviderById(identityProviderId);
+
+        assertEquals("Changed Name", identityProviderModel.getName());
+        assertEquals("value-added", identityProviderModel.getConfig().get("config-added"));
+        assertEquals(false, identityProviderModel.isEnabled());
+        assertEquals(false, identityProviderModel.isUpdateProfileFirstLogin());
+
+        identityProviderModel.setName("Changed Name Again");
+        identityProviderModel.getConfig().remove("config-added");
+        identityProviderModel.setEnabled(true);
+        identityProviderModel.setUpdateProfileFirstLogin(true);
+
+        realm.updateIdentityProvider(identityProviderModel);
+
+        commit();
+
+        realm = this.realmManager.getRealm(realm.getId());
+        identityProviderModel = realm.getIdentityProviderById(identityProviderId);
+
+        assertEquals("Changed Name Again", identityProviderModel.getName());
+        assertFalse(identityProviderModel.getConfig().containsKey("config-added"));
+        assertEquals(true, identityProviderModel.isEnabled());
+        assertEquals(true, identityProviderModel.isUpdateProfileFirstLogin());
+    }
+
+    @Test
+    public void testRemoveIdentityProvider() throws Exception {
+        RealmModel realm = installTestRealm();
+        List<IdentityProviderModel> identityProviders = realm.getIdentityProviders();
+
+        assertFalse(identityProviders.isEmpty());
+
+        IdentityProviderModel identityProviderModel = identityProviders.get(0);
+        String expectedId = identityProviderModel.getId();
+
+        realm.removeIdentityProviderById(expectedId);
+
+        commit();
+
+        realm = this.realmManager.getRealm(realm.getId());
+
+        assertNull(realm.getIdentityProviderById(expectedId));
+    }
+
+    private void assertIdentityProviderConfig(List<IdentityProviderModel> identityProviders) {
+        assertFalse(identityProviders.isEmpty());
+
+        Set<String> checkedProviders = new HashSet<String>(getExpectedProviders());
+
+        for (IdentityProviderModel identityProvider : identityProviders) {
+            String providerId = identityProvider.getProviderId();
+
+            if (SAMLIdentityProviderFactory.PROVIDER_ID.equals(providerId)) {
+                assertSamlIdentityProviderConfig(identityProvider);
+            } else if (GoogleIdentityProviderFactory.PROVIDER_ID.equals(providerId)) {
+                assertGoogleIdentityProviderConfig(identityProvider);
+            } else if (OIDCIdentityProviderFactory.PROVIDER_ID.equals(providerId)) {
+                assertOidcIdentityProviderConfig(identityProvider);
+            } else if (FacebookIdentityProviderFactory.PROVIDER_ID.equals(providerId)) {
+                assertFacebookIdentityProviderConfig(identityProvider);
+            } else if (GitHubIdentityProviderFactory.PROVIDER_ID.equals(providerId)) {
+                assertGitHubIdentityProviderConfig(identityProvider);
+            } else if (TwitterIdentityProviderFactory.PROVIDER_ID.equals(providerId)) {
+                assertTwitterIdentityProviderConfig(identityProvider);
+            }
+
+            checkedProviders.remove(providerId);
+        }
+
+        assertTrue(checkedProviders.isEmpty());
+    }
+
+    private void assertGoogleIdentityProviderConfig(IdentityProviderModel identityProvider) {
+        GoogleIdentityProvider googleIdentityProvider = new GoogleIdentityProviderFactory().create(identityProvider);
+        OIDCIdentityProviderConfig config = googleIdentityProvider.getConfig();
+
+        assertEquals("google", config.getId());
+        assertEquals(GoogleIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
+        assertEquals("Google", config.getName());
+        assertEquals(true, config.isEnabled());
+        assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals("clientId", config.getClientId());
+        assertEquals("clientSecret", config.getClientSecret());
+        assertEquals(GoogleIdentityProvider.AUTH_URL, config.getAuthorizationUrl());
+        assertEquals(GoogleIdentityProvider.TOKEN_URL, config.getTokenUrl());
+        assertEquals(GoogleIdentityProvider.PROFILE_URL, config.getUserInfoUrl());
+
+    }
+
+    private void assertSamlIdentityProviderConfig(IdentityProviderModel identityProvider) {
+        SAMLIdentityProvider samlIdentityProvider = new SAMLIdentityProviderFactory().create(identityProvider);
+        SAMLIdentityProviderConfig config = samlIdentityProvider.getConfig();
+
+        assertEquals("saml-idp", config.getId());
+        assertEquals(SAMLIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
+        assertEquals("SAML IdP", config.getName());
+        assertEquals(true, config.isEnabled());
+        assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals("http://localhost:8080/idp/", config.getSingleSignOnServiceUrl());
+        assertEquals("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", config.getNameIDPolicyFormat());
+        assertEquals("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB", config.getSigningPublicKey());
+        assertEquals(true, config.isWantAuthnRequestsSigned());
+        assertEquals(true, config.isForceAuthn());
+        assertEquals(true, config.isPostBindingAuthnRequest());
+        assertEquals(true, config.isPostBindingResponse());
+        assertEquals(true, config.isValidateSignature());
+    }
+
+    private void assertOidcIdentityProviderConfig(IdentityProviderModel identityProvider) {
+        OIDCIdentityProvider googleIdentityProvider = new OIDCIdentityProviderFactory().create(identityProvider);
+        OIDCIdentityProviderConfig config = googleIdentityProvider.getConfig();
+
+        assertEquals("oidc-idp", config.getId());
+        assertEquals(OIDCIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
+        assertEquals("OIDC IdP", config.getName());
+        assertEquals(false, config.isEnabled());
+        assertEquals(false, config.isUpdateProfileFirstLogin());
+        assertEquals("clientId", config.getClientId());
+        assertEquals("clientSecret", config.getClientSecret());
+    }
+
+    private void assertFacebookIdentityProviderConfig(IdentityProviderModel identityProvider) {
+        FacebookIdentityProvider facebookIdentityProvider = new FacebookIdentityProviderFactory().create(identityProvider);
+        OAuth2IdentityProviderConfig config = facebookIdentityProvider.getConfig();
+
+        assertEquals("facebook", config.getId());
+        assertEquals(FacebookIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
+        assertEquals("Facebook", config.getName());
+        assertEquals(true, config.isEnabled());
+        assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals("clientId", config.getClientId());
+        assertEquals("clientSecret", config.getClientSecret());
+        assertEquals(FacebookIdentityProvider.AUTH_URL, config.getAuthorizationUrl());
+        assertEquals(FacebookIdentityProvider.TOKEN_URL, config.getTokenUrl());
+        assertEquals(FacebookIdentityProvider.PROFILE_URL, config.getUserInfoUrl());
+    }
+
+    private void assertGitHubIdentityProviderConfig(IdentityProviderModel identityProvider) {
+        GitHubIdentityProvider gitHubIdentityProvider = new GitHubIdentityProviderFactory().create(identityProvider);
+        OAuth2IdentityProviderConfig config = gitHubIdentityProvider.getConfig();
+
+        assertEquals("github", config.getId());
+        assertEquals(GitHubIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
+        assertEquals("GitHub", config.getName());
+        assertEquals(true, config.isEnabled());
+        assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals("clientId", config.getClientId());
+        assertEquals("clientSecret", config.getClientSecret());
+        assertEquals(GitHubIdentityProvider.AUTH_URL, config.getAuthorizationUrl());
+        assertEquals(GitHubIdentityProvider.TOKEN_URL, config.getTokenUrl());
+        assertEquals(GitHubIdentityProvider.PROFILE_URL, config.getUserInfoUrl());
+    }
+
+    private void assertTwitterIdentityProviderConfig(IdentityProviderModel identityProvider) {
+        TwitterIdentityProvider gitHubIdentityProvider = new TwitterIdentityProviderFactory().create(identityProvider);
+        OAuth2IdentityProviderConfig config = gitHubIdentityProvider.getConfig();
+
+        assertEquals("twitter", config.getId());
+        assertEquals(TwitterIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
+        assertEquals("Twitter", config.getName());
+        assertEquals(true, config.isEnabled());
+        assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals("clientId", config.getClientId());
+        assertEquals("clientSecret", config.getClientSecret());
+    }
+
+    private RealmModel installTestRealm() throws IOException {
+        RealmRepresentation realmRepresentation = loadJson("model/test-realm-with-identity-provider.json");
+
+        assertNotNull(realmRepresentation);
+        assertEquals("test-realm-with-identity-provider", realmRepresentation.getRealm());
+
+        RealmModel realmModel = this.realmManager.importRealm(realmRepresentation);
+
+        commit();
+
+        realmModel = this.realmManager.getRealm(realmModel.getId());
+
+        assertNotNull(realmModel);
+
+        return realmModel;
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/provider/CustomIdentityProvider.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/provider/CustomIdentityProvider.java
new file mode 100644
index 0000000..4ef9241
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/provider/CustomIdentityProvider.java
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.broker.provider;
+
+import org.keycloak.broker.provider.AbstractIdentityProvider;
+import org.keycloak.broker.provider.AuthenticationRequest;
+import org.keycloak.broker.provider.AuthenticationResponse;
+import org.keycloak.models.IdentityProviderModel;
+
+/**
+ * @author pedroigor
+ */
+public class CustomIdentityProvider extends AbstractIdentityProvider<IdentityProviderModel> {
+
+    public CustomIdentityProvider(IdentityProviderModel config) {
+        super(config);
+    }
+
+    @Override
+    public AuthenticationResponse handleRequest(AuthenticationRequest request) {
+        return null;
+    }
+
+    @Override
+    public String getRelayState(AuthenticationRequest request) {
+        return null;
+    }
+
+    @Override
+    public AuthenticationResponse handleResponse(AuthenticationRequest request) {
+        return null;
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/provider/CustomIdentityProviderFactory.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/provider/CustomIdentityProviderFactory.java
new file mode 100644
index 0000000..b6ebb45
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/provider/CustomIdentityProviderFactory.java
@@ -0,0 +1,42 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.broker.provider;
+
+import org.keycloak.broker.provider.AbstractIdentityProviderFactory;
+import org.keycloak.models.IdentityProviderModel;
+
+/**
+ * @author pedroigor
+ */
+public class CustomIdentityProviderFactory extends AbstractIdentityProviderFactory<CustomIdentityProvider> {
+
+    @Override
+    public String getName() {
+        return "Custom Identity Provider";
+    }
+
+    @Override
+    public CustomIdentityProvider create(IdentityProviderModel model) {
+        return new CustomIdentityProvider(model);
+    }
+
+    @Override
+    public String getId() {
+        return "custom-identity-provider";
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/social/CustomSocialProvider.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/social/CustomSocialProvider.java
new file mode 100644
index 0000000..ae5d300
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/social/CustomSocialProvider.java
@@ -0,0 +1,49 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.broker.social;
+
+import org.keycloak.broker.provider.AbstractIdentityProvider;
+import org.keycloak.broker.provider.AuthenticationRequest;
+import org.keycloak.broker.provider.AuthenticationResponse;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.social.SocialIdentityProvider;
+
+/**
+ * @author pedroigor
+ */
+public class CustomSocialProvider extends AbstractIdentityProvider<IdentityProviderModel> implements SocialIdentityProvider<IdentityProviderModel> {
+
+    public CustomSocialProvider(IdentityProviderModel config) {
+        super(config);
+    }
+
+    @Override
+    public AuthenticationResponse handleRequest(AuthenticationRequest request) {
+        return null;
+    }
+
+    @Override
+    public String getRelayState(AuthenticationRequest request) {
+        return null;
+    }
+
+    @Override
+    public AuthenticationResponse handleResponse(AuthenticationRequest request) {
+        return null;
+    }
+}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/social/CustomSocialProviderFactory.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/social/CustomSocialProviderFactory.java
new file mode 100644
index 0000000..5fb2031
--- /dev/null
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/social/CustomSocialProviderFactory.java
@@ -0,0 +1,43 @@
+/*
+ * JBoss, Home of Professional Open Source
+ *
+ * Copyright 2013 Red Hat, Inc. and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.keycloak.testsuite.broker.social;
+
+import org.keycloak.broker.provider.AbstractIdentityProviderFactory;
+import org.keycloak.models.IdentityProviderModel;
+import org.keycloak.social.SocialIdentityProviderFactory;
+
+/**
+ * @author pedroigor
+ */
+public class CustomSocialProviderFactory extends AbstractIdentityProviderFactory<CustomSocialProvider> implements SocialIdentityProviderFactory<CustomSocialProvider> {
+
+    @Override
+    public String getName() {
+        return "Custom Social Provider";
+    }
+
+    @Override
+    public CustomSocialProvider create(IdentityProviderModel model) {
+        return new CustomSocialProvider(model);
+    }
+
+    @Override
+    public String getId() {
+        return "custom-social-provider";
+    }
+}
diff --git a/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderFactory b/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderFactory
new file mode 100644
index 0000000..3065616
--- /dev/null
+++ b/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.broker.provider.IdentityProviderFactory
@@ -0,0 +1 @@
+org.keycloak.testsuite.broker.provider.CustomIdentityProviderFactory
\ No newline at end of file
diff --git a/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.social.SocialIdentityProviderFactory b/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.social.SocialIdentityProviderFactory
new file mode 100644
index 0000000..06a646c
--- /dev/null
+++ b/testsuite/integration/src/test/resources/META-INF/services/org.keycloak.social.SocialIdentityProviderFactory
@@ -0,0 +1 @@
+org.keycloak.testsuite.broker.social.CustomSocialProviderFactory
\ No newline at end of file
diff --git a/testsuite/integration/src/test/resources/model/test-realm-with-identity-provider.json b/testsuite/integration/src/test/resources/model/test-realm-with-identity-provider.json
new file mode 100755
index 0000000..03a63dd
--- /dev/null
+++ b/testsuite/integration/src/test/resources/model/test-realm-with-identity-provider.json
@@ -0,0 +1,183 @@
+{
+    "realm": "test-realm-with-identity-provider",
+    "enabled": true,
+    "requiredCredentials": [ "password" ],
+    "defaultRoles": [ "foo", "bar" ],
+    "identityProviders" : [
+        {
+            "id" : "google",
+            "providerId" : "google",
+            "name" : "Google",
+            "enabled": true,
+            "updateProfileFirstLogin" : "true",
+            "config": {
+                "clientId": "clientId",
+                "clientSecret": "clientSecret"
+            }
+        },
+        {
+            "id" : "facebook",
+            "providerId" : "facebook",
+            "name" : "Facebook",
+            "enabled": true,
+            "updateProfileFirstLogin" : "true",
+            "config": {
+                "authorizationUrl": "authorizationUrl",
+                "tokenUrl": "tokenUrl",
+                "userInfoUrl": "userInfoUrl",
+                "clientId": "clientId",
+                "clientSecret": "clientSecret"
+            }
+        },
+        {
+            "id" : "github",
+            "providerId" : "github",
+            "name" : "GitHub",
+            "enabled": true,
+            "updateProfileFirstLogin" : "true",
+            "config": {
+                "authorizationUrl": "authorizationUrl",
+                "tokenUrl": "tokenUrl",
+                "userInfoUrl": "userInfoUrl",
+                "clientId": "clientId",
+                "clientSecret": "clientSecret"
+            }
+        },
+        {
+            "id" : "twitter",
+            "providerId" : "twitter",
+            "name" : "Twitter",
+            "enabled": true,
+            "updateProfileFirstLogin" : "true",
+            "config": {
+                "authorizationUrl": "authorizationUrl",
+                "tokenUrl": "tokenUrl",
+                "userInfoUrl": "userInfoUrl",
+                "clientId": "clientId",
+                "clientSecret": "clientSecret"
+            }
+        },
+        {
+            "id" : "saml-idp",
+            "providerId" : "saml",
+            "name" : "SAML IdP",
+            "enabled": true,
+            "updateProfileFirstLogin" : "true",
+            "config": {
+                "singleSignOnServiceUrl": "http://localhost:8080/idp/",
+                "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
+                "signingPublicKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrVrCuTtArbgaZzL1hvh0xtL5mc7o0NqPVnYXkLvgcwiC3BjLGw1tGEGoJaXDuSaRllobm53JBhjx33UNv+5z/UMG4kytBWxheNVKnL6GgqlNabMaFfPLPCF8kAgKnsi79NMo+n6KnSY8YeUmec/p2vjO2NjsSAVcWEQMVhJ31LwIDAQAB",
+                "wantAuthnRequestsSigned": true,
+                "forceAuthn": true,
+                "validateSignature": true,
+                "postBindingResponse": true,
+                "postBindingAuthnRequest": true
+            }
+        },
+        {
+            "id" : "oidc-idp",
+            "providerId" : "oidc",
+            "name" : "OIDC IdP",
+            "enabled": false,
+            "updateProfileFirstLogin" : "false",
+            "config": {
+                "clientId": "clientId",
+                "clientSecret": "clientSecret",
+                "prompt": "prompt",
+                "authorizationUrl": "authorizationUrl",
+                "tokenUrl": "tokenUrl",
+                "userInfoUrl": "userInfoUrl",
+                "defaultScope": "defaultScope",
+                "issuer": "issuer"
+            }
+        }
+    ],
+    "users": [
+        {
+            "username": "federated-user",
+            "enabled": true,
+            "federatedIdentities": [
+                {
+                    "identityProvider": "facebook",
+                    "userId": "facebook1",
+                    "userName": "fbuser1"
+                },
+                {
+                    "identityProvider": "twitter",
+                    "userId": "twitter1",
+                    "userName": "twuser1"
+                },
+                {
+                    "identityProvider": "google",
+                    "userId": "google1",
+                    "userName": "mySocialUser@gmail.com"
+                }
+            ]
+        }
+    ],
+    "applications": [
+        {
+            "name": "Application",
+            "enabled": true,
+            "nodeReRegistrationTimeout": 50,
+            "registeredNodes": {
+                "node1": 10,
+                "172.10.15.20": 20
+            }
+        },
+        {
+            "name": "OtherApp",
+            "enabled": true
+        }
+
+    ],
+    "oauthClients" : [
+        {
+            "name" : "oauthclient",
+            "enabled": true,
+            "secret": "clientpassword"
+        }
+    ],
+    "roles" : {
+        "realm" : [
+            {
+                "name": "admin"
+            }
+        ],
+        "application" : {
+            "Application" : [
+                {
+                    "name": "app-admin"
+                },
+                {
+                    "name": "app-user"
+                }
+            ],
+            "OtherApp" : [
+                {
+                    "name": "otherapp-admin"
+                },
+                {
+                    "name": "otherapp-user"
+                }
+            ]
+        }
+    },
+    "scopeMappings": [
+        {
+            "client": "oauthclient",
+            "roles": ["admin"]
+        }
+    ],
+    "applicationScopeMappings": {
+        "Application": [
+            {
+                "client": "oauthclient",
+                "roles": ["app-user"]
+            }
+        ]
+
+    }
+
+
+}
\ No newline at end of file