Details
diff --git a/common/src/main/java/org/keycloak/common/util/ObjectUtil.java b/common/src/main/java/org/keycloak/common/util/ObjectUtil.java
index d43d99c..2dd9bab 100644
--- a/common/src/main/java/org/keycloak/common/util/ObjectUtil.java
+++ b/common/src/main/java/org/keycloak/common/util/ObjectUtil.java
@@ -42,7 +42,38 @@ public class ObjectUtil {
return str1.equals(str2);
}
+
public static String capitalize(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
+
+
+ /**
+ * Forked from apache-commons StringUtils
+ *
+ * <p>Checks if a CharSequence is whitespace, empty ("") or null.</p>
+ *
+ * <pre>
+ * ObjectUtil.isBlank(null) = true
+ * ObjectUtil.isBlank("") = true
+ * ObjectUtil.isBlank(" ") = true
+ * ObjectUtil.isBlank("bob") = false
+ * ObjectUtil.isBlank(" bob ") = false
+ * </pre>
+ *
+ * @param cs
+ * @return {@code true} if the CharSequence is null, empty or whitespace
+ */
+ public static boolean isBlank(final CharSequence cs) {
+ int strLen;
+ if (cs == null || (strLen = cs.length()) == 0) {
+ return true;
+ }
+ for (int i = 0; i < strLen; i++) {
+ if (!Character.isWhitespace(cs.charAt(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
}
diff --git a/server-spi/src/main/java/org/keycloak/models/ClientModel.java b/server-spi/src/main/java/org/keycloak/models/ClientModel.java
index ae6453a..43e740a 100755
--- a/server-spi/src/main/java/org/keycloak/models/ClientModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/ClientModel.java
@@ -20,6 +20,8 @@ package org.keycloak.models;
import java.util.Map;
import java.util.Set;
+import org.keycloak.common.util.ObjectUtil;
+
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@@ -209,7 +211,7 @@ public interface ClientModel extends ClientScopeModel, RoleContainerModel, Prot
@Override
default String getConsentScreenText() {
String consentScreenText = ClientScopeModel.super.getConsentScreenText();
- if (consentScreenText == null) {
+ if (ObjectUtil.isBlank(consentScreenText)) {
consentScreenText = getClientId();
}
return consentScreenText;
diff --git a/server-spi/src/main/java/org/keycloak/models/ClientScopeModel.java b/server-spi/src/main/java/org/keycloak/models/ClientScopeModel.java
index c2c4c02..d40d0e0 100755
--- a/server-spi/src/main/java/org/keycloak/models/ClientScopeModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/ClientScopeModel.java
@@ -19,6 +19,8 @@ package org.keycloak.models;
import java.util.Map;
+import org.keycloak.common.util.ObjectUtil;
+
/**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $
@@ -63,7 +65,7 @@ public interface ClientScopeModel extends ProtocolMapperContainerModel, ScopeCon
// Fallback to name if consentScreenText attribute is null
default String getConsentScreenText() {
String consentScreenText = getAttribute(CONSENT_SCREEN_TEXT);
- if (consentScreenText == null) {
+ if (ObjectUtil.isBlank(consentScreenText)) {
consentScreenText = getName();
}
return consentScreenText;
diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCScopeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCScopeTest.java
index 1c1a590..944f304 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCScopeTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCScopeTest.java
@@ -27,6 +27,7 @@ import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.ClientScopeResource;
import org.keycloak.common.util.MultivaluedHashMap;
@@ -35,6 +36,7 @@ import org.keycloak.events.EventType;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
+import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory;
import org.keycloak.representations.AccessToken;
import org.keycloak.representations.AddressClaimSet;
import org.keycloak.representations.IDToken;
@@ -357,7 +359,40 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest {
assertPhone(idToken, false);
// Revert
+ thirdPartyRep.getAttributes().put(ClientScopeModel.DISPLAY_ON_CONSENT_SCREEN, "false");
+ thirdParty.update(thirdPartyRep);
+ }
+
+
+ // KEYCLOAK-7855
+ @Test
+ public void testClientDisplayedOnConsentScreenWithEmptyConsentText() throws Exception {
+ // Add "displayOnConsentScreen" to client
+ ClientResource thirdParty = ApiUtil.findClientByClientId(testRealm(), "third-party");
+ ClientRepresentation thirdPartyRep = thirdParty.toRepresentation();
thirdPartyRep.getAttributes().put(ClientScopeModel.DISPLAY_ON_CONSENT_SCREEN, "true");
+ thirdPartyRep.getAttributes().put(ClientScopeModel.CONSENT_SCREEN_TEXT, "");
+ thirdParty.update(thirdPartyRep);
+
+ // Change consent text on profile scope
+ ClientScopeResource profileScope = ApiUtil.findClientScopeByName(testRealm(), OAuth2Constants.SCOPE_PROFILE);
+ ClientScopeRepresentation profileScopeRep = profileScope.toRepresentation();
+ profileScopeRep.getAttributes().put(ClientScopeModel.CONSENT_SCREEN_TEXT, " ");
+ profileScope.update(profileScopeRep);
+
+ // Login. ConsentTexts are empty for the client and for the "profile" scope, so it should fallback to name/clientId
+ oauth.clientId("third-party");
+ oauth.doLoginGrant("john", "password");
+
+ grantPage.assertCurrent();
+ grantPage.assertGrants("profile", OAuthGrantPage.EMAIL_CONSENT_TEXT, OAuthGrantPage.ROLES_CONSENT_TEXT, "third-party");
+ grantPage.accept();
+
+ // Revert
+ profileScopeRep.getAttributes().put(ClientScopeModel.CONSENT_SCREEN_TEXT, OIDCLoginProtocolFactory.PROFILE_SCOPE_CONSENT_TEXT);
+ profileScope.update(profileScopeRep);
+
+ thirdPartyRep.getAttributes().put(ClientScopeModel.DISPLAY_ON_CONSENT_SCREEN, "false");
thirdParty.update(thirdPartyRep);
}