installation provider
This commit is contained in:
parent
1cbe5c4c80
commit
64de96d34b
16 changed files with 461 additions and 18 deletions
|
@ -0,0 +1,71 @@
|
|||
package org.keycloak.representations.info;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class ClientInstallationRepresentation {
|
||||
protected String id;
|
||||
protected String protocol;
|
||||
protected boolean downloadOnly;
|
||||
protected String displayType;
|
||||
protected String helpText;
|
||||
protected String filename;
|
||||
protected String mediaType;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public void setProtocol(String protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public boolean isDownloadOnly() {
|
||||
return downloadOnly;
|
||||
}
|
||||
|
||||
public void setDownloadOnly(boolean downloadOnly) {
|
||||
this.downloadOnly = downloadOnly;
|
||||
}
|
||||
|
||||
public String getDisplayType() {
|
||||
return displayType;
|
||||
}
|
||||
|
||||
public void setDisplayType(String displayType) {
|
||||
this.displayType = displayType;
|
||||
}
|
||||
|
||||
public String getHelpText() {
|
||||
return helpText;
|
||||
}
|
||||
|
||||
public void setHelpText(String helpText) {
|
||||
this.helpText = helpText;
|
||||
}
|
||||
|
||||
public String getFilename() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
public void setFilename(String filename) {
|
||||
this.filename = filename;
|
||||
}
|
||||
|
||||
public String getMediaType() {
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
public void setMediaType(String mediaType) {
|
||||
this.mediaType = mediaType;
|
||||
}
|
||||
}
|
9
core/src/main/java/org/keycloak/representations/info/ServerInfoRepresentation.java
Normal file → Executable file
9
core/src/main/java/org/keycloak/representations/info/ServerInfoRepresentation.java
Normal file → Executable file
|
@ -24,6 +24,7 @@ public class ServerInfoRepresentation {
|
|||
|
||||
private Map<String, List<ProtocolMapperTypeRepresentation>> protocolMapperTypes;
|
||||
private Map<String, List<ProtocolMapperRepresentation>> builtinProtocolMappers;
|
||||
private Map<String, List<ClientInstallationRepresentation>> clientInstallations;
|
||||
|
||||
private Map<String, List<String>> enums;
|
||||
|
||||
|
@ -105,4 +106,12 @@ public class ServerInfoRepresentation {
|
|||
public void setEnums(Map<String, List<String>> enums) {
|
||||
this.enums = enums;
|
||||
}
|
||||
|
||||
public Map<String, List<ClientInstallationRepresentation>> getClientInstallations() {
|
||||
return clientInstallations;
|
||||
}
|
||||
|
||||
public void setClientInstallations(Map<String, List<ClientInstallationRepresentation>> clientInstallations) {
|
||||
this.clientInstallations = clientInstallations;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1109,6 +1109,9 @@ module.config([ '$routeProvider', function($routeProvider) {
|
|||
},
|
||||
client : function(ClientLoader) {
|
||||
return ClientLoader();
|
||||
},
|
||||
serverInfo : function(ServerInfoLoader) {
|
||||
return ServerInfoLoader();
|
||||
}
|
||||
},
|
||||
controller : 'ClientInstallationCtrl'
|
||||
|
|
|
@ -685,7 +685,7 @@ module.controller('ClientListCtrl', function($scope, realm, clients, Client, ser
|
|||
};
|
||||
});
|
||||
|
||||
module.controller('ClientInstallationCtrl', function($scope, realm, client, ClientInstallation,ClientInstallationJBoss, $http, $routeParams) {
|
||||
module.controller('ClientInstallationCtrl', function($scope, realm, client, serverInfo, ClientInstallation,$http, $routeParams) {
|
||||
$scope.realm = realm;
|
||||
$scope.client = client;
|
||||
$scope.installation = null;
|
||||
|
@ -693,11 +693,25 @@ module.controller('ClientInstallationCtrl', function($scope, realm, client, Clie
|
|||
$scope.configFormat = null;
|
||||
$scope.filename = null;
|
||||
|
||||
$scope.configFormats = [
|
||||
"Keycloak JSON",
|
||||
"Wildfly/EAP Subsystem XML"
|
||||
];
|
||||
var protocol = client.protocol;
|
||||
if (!protocol) protocol = 'openid-connect';
|
||||
$scope.configFormats = serverInfo.clientInstallations[protocol];
|
||||
console.log('configFormats.length: ' + $scope.configFormats.length);
|
||||
|
||||
$scope.changeFormat = function() {
|
||||
var url = ClientInstallation.url({ realm: $routeParams.realm, client: $routeParams.client, provider: $scope.configFormat.id });
|
||||
$http.get(url).success(function(data) {
|
||||
var installation = data;
|
||||
if ($scope.configFormat.mediaType == 'application/json') {
|
||||
installation = angular.fromJson(data);
|
||||
installation = angular.toJson(installation, true);
|
||||
}
|
||||
$scope.installation = installation;
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
$scope.changeFormat = function() {
|
||||
if ($scope.configFormat == "Keycloak JSON") {
|
||||
$scope.filename = 'keycloak.json';
|
||||
|
@ -720,9 +734,10 @@ module.controller('ClientInstallationCtrl', function($scope, realm, client, Clie
|
|||
|
||||
console.debug($scope.filename);
|
||||
};
|
||||
*/
|
||||
|
||||
$scope.download = function() {
|
||||
saveAs(new Blob([$scope.installation], { type: $scope.type }), $scope.filename);
|
||||
saveAs(new Blob([$scope.installation], { type: $scope.configFormat.mediaType }), $scope.configFormat.filename);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -284,15 +284,6 @@ module.factory('ClientClaimsLoader', function(Loader, ClientClaims, $route, $q)
|
|||
});
|
||||
});
|
||||
|
||||
module.factory('ClientInstallationLoader', function(Loader, ClientInstallation, $route, $q) {
|
||||
return Loader.get(ClientInstallation, function() {
|
||||
return {
|
||||
realm : $route.current.params.realm,
|
||||
client : $route.current.params.client
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
module.factory('ClientRoleListLoader', function(Loader, ClientRole, $route, $q) {
|
||||
return Loader.query(ClientRole, function() {
|
||||
return {
|
||||
|
|
|
@ -1044,16 +1044,28 @@ module.factory('ClientDescriptionConverter', function($resource) {
|
|||
});
|
||||
});
|
||||
|
||||
/*
|
||||
module.factory('ClientInstallation', function($resource) {
|
||||
return $resource(authUrl + '/admin/realms/:realm/clients/:client/installation/providers/:provider', {
|
||||
realm : '@realm',
|
||||
client : '@client',
|
||||
provider : '@provider'
|
||||
});
|
||||
});
|
||||
*/
|
||||
|
||||
|
||||
|
||||
module.factory('ClientInstallation', function($resource) {
|
||||
var url = authUrl + '/admin/realms/:realm/clients/:client/installation/json';
|
||||
var url = authUrl + '/admin/realms/:realm/clients/:client/installation/providers/:provider';
|
||||
return {
|
||||
url : function(parameters)
|
||||
{
|
||||
return url.replace(':realm', parameters.realm).replace(':client', parameters.client);
|
||||
return url.replace(':realm', parameters.realm).replace(':client', parameters.client).replace(':provider', parameters.provider);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
module.factory('ClientInstallationJBoss', function($resource) {
|
||||
var url = authUrl + '/admin/realms/:realm/clients/:client/installation/jboss';
|
||||
return {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<div class="col-md-6">
|
||||
<div class="input-group">
|
||||
<div>
|
||||
<select class="form-control" id="configFormats" name="configFormats" ng-change="changeFormat()" ng-model="configFormat" ng-options="a for a in configFormats">
|
||||
<select class="form-control" id="configFormats" name="configFormats" ng-change="changeFormat()" ng-model="configFormat" ng-options="a.displayType for a in configFormats">
|
||||
<option value="" selected> {{:: 'select-a-format' | translate}} </option>
|
||||
</select>
|
||||
</div>
|
||||
|
|
27
services/src/main/java/org/keycloak/protocol/ClientInstallationProvider.java
Executable file
27
services/src/main/java/org/keycloak/protocol/ClientInstallationProvider.java
Executable file
|
@ -0,0 +1,27 @@
|
|||
package org.keycloak.protocol;
|
||||
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Provides a template/sample client config adapter file. For example keycloak.json for our OIDC adapter. keycloak-saml.xml for our SAML client adapter
|
||||
*
|
||||
*
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public interface ClientInstallationProvider extends Provider, ProviderFactory<ClientInstallationProvider> {
|
||||
Response generateInstallation(KeycloakSession session, RealmModel realm, ClientModel client, URI serverBaseUri);
|
||||
String getProtocol();
|
||||
String getDisplayType();
|
||||
String getHelpText();
|
||||
String getFilename();
|
||||
String getMediaType();
|
||||
boolean isDownloadOnly();
|
||||
}
|
32
services/src/main/java/org/keycloak/protocol/ClientInstallationSpi.java
Executable file
32
services/src/main/java/org/keycloak/protocol/ClientInstallationSpi.java
Executable file
|
@ -0,0 +1,32 @@
|
|||
package org.keycloak.protocol;
|
||||
|
||||
import org.keycloak.provider.Provider;
|
||||
import org.keycloak.provider.ProviderFactory;
|
||||
import org.keycloak.provider.Spi;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||
*/
|
||||
public class ClientInstallationSpi implements Spi {
|
||||
|
||||
@Override
|
||||
public boolean isInternal() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "client-installation";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Provider> getProviderClass() {
|
||||
return ClientInstallationProvider.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends ProviderFactory> getProviderFactoryClass() {
|
||||
return ClientInstallationProvider.class;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,129 @@
|
|||
package org.keycloak.protocol.oidc.installation;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.authentication.ClientAuthenticator;
|
||||
import org.keycloak.authentication.ClientAuthenticatorFactory;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.protocol.ClientInstallationProvider;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
import org.keycloak.services.managers.ClientManager;
|
||||
import org.keycloak.util.JsonSerialization;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class KeycloakOIDCClientInstallation implements ClientInstallationProvider {
|
||||
|
||||
@Override
|
||||
public Response generateInstallation(KeycloakSession session, RealmModel realm, ClientModel client, URI baseUri) {
|
||||
ClientManager.InstallationAdapterConfig rep = new ClientManager.InstallationAdapterConfig();
|
||||
rep.setAuthServerUrl(baseUri.toString());
|
||||
rep.setRealm(realm.getName());
|
||||
rep.setRealmKey(realm.getPublicKeyPem());
|
||||
rep.setSslRequired(realm.getSslRequired().name().toLowerCase());
|
||||
|
||||
if (client.isPublicClient() && !client.isBearerOnly()) rep.setPublicClient(true);
|
||||
if (client.isBearerOnly()) rep.setBearerOnly(true);
|
||||
if (client.getRoles().size() > 0) rep.setUseResourceRoleMappings(true);
|
||||
|
||||
rep.setResource(client.getClientId());
|
||||
|
||||
if (showClientCredentialsAdapterConfig(client)) {
|
||||
Map<String, Object> adapterConfig = getClientCredentialsAdapterConfig(session, client);
|
||||
rep.setCredentials(adapterConfig);
|
||||
}
|
||||
String json = null;
|
||||
try {
|
||||
json = JsonSerialization.writeValueAsPrettyString(rep);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return Response.ok(json, MediaType.TEXT_PLAIN_TYPE).build();
|
||||
}
|
||||
|
||||
public static Map<String, Object> getClientCredentialsAdapterConfig(KeycloakSession session, ClientModel client) {
|
||||
String clientAuthenticator = client.getClientAuthenticatorType();
|
||||
ClientAuthenticatorFactory authenticator = (ClientAuthenticatorFactory) session.getKeycloakSessionFactory().getProviderFactory(ClientAuthenticator.class, clientAuthenticator);
|
||||
return authenticator.getAdapterConfiguration(client);
|
||||
}
|
||||
|
||||
|
||||
public static boolean showClientCredentialsAdapterConfig(ClientModel client) {
|
||||
if (client.isPublicClient()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (client.isBearerOnly() && client.getNodeReRegistrationTimeout() <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return OIDCLoginProtocol.LOGIN_PROTOCOL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayType() {
|
||||
return "Keycloak OIDC keycloak.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpText() {
|
||||
return "keycloak.json file used by the Keycloak OIDC client adapter to configure clients. This must be saved to a keycloak.json file and put in your WEB-INF directory of your WAR file. You may also want to tweak this file after you download it.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientInstallationProvider create(KeycloakSession session) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "keycloak-oidc-keycloak-json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDownloadOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFilename() {
|
||||
return "keycloak.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMediaType() {
|
||||
return MediaType.APPLICATION_JSON;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package org.keycloak.protocol.oidc.installation;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.protocol.ClientInstallationProvider;
|
||||
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
|
||||
* @version $Revision: 1 $
|
||||
*/
|
||||
public class KeycloakOIDCJbossSubsystemClientInstallation implements ClientInstallationProvider {
|
||||
@Override
|
||||
public Response generateInstallation(KeycloakSession session, RealmModel realm, ClientModel client, URI baseUri) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append("<secure-deployment name=\"WAR MODULE NAME.war\">\n");
|
||||
buffer.append(" <realm>").append(realm.getName()).append("</realm>\n");
|
||||
buffer.append(" <realm-public-key>").append(realm.getPublicKeyPem()).append("</realm-public-key>\n");
|
||||
buffer.append(" <auth-server-url>").append(baseUri.toString()).append("</auth-server-url>\n");
|
||||
if (client.isBearerOnly()){
|
||||
buffer.append(" <bearer-only>true</bearer-only>\n");
|
||||
|
||||
} else if (client.isPublicClient()) {
|
||||
buffer.append(" <public-client>true</public-client>\n");
|
||||
}
|
||||
buffer.append(" <ssl-required>").append(realm.getSslRequired().name()).append("</ssl-required>\n");
|
||||
buffer.append(" <resource>").append(client.getClientId()).append("</resource>\n");
|
||||
String cred = client.getSecret();
|
||||
if (KeycloakOIDCClientInstallation.showClientCredentialsAdapterConfig(client)) {
|
||||
Map<String, Object> adapterConfig = KeycloakOIDCClientInstallation.getClientCredentialsAdapterConfig(session, client);
|
||||
for (Map.Entry<String, Object> entry : adapterConfig.entrySet()) {
|
||||
buffer.append(" <credential name=\"" + entry.getKey() + "\">");
|
||||
|
||||
Object value = entry.getValue();
|
||||
if (value instanceof Map) {
|
||||
buffer.append("\n");
|
||||
Map<String, Object> asMap = (Map<String, Object>) value;
|
||||
for (Map.Entry<String, Object> credEntry : asMap.entrySet()) {
|
||||
buffer.append(" <" + credEntry.getKey() + ">" + credEntry.getValue().toString() + "</" + credEntry.getKey() + ">\n");
|
||||
}
|
||||
buffer.append(" </credential>\n");
|
||||
} else {
|
||||
buffer.append(value.toString()).append("</credential>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (client.getRoles().size() > 0) {
|
||||
buffer.append(" <use-resource-role-mappings>true</use-resource-role-mappings>\n");
|
||||
}
|
||||
buffer.append("</secure-deployment>\n");
|
||||
return Response.ok(buffer.toString(), MediaType.TEXT_PLAIN_TYPE).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocol() {
|
||||
return OIDCLoginProtocol.LOGIN_PROTOCOL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayType() {
|
||||
return "Keycloak OIDC JBoss Subsystem XML";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpText() {
|
||||
return "XML snippet you must edit and add to the Keycloak OIDC subsystem on your client app server. This type of configuration is useful when you can't or don't want to crack open your WAR file.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientInstallationProvider create(KeycloakSession session) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "keycloak-oidc-jboss-subsystem";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDownloadOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFilename() {
|
||||
return "keycloak-oidc-subsystem.xml";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMediaType() {
|
||||
return MediaType.APPLICATION_XML;
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ import org.keycloak.models.UserSessionModel;
|
|||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.models.utils.RepresentationToModel;
|
||||
import org.keycloak.protocol.ClientInstallationProvider;
|
||||
import org.keycloak.representations.adapters.action.GlobalRequestResult;
|
||||
import org.keycloak.representations.idm.ClientRepresentation;
|
||||
import org.keycloak.representations.idm.CredentialRepresentation;
|
||||
|
@ -143,6 +144,15 @@ public class ClientResource {
|
|||
return new ClientAttributeCertificateResource(realm, auth, client, session, attributePrefix, adminEvent);
|
||||
}
|
||||
|
||||
@GET
|
||||
@NoCache
|
||||
@Path("installation/providers/{providerId}")
|
||||
public Response getInstallationProvider(@PathParam("providerId") String providerId) {
|
||||
ClientInstallationProvider provider = session.getProvider(ClientInstallationProvider.class, providerId);
|
||||
if (provider == null) throw new NotFoundException("Unknown Provider");
|
||||
return provider.generateInstallation(session, realm, client, keycloak.getBaseUri(uriInfo));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get keycloak.json file
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.keycloak.freemarker.ThemeProvider;
|
|||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.utils.ModelToRepresentation;
|
||||
import org.keycloak.protocol.ClientInstallationProvider;
|
||||
import org.keycloak.protocol.LoginProtocol;
|
||||
import org.keycloak.protocol.LoginProtocolFactory;
|
||||
import org.keycloak.protocol.ProtocolMapper;
|
||||
|
@ -61,6 +62,7 @@ public class ServerInfoAdminResource {
|
|||
setProviders(info);
|
||||
setProtocolMapperTypes(info);
|
||||
setBuiltinProtocolMappers(info);
|
||||
setClientInstallations(info);
|
||||
info.setEnums(ENUMS);
|
||||
return info;
|
||||
}
|
||||
|
@ -144,6 +146,27 @@ public class ServerInfoAdminResource {
|
|||
}
|
||||
}
|
||||
|
||||
private void setClientInstallations(ServerInfoRepresentation info) {
|
||||
info.setClientInstallations(new HashMap<String, List<ClientInstallationRepresentation>>());
|
||||
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(ClientInstallationProvider.class)) {
|
||||
ClientInstallationProvider provider = (ClientInstallationProvider)p;
|
||||
List<ClientInstallationRepresentation> types = info.getClientInstallations().get(provider.getProtocol());
|
||||
if (types == null) {
|
||||
types = new LinkedList<>();
|
||||
info.getClientInstallations().put(provider.getProtocol(), types);
|
||||
}
|
||||
ClientInstallationRepresentation rep = new ClientInstallationRepresentation();
|
||||
rep.setId(p.getId());
|
||||
rep.setHelpText(provider.getHelpText());
|
||||
rep.setDisplayType( provider.getDisplayType());
|
||||
rep.setProtocol( provider.getProtocol());
|
||||
rep.setDownloadOnly( provider.isDownloadOnly());
|
||||
rep.setFilename(provider.getFilename());
|
||||
rep.setMediaType(provider.getMediaType());
|
||||
types.add(rep);
|
||||
}
|
||||
}
|
||||
|
||||
private void setProtocolMapperTypes(ServerInfoRepresentation info) {
|
||||
info.setProtocolMapperTypes(new HashMap<String, List<ProtocolMapperTypeRepresentation>>());
|
||||
for (ProviderFactory p : session.getKeycloakSessionFactory().getProviderFactories(ProtocolMapper.class)) {
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
org.keycloak.protocol.oidc.installation.KeycloakOIDCClientInstallation
|
||||
org.keycloak.protocol.oidc.installation.KeycloakOIDCJbossSubsystemClientInstallation
|
|
@ -9,3 +9,4 @@ org.keycloak.authentication.RequiredActionSpi
|
|||
org.keycloak.authentication.FormAuthenticatorSpi
|
||||
org.keycloak.authentication.FormActionSpi
|
||||
org.keycloak.services.clientregistration.ClientRegistrationSpi
|
||||
org.keycloak.protocol.ClientInstallationSpi
|
||||
|
|
|
@ -122,6 +122,7 @@ public class RealmTest extends AbstractClientTest {
|
|||
realm2 = keycloak.realms().realm("test-immutable").toRepresentation();
|
||||
|
||||
keycloak.realms().realm("test-immutable-old").remove();
|
||||
keycloak.realms().realm("test-immutable").remove();
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue