170 lines
4.9 KiB
Java
170 lines
4.9 KiB
Java
package org.gcube.service.idm.keycloack;
|
|
|
|
import java.rmi.ServerException;
|
|
import java.util.List;
|
|
|
|
import org.gcube.common.security.providers.SecretManagerProvider;
|
|
import org.gcube.common.security.secrets.Secret;
|
|
import org.gcube.idm.common.is.InfrastrctureServiceClient;
|
|
import org.gcube.idm.common.is.IsServerConfig;
|
|
import org.keycloak.admin.client.Keycloak;
|
|
import org.keycloak.admin.client.KeycloakBuilder;
|
|
import org.keycloak.admin.client.resource.ClientResource;
|
|
import org.keycloak.admin.client.resource.RealmResource;
|
|
import org.keycloak.representations.idm.ClientRepresentation;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import jakarta.ws.rs.InternalServerErrorException;
|
|
import jakarta.ws.rs.NotFoundException;
|
|
|
|
public class KkClientFactory {
|
|
private static final Logger logger = LoggerFactory.getLogger(KkClientFactory.class);
|
|
|
|
private final static String RUNTIME_RESOURCE_NAME = "IAM";
|
|
private final static String CATEGORY = "Service";
|
|
private final static String END_POINT_NAME = "d4science";
|
|
private final static boolean IS_ROOT_SERVICE = true;
|
|
|
|
// the singleton obj
|
|
private IsServerConfig config;
|
|
private Secret secret;
|
|
|
|
private static KkClientFactory singleton = new KkClientFactory();
|
|
|
|
public static KkClientFactory getSingleton() {
|
|
if (singleton == null)
|
|
singleton = new KkClientFactory();
|
|
return singleton;
|
|
}
|
|
|
|
/**
|
|
* keycloak configuration obtained from IS in the private constructor
|
|
* using the singleton pattern, it's retrieved from IS only for the first
|
|
* access, then kept in the singleton object
|
|
*/
|
|
|
|
public Secret getSecret() {
|
|
return secret;
|
|
}
|
|
|
|
public void setSecret(Secret secret) {
|
|
this.secret = secret;
|
|
this.config = fetchIsConfig(this.secret);
|
|
}
|
|
|
|
// allows to configure the factory
|
|
// e.g. from external configuration file
|
|
public void setConfig(IsServerConfig configuration) {
|
|
config = configuration;
|
|
}
|
|
|
|
public IsServerConfig fetchIsConfig(Secret secret) throws InternalServerErrorException {
|
|
|
|
try {
|
|
if (this.secret == null)
|
|
this.secret = InfrastrctureServiceClient.getSecretForInfrastructure();
|
|
|
|
IsServerConfig cfg = InfrastrctureServiceClient.serviceConfigFromIS(RUNTIME_RESOURCE_NAME, CATEGORY,
|
|
END_POINT_NAME, IS_ROOT_SERVICE, secret);
|
|
logger.info("KeycloakAPICredentials object built {} - {}", cfg.getServerUrl(), cfg.getName());
|
|
|
|
return cfg;
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
throw new InternalServerErrorException(e);
|
|
}
|
|
}
|
|
|
|
public KeycloackApiClient createtKeycloakInstance(String context) {
|
|
if (this.config == null) {
|
|
this.config = fetchIsConfig(this.secret);
|
|
}
|
|
return createtKeycloakInstance(this.config, context);
|
|
}
|
|
|
|
public static KeycloackApiClient createtKeycloakInstance(IsServerConfig config, String context) {
|
|
|
|
Keycloak kclient = KeycloakBuilder.builder()
|
|
.serverUrl(config.getServerUrl())
|
|
.realm(config.getName())
|
|
.grantType(config.getGrantType())
|
|
.clientId(config.getClientId()) //
|
|
.clientSecret(config.getClientSecret()).build();
|
|
|
|
return new KeycloackApiClient(kclient, config.getName(), context);
|
|
}
|
|
|
|
public RealmResource getKKRealm() {
|
|
String ctx = SecretManagerProvider.get().getContext();
|
|
return getKKRealm(ctx);
|
|
}
|
|
|
|
public RealmResource getKKRealm(String ctx) {
|
|
logger.info("Searching client for contex");
|
|
|
|
KeycloackApiClient keycloackApiClient = createtKeycloakInstance(ctx);
|
|
RealmResource realm = keycloackApiClient.kclient.realm(keycloackApiClient.realmName);
|
|
return realm;
|
|
}
|
|
|
|
public ClientResource getKKClient() {
|
|
String ctx = SecretManagerProvider.get().getContext();
|
|
return getKKClient(ctx);
|
|
}
|
|
|
|
public ClientResource getKKClient(String ctx) {
|
|
logger.info("Searching client for contex");
|
|
|
|
RealmResource realm = getKKRealm(ctx);
|
|
|
|
List<ClientRepresentation> clients = realm.clients().findByClientId(encodeClientIdContext(ctx));
|
|
|
|
if (clients.size() == 0) {
|
|
return null;
|
|
}
|
|
String id = clients.get(0).getId();
|
|
return realm.clients().get(id);
|
|
}
|
|
|
|
/**
|
|
* select the ClientResource by name, or current client if clientId parameter is
|
|
* null;
|
|
*
|
|
* @param clientId
|
|
* @return
|
|
* @throws ServerException
|
|
* @throws NotFoundException
|
|
*/
|
|
public ClientResource getKKClientById(String clientId) {
|
|
|
|
if (clientId == null)
|
|
return KkClientFactory.getSingleton().getKKClient();
|
|
|
|
RealmResource realmResource = getKKRealm();
|
|
|
|
List<ClientRepresentation> clients = realmResource.clients().findByClientId(clientId);
|
|
|
|
if (clients.size() == 0) {
|
|
throw new NotFoundException();
|
|
}
|
|
String id = clients.get(0).getId();
|
|
|
|
return realmResource.clients().get(id);
|
|
}
|
|
|
|
// TODO: REMOVE
|
|
// static IsServerConfig getTestConfig() {
|
|
// String serverUrl = "https://accounts.dev.d4science.org/auth";
|
|
// String realm = "d4science";
|
|
// String clientId = "id.d4science.org";
|
|
// String clientSecret = "";
|
|
|
|
// return new IsServerConfig(serverUrl, realm, clientId, clientSecret);
|
|
// }
|
|
|
|
public static String encodeClientIdContext(String context) {
|
|
return context.replace("/", "%2F");
|
|
}
|
|
}
|