keycloak-aplcache

Merge pull request #1324 from velias/KEYCLOAK-1371 KEYCLOAK-1371

6/4/2015 10:19:59 AM

Changes

Details

diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml
index b2000c0..fef242c 100755
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.3.0.Beta1.xml
@@ -112,7 +112,17 @@
         </addColumn>
         <addColumn tableName="IDENTITY_PROVIDER">
             <column name="TRUST_EMAIL" type="BOOLEAN" defaultValueBoolean="false"/>
+            <column name="UPDATE_PROFILE_FIRST_LOGIN_MODE" type="VARCHAR(10)" defaultValue="on">
+                <constraints nullable="false"/>
+            </column>
         </addColumn>
+        <!-- migrate value from UPDATE_PROFILE_FIRST_LOGIN to UPDATE_PROFILE_FIRST_LOGIN_MODE then drop it -->
+        <update tableName="IDENTITY_PROVIDER">
+            <column name="UPDATE_PROFILE_FIRST_LOGIN_MODE" value="off"/>
+            <where>UPDATE_PROFILE_FIRST_LOGIN = false</where>
+        </update>
+        <dropColumn tableName="IDENTITY_PROVIDER" columnName="UPDATE_PROFILE_FIRST_LOGIN"/>
+        
         <addColumn tableName="USER_REQUIRED_ACTION">
             <column name="REQUIRED_ACTION" type="VARCHAR(36)">
                 <constraints nullable="false"/>
diff --git a/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java
index 8d9a14e..1e74002 100755
--- a/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/IdentityProviderRepresentation.java
@@ -29,7 +29,25 @@ public class IdentityProviderRepresentation {
     protected String internalId;
     protected String providerId;
     protected boolean enabled = true;
-    protected boolean updateProfileFirstLogin = true;
+
+    public static final String UPFLM_ON = "on";
+    public static final String UPFLM_MISSING = "missing";
+    public static final String UPFLM_OFF = "off";
+
+    /**
+     * Mode of profile update after first login when user is created over this identity provider. Possible values:
+     * <ul>
+     * <li><code>on</code> - update profile page is presented for all users
+     * <li><code>missing</code> - update profile page is presented for users with missing some of mandatory user profile fields
+     * <li><code>off</code> - update profile page is newer shown after first login
+     * </ul>
+     * 
+     * @see #UPFLM_ON
+     * @see #UPFLM_MISSING
+     * @see #UPFLM_OFF
+     */
+    protected String updateProfileFirstLoginMode = UPFLM_ON;
+
     protected boolean trustEmail;
     protected boolean storeToken;
     protected boolean addReadTokenRoleOnCreate;
@@ -76,12 +94,29 @@ public class IdentityProviderRepresentation {
         this.enabled = enabled;
     }
 
-    public boolean isUpdateProfileFirstLogin() {
-        return this.updateProfileFirstLogin;
+    /**
+     * 
+     * Deprecated because replaced by {@link #updateProfileFirstLoginMode}. Kept here to allow import of old realms.
+     * 
+     * @deprecated {@link #setUpdateProfileFirstLoginMode(String)}
+     */
+    @Deprecated
+    public void setUpdateProfileFirstLogin(boolean updateProfileFirstLogin) {
+        this.updateProfileFirstLoginMode = updateProfileFirstLogin ? UPFLM_ON : UPFLM_OFF;
+    }
+
+    /**
+     * @return see {@link #updateProfileFirstLoginMode}
+     */
+    public String getUpdateProfileFirstLoginMode() {
+        return updateProfileFirstLoginMode;
     }
 
-    public void setUpdateProfileFirstLogin(boolean updateProfileFirstLogin) {
-        this.updateProfileFirstLogin = updateProfileFirstLogin;
+    /**
+     * @param updateProfileFirstLoginMode see {@link #updateProfileFirstLoginMode}
+     */
+    public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
+        this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
     }
 
     public boolean isAuthenticateByDefault() {
diff --git a/docbook/reference/en/en-US/modules/identity-broker.xml b/docbook/reference/en/en-US/modules/identity-broker.xml
index 11460ea..75df2c7 100755
--- a/docbook/reference/en/en-US/modules/identity-broker.xml
+++ b/docbook/reference/en/en-US/modules/identity-broker.xml
@@ -299,9 +299,11 @@
                         </entry>
                         <entry>
                             Allows you to force users to update their profile right after the authentication finishes and
-                            before the account is actually created in Keycloak. When enabled, users will be presented with the
+                            before the account is actually created in Keycloak. When "On", users will be always presented with the
                             <emphasis>update profile page</emphasis> asking for additional information in order to federate their identities.
-                            If disabled, the account will be created with the minimal information obtained from the identity provider
+                            When "On missing info", users will be presented with the <emphasis>update profile page</emphasis> only if some 
+                            mandatory information (email, first name, last name) is not provided by identity provider.
+                            If "Off", the account will be created with the minimal information obtained from the identity provider
                             during the authentication process.
                         </entry>
                     </row>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
index f60e20e..53ad7ae 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
@@ -597,7 +597,7 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
         if (instance && instance.alias) {
 
         } else {
-            $scope.identityProvider.updateProfileFirstLogin = false;
+            $scope.identityProvider.updateProfileFirstLoginMode = "on";
         }
 
     };
@@ -645,7 +645,7 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
 
         } else {
             $scope.identityProvider.config.nameIDPolicyFormat = $scope.nameIdFormats[0].format;
-            $scope.identityProvider.updateProfileFirstLogin = false;
+            $scope.identityProvider.updateProfileFirstLoginMode = "off";
         }
     }
 
@@ -663,7 +663,7 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
         $scope.identityProvider.alias = providerFactory.id;
         $scope.identityProvider.providerId = providerFactory.id;
         $scope.identityProvider.enabled = true;
-        $scope.identityProvider.updateProfileFirstLogin = false;
+        $scope.identityProvider.updateProfileFirstLoginMode = "off";
         $scope.identityProvider.authenticateByDefault = false;
         $scope.newIdentityProvider = true;
     }
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
index c826a16..9a2a28f 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html
@@ -8,7 +8,7 @@
                     <caption class="hidden">Table of identity providers</caption>
                     <thead>
                     <tr>
-                        <th colspan="3" class="kc-table-actions">
+                        <th colspan="4" class="kc-table-actions">
                             <div class="dropdown pull-right">
                                 <select class="form-control" ng-model="provider"
                                         ng-options="p.name group by p.groupName for p in allProviders track by p.id"
@@ -21,6 +21,7 @@
                     <tr ng-show="configuredProviders.length > 0">
                         <th>Name</th>
                         <th>Provider</th>
+                        <th>Enabled</th>
                         <th width="15%">GUI order</th>
                     </tr>
                     </thead>
@@ -30,6 +31,7 @@
                             <a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.alias}}</a>
                         </td>
                         <td>{{identityProvider.providerId}}</td>
+                        <td>{{identityProvider.enabled}}</td>
                         <td>{{identityProvider.config.guiOrder}}</td>
                     </tr>
                     </tbody>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html
index 40c0cab..d2a267b 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html
@@ -59,11 +59,17 @@
                 <kc-tooltip>Enable/disable new users can read any stored tokens.  This assigns the broker.read-token role.</kc-tooltip>
             </div>
             <div class="form-group">
-                <label class="col-md-2 control-label" for="updateProfileFirstLogin">Update Profile on First Login</label>
-                <div class="col-md-6">
-                    <input ng-model="identityProvider.updateProfileFirstLogin" name="identityProvider.updateProfileFirstLogin" id="updateProfileFirstLogin" onoffswitch />
+                <label class="col-md-2 control-label" for="updateProfileFirstLoginMode">Update Profile on First Login</label>
+                <div class="col-md-2">
+                		<div>
+                        <select id="updateProfileFirstLoginMode" ng-model="identityProvider.updateProfileFirstLoginMode" class="form-control">
+                            <option value="on">On</option>
+                            <option value="missing">On missing info</option>
+                            <option value="off">Off</option>
+                        </select>
+                    </div>
                 </div>
-                <kc-tooltip>Indicates if user must update his profile right after the first login.</kc-tooltip>
+                <kc-tooltip>Define under which conditions must user update his profile right after the first login.</kc-tooltip>
             </div>
             <div class="form-group">
                 <label class="col-md-2 control-label" for="trustEmail">Trust email</label>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html
index 1588151..d2aaf4e 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html
@@ -60,11 +60,17 @@
                 <kc-tooltip>Enable/disable new users can read any stored tokens.  This assigns the broker.read-token role.</kc-tooltip>
             </div>
             <div class="form-group">
-                <label class="col-md-2 control-label" for="updateProfileFirstLogin">Update Profile on First Login</label>
-                <div class="col-md-6">
-                    <input ng-model="identityProvider.updateProfileFirstLogin" name="identityProvider.updateProfileFirstLogin" id="updateProfileFirstLogin" onoffswitch />
+                <label class="col-md-2 control-label" for="updateProfileFirstLoginMode">Update Profile on First Login</label>
+                <div class="col-md-2">
+                		<div>
+                        <select id="updateProfileFirstLoginMode" ng-model="identityProvider.updateProfileFirstLoginMode" class="form-control">
+                            <option value="on">On</option>
+                            <option value="missing">On missing info</option>
+                            <option value="off">Off</option>
+                        </select>
+                    </div>
                 </div>
-                <kc-tooltip>Indicates if user must update his profile right after the first login.</kc-tooltip>
+                <kc-tooltip>Define under which conditions must user update his profile right after the first login.</kc-tooltip>
             </div>
             <div class="form-group">
                 <label class="col-md-2 control-label" for="trustEmail">Trust email</label>
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html
index 2466772..623bcf0 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html
@@ -70,11 +70,17 @@
                 <kc-tooltip>Enable/disable this identity provider.</kc-tooltip>
             </div>
             <div class="form-group">
-                <label class="col-md-2 control-label" for="updateProfileFirstLogin">Update Profile on First Login</label>
-                <div class="col-md-6">
-                    <input ng-model="identityProvider.updateProfileFirstLogin" name="identityProvider.updateProfileFirstLogin" id="updateProfileFirstLogin" onoffswitch />
+                <label class="col-md-2 control-label" for="updateProfileFirstLoginMode">Update Profile on First Login</label>
+                <div class="col-md-2">
+                		<div>
+                        <select id="updateProfileFirstLoginMode" ng-model="identityProvider.updateProfileFirstLoginMode" class="form-control">
+                            <option value="on">On</option>
+                            <option value="missing">On missing info</option>
+                            <option value="off">Off</option>
+                        </select>
+                    </div>
                 </div>
-                <kc-tooltip>Indicates if user must update his profile right after the first login.</kc-tooltip>
+                <kc-tooltip>Define under which conditions must user update his profile right after the first login.</kc-tooltip>
             </div>
             <div class="form-group">
                 <label class="col-md-2 control-label" for="trustEmail">Trust email</label>
diff --git a/model/api/src/main/java/org/keycloak/models/entities/IdentityProviderEntity.java b/model/api/src/main/java/org/keycloak/models/entities/IdentityProviderEntity.java
index f4c3271..c4cdd62 100755
--- a/model/api/src/main/java/org/keycloak/models/entities/IdentityProviderEntity.java
+++ b/model/api/src/main/java/org/keycloak/models/entities/IdentityProviderEntity.java
@@ -30,7 +30,7 @@ public class IdentityProviderEntity {
     private String providerId;
     private String name;
     private boolean enabled;
-    private boolean updateProfileFirstLogin;
+    private String updateProfileFirstLoginMode;
     private boolean trustEmail;
     private boolean storeToken;
     protected boolean addReadTokenRoleOnCreate;
@@ -62,12 +62,12 @@ public class IdentityProviderEntity {
         this.enabled = enabled;
     }
 
-    public boolean isUpdateProfileFirstLogin() {
-        return updateProfileFirstLogin;
+    public String getUpdateProfileFirstLoginMode() {
+        return updateProfileFirstLoginMode;
     }
 
-    public void setUpdateProfileFirstLogin(boolean updateProfileFirstLogin) {
-        this.updateProfileFirstLogin = updateProfileFirstLogin;
+    public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
+        this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
     }
 
     public boolean isAuthenticateByDefault() {
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 56f73c3..0c34e4b 100755
--- a/model/api/src/main/java/org/keycloak/models/IdentityProviderModel.java
+++ b/model/api/src/main/java/org/keycloak/models/IdentityProviderModel.java
@@ -20,6 +20,8 @@ package org.keycloak.models;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
+
 /**
  * <p>A model type representing the configuration for identity providers. It provides some common properties and also a {@link org.keycloak.models.IdentityProviderModel#config}
  * for configuration options and properties specifics to a identity provider.</p>
@@ -43,7 +45,13 @@ public class IdentityProviderModel {
 
     private boolean enabled;
 
-    private boolean updateProfileFirstLogin = true;
+    /**
+     * For possible values see {@link IdentityProviderRepresentation#getUpdateProfileFirstLoginMode()}
+     * @see IdentityProviderRepresentation#UPFLM_ON
+     * @see IdentityProviderRepresentation#UPFLM_MISSING
+     * @see IdentityProviderRepresentation#UPFLM_OFF
+     */
+    protected String updateProfileFirstLoginMode = IdentityProviderRepresentation.UPFLM_ON;
     
     private boolean trustEmail;
 
@@ -70,7 +78,7 @@ public class IdentityProviderModel {
         this.alias = model.getAlias();
         this.config = new HashMap<String, String>(model.getConfig());
         this.enabled = model.isEnabled();
-        this.updateProfileFirstLogin = model.isUpdateProfileFirstLogin();
+        this.updateProfileFirstLoginMode = model.getUpdateProfileFirstLoginMode();
         this.trustEmail = model.isTrustEmail();
         this.storeToken = model.isStoreToken();
         this.authenticateByDefault = model.isAuthenticateByDefault();
@@ -109,12 +117,18 @@ public class IdentityProviderModel {
         this.enabled = enabled;
     }
 
-    public boolean isUpdateProfileFirstLogin() {
-        return this.updateProfileFirstLogin;
+    /**
+     * @see IdentityProviderRepresentation#getUpdateProfileFirstLoginMode() 
+     */
+    public String getUpdateProfileFirstLoginMode() {
+        return updateProfileFirstLoginMode;
     }
 
-    public void setUpdateProfileFirstLogin(boolean updateProfileFirstLogin) {
-        this.updateProfileFirstLogin = updateProfileFirstLogin;
+    /**
+     * @see IdentityProviderRepresentation#setUpdateProfileFirstLoginMode(String) 
+     */
+    public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
+        this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
     }
 
     public boolean isStoreToken() {
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 aa29778..2adcb25 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
@@ -324,7 +324,7 @@ public class ModelToRepresentation {
         providerRep.setAlias(identityProviderModel.getAlias());
         providerRep.setEnabled(identityProviderModel.isEnabled());
         providerRep.setStoreToken(identityProviderModel.isStoreToken());
-        providerRep.setUpdateProfileFirstLogin(identityProviderModel.isUpdateProfileFirstLogin());
+        providerRep.setUpdateProfileFirstLoginMode(identityProviderModel.getUpdateProfileFirstLoginMode());
         providerRep.setTrustEmail(identityProviderModel.isTrustEmail());
         providerRep.setAuthenticateByDefault(identityProviderModel.isAuthenticateByDefault());
         providerRep.setConfig(identityProviderModel.getConfig());
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 c497d37..c9611af 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
@@ -917,7 +917,7 @@ public class RepresentationToModel {
         identityProviderModel.setAlias(representation.getAlias());
         identityProviderModel.setProviderId(representation.getProviderId());
         identityProviderModel.setEnabled(representation.isEnabled());
-        identityProviderModel.setUpdateProfileFirstLogin(representation.isUpdateProfileFirstLogin());
+        identityProviderModel.setUpdateProfileFirstLoginMode(representation.getUpdateProfileFirstLoginMode());
         identityProviderModel.setTrustEmail(representation.isTrustEmail());
         identityProviderModel.setAuthenticateByDefault(representation.isAuthenticateByDefault());
         identityProviderModel.setStoreToken(representation.isStoreToken());
diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java
index 2ad8e87..4cfefb4 100755
--- a/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java
+++ b/model/jpa/src/main/java/org/keycloak/models/jpa/entities/IdentityProviderEntity.java
@@ -41,8 +41,8 @@ public class IdentityProviderEntity {
     @Column(name="ENABLED")
     private boolean enabled;
 
-    @Column(name="UPDATE_PROFILE_FIRST_LOGIN")
-    private boolean updateProfileFirstLogin;
+    @Column(name = "UPDATE_PROFILE_FIRST_LOGIN_MODE")
+    private String updateProfileFirstLoginMode;
 
     @Column(name = "TRUST_EMAIL")
     private boolean trustEmail;
@@ -102,12 +102,12 @@ public class IdentityProviderEntity {
         this.enabled = enabled;
     }
 
-    public boolean isUpdateProfileFirstLogin() {
-        return this.updateProfileFirstLogin;
+    public String getUpdateProfileFirstLoginMode() {
+        return updateProfileFirstLoginMode;
     }
 
-    public void setUpdateProfileFirstLogin(boolean updateProfileFirstLogin) {
-        this.updateProfileFirstLogin = updateProfileFirstLogin;
+    public void setUpdateProfileFirstLoginMode(String updateProfileFirstLoginMode) {
+        this.updateProfileFirstLoginMode = updateProfileFirstLoginMode;
     }
 
     public boolean isStoreToken() {
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 34241b3..5199c09 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
@@ -1153,7 +1153,7 @@ public class RealmAdapter implements RealmModel {
             identityProviderModel.setInternalId(entity.getInternalId());
             identityProviderModel.setConfig(entity.getConfig());
             identityProviderModel.setEnabled(entity.isEnabled());
-            identityProviderModel.setUpdateProfileFirstLogin(entity.isUpdateProfileFirstLogin());
+            identityProviderModel.setUpdateProfileFirstLoginMode(entity.getUpdateProfileFirstLoginMode());
             identityProviderModel.setTrustEmail(entity.isTrustEmail());
             identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
             identityProviderModel.setStoreToken(entity.isStoreToken());
@@ -1186,7 +1186,7 @@ public class RealmAdapter implements RealmModel {
         entity.setEnabled(identityProvider.isEnabled());
         entity.setStoreToken(identityProvider.isStoreToken());
         entity.setAddReadTokenRoleOnCreate(identityProvider.isAddReadTokenRoleOnCreate());
-        entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
+        entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
         entity.setTrustEmail(identityProvider.isTrustEmail());
         entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
         entity.setConfig(identityProvider.getConfig());
@@ -1213,7 +1213,7 @@ public class RealmAdapter implements RealmModel {
             if (entity.getInternalId().equals(identityProvider.getInternalId())) {
                 entity.setAlias(identityProvider.getAlias());
                 entity.setEnabled(identityProvider.isEnabled());
-                entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
+                entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
                 entity.setTrustEmail(identityProvider.isTrustEmail());
                 entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
                 entity.setAddReadTokenRoleOnCreate(identityProvider.isAddReadTokenRoleOnCreate());
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 48baaa3..940f2cf 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
@@ -771,7 +771,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
             identityProviderModel.setInternalId(entity.getInternalId());
             identityProviderModel.setConfig(entity.getConfig());
             identityProviderModel.setEnabled(entity.isEnabled());
-            identityProviderModel.setUpdateProfileFirstLogin(entity.isUpdateProfileFirstLogin());
+            identityProviderModel.setUpdateProfileFirstLoginMode(entity.getUpdateProfileFirstLoginMode());
             identityProviderModel.setTrustEmail(entity.isTrustEmail());
             identityProviderModel.setAuthenticateByDefault(entity.isAuthenticateByDefault());
             identityProviderModel.setStoreToken(entity.isStoreToken());
@@ -802,7 +802,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
         entity.setAlias(identityProvider.getAlias());
         entity.setProviderId(identityProvider.getProviderId());
         entity.setEnabled(identityProvider.isEnabled());
-        entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
+        entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
         entity.setTrustEmail(identityProvider.isTrustEmail());
         entity.setAddReadTokenRoleOnCreate(identityProvider.isAddReadTokenRoleOnCreate());
         entity.setStoreToken(identityProvider.isStoreToken());
@@ -815,7 +815,6 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
 
     @Override
     public void removeIdentityProviderByAlias(String alias) {
-        IdentityProviderEntity toRemove;
         for (IdentityProviderEntity entity : realm.getIdentityProviders()) {
             if (entity.getAlias().equals(alias)) {
                 realm.getIdentityProviders().remove(entity);
@@ -831,7 +830,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
             if (entity.getInternalId().equals(identityProvider.getInternalId())) {
                 entity.setAlias(identityProvider.getAlias());
                 entity.setEnabled(identityProvider.isEnabled());
-                entity.setUpdateProfileFirstLogin(identityProvider.isUpdateProfileFirstLogin());
+                entity.setUpdateProfileFirstLoginMode(identityProvider.getUpdateProfileFirstLoginMode());
                 entity.setTrustEmail(identityProvider.isTrustEmail());
                 entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
                 entity.setAddReadTokenRoleOnCreate(identityProvider.isAddReadTokenRoleOnCreate());
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index 3ada879..e76ab3a 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -443,7 +443,7 @@ public class AuthenticationManager {
             Iterator<String> i = user.getRequiredActions().iterator();
             String action = i.next();
             
-            if (action.equals(UserModel.RequiredAction.VERIFY_EMAIL.name()) && Validation.isEmpty(user.getEmail())) {
+            if (action.equals(UserModel.RequiredAction.VERIFY_EMAIL.name()) && Validation.isBlank(user.getEmail())) {
                 if (i.hasNext())
                     action = i.next();
                 else
diff --git a/services/src/main/java/org/keycloak/services/resources/AccountService.java b/services/src/main/java/org/keycloak/services/resources/AccountService.java
index 39f6299..697a28f 100755
--- a/services/src/main/java/org/keycloak/services/resources/AccountService.java
+++ b/services/src/main/java/org/keycloak/services/resources/AccountService.java
@@ -580,7 +580,7 @@ public class AccountService {
         String totp = formData.getFirst("totp");
         String totpSecret = formData.getFirst("totpSecret");
 
-        if (Validation.isEmpty(totp)) {
+        if (Validation.isBlank(totp)) {
             setReferrerOnPage();
             return account.setError(Messages.MISSING_TOTP).createResponse(AccountPages.TOTP);
         } else if (!new TimeBasedOTP().validate(totp, totpSecret.getBytes())) {
@@ -640,7 +640,7 @@ public class AccountService {
         String passwordConfirm = formData.getFirst("password-confirm");
 
         if (requireCurrent) {
-            if (Validation.isEmpty(password)) {
+            if (Validation.isBlank(password)) {
                 setReferrerOnPage();
                 return account.setError(Messages.MISSING_PASSWORD).createResponse(AccountPages.PASSWORD);
             }
diff --git a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
index 0127956..e1d6bfa 100755
--- a/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
+++ b/services/src/main/java/org/keycloak/services/resources/IdentityBrokerService.java
@@ -44,10 +44,10 @@ import org.keycloak.models.RealmModel;
 import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserSessionModel;
-import org.keycloak.models.utils.KeycloakModelUtils;
 import org.keycloak.protocol.oidc.TokenManager;
 import org.keycloak.provider.ProviderFactory;
 import org.keycloak.representations.AccessToken;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.services.managers.AppAuthManager;
 import org.keycloak.services.managers.AuthenticationManager;
 import org.keycloak.services.managers.AuthenticationManager.AuthResult;
@@ -71,6 +71,7 @@ import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.UriBuilder;
 import javax.ws.rs.core.UriInfo;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -278,13 +279,14 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
             try {
                 federatedUser = createUser(context);
 
-                if (identityProviderConfig.isUpdateProfileFirstLogin()) {
+                if (IdentityProviderRepresentation.UPFLM_ON.equals(identityProviderConfig.getUpdateProfileFirstLoginMode()) 
+                        || (IdentityProviderRepresentation.UPFLM_MISSING.equals(identityProviderConfig.getUpdateProfileFirstLoginMode()) && !Validation.validateUserMandatoryFields(realmModel, federatedUser))) {
                     if (isDebugEnabled()) {
                         LOGGER.debugf("Identity provider requires update profile action.", federatedUser);
                     }
                     federatedUser.addRequiredAction(UPDATE_PROFILE);
                 }
-                if(identityProviderConfig.isTrustEmail() && federatedUser.getEmail() != null && federatedUser.getEmail().trim().length()>0){
+                if(identityProviderConfig.isTrustEmail() && !Validation.isBlank(federatedUser.getEmail())){
                     federatedUser.setEmailVerified(true);
                 }
             } catch (Exception e) {
@@ -509,7 +511,7 @@ public class IdentityBrokerService implements IdentityProvider.AuthenticationCal
         String username = context.getModelUsername();
         if (username == null) {
             username = context.getUsername();
-            if (this.realmModel.isRegistrationEmailAsUsername() && !Validation.isEmpty(context.getEmail())) {
+            if (this.realmModel.isRegistrationEmailAsUsername() && !Validation.isBlank(context.getEmail())) {
                 username = context.getEmail();
             } else if (username == null) {
                 username = context.getIdpConfig().getAlias() + "." + context.getId();
diff --git a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
index 3af66d3..c2571d9 100755
--- a/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
+++ b/services/src/main/java/org/keycloak/services/resources/LoginActionsService.java
@@ -829,7 +829,7 @@ public class LoginActionsService {
         String totpSecret = formData.getFirst("totpSecret");
 
         LoginFormsProvider loginForms = session.getProvider(LoginFormsProvider.class).setUser(user);
-        if (Validation.isEmpty(totp)) {
+        if (Validation.isBlank(totp)) {
             return loginForms.setError(Messages.MISSING_TOTP)
                     .setClientSessionCode(accessCode.getCode())
                     .createResponse(RequiredAction.CONFIGURE_TOTP);
@@ -875,7 +875,7 @@ public class LoginActionsService {
 
         LoginFormsProvider loginForms = session.getProvider(LoginFormsProvider.class)
                 .setUser(user);
-        if (Validation.isEmpty(passwordNew)) {
+        if (Validation.isBlank(passwordNew)) {
             return loginForms.setError(Messages.MISSING_PASSWORD)
                     .setClientSessionCode(accessCode.getCode())
                     .createResponse(RequiredAction.UPDATE_PASSWORD);
diff --git a/services/src/main/java/org/keycloak/services/validation/Validation.java b/services/src/main/java/org/keycloak/services/validation/Validation.java
index fefe74e..d3abc4d 100755
--- a/services/src/main/java/org/keycloak/services/validation/Validation.java
+++ b/services/src/main/java/org/keycloak/services/validation/Validation.java
@@ -2,11 +2,13 @@ package org.keycloak.services.validation;
 
 import org.keycloak.models.PasswordPolicy;
 import org.keycloak.models.RealmModel;
+import org.keycloak.models.UserModel;
 import org.keycloak.models.utils.FormMessage;
 import org.keycloak.representations.idm.CredentialRepresentation;
 import org.keycloak.services.messages.Messages;
 
 import javax.ws.rs.core.MultivaluedMap;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Pattern;
@@ -26,26 +28,26 @@ public class Validation {
     public static List<FormMessage> validateRegistrationForm(RealmModel realm, MultivaluedMap<String, String> formData, List<String> requiredCredentialTypes, PasswordPolicy policy) {
         List<FormMessage> errors = new ArrayList<>();
 
-        if (!realm.isRegistrationEmailAsUsername() && isEmpty(formData.getFirst(FIELD_USERNAME))) {
+        if (!realm.isRegistrationEmailAsUsername() && isBlank(formData.getFirst(FIELD_USERNAME))) {
             addError(errors, FIELD_USERNAME, Messages.MISSING_USERNAME);
         }
 
-        if (isEmpty(formData.getFirst(FIELD_FIRST_NAME))) {
+        if (isBlank(formData.getFirst(FIELD_FIRST_NAME))) {
             addError(errors, FIELD_FIRST_NAME, Messages.MISSING_FIRST_NAME);
         }
 
-        if (isEmpty(formData.getFirst(FIELD_LAST_NAME))) {
+        if (isBlank(formData.getFirst(FIELD_LAST_NAME))) {
             addError(errors, FIELD_LAST_NAME, Messages.MISSING_LAST_NAME);
         }
 
-        if (isEmpty(formData.getFirst(FIELD_EMAIL))) {
+        if (isBlank(formData.getFirst(FIELD_EMAIL))) {
             addError(errors, FIELD_EMAIL, Messages.MISSING_EMAIL);
         } else if (!isEmailValid(formData.getFirst(FIELD_EMAIL))) {
             addError(errors, FIELD_EMAIL, Messages.INVALID_EMAIL);
         }
 
         if (requiredCredentialTypes.contains(CredentialRepresentation.PASSWORD)) {
-            if (isEmpty(formData.getFirst(FIELD_PASSWORD))) {
+            if (isBlank(formData.getFirst(FIELD_PASSWORD))) {
                 addError(errors, FIELD_PASSWORD, Messages.MISSING_PASSWORD);
             } else if (!formData.getFirst(FIELD_PASSWORD).equals(formData.getFirst(FIELD_PASSWORD_CONFIRM))) {
                 addError(errors, FIELD_PASSWORD_CONFIRM, Messages.INVALID_PASSWORD_CONFIRM);
@@ -72,19 +74,19 @@ public class Validation {
     public static List<FormMessage> validateUpdateProfileForm(RealmModel realm, MultivaluedMap<String, String> formData) {
         List<FormMessage> errors = new ArrayList<>();
         
-        if (realm != null && realm.isEditUsernameAllowed() && isEmpty(formData.getFirst(FIELD_USERNAME))) {
+        if (realm != null && realm.isEditUsernameAllowed() && isBlank(formData.getFirst(FIELD_USERNAME))) {
             addError(errors, FIELD_USERNAME, Messages.MISSING_USERNAME);
         }
 
-        if (isEmpty(formData.getFirst(FIELD_FIRST_NAME))) {
+        if (isBlank(formData.getFirst(FIELD_FIRST_NAME))) {
             addError(errors, FIELD_FIRST_NAME, Messages.MISSING_FIRST_NAME);
         }
 
-        if (isEmpty(formData.getFirst(FIELD_LAST_NAME))) {
+        if (isBlank(formData.getFirst(FIELD_LAST_NAME))) {
             addError(errors, FIELD_LAST_NAME, Messages.MISSING_LAST_NAME);
         }
 
-        if (isEmpty(formData.getFirst(FIELD_EMAIL))) {
+        if (isBlank(formData.getFirst(FIELD_EMAIL))) {
             addError(errors, FIELD_EMAIL, Messages.MISSING_EMAIL);
         } else if (!isEmailValid(formData.getFirst(FIELD_EMAIL))) {
             addError(errors, FIELD_EMAIL, Messages.INVALID_EMAIL);
@@ -92,10 +94,37 @@ public class Validation {
 
         return errors;
     }
+    
+    /**
+     * Validate if user object contains all mandatory fields.
+     * 
+     * @param realm user is for
+     * @param user to validate
+     * @return true if user object contains all mandatory values, false if some mandatory value is missing
+     */
+    public static boolean validateUserMandatoryFields(RealmModel realm, UserModel user){
+        return!(isBlank(user.getFirstName()) || isBlank(user.getLastName()) || isBlank(user.getEmail()));        
+    }
 
+    /**
+     * Check if string is empty (null or lenght is 0)
+     * 
+     * @param s to check
+     * @return true if string is empty
+     */
     public static boolean isEmpty(String s) {
         return s == null || s.length() == 0;
     }
+    
+    /**
+     * Check if string is blank (null or lenght is 0 or contains only white characters)
+     * 
+     * @param s to check
+     * @return true if string is blank
+     */
+    public static boolean isBlank(String s) {
+        return s == null || s.trim().length() == 0;
+    }
 
     public static boolean isEmailValid(String email) {
         return EMAIL_PATTERN.matcher(email).matches();
diff --git a/services/src/test/java/org/keycloak/test/ValidationTest.java b/services/src/test/java/org/keycloak/test/ValidationTest.java
index 0da7dfa..72f5926 100644
--- a/services/src/test/java/org/keycloak/test/ValidationTest.java
+++ b/services/src/test/java/org/keycloak/test/ValidationTest.java
@@ -24,4 +24,26 @@ public class ValidationTest {
         Assert.assertFalse(Validation.isEmailValid("abc@foo."));
         Assert.assertFalse(Validation.isEmailValid("abc@foo..bar"));
     }
+    
+    @Test
+    public void testIsEmpty(){
+        Assert.assertTrue(Validation.isEmpty(null));
+        Assert.assertTrue(Validation.isEmpty(""));
+        Assert.assertFalse(Validation.isEmpty(" "));
+        Assert.assertFalse(Validation.isEmpty("     "));
+        Assert.assertFalse(Validation.isEmpty("a"));
+        Assert.assertFalse(Validation.isEmpty("    a "));
+        Assert.assertFalse(Validation.isEmpty("asgadfgedfs"));
+    }
+    
+    @Test
+    public void testIsBlank(){
+        Assert.assertTrue(Validation.isBlank(null));
+        Assert.assertTrue(Validation.isBlank(""));
+        Assert.assertTrue(Validation.isBlank(" "));
+        Assert.assertTrue(Validation.isBlank("  \n   "));
+        Assert.assertFalse(Validation.isBlank("a"));
+        Assert.assertFalse(Validation.isBlank("    a "));
+        Assert.assertFalse(Validation.isBlank("asgadfgedfs"));
+    }
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
index 9b72cd9..a7bae96 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/admin/IdentityProviderTest.java
@@ -52,7 +52,7 @@ public class IdentityProviderTest extends AbstractClientTest {
         assertEquals("clientSecret", representation.getConfig().get("clientSecret"));
         assertTrue(representation.isEnabled());
         assertFalse(representation.isStoreToken());
-        assertTrue(representation.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_ON, representation.getUpdateProfileFirstLoginMode());
         assertFalse(representation.isTrustEmail());
     }
 
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
index f6f7345..3f4ffa5 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/AbstractIdentityProviderTest.java
@@ -34,6 +34,7 @@ import org.keycloak.models.RoleModel;
 import org.keycloak.models.UserModel;
 import org.keycloak.models.UserModel.RequiredAction;
 import org.keycloak.representations.IDToken;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.services.Urls;
 import org.keycloak.testsuite.MailUtil;
 import org.keycloak.testsuite.OAuthClient;
@@ -137,18 +138,34 @@ public abstract class AbstractIdentityProviderTest {
     @Test
     public void testSuccessfulAuthentication() {
         IdentityProviderModel identityProviderModel = getIdentityProviderModel();
-        identityProviderModel.setUpdateProfileFirstLogin(true);
+        identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_ON);
 
-        UserModel user = assertSuccessfulAuthentication(identityProviderModel, "test-user", "new@email.com");
+        UserModel user = assertSuccessfulAuthentication(identityProviderModel, "test-user", "new@email.com", true);
         Assert.assertEquals("617-666-7777", user.getAttribute("mobile"));
     }
 
     @Test
+    public void testSuccessfulAuthenticationUpdateProfileOnMissing_nothingMissing() {
+        IdentityProviderModel identityProviderModel = getIdentityProviderModel();
+        identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_MISSING);
+
+        assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
+    }
+
+    @Test
+    public void testSuccessfulAuthenticationUpdateProfileOnMissing_missingEmail() {
+        IdentityProviderModel identityProviderModel = getIdentityProviderModel();
+        identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_MISSING);
+
+        assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", "new@email.com", true);
+    }
+
+    @Test
     public void testSuccessfulAuthenticationWithoutUpdateProfile() {
         IdentityProviderModel identityProviderModel = getIdentityProviderModel();
-        identityProviderModel.setUpdateProfileFirstLogin(false);
+        identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
 
-        assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost");
+        assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
     }
 
     /**
@@ -165,10 +182,10 @@ public abstract class AbstractIdentityProviderTest {
 
         IdentityProviderModel identityProviderModel = getIdentityProviderModel();
         try {
-            identityProviderModel.setUpdateProfileFirstLogin(false);
+            identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
             identityProviderModel.setTrustEmail(false);
 
-            UserModel federatedUser = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "test-user@localhost");
+            UserModel federatedUser = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "test-user@localhost", false);
 
             // email is verified now
             assertFalse(federatedUser.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL.name()));
@@ -178,9 +195,10 @@ public abstract class AbstractIdentityProviderTest {
         }
     }
 
-    private UserModel assertSuccessfulAuthenticationWithEmailVerification(IdentityProviderModel identityProviderModel, String username, String expectedEmail)
+    private UserModel assertSuccessfulAuthenticationWithEmailVerification(IdentityProviderModel identityProviderModel, String username, String expectedEmail,
+            boolean isProfileUpdateExpected)
             throws IOException, MessagingException {
-        authenticateWithIdentityProvider(identityProviderModel, username);
+        authenticateWithIdentityProvider(identityProviderModel, username, isProfileUpdateExpected);
 
         // verify email is sent
         Assert.assertTrue(verifyEmailPage.isCurrent());
@@ -199,7 +217,7 @@ public abstract class AbstractIdentityProviderTest {
 
         assertNotNull(federatedUser);
 
-        doAssertFederatedUser(federatedUser, identityProviderModel, expectedEmail);
+        doAssertFederatedUser(federatedUser, identityProviderModel, expectedEmail, isProfileUpdateExpected);
 
         brokerServerRule.stopSession(session, true);
         session = brokerServerRule.startSession();
@@ -233,9 +251,9 @@ public abstract class AbstractIdentityProviderTest {
 
         try {
             IdentityProviderModel identityProviderModel = getIdentityProviderModel();
-            identityProviderModel.setUpdateProfileFirstLogin(false);
+            identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
 
-            UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", null);
+            UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user-noemail", null, false);
 
             assertTrue(federatedUser.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL.name()));
 
@@ -255,10 +273,10 @@ public abstract class AbstractIdentityProviderTest {
 
         IdentityProviderModel identityProviderModel = getIdentityProviderModel();
         try {
-            identityProviderModel.setUpdateProfileFirstLogin(false);
+            identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
             identityProviderModel.setTrustEmail(true);
 
-            UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost");
+            UserModel federatedUser = assertSuccessfulAuthentication(identityProviderModel, "test-user", "test-user@localhost", false);
 
             assertFalse(federatedUser.getRequiredActions().contains(RequiredAction.VERIFY_EMAIL.name()));
 
@@ -282,10 +300,10 @@ public abstract class AbstractIdentityProviderTest {
 
         IdentityProviderModel identityProviderModel = getIdentityProviderModel();
         try {
-            identityProviderModel.setUpdateProfileFirstLogin(true);
+            identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_ON);
             identityProviderModel.setTrustEmail(true);
 
-            UserModel user = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "new@email.com");
+            UserModel user = assertSuccessfulAuthenticationWithEmailVerification(identityProviderModel, "test-user", "new@email.com", true);
             Assert.assertEquals("617-666-7777", user.getAttribute("mobile"));
         } finally {
             identityProviderModel.setTrustEmail(false);
@@ -302,9 +320,9 @@ public abstract class AbstractIdentityProviderTest {
 
         try {
             IdentityProviderModel identityProviderModel = getIdentityProviderModel();
-            identityProviderModel.setUpdateProfileFirstLogin(false);
+            identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
 
-            authenticateWithIdentityProvider(identityProviderModel, "test-user");
+            authenticateWithIdentityProvider(identityProviderModel, "test-user", false);
 
             // authenticated and redirected to app
             assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/test-app"));
@@ -321,7 +339,7 @@ public abstract class AbstractIdentityProviderTest {
 
             assertEquals("test-user@localhost", federatedUser.getUsername());
 
-            doAssertFederatedUser(federatedUser, identityProviderModel, "test-user@localhost");
+            doAssertFederatedUser(federatedUser, identityProviderModel, "test-user@localhost", false);
 
             Set<FederatedIdentityModel> federatedIdentities = this.session.users().getFederatedIdentities(federatedUser, realm);
 
@@ -350,9 +368,9 @@ public abstract class AbstractIdentityProviderTest {
 
         try {
             IdentityProviderModel identityProviderModel = getIdentityProviderModel();
-            identityProviderModel.setUpdateProfileFirstLogin(false);
+            identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
 
-            authenticateWithIdentityProvider(identityProviderModel, "test-user-noemail");
+            authenticateWithIdentityProvider(identityProviderModel, "test-user-noemail", false);
 
             brokerServerRule.stopSession(session, true);
             session = brokerServerRule.startSession();
@@ -455,7 +473,7 @@ public abstract class AbstractIdentityProviderTest {
     public void testUserAlreadyExistsWhenNotUpdatingProfile() {
         IdentityProviderModel identityProviderModel = getIdentityProviderModel();
 
-        identityProviderModel.setUpdateProfileFirstLogin(false);
+        identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
 
         this.driver.navigate().to("http://localhost:8081/test-app/");
 
@@ -593,7 +611,7 @@ public abstract class AbstractIdentityProviderTest {
 
         identityProviderModel.setStoreToken(true);
 
-        authenticateWithIdentityProvider(identityProviderModel, "test-user");
+        authenticateWithIdentityProvider(identityProviderModel, "test-user", true);
 
         UserModel federatedUser = getFederatedUser();
         RealmModel realm = getRealm();
@@ -658,17 +676,18 @@ public abstract class AbstractIdentityProviderTest {
 
     protected abstract void doAssertTokenRetrieval(String pageSource);
 
-    private UserModel assertSuccessfulAuthentication(IdentityProviderModel identityProviderModel, String username, String expectedEmail) {
-        authenticateWithIdentityProvider(identityProviderModel, username);
+    private UserModel assertSuccessfulAuthentication(IdentityProviderModel identityProviderModel, String username, String expectedEmail, boolean isProfileUpdateExpected) {
+        authenticateWithIdentityProvider(identityProviderModel, username, isProfileUpdateExpected);
 
         // authenticated and redirected to app
-        assertTrue(this.driver.getCurrentUrl().startsWith("http://localhost:8081/test-app"));
+        assertTrue("Bad current URL " + this.driver.getCurrentUrl() + " and page source: " + this.driver.getPageSource(),
+                this.driver.getCurrentUrl().startsWith("http://localhost:8081/test-app"));
 
         UserModel federatedUser = getFederatedUser();
 
         assertNotNull(federatedUser);
 
-        doAssertFederatedUser(federatedUser, identityProviderModel, expectedEmail);
+        doAssertFederatedUser(federatedUser, identityProviderModel, expectedEmail, isProfileUpdateExpected);
 
         brokerServerRule.stopSession(session, true);
         session = brokerServerRule.startSession();
@@ -691,11 +710,11 @@ public abstract class AbstractIdentityProviderTest {
         return federatedUser;
     }
 
-    private void authenticateWithIdentityProvider(IdentityProviderModel identityProviderModel, String username) {
+    private void authenticateWithIdentityProvider(IdentityProviderModel identityProviderModel, String username, boolean isProfileUpdateExpected) {
         loginIDP(username);
 
 
-        if (identityProviderModel.isUpdateProfileFirstLogin()) {
+        if (isProfileUpdateExpected) {
             String userEmail = "new@email.com";
             String userFirstName = "New first";
             String userLastName = "New last";
@@ -704,6 +723,7 @@ public abstract class AbstractIdentityProviderTest {
             this.updateProfilePage.assertCurrent();
             this.updateProfilePage.update(userFirstName, userLastName, userEmail);
         }
+
     }
 
     private void loginIDP(String username) {
@@ -749,7 +769,7 @@ public abstract class AbstractIdentityProviderTest {
 
         assertNotNull(identityProviderModel);
 
-        identityProviderModel.setUpdateProfileFirstLogin(true);
+        identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_ON);
         identityProviderModel.setEnabled(true);
 
         return identityProviderModel;
@@ -759,8 +779,8 @@ public abstract class AbstractIdentityProviderTest {
         return this.session.realms().getRealm("realm-with-broker");
     }
 
-    protected void doAssertFederatedUser(UserModel federatedUser, IdentityProviderModel identityProviderModel, String expectedEmail) {
-        if (identityProviderModel.isUpdateProfileFirstLogin()) {
+    protected void doAssertFederatedUser(UserModel federatedUser, IdentityProviderModel identityProviderModel, String expectedEmail, boolean isProfileUpdateExpected) {
+        if (isProfileUpdateExpected) {
             String userFirstName = "New first";
             String userLastName = "New last";
 
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
index 7b8c7a5..b2e3605 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/ImportIdentityProviderTest.java
@@ -33,6 +33,7 @@ import org.keycloak.broker.saml.SAMLIdentityProviderFactory;
 import org.keycloak.models.ClientModel;
 import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.RealmModel;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.representations.idm.RealmRepresentation;
 import org.keycloak.social.facebook.FacebookIdentityProvider;
 import org.keycloak.social.facebook.FacebookIdentityProviderFactory;
@@ -80,7 +81,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
 
         identityProviderModel.getConfig().put("config-added", "value-added");
         identityProviderModel.setEnabled(false);
-        identityProviderModel.setUpdateProfileFirstLogin(false);
+        identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_OFF);
         identityProviderModel.setTrustEmail(true);
         identityProviderModel.setStoreToken(true);
         identityProviderModel.setAuthenticateByDefault(true);
@@ -95,14 +96,14 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
 
         assertEquals("value-added", identityProviderModel.getConfig().get("config-added"));
         assertFalse(identityProviderModel.isEnabled());
-        assertFalse(identityProviderModel.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_OFF, identityProviderModel.getUpdateProfileFirstLoginMode());
         assertTrue(identityProviderModel.isTrustEmail());
         assertTrue(identityProviderModel.isStoreToken());
         assertTrue(identityProviderModel.isAuthenticateByDefault());
 
         identityProviderModel.getConfig().remove("config-added");
         identityProviderModel.setEnabled(true);
-        identityProviderModel.setUpdateProfileFirstLogin(true);
+        identityProviderModel.setUpdateProfileFirstLoginMode(IdentityProviderRepresentation.UPFLM_MISSING);
         identityProviderModel.setTrustEmail(false);
         identityProviderModel.setAuthenticateByDefault(false);
 
@@ -115,7 +116,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
 
         assertFalse(identityProviderModel.getConfig().containsKey("config-added"));
         assertTrue(identityProviderModel.isEnabled());
-        assertTrue(identityProviderModel.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_MISSING, identityProviderModel.getUpdateProfileFirstLoginMode());
         assertFalse(identityProviderModel.isTrustEmail());
         assertFalse(identityProviderModel.isAuthenticateByDefault());
         this.realmManager.removeRealm(realm);
@@ -164,7 +165,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
         assertEquals("model-google", config.getAlias());
         assertEquals(GoogleIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
         assertEquals(true, config.isEnabled());
-        assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_ON, config.getUpdateProfileFirstLoginMode());
         assertEquals(true, config.isTrustEmail());
         assertEquals(false, config.isAuthenticateByDefault());
         assertEquals(true, config.isStoreToken());
@@ -183,7 +184,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
         assertEquals("model-saml-signed-idp", config.getAlias());
         assertEquals(SAMLIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
         assertEquals(true, config.isEnabled());
-        assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_ON, config.getUpdateProfileFirstLoginMode());
         assertEquals(false, config.isAuthenticateByDefault());
         assertEquals(false, config.isTrustEmail());
         assertEquals(false, config.isStoreToken());
@@ -204,7 +205,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
         assertEquals("model-oidc-idp", config.getAlias());
         assertEquals(OIDCIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
         assertEquals(false, config.isEnabled());
-        assertEquals(false, config.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
         assertEquals(false, config.isTrustEmail());
         assertEquals(false, config.isAuthenticateByDefault());
         assertEquals(false, config.isStoreToken());
@@ -219,7 +220,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
         assertEquals("model-facebook", config.getAlias());
         assertEquals(FacebookIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
         assertEquals(true, config.isEnabled());
-        assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
         assertEquals(false, config.isTrustEmail());
         assertEquals(false, config.isAuthenticateByDefault());
         assertEquals(false, config.isStoreToken());
@@ -237,7 +238,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
         assertEquals("model-github", config.getAlias());
         assertEquals(GitHubIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
         assertEquals(true, config.isEnabled());
-        assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_ON, config.getUpdateProfileFirstLoginMode());
         assertEquals(false, config.isTrustEmail());
         assertEquals(false, config.isAuthenticateByDefault());
         assertEquals(false, config.isStoreToken());
@@ -255,7 +256,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
         assertEquals("model-linkedin", config.getAlias());
       assertEquals(LinkedInIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
       assertEquals(true, config.isEnabled());
-      assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_MISSING, config.getUpdateProfileFirstLoginMode());
         assertEquals(false, config.isTrustEmail());
       assertEquals(false, config.isAuthenticateByDefault());
       assertEquals(false, config.isStoreToken());
@@ -273,7 +274,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
         assertEquals("model-stackoverflow", config.getAlias());
         assertEquals(StackoverflowIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
         assertEquals(true, config.isEnabled());
-        assertEquals(false, config.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
         assertEquals(false, config.isTrustEmail());
         assertEquals(false, config.isAuthenticateByDefault());
         assertEquals(false, config.isStoreToken());
@@ -292,7 +293,7 @@ public class ImportIdentityProviderTest extends AbstractIdentityProviderModelTes
         assertEquals("model-twitter", config.getAlias());
         assertEquals(TwitterIdentityProviderFactory.PROVIDER_ID, config.getProviderId());
         assertEquals(true, config.isEnabled());
-        assertEquals(true, config.isUpdateProfileFirstLogin());
+        assertEquals(IdentityProviderRepresentation.UPFLM_OFF, config.getUpdateProfileFirstLoginMode());
         assertEquals(false, config.isTrustEmail());
         assertEquals(false, config.isAuthenticateByDefault());
         assertEquals(true, config.isStoreToken());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java
index 46bfa3d..c0ffd00 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerBasicTest.java
@@ -6,6 +6,7 @@ import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.rule.AbstractKeycloakRule;
 import org.keycloak.testsuite.KeycloakServer;
@@ -50,9 +51,9 @@ public class SAMLKeyCloakServerBrokerBasicTest extends AbstractIdentityProviderT
     }
 
     @Override
-    protected void doAssertFederatedUser(UserModel federatedUser, IdentityProviderModel identityProviderModel, String expectedEmail) {
-        if (identityProviderModel.isUpdateProfileFirstLogin()) {
-            super.doAssertFederatedUser(federatedUser, identityProviderModel, expectedEmail);
+    protected void doAssertFederatedUser(UserModel federatedUser, IdentityProviderModel identityProviderModel, String expectedEmail, boolean isProfileUpdateExpected) {
+        if (isProfileUpdateExpected) {
+            super.doAssertFederatedUser(federatedUser, identityProviderModel, expectedEmail, isProfileUpdateExpected);
         } else {
             if (expectedEmail == null) {
                 // Need to handle differences for various databases (like Oracle)
@@ -114,4 +115,9 @@ public class SAMLKeyCloakServerBrokerBasicTest extends AbstractIdentityProviderT
     public void testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername() {
         super.testSuccessfulAuthenticationWithoutUpdateProfile_newUser_emailAsUsername();
     }
+
+    @Test
+    public void testSuccessfulAuthenticationUpdateProfileOnMissing_nothingMissing() {
+        // skip this test as this provider do not return name and surname so something is missing always
+    }
 }
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java
index 821fc0e..34c10d5 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/broker/SAMLKeyCloakServerBrokerWithSignatureTest.java
@@ -6,6 +6,7 @@ import org.keycloak.models.IdentityProviderModel;
 import org.keycloak.models.KeycloakSession;
 import org.keycloak.models.RealmModel;
 import org.keycloak.models.UserModel;
+import org.keycloak.representations.idm.IdentityProviderRepresentation;
 import org.keycloak.services.managers.RealmManager;
 import org.keycloak.testsuite.rule.AbstractKeycloakRule;
 import org.keycloak.testsuite.KeycloakServer;
@@ -50,9 +51,9 @@ public class SAMLKeyCloakServerBrokerWithSignatureTest extends AbstractIdentityP
     }
 
     @Override
-    protected void doAssertFederatedUser(UserModel federatedUser, IdentityProviderModel identityProviderModel, String expectedEmail) {
-        if (identityProviderModel.isUpdateProfileFirstLogin()) {
-            super.doAssertFederatedUser(federatedUser, identityProviderModel, expectedEmail);
+    protected void doAssertFederatedUser(UserModel federatedUser, IdentityProviderModel identityProviderModel, String expectedEmail, boolean isProfileUpdateExpected) {
+        if (isProfileUpdateExpected) {
+            super.doAssertFederatedUser(federatedUser, identityProviderModel, expectedEmail, isProfileUpdateExpected);
         } else {
             if (expectedEmail == null) {
                 // Need to handle differences for various databases (like Oracle)
@@ -102,4 +103,9 @@ public class SAMLKeyCloakServerBrokerWithSignatureTest extends AbstractIdentityP
     public void testAccountManagementLinkIdentity() {
         super.testAccountManagementLinkIdentity();
     }
+
+    @Test
+    public void testSuccessfulAuthenticationUpdateProfileOnMissing_nothingMissing() {
+        // skip this test as this provider do not return name and surname so something is missing always
+    }
 }
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 3da5f75..a6ace52 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
@@ -29,7 +29,7 @@
             "alias" : "model-facebook",
             "providerId" : "facebook",
             "enabled": true,
-            "updateProfileFirstLogin" : "true",
+            "updateProfileFirstLogin" : "false",
             "config": {
                 "authorizationUrl": "authorizationUrl",
                 "tokenUrl": "tokenUrl",
@@ -42,7 +42,7 @@
             "alias" : "model-github",
             "providerId" : "github",
             "enabled": true,
-            "updateProfileFirstLogin" : "true",
+            "updateProfileFirstLoginMode" : "on",
             "storeToken": "false",
             "config": {
                 "authorizationUrl": "authorizationUrl",
@@ -56,7 +56,7 @@
             "alias" : "model-twitter",
             "providerId" : "twitter",
             "enabled": true,
-            "updateProfileFirstLogin" : "true",
+            "updateProfileFirstLoginMode" : "off",
             "storeToken": true,
             "config": {
                 "authorizationUrl": "authorizationUrl",
@@ -70,7 +70,7 @@
             "alias" : "model-linkedin",
             "providerId" : "linkedin",
             "enabled": true,
-            "updateProfileFirstLogin" : "true",
+            "updateProfileFirstLoginMode" : "missing",
             "storeToken": false,
             "config": {
                 "authorizationUrl": "authorizationUrl",
@@ -84,7 +84,7 @@
             "alias" : "model-stackoverflow",
             "providerId" : "stackoverflow",
             "enabled": true,
-            "updateProfileFirstLogin" : "false",
+            "updateProfileFirstLoginMode" : "off",
             "storeToken": false,
             "config": {
                 "key": "keyValue",
@@ -99,7 +99,7 @@
           "alias" : "model-saml-signed-idp",
           "providerId" : "saml",
           "enabled": true,
-          "updateProfileFirstLogin" : "true",
+          "updateProfileFirstLoginMode" : "on",
           "config": {
             "singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-identity-provider/protocol/saml",
             "nameIDPolicyFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress",
@@ -115,7 +115,7 @@
             "alias" : "kc-saml-signed-idp",
             "providerId" : "saml",
             "enabled": true,
-            "updateProfileFirstLogin" : true,
+            "updateProfileFirstLoginMode" : "on",
             "addReadTokenRoleOnCreate": true,
             "config": {
                 "singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-signed-idp/protocol/saml",
@@ -134,7 +134,7 @@
             "alias" : "kc-saml-idp-basic",
             "providerId" : "saml",
             "enabled": true,
-            "updateProfileFirstLogin" : true,
+            "updateProfileFirstLoginMode" : "on",
             "trustEmail" : false,
             "addReadTokenRoleOnCreate": true,
             "config": {
@@ -150,7 +150,7 @@
             "alias" : "model-oidc-idp",
             "providerId" : "oidc",
             "enabled": false,
-            "updateProfileFirstLogin" : "false",
+            "updateProfileFirstLoginMode" : "off",
             "authenticateByDefault" : "false",
             "config": {
                 "clientId": "clientId",
@@ -166,7 +166,7 @@
             "alias" : "kc-oidc-idp",
             "providerId" : "keycloak-oidc",
             "enabled": true,
-            "updateProfileFirstLogin" : "false",
+            "updateProfileFirstLoginMode" : "off",
             "storeToken" : true,
             "addReadTokenRoleOnCreate": true,
             "config": {