keycloak-aplcache
Changes
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider.html 4(+3 -1)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-oidc.html 7(+7 -0)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-saml.html 7(+7 -0)
forms/common-themes/src/main/resources/theme/base/admin/resources/partials/realm-identity-provider-social.html 7(+7 -0)
forms/login-freemarker/pom.xml 6(+6 -0)
Details
diff --git a/docbook/reference/en/en-US/modules/identity-broker.xml b/docbook/reference/en/en-US/modules/identity-broker.xml
index 397fd02..4c1a3c2 100755
--- a/docbook/reference/en/en-US/modules/identity-broker.xml
+++ b/docbook/reference/en/en-US/modules/identity-broker.xml
@@ -284,6 +284,15 @@
during the authentication process.
</entry>
</row>
+ <row>
+ <entry>
+ <literal>GUI order</literal>
+ </entry>
+ <entry>
+ Allows you to define order of the provider when shown on login page.
+ You can put number into this field, providers with lower numbers are shown first.
+ </entry>
+ </row>
<!--<row>-->
<!--<entry>-->
<!--<literal>Store Tokens</literal>-->
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 1c0ed54..778bb2c 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
@@ -12,7 +12,7 @@
<caption class="hidden">Table of identity providers</caption>
<thead>
<tr>
- <th colspan="5" class="kc-table-actions">
+ <th colspan="3" class="kc-table-actions">
<div class="pull-right">
<div class="select-kc">
<select ng-model="provider"
@@ -27,6 +27,7 @@
<tr ng-show="configuredProviders.length > 0">
<th>Name</th>
<th>Provider</th>
+ <th width="15%">GUI order</th>
</tr>
</thead>
<tbody ng-show="configuredProviders.length > 0">
@@ -35,6 +36,7 @@
<a href="#/realms/{{realm.realm}}/identity-provider-settings/provider/{{identityProvider.providerId}}/{{identityProvider.alias}}">{{identityProvider.alias}}</a>
</td>
<td>{{identityProvider.providerId}}</td>
+ <td>{{identityProvider.config.guiOrder}}</td>
</tr>
</tbody>
</table>
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 7bf4035..d093744 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
@@ -55,6 +55,13 @@
</div>
<span tooltip-placement="right" tooltip="Indicates if user must update his profile right after the first login." class="fa fa-info-circle"></span>
</div>
+ <div class="form-group">
+ <label class="col-sm-2 control-label" for="guiOrder">GUI order</label>
+ <div class="col-sm-4">
+ <input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder">
+ </div>
+ <span tooltip-placement="right" tooltip="Number defining order of the provider in GUI (eg. on Login page)." class="fa fa-info-circle"></span>
+ </div>
</fieldset>
<fieldset>
<legend uncollapsed><span class="text">OpenID Connect Config</span> <span tooltip-placement="right" tooltip="OIDC SP and external IDP configuration." class="fa fa-info-circle"></span></legend>
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 10327e6..3e151fd 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
@@ -55,6 +55,13 @@
</div>
<span tooltip-placement="right" tooltip="Indicates if user must update his profile right after the first login." class="fa fa-info-circle"></span>
</div>
+ <div class="form-group">
+ <label class="col-sm-2 control-label" for="guiOrder">GUI order</label>
+ <div class="col-sm-4">
+ <input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder">
+ </div>
+ <span tooltip-placement="right" tooltip="Number defining order of the provider in GUI (eg. on Login page)." class="fa fa-info-circle"></span>
+ </div>
</fieldset>
<fieldset>
<legend uncollapsed><span class="text">SAML Config</span> <span tooltip-placement="right" tooltip="SAML SP and external IDP configuration." class="fa fa-info-circle"></span></legend>
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 0a8b56a..809984b 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
@@ -73,6 +73,13 @@
</div>
<span tooltip-placement="right" tooltip="Indicates if this provider should be tried by default for authentication even before displaying login screen" class="fa fa-info-circle"></span>
</div>
+ <div class="form-group">
+ <label class="col-sm-2 control-label" for="guiOrder">GUI order</label>
+ <div class="col-sm-4">
+ <input class="form-control" id="guiOrder" type="text" ng-model="identityProvider.config.guiOrder">
+ </div>
+ <span tooltip-placement="right" tooltip="Number defining order of the provider in GUI (eg. on Login page)." class="fa fa-info-circle"></span>
+ </div>
</fieldset>
<div class="pull-right form-actions">
forms/login-freemarker/pom.xml 6(+6 -0)
diff --git a/forms/login-freemarker/pom.xml b/forms/login-freemarker/pom.xml
index e83bc52..c5b7134 100755
--- a/forms/login-freemarker/pom.xml
+++ b/forms/login-freemarker/pom.xml
@@ -71,6 +71,12 @@
<artifactId>jboss-logging</artifactId>
<scope>provided</scope>
</dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java
index cd11bfd..65e0272 100755
--- a/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java
+++ b/forms/login-freemarker/src/main/java/org/keycloak/login/freemarker/model/IdentityProviderBean.java
@@ -27,11 +27,15 @@ import org.keycloak.services.resources.flows.Urls;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
+import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
/**
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
+ * @author Vlastimil Elias (velias at redhat dot com)
*/
public class IdentityProviderBean {
@@ -45,23 +49,24 @@ public class IdentityProviderBean {
List<IdentityProviderModel> identityProviders = realm.getIdentityProviders();
if (!identityProviders.isEmpty()) {
- providers = new LinkedList<IdentityProvider>();
-
+ Set<IdentityProvider> orderedSet = new TreeSet<>(IdentityProviderComparator.INSTANCE);
for (IdentityProviderModel identityProvider : identityProviders) {
if (identityProvider.isEnabled()) {
- addIdentityProvider(realm, baseURI, identityProvider);
+ addIdentityProvider(orderedSet, realm, baseURI, identityProvider);
}
}
- if (!providers.isEmpty()) {
+ if (!orderedSet.isEmpty()) {
+ providers = new LinkedList<IdentityProvider>(orderedSet);
displaySocial = true;
}
}
}
- private void addIdentityProvider(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();
- providers.add(new IdentityProvider(identityProvider.getAlias(), identityProvider.getProviderId(), loginUrl));
+ orderedSet.add(new IdentityProvider(identityProvider.getAlias(), identityProvider.getProviderId(), loginUrl,
+ identityProvider.getConfig() != null ? identityProvider.getConfig().get("guiOrder") : null));
}
public List<IdentityProvider> getProviders() {
@@ -77,12 +82,13 @@ public class IdentityProviderBean {
private final String alias;
private final String providerId; // This refer to providerType (facebook, google, etc.)
private final String loginUrl;
+ private final String guiOrder;
- public IdentityProvider(String alias, String providerId,String loginUrl) {
+ public IdentityProvider(String alias, String providerId, String loginUrl, String guiOrder) {
this.alias = alias;
this.providerId = providerId;
-
this.loginUrl = loginUrl;
+ this.guiOrder = guiOrder;
}
public String getAlias() {
@@ -96,5 +102,44 @@ public class IdentityProviderBean {
public String getProviderId() {
return providerId;
}
+
+ public String getGuiOrder() {
+ return guiOrder;
+ }
+ }
+
+ public static class IdentityProviderComparator implements Comparator<IdentityProvider> {
+
+ public static IdentityProviderComparator INSTANCE = new IdentityProviderComparator();
+
+ private IdentityProviderComparator() {
+
+ }
+
+ @Override
+ public int compare(IdentityProvider o1, IdentityProvider o2) {
+
+ int o1order = parseOrder(o1);
+ int o2order = parseOrder(o2);
+
+ if (o1order > o2order)
+ return 1;
+ else if (o1order < o2order)
+ return -1;
+
+ return 1;
+ }
+
+ private int parseOrder(IdentityProvider ip) {
+ if (ip != null && ip.getGuiOrder() != null) {
+ try {
+ return Integer.parseInt(ip.getGuiOrder());
+ } catch (NumberFormatException e) {
+ // ignore it and use defaulr
+ }
+ }
+ return 10000;
+ }
+
}
}
diff --git a/forms/login-freemarker/src/test/java/org/keycloak/login/freemarker/model/IdentityProviderBeanTest.java b/forms/login-freemarker/src/test/java/org/keycloak/login/freemarker/model/IdentityProviderBeanTest.java
new file mode 100644
index 0000000..dda3316
--- /dev/null
+++ b/forms/login-freemarker/src/test/java/org/keycloak/login/freemarker/model/IdentityProviderBeanTest.java
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @authors tag. All rights reserved.
+ */
+package org.keycloak.login.freemarker.model;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.keycloak.login.freemarker.model.IdentityProviderBean.IdentityProvider;
+import org.keycloak.login.freemarker.model.IdentityProviderBean.IdentityProviderComparator;
+
+/**
+ * Unit test for {@link IdentityProviderBean}
+ *
+ * @author Vlastimil Elias (velias at redhat dot com)
+ */
+public class IdentityProviderBeanTest {
+
+
+ @Test
+ public void testIdentityProviderComparator() {
+
+ IdentityProvider o1 = new IdentityProvider("alias1", "id1", "ur1", null);
+ IdentityProvider o2 = new IdentityProvider("alias2", "id2", "ur2", null);
+
+ // guiOrder not defined at any object - first is always lower
+ Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
+ Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
+
+ // 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");
+ Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
+ Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
+
+ // guiOrder is defined for one only to it is always first
+ o1 = new IdentityProvider("alias1", "id1", "ur1", "0");
+ Assert.assertEquals(-1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
+ Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
+
+ // guiOrder is defined for both but is same - first is always lower
+ o1 = new IdentityProvider("alias1", "id1", "ur1", "0");
+ o2 = new IdentityProvider("alias2", "id2", "ur2", "0");
+ Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
+ Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
+
+ // guiOrder is reflected
+ o1 = new IdentityProvider("alias1", "id1", "ur1", "0");
+ o2 = new IdentityProvider("alias2", "id2", "ur2", "1");
+ Assert.assertEquals(-1, IdentityProviderComparator.INSTANCE.compare(o1, o2));
+ Assert.assertEquals(1, IdentityProviderComparator.INSTANCE.compare(o2, o1));
+
+ }
+
+}