[KEYCLOAK-2438] - Add display name to social login buttons
[KEYCLOAK-3291] - Names of social identity providers are wrongly capitalized (eg GitHub vs Github)
This commit is contained in:
parent
af49d184a2
commit
98d2fe15e8
36 changed files with 249 additions and 56 deletions
|
@ -25,6 +25,7 @@ import java.util.Map;
|
||||||
public class IdentityProviderRepresentation {
|
public class IdentityProviderRepresentation {
|
||||||
|
|
||||||
protected String alias;
|
protected String alias;
|
||||||
|
protected String displayName;
|
||||||
protected String internalId;
|
protected String internalId;
|
||||||
protected String providerId;
|
protected String providerId;
|
||||||
protected boolean enabled = true;
|
protected boolean enabled = true;
|
||||||
|
@ -176,4 +177,12 @@ public class IdentityProviderRepresentation {
|
||||||
this.trustEmail = trustEmail;
|
this.trustEmail = trustEmail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,9 @@
|
||||||
package org.keycloak.models.jpa;
|
package org.keycloak.models.jpa;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
|
||||||
import org.keycloak.common.util.StringPropertyReplacer;
|
|
||||||
import org.keycloak.component.ComponentModel;
|
|
||||||
import org.keycloak.common.enums.SslRequired;
|
import org.keycloak.common.enums.SslRequired;
|
||||||
|
import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.jose.jwk.JWKBuilder;
|
import org.keycloak.jose.jwk.JWKBuilder;
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
import org.keycloak.models.AuthenticationFlowModel;
|
import org.keycloak.models.AuthenticationFlowModel;
|
||||||
|
@ -43,12 +42,28 @@ import org.keycloak.models.RoleModel;
|
||||||
import org.keycloak.models.UserFederationMapperModel;
|
import org.keycloak.models.UserFederationMapperModel;
|
||||||
import org.keycloak.models.UserFederationProviderCreationEventImpl;
|
import org.keycloak.models.UserFederationProviderCreationEventImpl;
|
||||||
import org.keycloak.models.UserFederationProviderModel;
|
import org.keycloak.models.UserFederationProviderModel;
|
||||||
import org.keycloak.models.jpa.entities.*;
|
import org.keycloak.models.jpa.entities.AuthenticationExecutionEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.AuthenticationFlowEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.AuthenticatorConfigEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.ClientEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.ClientTemplateEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.ComponentConfigEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.ComponentEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.GroupEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.IdentityProviderEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.IdentityProviderMapperEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.RealmAttributeEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.RealmAttributes;
|
||||||
|
import org.keycloak.models.jpa.entities.RealmEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.RequiredActionProviderEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.RequiredCredentialEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.RoleEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.UserFederationMapperEntity;
|
||||||
|
import org.keycloak.models.jpa.entities.UserFederationProviderEntity;
|
||||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
|
|
||||||
import java.security.Key;
|
import java.security.Key;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
|
@ -1255,9 +1270,10 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
for (IdentityProviderEntity entity: entities) {
|
for (IdentityProviderEntity entity: entities) {
|
||||||
IdentityProviderModel identityProviderModel = new IdentityProviderModel();
|
IdentityProviderModel identityProviderModel = new IdentityProviderModel();
|
||||||
|
|
||||||
identityProviderModel.setProviderId(entity.getProviderId());
|
identityProviderModel.setProviderId(entity.getProviderId());
|
||||||
identityProviderModel.setAlias(entity.getAlias());
|
identityProviderModel.setAlias(entity.getAlias());
|
||||||
|
identityProviderModel.setDisplayName(entity.getDisplayName());
|
||||||
|
|
||||||
identityProviderModel.setInternalId(entity.getInternalId());
|
identityProviderModel.setInternalId(entity.getInternalId());
|
||||||
Map<String, String> config = entity.getConfig();
|
Map<String, String> config = entity.getConfig();
|
||||||
Map<String, String> copy = new HashMap<>();
|
Map<String, String> copy = new HashMap<>();
|
||||||
|
@ -1294,6 +1310,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
|
|
||||||
entity.setInternalId(KeycloakModelUtils.generateId());
|
entity.setInternalId(KeycloakModelUtils.generateId());
|
||||||
entity.setAlias(identityProvider.getAlias());
|
entity.setAlias(identityProvider.getAlias());
|
||||||
|
entity.setDisplayName(identityProvider.getDisplayName());
|
||||||
entity.setProviderId(identityProvider.getProviderId());
|
entity.setProviderId(identityProvider.getProviderId());
|
||||||
entity.setEnabled(identityProvider.isEnabled());
|
entity.setEnabled(identityProvider.isEnabled());
|
||||||
entity.setStoreToken(identityProvider.isStoreToken());
|
entity.setStoreToken(identityProvider.isStoreToken());
|
||||||
|
@ -1327,6 +1344,7 @@ public class RealmAdapter implements RealmModel, JpaModel<RealmEntity> {
|
||||||
for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
|
for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
|
||||||
if (entity.getInternalId().equals(identityProvider.getInternalId())) {
|
if (entity.getInternalId().equals(identityProvider.getInternalId())) {
|
||||||
entity.setAlias(identityProvider.getAlias());
|
entity.setAlias(identityProvider.getAlias());
|
||||||
|
entity.setDisplayName(identityProvider.getDisplayName());
|
||||||
entity.setEnabled(identityProvider.isEnabled());
|
entity.setEnabled(identityProvider.isEnabled());
|
||||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||||
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
||||||
|
|
|
@ -59,6 +59,9 @@ public class IdentityProviderEntity {
|
||||||
@Column(name="PROVIDER_ALIAS")
|
@Column(name="PROVIDER_ALIAS")
|
||||||
private String alias;
|
private String alias;
|
||||||
|
|
||||||
|
@Column(name="PROVIDER_DISPLAY_NAME")
|
||||||
|
private String displayName;
|
||||||
|
|
||||||
@Column(name="ENABLED")
|
@Column(name="ENABLED")
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
|
||||||
|
@ -182,6 +185,14 @@ public class IdentityProviderEntity {
|
||||||
this.trustEmail = trustEmail;
|
this.trustEmail = trustEmail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|
|
@ -24,6 +24,10 @@
|
||||||
<column name="RESOURCE_TYPE" type="VARCHAR(64)"></column>
|
<column name="RESOURCE_TYPE" type="VARCHAR(64)"></column>
|
||||||
</addColumn>
|
</addColumn>
|
||||||
|
|
||||||
|
<addColumn tableName="IDENTITY_PROVIDER">
|
||||||
|
<column name="PROVIDER_DISPLAY_NAME" type="VARCHAR(36)"></column>
|
||||||
|
</addColumn>
|
||||||
|
|
||||||
<createTable tableName="CREDENTIAL_ATTRIBUTE">
|
<createTable tableName="CREDENTIAL_ATTRIBUTE">
|
||||||
<column name="ID" type="VARCHAR(36)">
|
<column name="ID" type="VARCHAR(36)">
|
||||||
<constraints nullable="false"/>
|
<constraints nullable="false"/>
|
||||||
|
|
|
@ -21,7 +21,6 @@ import com.mongodb.DBObject;
|
||||||
import com.mongodb.QueryBuilder;
|
import com.mongodb.QueryBuilder;
|
||||||
|
|
||||||
import org.keycloak.common.util.MultivaluedHashMap;
|
import org.keycloak.common.util.MultivaluedHashMap;
|
||||||
import org.keycloak.common.util.StringPropertyReplacer;
|
|
||||||
import org.keycloak.component.ComponentModel;
|
import org.keycloak.component.ComponentModel;
|
||||||
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
import org.keycloak.connections.mongo.api.context.MongoStoreInvocationContext;
|
||||||
import org.keycloak.common.enums.SslRequired;
|
import org.keycloak.common.enums.SslRequired;
|
||||||
|
@ -914,6 +913,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
|
|
||||||
identityProviderModel.setProviderId(entity.getProviderId());
|
identityProviderModel.setProviderId(entity.getProviderId());
|
||||||
identityProviderModel.setAlias(entity.getAlias());
|
identityProviderModel.setAlias(entity.getAlias());
|
||||||
|
identityProviderModel.setDisplayName(entity.getDisplayName());
|
||||||
identityProviderModel.setInternalId(entity.getInternalId());
|
identityProviderModel.setInternalId(entity.getInternalId());
|
||||||
Map<String, String> config = entity.getConfig();
|
Map<String, String> config = entity.getConfig();
|
||||||
Map<String, String> copy = new HashMap<>();
|
Map<String, String> copy = new HashMap<>();
|
||||||
|
@ -950,6 +950,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
|
|
||||||
entity.setInternalId(KeycloakModelUtils.generateId());
|
entity.setInternalId(KeycloakModelUtils.generateId());
|
||||||
entity.setAlias(identityProvider.getAlias());
|
entity.setAlias(identityProvider.getAlias());
|
||||||
|
entity.setDisplayName(identityProvider.getDisplayName());
|
||||||
entity.setProviderId(identityProvider.getProviderId());
|
entity.setProviderId(identityProvider.getProviderId());
|
||||||
entity.setEnabled(identityProvider.isEnabled());
|
entity.setEnabled(identityProvider.isEnabled());
|
||||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||||
|
@ -980,6 +981,7 @@ public class RealmAdapter extends AbstractMongoAdapter<MongoRealmEntity> impleme
|
||||||
for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
|
for (IdentityProviderEntity entity : this.realm.getIdentityProviders()) {
|
||||||
if (entity.getInternalId().equals(identityProvider.getInternalId())) {
|
if (entity.getInternalId().equals(identityProvider.getInternalId())) {
|
||||||
entity.setAlias(identityProvider.getAlias());
|
entity.setAlias(identityProvider.getAlias());
|
||||||
|
entity.setDisplayName(identityProvider.getDisplayName());
|
||||||
entity.setEnabled(identityProvider.isEnabled());
|
entity.setEnabled(identityProvider.isEnabled());
|
||||||
entity.setTrustEmail(identityProvider.isTrustEmail());
|
entity.setTrustEmail(identityProvider.isTrustEmail());
|
||||||
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
entity.setAuthenticateByDefault(identityProvider.isAuthenticateByDefault());
|
||||||
|
|
|
@ -57,6 +57,8 @@ public class IdentityProviderModel implements Serializable {
|
||||||
|
|
||||||
private String postBrokerLoginFlowId;
|
private String postBrokerLoginFlowId;
|
||||||
|
|
||||||
|
private String displayName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>A map containing the configuration and properties for a specific identity provider instance and implementation. The items
|
* <p>A map containing the configuration and properties for a specific identity provider instance and implementation. The items
|
||||||
* in the map are understood by the identity provider implementation.</p>
|
* in the map are understood by the identity provider implementation.</p>
|
||||||
|
@ -70,6 +72,7 @@ public class IdentityProviderModel implements Serializable {
|
||||||
this.internalId = model.getInternalId();
|
this.internalId = model.getInternalId();
|
||||||
this.providerId = model.getProviderId();
|
this.providerId = model.getProviderId();
|
||||||
this.alias = model.getAlias();
|
this.alias = model.getAlias();
|
||||||
|
this.displayName = model.getDisplayName();
|
||||||
this.config = new HashMap<String, String>(model.getConfig());
|
this.config = new HashMap<String, String>(model.getConfig());
|
||||||
this.enabled = model.isEnabled();
|
this.enabled = model.isEnabled();
|
||||||
this.trustEmail = model.isTrustEmail();
|
this.trustEmail = model.isTrustEmail();
|
||||||
|
@ -170,4 +173,12 @@ public class IdentityProviderModel implements Serializable {
|
||||||
this.trustEmail = trustEmail;
|
this.trustEmail = trustEmail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ public class IdentityProviderEntity {
|
||||||
|
|
||||||
private String internalId;
|
private String internalId;
|
||||||
private String alias;
|
private String alias;
|
||||||
|
private String displayName;
|
||||||
private String providerId;
|
private String providerId;
|
||||||
private String name;
|
private String name;
|
||||||
private boolean enabled;
|
private boolean enabled;
|
||||||
|
@ -134,6 +135,14 @@ public class IdentityProviderEntity {
|
||||||
this.trustEmail = trustEmail;
|
this.trustEmail = trustEmail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
package org.keycloak.models.utils;
|
package org.keycloak.models.utils;
|
||||||
|
|
||||||
import org.bouncycastle.openssl.PEMWriter;
|
import org.bouncycastle.openssl.PEMWriter;
|
||||||
|
import org.keycloak.broker.social.SocialIdentityProvider;
|
||||||
|
import org.keycloak.broker.social.SocialIdentityProviderFactory;
|
||||||
import org.keycloak.common.util.Base64Url;
|
import org.keycloak.common.util.Base64Url;
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
import org.keycloak.models.AuthenticationFlowModel;
|
import org.keycloak.models.AuthenticationFlowModel;
|
||||||
|
@ -47,8 +49,6 @@ import org.keycloak.common.util.PemUtils;
|
||||||
import org.keycloak.transaction.JtaTransactionManagerLookup;
|
import org.keycloak.transaction.JtaTransactionManagerLookup;
|
||||||
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import javax.naming.InitialContext;
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import javax.transaction.InvalidTransactionException;
|
import javax.transaction.InvalidTransactionException;
|
||||||
import javax.transaction.SystemException;
|
import javax.transaction.SystemException;
|
||||||
import javax.transaction.Transaction;
|
import javax.transaction.Transaction;
|
||||||
|
@ -62,7 +62,6 @@ import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -70,7 +69,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of helper methods, which are useful in various model implementations.
|
* Set of helper methods, which are useful in various model implementations.
|
||||||
|
@ -689,4 +687,27 @@ public final class KeycloakModelUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve display name based on identity provider type
|
||||||
|
* @param session
|
||||||
|
* @param displayName
|
||||||
|
* @param providerId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getIdentityProviderDisplayName(KeycloakSession session, String displayName, String providerId) {
|
||||||
|
|
||||||
|
SocialIdentityProviderFactory providerFactory = (SocialIdentityProviderFactory) session.getKeycloakSessionFactory()
|
||||||
|
.getProviderFactory(SocialIdentityProvider.class, providerId);
|
||||||
|
|
||||||
|
if ((displayName == null || displayName.isEmpty()) && (providerId.contains("saml") || providerId.contains("oidc"))) {
|
||||||
|
return providerId;
|
||||||
|
} else if (providerFactory != null && (displayName == null || displayName.isEmpty())) {
|
||||||
|
return providerFactory.getName();
|
||||||
|
} else {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -627,6 +627,7 @@ public class ModelToRepresentation {
|
||||||
providerRep.setInternalId(identityProviderModel.getInternalId());
|
providerRep.setInternalId(identityProviderModel.getInternalId());
|
||||||
providerRep.setProviderId(identityProviderModel.getProviderId());
|
providerRep.setProviderId(identityProviderModel.getProviderId());
|
||||||
providerRep.setAlias(identityProviderModel.getAlias());
|
providerRep.setAlias(identityProviderModel.getAlias());
|
||||||
|
providerRep.setDisplayName(identityProviderModel.getDisplayName());
|
||||||
providerRep.setEnabled(identityProviderModel.isEnabled());
|
providerRep.setEnabled(identityProviderModel.isEnabled());
|
||||||
providerRep.setStoreToken(identityProviderModel.isStoreToken());
|
providerRep.setStoreToken(identityProviderModel.isStoreToken());
|
||||||
providerRep.setTrustEmail(identityProviderModel.isTrustEmail());
|
providerRep.setTrustEmail(identityProviderModel.isTrustEmail());
|
||||||
|
|
|
@ -1524,6 +1524,7 @@ public class RepresentationToModel {
|
||||||
|
|
||||||
identityProviderModel.setInternalId(representation.getInternalId());
|
identityProviderModel.setInternalId(representation.getInternalId());
|
||||||
identityProviderModel.setAlias(representation.getAlias());
|
identityProviderModel.setAlias(representation.getAlias());
|
||||||
|
identityProviderModel.setDisplayName(representation.getDisplayName());
|
||||||
identityProviderModel.setProviderId(representation.getProviderId());
|
identityProviderModel.setProviderId(representation.getProviderId());
|
||||||
identityProviderModel.setEnabled(representation.isEnabled());
|
identityProviderModel.setEnabled(representation.isEnabled());
|
||||||
identityProviderModel.setTrustEmail(representation.isTrustEmail());
|
identityProviderModel.setTrustEmail(representation.isTrustEmail());
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.keycloak.models.IdentityProviderModel;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.models.UserModel;
|
import org.keycloak.models.UserModel;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.services.resources.AccountService;
|
import org.keycloak.services.resources.AccountService;
|
||||||
import org.keycloak.services.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
|
@ -70,7 +71,9 @@ public class AccountFederatedIdentityBean {
|
||||||
.queryParam("stateChecker", stateChecker)
|
.queryParam("stateChecker", stateChecker)
|
||||||
.build().toString();
|
.build().toString();
|
||||||
|
|
||||||
FederatedIdentityEntry entry = new FederatedIdentityEntry(identity, provider.getAlias(), provider.getAlias(), actionUrl,
|
String displayName = KeycloakModelUtils.getIdentityProviderDisplayName(session,
|
||||||
|
provider.getDisplayName(), provider.getProviderId());
|
||||||
|
FederatedIdentityEntry entry = new FederatedIdentityEntry(identity, displayName, provider.getAlias(), provider.getAlias(), actionUrl,
|
||||||
provider.getConfig() != null ? provider.getConfig().get("guiOrder") : null);
|
provider.getConfig() != null ? provider.getConfig().get("guiOrder") : null);
|
||||||
orderedSet.add(entry);
|
orderedSet.add(entry);
|
||||||
}
|
}
|
||||||
|
@ -106,10 +109,12 @@ public class AccountFederatedIdentityBean {
|
||||||
private final String providerName;
|
private final String providerName;
|
||||||
private final String actionUrl;
|
private final String actionUrl;
|
||||||
private final String guiOrder;
|
private final String guiOrder;
|
||||||
|
private final String displayName;
|
||||||
|
|
||||||
public FederatedIdentityEntry(FederatedIdentityModel federatedIdentityModel, String providerId, String providerName, String actionUrl, String guiOrder
|
public FederatedIdentityEntry(FederatedIdentityModel federatedIdentityModel, String displayName, String providerId,
|
||||||
) {
|
String providerName, String actionUrl, String guiOrder) {
|
||||||
this.federatedIdentityModel = federatedIdentityModel;
|
this.federatedIdentityModel = federatedIdentityModel;
|
||||||
|
this.displayName = displayName;
|
||||||
this.providerId = providerId;
|
this.providerId = providerId;
|
||||||
this.providerName = providerName;
|
this.providerName = providerName;
|
||||||
this.actionUrl = actionUrl;
|
this.actionUrl = actionUrl;
|
||||||
|
@ -143,6 +148,11 @@ public class AccountFederatedIdentityBean {
|
||||||
public String getGuiOrder() {
|
public String getGuiOrder() {
|
||||||
return guiOrder;
|
return guiOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class IdentityProviderComparator implements Comparator<FederatedIdentityEntry> {
|
public static class IdentityProviderComparator implements Comparator<FederatedIdentityEntry> {
|
||||||
|
|
|
@ -250,7 +250,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
|
|
||||||
List<IdentityProviderModel> identityProviders = realm.getIdentityProviders();
|
List<IdentityProviderModel> identityProviders = realm.getIdentityProviders();
|
||||||
identityProviders = LoginFormsUtil.filterIdentityProviders(identityProviders, session, realm, attributes, formData);
|
identityProviders = LoginFormsUtil.filterIdentityProviders(identityProviders, session, realm, attributes, formData);
|
||||||
attributes.put("social", new IdentityProviderBean(realm, identityProviders, baseUri, uriInfo));
|
attributes.put("social", new IdentityProviderBean(realm, session, identityProviders, baseUri, uriInfo));
|
||||||
|
|
||||||
attributes.put("url", new UrlBean(realm, theme, baseUri, this.actionUri));
|
attributes.put("url", new UrlBean(realm, theme, baseUri, this.actionUri));
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
|
|
||||||
List<IdentityProviderModel> identityProviders = realm.getIdentityProviders();
|
List<IdentityProviderModel> identityProviders = realm.getIdentityProviders();
|
||||||
identityProviders = LoginFormsUtil.filterIdentityProviders(identityProviders, session, realm, attributes, formData);
|
identityProviders = LoginFormsUtil.filterIdentityProviders(identityProviders, session, realm, attributes, formData);
|
||||||
attributes.put("social", new IdentityProviderBean(realm, identityProviders, baseUri, uriInfo));
|
attributes.put("social", new IdentityProviderBean(realm, session, identityProviders, baseUri, uriInfo));
|
||||||
|
|
||||||
attributes.put("url", new UrlBean(realm, theme, baseUri, this.actionUri));
|
attributes.put("url", new UrlBean(realm, theme, baseUri, this.actionUri));
|
||||||
attributes.put("requiredActionUrl", new RequiredActionUrlFormatterMethod(realm, baseUri));
|
attributes.put("requiredActionUrl", new RequiredActionUrlFormatterMethod(realm, baseUri));
|
||||||
|
@ -425,7 +425,6 @@ public class FreeMarkerLoginFormsProvider implements LoginFormsProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Response createLogin() {
|
public Response createLogin() {
|
||||||
return createResponse(LoginFormsPages.LOGIN);
|
return createResponse(LoginFormsPages.LOGIN);
|
||||||
|
|
|
@ -17,7 +17,9 @@
|
||||||
package org.keycloak.forms.login.freemarker.model;
|
package org.keycloak.forms.login.freemarker.model;
|
||||||
|
|
||||||
import org.keycloak.models.IdentityProviderModel;
|
import org.keycloak.models.IdentityProviderModel;
|
||||||
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
|
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||||
import org.keycloak.services.Urls;
|
import org.keycloak.services.Urls;
|
||||||
|
|
||||||
import javax.ws.rs.core.UriInfo;
|
import javax.ws.rs.core.UriInfo;
|
||||||
|
@ -35,12 +37,13 @@ import java.util.TreeSet;
|
||||||
public class IdentityProviderBean {
|
public class IdentityProviderBean {
|
||||||
|
|
||||||
private boolean displaySocial;
|
private boolean displaySocial;
|
||||||
|
|
||||||
private List<IdentityProvider> providers;
|
private List<IdentityProvider> providers;
|
||||||
private RealmModel realm;
|
private RealmModel realm;
|
||||||
|
private final KeycloakSession session;
|
||||||
|
|
||||||
public IdentityProviderBean(RealmModel realm, List<IdentityProviderModel> identityProviders, URI baseURI, UriInfo uriInfo) {
|
public IdentityProviderBean(RealmModel realm, KeycloakSession session, List<IdentityProviderModel> identityProviders, URI baseURI, UriInfo uriInfo) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
|
this.session = session;
|
||||||
|
|
||||||
if (!identityProviders.isEmpty()) {
|
if (!identityProviders.isEmpty()) {
|
||||||
Set<IdentityProvider> orderedSet = new TreeSet<>(IdentityProviderComparator.INSTANCE);
|
Set<IdentityProvider> orderedSet = new TreeSet<>(IdentityProviderComparator.INSTANCE);
|
||||||
|
@ -59,7 +62,11 @@ public class IdentityProviderBean {
|
||||||
|
|
||||||
private void addIdentityProvider(Set<IdentityProvider> orderedSet, RealmModel realm, URI baseURI, IdentityProviderModel identityProvider) {
|
private void addIdentityProvider(Set<IdentityProvider> orderedSet, RealmModel realm, URI baseURI, IdentityProviderModel identityProvider) {
|
||||||
String loginUrl = Urls.identityProviderAuthnRequest(baseURI, identityProvider.getAlias(), realm.getName()).toString();
|
String loginUrl = Urls.identityProviderAuthnRequest(baseURI, identityProvider.getAlias(), realm.getName()).toString();
|
||||||
orderedSet.add(new IdentityProvider(identityProvider.getAlias(), identityProvider.getProviderId(), loginUrl,
|
String displayName = KeycloakModelUtils.getIdentityProviderDisplayName(session,
|
||||||
|
identityProvider.getDisplayName(), identityProvider.getProviderId());
|
||||||
|
|
||||||
|
orderedSet.add(new IdentityProvider(identityProvider.getAlias(),
|
||||||
|
displayName, identityProvider.getProviderId(), loginUrl,
|
||||||
identityProvider.getConfig() != null ? identityProvider.getConfig().get("guiOrder") : null));
|
identityProvider.getConfig() != null ? identityProvider.getConfig().get("guiOrder") : null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,9 +84,11 @@ public class IdentityProviderBean {
|
||||||
private final String providerId; // This refer to providerType (facebook, google, etc.)
|
private final String providerId; // This refer to providerType (facebook, google, etc.)
|
||||||
private final String loginUrl;
|
private final String loginUrl;
|
||||||
private final String guiOrder;
|
private final String guiOrder;
|
||||||
|
private final String displayName;
|
||||||
|
|
||||||
public IdentityProvider(String alias, String providerId, String loginUrl, String guiOrder) {
|
public IdentityProvider(String alias, String displayName, String providerId, String loginUrl, String guiOrder) {
|
||||||
this.alias = alias;
|
this.alias = alias;
|
||||||
|
this.displayName = displayName;
|
||||||
this.providerId = providerId;
|
this.providerId = providerId;
|
||||||
this.loginUrl = loginUrl;
|
this.loginUrl = loginUrl;
|
||||||
this.guiOrder = guiOrder;
|
this.guiOrder = guiOrder;
|
||||||
|
@ -100,6 +109,10 @@ public class IdentityProviderBean {
|
||||||
public String getGuiOrder() {
|
public String getGuiOrder() {
|
||||||
return guiOrder;
|
return guiOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class IdentityProviderComparator implements Comparator<IdentityProvider> {
|
public static class IdentityProviderComparator implements Comparator<IdentityProvider> {
|
||||||
|
@ -134,6 +147,5 @@ public class IdentityProviderBean {
|
||||||
}
|
}
|
||||||
return 10000;
|
return 10000;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,32 +32,32 @@ public class IdentityProviderBeanTest {
|
||||||
@Test
|
@Test
|
||||||
public void testIdentityProviderComparator() {
|
public void testIdentityProviderComparator() {
|
||||||
|
|
||||||
IdentityProvider o1 = new IdentityProvider("alias1", "id1", "ur1", null);
|
IdentityProvider o1 = new IdentityProvider("alias1", "displayName1", "id1", "ur1", null);
|
||||||
IdentityProvider o2 = new IdentityProvider("alias2", "id2", "ur2", null);
|
IdentityProvider o2 = new IdentityProvider("alias2", "displayName2", "id2", "ur2", null);
|
||||||
|
|
||||||
// guiOrder not defined at any object - first is always lower
|
// guiOrder not defined at any object - first is always lower
|
||||||
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
|
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
|
||||||
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
|
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
|
||||||
|
|
||||||
// guiOrder is not a number so it is same as not defined - first is always lower
|
// guiOrder is not a number so it is same as not defined - first is always lower
|
||||||
o1 = new IdentityProvider("alias1", "id1", "ur1", "not a number");
|
o1 = new IdentityProvider("alias1", "displayName1", "id1", "ur1", "not a number");
|
||||||
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
|
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
|
||||||
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
|
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
|
||||||
|
|
||||||
// guiOrder is defined for one only to it is always first
|
// guiOrder is defined for one only to it is always first
|
||||||
o1 = new IdentityProvider("alias1", "id1", "ur1", "0");
|
o1 = new IdentityProvider("alias1", "displayName1", "id1", "ur1", "0");
|
||||||
Assert.assertEquals(-1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
|
Assert.assertEquals(-1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
|
||||||
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
|
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
|
||||||
|
|
||||||
// guiOrder is defined for both but is same - first is always lower
|
// guiOrder is defined for both but is same - first is always lower
|
||||||
o1 = new IdentityProvider("alias1", "id1", "ur1", "0");
|
o1 = new IdentityProvider("alias1", "displayName1", "id1", "ur1", "0");
|
||||||
o2 = new IdentityProvider("alias2", "id2", "ur2", "0");
|
o2 = new IdentityProvider("alias2", "displayName2", "id2", "ur2", "0");
|
||||||
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
|
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
|
||||||
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
|
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
|
||||||
|
|
||||||
// guiOrder is reflected
|
// guiOrder is reflected
|
||||||
o1 = new IdentityProvider("alias1", "id1", "ur1", "0");
|
o1 = new IdentityProvider("alias1", "displayName1", "id1", "ur1", "0");
|
||||||
o2 = new IdentityProvider("alias2", "id2", "ur2", "1");
|
o2 = new IdentityProvider("alias2", "displayName2", "id2", "ur2", "1");
|
||||||
Assert.assertEquals(-1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
|
Assert.assertEquals(-1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
|
||||||
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
|
Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||||
import org.keycloak.testsuite.pages.ErrorPage;
|
import org.keycloak.testsuite.pages.ErrorPage;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
import org.keycloak.testsuite.pages.RegisterPage;
|
import org.keycloak.testsuite.pages.RegisterPage;
|
||||||
|
import org.keycloak.testsuite.util.IdentityProviderBuilder;
|
||||||
import org.openqa.selenium.By;
|
import org.openqa.selenium.By;
|
||||||
import org.openqa.selenium.WebDriver;
|
import org.openqa.selenium.WebDriver;
|
||||||
|
|
||||||
|
@ -75,6 +76,20 @@ public class AccountTest extends TestRealmKeycloakTest {
|
||||||
.password("password")
|
.password("password")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
testRealm.addIdentityProvider(IdentityProviderBuilder.create()
|
||||||
|
.providerId("github")
|
||||||
|
.alias("github")
|
||||||
|
.build());
|
||||||
|
testRealm.addIdentityProvider(IdentityProviderBuilder.create()
|
||||||
|
.providerId("saml")
|
||||||
|
.alias("saml")
|
||||||
|
.build());
|
||||||
|
testRealm.addIdentityProvider(IdentityProviderBuilder.create()
|
||||||
|
.providerId("oidc")
|
||||||
|
.alias("oidc")
|
||||||
|
.displayName("MyOIDC")
|
||||||
|
.build());
|
||||||
|
|
||||||
RealmBuilder.edit(testRealm)
|
RealmBuilder.edit(testRealm)
|
||||||
.user(user2);
|
.user(user2);
|
||||||
}
|
}
|
||||||
|
@ -790,4 +805,13 @@ public class AccountTest extends TestRealmKeycloakTest {
|
||||||
events.clear();
|
events.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIdentityProviderCapitalization(){
|
||||||
|
loginPage.open();
|
||||||
|
Assert.assertEquals("GitHub", loginPage.findSocialButton("github").getText());
|
||||||
|
Assert.assertEquals("saml", loginPage.findSocialButton("saml").getText());
|
||||||
|
Assert.assertEquals("MyOIDC", loginPage.findSocialButton("oidc").getText());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,9 +20,6 @@ package org.keycloak.testsuite.admin;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -31,16 +28,12 @@ import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.keycloak.admin.client.resource.RealmResource;
|
import org.keycloak.admin.client.resource.RealmResource;
|
||||||
import org.keycloak.events.log.JBossLoggingEventListenerProviderFactory;
|
import org.keycloak.events.log.JBossLoggingEventListenerProviderFactory;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
|
||||||
import org.keycloak.representations.idm.IdentityProviderRepresentation;
|
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.testsuite.TestRealmKeycloakTest;
|
import org.keycloak.testsuite.TestRealmKeycloakTest;
|
||||||
import org.keycloak.testsuite.events.EventsListenerProviderFactory;
|
import org.keycloak.testsuite.events.EventsListenerProviderFactory;
|
||||||
import org.keycloak.testsuite.util.AssertAdminEvents;
|
import org.keycloak.testsuite.util.AssertAdminEvents;
|
||||||
import org.keycloak.util.JsonSerialization;
|
import org.keycloak.util.JsonSerialization;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class adapts the functionality from the old testsuite to make tests
|
* This class adapts the functionality from the old testsuite to make tests
|
||||||
* easier to port.
|
* easier to port.
|
||||||
|
|
|
@ -205,6 +205,7 @@ public class ConsentsTest extends AbstractKeycloakTest {
|
||||||
IdentityProviderRepresentation identityProviderRepresentation = new IdentityProviderRepresentation();
|
IdentityProviderRepresentation identityProviderRepresentation = new IdentityProviderRepresentation();
|
||||||
|
|
||||||
identityProviderRepresentation.setAlias(alias);
|
identityProviderRepresentation.setAlias(alias);
|
||||||
|
identityProviderRepresentation.setDisplayName(providerId);
|
||||||
identityProviderRepresentation.setProviderId(providerId);
|
identityProviderRepresentation.setProviderId(providerId);
|
||||||
identityProviderRepresentation.setEnabled(true);
|
identityProviderRepresentation.setEnabled(true);
|
||||||
|
|
||||||
|
|
|
@ -177,6 +177,7 @@ public class IdentityProviderTest extends AbstractAdminTest {
|
||||||
IdentityProviderRepresentation idp = new IdentityProviderRepresentation();
|
IdentityProviderRepresentation idp = new IdentityProviderRepresentation();
|
||||||
|
|
||||||
idp.setAlias(id);
|
idp.setAlias(id);
|
||||||
|
idp.setDisplayName(id);
|
||||||
idp.setProviderId(providerId);
|
idp.setProviderId(providerId);
|
||||||
idp.setEnabled(true);
|
idp.setEnabled(true);
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
|
|
|
@ -1440,7 +1440,8 @@ public class PermissionsTest extends AbstractKeycloakTest {
|
||||||
}, Resource.IDENTITY_PROVIDER, false);
|
}, Resource.IDENTITY_PROVIDER, false);
|
||||||
invoke(new InvocationWithResponse() {
|
invoke(new InvocationWithResponse() {
|
||||||
public void invoke(RealmResource realm, AtomicReference<Response> response) {
|
public void invoke(RealmResource realm, AtomicReference<Response> response) {
|
||||||
response.set(realm.identityProviders().create(IdentityProviderBuilder.create().providerId("nosuch").alias("foo").build()));
|
response.set(realm.identityProviders().create(IdentityProviderBuilder.create().providerId("nosuch")
|
||||||
|
.displayName("nosuch-foo").alias("foo").build()));
|
||||||
}
|
}
|
||||||
}, Resource.IDENTITY_PROVIDER, true);
|
}, Resource.IDENTITY_PROVIDER, true);
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,7 @@ public abstract class AbstractBrokerTest extends AbstractKeycloakTest {
|
||||||
IdentityProviderRepresentation identityProviderRepresentation = new IdentityProviderRepresentation();
|
IdentityProviderRepresentation identityProviderRepresentation = new IdentityProviderRepresentation();
|
||||||
|
|
||||||
identityProviderRepresentation.setAlias(alias);
|
identityProviderRepresentation.setAlias(alias);
|
||||||
|
identityProviderRepresentation.setDisplayName(providerId);
|
||||||
identityProviderRepresentation.setProviderId(providerId);
|
identityProviderRepresentation.setProviderId(providerId);
|
||||||
identityProviderRepresentation.setEnabled(true);
|
identityProviderRepresentation.setEnabled(true);
|
||||||
|
|
||||||
|
|
|
@ -23,10 +23,12 @@ import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.keycloak.adapters.HttpClientBuilder;
|
import org.keycloak.adapters.HttpClientBuilder;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
|
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
import org.jboss.arquillian.graphene.page.Page;
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.keycloak.testsuite.util.IdentityProviderBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
|
* @author <a href="mailto:gerbermichi@me.com">Michael Gerber</a>
|
||||||
|
@ -37,6 +39,24 @@ public class LoginPageTest extends AbstractI18NTest {
|
||||||
@Page
|
@Page
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureTestRealm(RealmRepresentation testRealm) {
|
||||||
|
testRealm.addIdentityProvider(IdentityProviderBuilder.create()
|
||||||
|
.providerId("github")
|
||||||
|
.alias("github")
|
||||||
|
.build());
|
||||||
|
testRealm.addIdentityProvider(IdentityProviderBuilder.create()
|
||||||
|
.providerId("saml")
|
||||||
|
.alias("saml")
|
||||||
|
.build());
|
||||||
|
testRealm.addIdentityProvider(IdentityProviderBuilder.create()
|
||||||
|
.providerId("oidc")
|
||||||
|
.alias("oidc")
|
||||||
|
.displayName("MyOIDC")
|
||||||
|
.build());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void languageDropdown() {
|
public void languageDropdown() {
|
||||||
loginPage.open();
|
loginPage.open();
|
||||||
|
@ -87,4 +107,13 @@ public class LoginPageTest extends AbstractI18NTest {
|
||||||
response = client.target(driver.getCurrentUrl()).request().acceptLanguage("en").get();
|
response = client.target(driver.getCurrentUrl()).request().acceptLanguage("en").get();
|
||||||
Assert.assertTrue(response.readEntity(String.class).contains("Log in to test"));
|
Assert.assertTrue(response.readEntity(String.class).contains("Log in to test"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIdentityProviderCapitalization(){
|
||||||
|
loginPage.open();
|
||||||
|
Assert.assertEquals("GitHub", loginPage.findSocialButton("github").getText());
|
||||||
|
Assert.assertEquals("saml", loginPage.findSocialButton("saml").getText());
|
||||||
|
Assert.assertEquals("MyOIDC", loginPage.findSocialButton("oidc").getText());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,11 @@ public class IdentityProviderBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IdentityProviderBuilder displayName(String displayName) {
|
||||||
|
rep.setDisplayName(displayName);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public IdentityProviderRepresentation build() {
|
public IdentityProviderRepresentation build() {
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,6 +94,7 @@
|
||||||
{
|
{
|
||||||
"alias" : "model-saml-signed-idp",
|
"alias" : "model-saml-signed-idp",
|
||||||
"providerId" : "saml",
|
"providerId" : "saml",
|
||||||
|
"displayName": "My SAML",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"config": {
|
"config": {
|
||||||
"singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-identity-provider/protocol/saml",
|
"singleSignOnServiceUrl": "http://localhost:8082/auth/realms/realm-with-saml-identity-provider/protocol/saml",
|
||||||
|
@ -157,6 +158,7 @@
|
||||||
{
|
{
|
||||||
"alias" : "model-oidc-idp",
|
"alias" : "model-oidc-idp",
|
||||||
"providerId" : "oidc",
|
"providerId" : "oidc",
|
||||||
|
"displayName": "My OIDC",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
"authenticateByDefault" : "false",
|
"authenticateByDefault" : "false",
|
||||||
"config": {
|
"config": {
|
||||||
|
@ -172,6 +174,7 @@
|
||||||
{
|
{
|
||||||
"alias" : "kc-oidc-idp",
|
"alias" : "kc-oidc-idp",
|
||||||
"providerId" : "keycloak-oidc",
|
"providerId" : "keycloak-oidc",
|
||||||
|
"displayName": "My Keycloak OIDC",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"storeToken" : true,
|
"storeToken" : true,
|
||||||
"addReadTokenRoleOnCreate": true,
|
"addReadTokenRoleOnCreate": true,
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<#list federatedIdentity.identities as identity>
|
<#list federatedIdentity.identities as identity>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-sm-2 col-md-2">
|
<div class="col-sm-2 col-md-2">
|
||||||
<label for="${identity.providerId!}" class="control-label">${identity.providerName!}</label>
|
<label for="${identity.providerId!}" class="control-label">${identity.displayName!}</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-5 col-md-5">
|
<div class="col-sm-5 col-md-5">
|
||||||
<input disabled="true" class="form-control" value="${identity.userName!}">
|
<input disabled="true" class="form-control" value="${identity.userName!}">
|
||||||
|
|
|
@ -418,7 +418,9 @@ post-broker-login-flow=Post Login Flow
|
||||||
redirect-uri=Redirect URI
|
redirect-uri=Redirect URI
|
||||||
redirect-uri.tooltip=The redirect uri to use when configuring the identity provider.
|
redirect-uri.tooltip=The redirect uri to use when configuring the identity provider.
|
||||||
alias=Alias
|
alias=Alias
|
||||||
|
display-name=Display Name
|
||||||
identity-provider.alias.tooltip=The alias uniquely identifies an identity provider and it is also used to build the redirect uri.
|
identity-provider.alias.tooltip=The alias uniquely identifies an identity provider and it is also used to build the redirect uri.
|
||||||
|
identity-provider.display-name.tooltip=Friendly name for Identity Providers.
|
||||||
identity-provider.enabled.tooltip=Enable/disable this identity provider.
|
identity-provider.enabled.tooltip=Enable/disable this identity provider.
|
||||||
authenticate-by-default=Authenticate by Default
|
authenticate-by-default=Authenticate by Default
|
||||||
identity-provider.authenticate-by-default.tooltip=Indicates if this provider should be tried by default for authentication even before displaying login screen.
|
identity-provider.authenticate-by-default.tooltip=Indicates if this provider should be tried by default for authentication even before displaying login screen.
|
||||||
|
|
16
themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
Executable file → Normal file
16
themes/src/main/resources/theme/base/admin/resources/js/controllers/realm.js
Executable file → Normal file
|
@ -689,6 +689,14 @@ module.controller('RealmDefaultRolesCtrl', function ($scope, Realm, realm, clien
|
||||||
|
|
||||||
|
|
||||||
module.controller('IdentityProviderTabCtrl', function(Dialog, $scope, Current, Notifications, $location) {
|
module.controller('IdentityProviderTabCtrl', function(Dialog, $scope, Current, Notifications, $location) {
|
||||||
|
for (var i in $scope.allProviders) {
|
||||||
|
var provider = $scope.allProviders[i];
|
||||||
|
if (provider.groupName == 'Social' && (provider.id == $scope.identityProvider.alias)) {
|
||||||
|
$scope.identityProvider.displayName = provider.name;
|
||||||
|
} else if (!$scope.identityProvider.displayName) {
|
||||||
|
$scope.identityProvider.displayName = provider.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
$scope.removeIdentityProvider = function() {
|
$scope.removeIdentityProvider = function() {
|
||||||
Dialog.confirmDelete($scope.identityProvider.alias, 'provider', function() {
|
Dialog.confirmDelete($scope.identityProvider.alias, 'provider', function() {
|
||||||
$scope.identityProvider.$remove({
|
$scope.identityProvider.$remove({
|
||||||
|
@ -773,6 +781,8 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
|
||||||
$scope.identityProvider.config = {};
|
$scope.identityProvider.config = {};
|
||||||
$scope.identityProvider.alias = providerFactory.id;
|
$scope.identityProvider.alias = providerFactory.id;
|
||||||
$scope.identityProvider.providerId = providerFactory.id;
|
$scope.identityProvider.providerId = providerFactory.id;
|
||||||
|
$scope.identityProvider.displayName = providerFactory.displayName;
|
||||||
|
|
||||||
$scope.identityProvider.enabled = true;
|
$scope.identityProvider.enabled = true;
|
||||||
$scope.identityProvider.authenticateByDefault = false;
|
$scope.identityProvider.authenticateByDefault = false;
|
||||||
$scope.identityProvider.firstBrokerLoginFlowAlias = 'first broker login';
|
$scope.identityProvider.firstBrokerLoginFlowAlias = 'first broker login';
|
||||||
|
@ -836,7 +846,6 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$scope.uploadFile = function() {
|
$scope.uploadFile = function() {
|
||||||
if (!$scope.identityProvider.alias) {
|
if (!$scope.identityProvider.alias) {
|
||||||
Notifications.error("You must specify an alias");
|
Notifications.error("You must specify an alias");
|
||||||
|
@ -909,10 +918,15 @@ module.controller('RealmIdentityProviderCtrl', function($scope, $filter, $upload
|
||||||
|
|
||||||
if (provider.groupName == 'Social' && (provider.id == configProvidedId)) {
|
if (provider.groupName == 'Social' && (provider.id == configProvidedId)) {
|
||||||
$scope.allProviders.splice(i, 1);
|
$scope.allProviders.splice(i, 1);
|
||||||
|
configuredProviders[j].displayName = provider.name;
|
||||||
|
break;
|
||||||
|
} else if (!configuredProviders[j].displayName) {
|
||||||
|
configuredProviders[j].displayName = configProvidedId;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$scope.configuredProviders = angular.copy(configuredProviders);
|
||||||
}
|
}
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
||||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.alias}}</a></li>
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.displayName}}</a></li>
|
||||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-mappers/{{identityProvider.alias}}/mappers">{{:: 'identity-provider-mappers' | translate}}</a></li>
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-mappers/{{identityProvider.alias}}/mappers">{{:: 'identity-provider-mappers' | translate}}</a></li>
|
||||||
<li class="active" data-ng-show="create">{{:: 'create-identity-provider-mapper' | translate}}</li>
|
<li class="active" data-ng-show="create">{{:: 'create-identity-provider-mapper' | translate}}</li>
|
||||||
<li class="active" data-ng-hide="create">{{mapper.name|capitalize}}</li>
|
<li class="active" data-ng-hide="create">{{mapper.name|capitalize}}</li>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
||||||
<li>{{identityProvider.alias}}</li>
|
<li>{{identityProvider.displayName}}</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<kc-tabs-identity-provider></kc-tabs-identity-provider>
|
<kc-tabs-identity-provider></kc-tabs-identity-provider>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" data-ng-init="initProvider()">
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" data-ng-init="initProvider()">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
||||||
<li>{{identityProvider.alias}}</li>
|
<li>{{identityProvider.displayName}}</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<kc-tabs-identity-provider></kc-tabs-identity-provider>
|
<kc-tabs-identity-provider></kc-tabs-identity-provider>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
||||||
<li>{{identityProvider.alias}}</li>
|
<li>{{identityProvider.displayName}}</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<kc-tabs-identity-provider></kc-tabs-identity-provider>
|
<kc-tabs-identity-provider></kc-tabs-identity-provider>
|
||||||
|
@ -27,6 +27,13 @@
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'identity-provider.alias.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'identity-provider.alias.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group clearfix">
|
||||||
|
<label class="col-md-2 control-label" for="displayName"> {{:: 'display-name' | translate}}</label>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input class="form-control" id="displayName" type="text" ng-model="identityProvider.displayName">
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'identity-provider.display-name.tooltip' | translate}}</kc-tooltip>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label>
|
<label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" data-ng-init="initSamlProvider()">
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2" data-ng-init="initSamlProvider()">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
||||||
<li>{{identityProvider.alias}}</li>
|
<li>{{identityProvider.displayName}}</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<kc-tabs-identity-provider></kc-tabs-identity-provider>
|
<kc-tabs-identity-provider></kc-tabs-identity-provider>
|
||||||
|
@ -24,6 +24,13 @@
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'identity-provider.alias.tooltip' | translate}}</kc-tooltip>
|
<kc-tooltip>{{:: 'identity-provider.alias.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group clearfix">
|
||||||
|
<label class="col-md-2 control-label" for="displayName"> {{:: 'display-name' | translate}}</label>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<input class="form-control" id="displayName" type="text" ng-model="identityProvider.displayName">
|
||||||
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'identity-provider.display-name.tooltip' | translate}}</kc-tooltip>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label>
|
<label class="col-md-2 control-label" for="enabled">{{:: 'enabled' | translate}}</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
<div class="col-sm-9 col-md-10 col-sm-push-3 col-md-push-2">
|
||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
<li><a href="#/realms/{{realm.realm}}/identity-provider-settings">{{:: 'identity-providers' | translate}}</a></li>
|
||||||
<li>{{identityProvider.alias}}</li>
|
<li>{{identityProvider.displayName}}</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<kc-tabs-identity-provider></kc-tabs-identity-provider>
|
<kc-tabs-identity-provider></kc-tabs-identity-provider>
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="identityProvider in configuredProviders">
|
<tr ng-repeat="identityProvider in configuredProviders">
|
||||||
<td>
|
<td>
|
||||||
<a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.alias}}</a>
|
<a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.displayName}}</a>
|
||||||
</td>
|
</td>
|
||||||
<td>{{identityProvider.providerId}}</td>
|
<td>{{identityProvider.providerId}}</td>
|
||||||
<td translate="{{identityProvider.enabled}}"></td>
|
<td translate="{{identityProvider.enabled}}"></td>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div data-ng-controller="IdentityProviderTabCtrl">
|
<div data-ng-controller="IdentityProviderTabCtrl">
|
||||||
<h1 data-ng-hide="path[0] == 'create'">
|
<h1 data-ng-hide="path[0] == 'create'">
|
||||||
{{identityProvider.alias|capitalize}}
|
{{identityProvider.displayName}}
|
||||||
<i class="pficon pficon-delete clickable" data-ng-hide="newIdentityProvider || changed" data-ng-click="removeIdentityProvider()"></i>
|
<i class="pficon pficon-delete clickable" data-ng-hide="newIdentityProvider || changed" data-ng-click="removeIdentityProvider()"></i>
|
||||||
</h1>
|
</h1>
|
||||||
<h1 data-ng-show="path[0] == 'create'">{{:: 'add-identity-provider' | translate}}</h1>
|
<h1 data-ng-show="path[0] == 'create'">{{:: 'add-identity-provider' | translate}}</h1>
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
<div id="kc-social-providers">
|
<div id="kc-social-providers">
|
||||||
<ul>
|
<ul>
|
||||||
<#list social.providers as p>
|
<#list social.providers as p>
|
||||||
<li><a href="${p.loginUrl}" id="zocial-${p.alias}" class="zocial ${p.providerId}"> <span class="text">${p.alias}</span></a></li>
|
<li><a href="${p.loginUrl}" id="zocial-${p.alias}" class="zocial ${p.providerId}"> <span class="text">${p.displayName}</span></a></li>
|
||||||
</#list>
|
</#list>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -229,9 +229,6 @@ ol#kc-totp-settings li:first-of-type {
|
||||||
.zocial.google {
|
.zocial.google {
|
||||||
background-color: #dd4b39 !important;
|
background-color: #dd4b39 !important;
|
||||||
}
|
}
|
||||||
.zocial.google .text:after {
|
|
||||||
content: "+";
|
|
||||||
}
|
|
||||||
|
|
||||||
.zocial.facebook:hover,
|
.zocial.facebook:hover,
|
||||||
.zocial.github:hover,
|
.zocial.github:hover,
|
||||||
|
|
Loading…
Reference in a new issue