diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js index 6fa9473bee..6e0c028691 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js +++ b/admin-ui/src/main/resources/META-INF/resources/admin/js/app.js @@ -140,6 +140,39 @@ module.config([ '$routeProvider', function($routeProvider) { }, controller : 'RealmAuditCtrl' }) + .when('/realms/:realm/auth-settings', { + templateUrl : 'partials/realm-auth-list.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + } + }, + controller : 'RealmAuthSettingsCtrl' + }) + .when('/realms/:realm/auth-settings/create', { + templateUrl : 'partials/realm-auth-detail.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + serverInfo : function(ServerInfoLoader) { + return ServerInfoLoader(); + } + }, + controller : 'RealmAuthSettingsDetailCtrl' + }) + .when('/realms/:realm/auth-settings/:index', { + templateUrl : 'partials/realm-auth-detail.html', + resolve : { + realm : function(RealmLoader) { + return RealmLoader(); + }, + serverInfo : function(ServerInfoLoader) { + return ServerInfoLoader(); + } + }, + controller : 'RealmAuthSettingsDetailCtrl' + }) .when('/create/user/:realm', { templateUrl : 'partials/user-detail.html', resolve : { @@ -1018,6 +1051,18 @@ module.filter('remove', function() { module.filter('capitalize', function() { return function(input) { - return input.substring(0, 1).toUpperCase() + input.substring(1); - } + if (!input) { + return; + } + var result = input.substring(0, 1).toUpperCase(); + var s = input.substring(1); + for (var i=0; i +
+ + +
+ +

Add Authentication provider

+ +

{{authProvider.providerName|humanFriendlyFormat}}'s Attributes

+ +
+
+
+ +
+
+
+ +
+
+
+
+ +
+ +
+ +
+
+ +
+ +
+ {{authProvider.providerName|humanFriendlyFormat}}'s provider options +
+ + +
+ +
+
+ +
+ +
+ + +
+ +
+ + + +
+ +
+
+
\ No newline at end of file diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-auth-list.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-auth-list.html new file mode 100644 index 0000000000..d2aebfdf27 --- /dev/null +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-auth-list.html @@ -0,0 +1,41 @@ +
+
+ +
+ +

{{realm.realm}} Authentication Providers

+ +
+ + + + + + + + + + + + + + + + + + + + + +
+ +
Provider NamePassword Update SupportedConfiguration
{{authProvider.providerName|humanFriendlyFormat}}{{authProvider.passwordUpdateSupported}}{{authProvider.config}}
No authentication providers available
+
+
+
\ No newline at end of file diff --git a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html index e2d0a2bf43..5d929c4fe0 100755 --- a/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html +++ b/admin-ui/src/main/resources/META-INF/resources/admin/partials/realm-menu.html @@ -1,7 +1,9 @@ \ No newline at end of file diff --git a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java index 04cda2133e..46449f3d62 100644 --- a/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java +++ b/services/src/main/java/org/keycloak/services/resources/admin/ServerInfoAdminResource.java @@ -3,6 +3,8 @@ package org.keycloak.services.resources.admin; import org.keycloak.freemarker.Theme; import org.keycloak.freemarker.ThemeProvider; import org.keycloak.social.SocialProvider; +import org.keycloak.spi.authentication.AuthenticationProvider; +import org.keycloak.spi.authentication.AuthenticationProviderManager; import org.keycloak.util.ProviderLoader; import javax.ws.rs.GET; @@ -22,6 +24,7 @@ public class ServerInfoAdminResource { ServerInfoRepresentation info = new ServerInfoRepresentation(); setSocialProviders(info); setThemes(info); + setAuthProviders(info); return info; } @@ -46,12 +49,22 @@ public class ServerInfoAdminResource { Collections.sort(info.socialProviders); } + private void setAuthProviders(ServerInfoRepresentation info) { + info.authProviders = new HashMap>(); + Iterable authProviders = AuthenticationProviderManager.load(); + for (AuthenticationProvider authProvider : authProviders) { + info.authProviders.put(authProvider.getName(), authProvider.getAvailableOptions()); + } + } + public static class ServerInfoRepresentation { private Map> themes; private List socialProviders; + private Map> authProviders; + public ServerInfoRepresentation() { } @@ -63,6 +76,9 @@ public class ServerInfoAdminResource { return socialProviders; } + public Map> getAuthProviders() { + return authProviders; + } } } diff --git a/spi/authentication-model/src/main/java/org/keycloak/spi/authentication/model/ExternalModelAuthenticationProvider.java b/spi/authentication-model/src/main/java/org/keycloak/spi/authentication/model/ExternalModelAuthenticationProvider.java index a4d129bdc3..a1dfa107dc 100644 --- a/spi/authentication-model/src/main/java/org/keycloak/spi/authentication/model/ExternalModelAuthenticationProvider.java +++ b/spi/authentication-model/src/main/java/org/keycloak/spi/authentication/model/ExternalModelAuthenticationProvider.java @@ -1,5 +1,7 @@ package org.keycloak.spi.authentication.model; +import java.util.Arrays; +import java.util.List; import java.util.Map; import org.jboss.resteasy.spi.ResteasyProviderFactory; @@ -22,6 +24,11 @@ public class ExternalModelAuthenticationProvider extends AbstractModelAuthentica return AuthProviderConstants.PROVIDER_NAME_EXTERNAL_MODEL; } + @Override + public List getAvailableOptions() { + return Arrays.asList(AuthProviderConstants.EXTERNAL_REALM_ID); + } + @Override public RealmModel getRealm(RealmModel currentRealm, Map configuration) throws AuthenticationProviderException { String realmId = configuration.get(AuthProviderConstants.EXTERNAL_REALM_ID); diff --git a/spi/authentication-model/src/main/java/org/keycloak/spi/authentication/model/ModelAuthenticationProvider.java b/spi/authentication-model/src/main/java/org/keycloak/spi/authentication/model/ModelAuthenticationProvider.java index 29ab43aafe..cd28aba9f2 100644 --- a/spi/authentication-model/src/main/java/org/keycloak/spi/authentication/model/ModelAuthenticationProvider.java +++ b/spi/authentication-model/src/main/java/org/keycloak/spi/authentication/model/ModelAuthenticationProvider.java @@ -1,11 +1,11 @@ package org.keycloak.spi.authentication.model; +import java.util.Collections; +import java.util.List; import java.util.Map; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserModel; import org.keycloak.spi.authentication.AuthProviderConstants; -import org.keycloak.spi.authentication.AuthUser; /** * AbstractModelAuthenticationProvider, which uses current realm to call operations on @@ -19,6 +19,11 @@ public class ModelAuthenticationProvider extends AbstractModelAuthenticationProv return AuthProviderConstants.PROVIDER_NAME_MODEL; } + @Override + public List getAvailableOptions() { + return Collections.EMPTY_LIST; + } + @Override protected RealmModel getRealm(RealmModel currentRealm, Map config) { return currentRealm; diff --git a/spi/authentication-picketlink/src/main/java/org/keycloak/spi/authentication/picketlink/PicketlinkAuthenticationProvider.java b/spi/authentication-picketlink/src/main/java/org/keycloak/spi/authentication/picketlink/PicketlinkAuthenticationProvider.java index ffc1ab6b37..4111806eca 100755 --- a/spi/authentication-picketlink/src/main/java/org/keycloak/spi/authentication/picketlink/PicketlinkAuthenticationProvider.java +++ b/spi/authentication-picketlink/src/main/java/org/keycloak/spi/authentication/picketlink/PicketlinkAuthenticationProvider.java @@ -1,5 +1,7 @@ package org.keycloak.spi.authentication.picketlink; +import java.util.Collections; +import java.util.List; import java.util.Map; import org.jboss.logging.Logger; @@ -34,6 +36,11 @@ public class PicketlinkAuthenticationProvider implements AuthenticationProvider return AuthProviderConstants.PROVIDER_NAME_PICKETLINK; } + @Override + public List getAvailableOptions() { + return Collections.EMPTY_LIST; + } + @Override public AuthUser getUser(RealmModel realm, Map configuration, String username) throws AuthenticationProviderException { IdentityManager identityManager = getIdentityManager(realm); diff --git a/spi/authentication-spi/src/main/java/org/keycloak/spi/authentication/AuthenticationProvider.java b/spi/authentication-spi/src/main/java/org/keycloak/spi/authentication/AuthenticationProvider.java index 014d432ba7..550da90617 100644 --- a/spi/authentication-spi/src/main/java/org/keycloak/spi/authentication/AuthenticationProvider.java +++ b/spi/authentication-spi/src/main/java/org/keycloak/spi/authentication/AuthenticationProvider.java @@ -1,5 +1,6 @@ package org.keycloak.spi.authentication; +import java.util.List; import java.util.Map; import org.keycloak.models.RealmModel; @@ -11,6 +12,13 @@ public interface AuthenticationProvider { String getName(); + /** + * Get names of all available configuration options of current provider + * + * @return options or empty list if no options available + */ + List getAvailableOptions(); + /** * Get user by given username or email. Return user instance or null if user doesn't exists in this authentication provider * diff --git a/spi/authentication-spi/src/main/java/org/keycloak/spi/authentication/AuthenticationProviderManager.java b/spi/authentication-spi/src/main/java/org/keycloak/spi/authentication/AuthenticationProviderManager.java index c6a59a1a8f..3319cff3bc 100644 --- a/spi/authentication-spi/src/main/java/org/keycloak/spi/authentication/AuthenticationProviderManager.java +++ b/spi/authentication-spi/src/main/java/org/keycloak/spi/authentication/AuthenticationProviderManager.java @@ -38,7 +38,7 @@ public class AuthenticationProviderManager { return new AuthenticationProviderManager(realm, providersMap); } - private static Iterable load() { + public static Iterable load() { return ProviderLoader.load(AuthenticationProvider.class); }