idm-service/src/main/java/org/gcube/service/idm/keycloack/KkClientFactory.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");
}
}