config keycloak client

This commit is contained in:
Alfredo Oliviero 2024-03-28 15:40:09 +01:00
parent 9508b7329c
commit bc534cc6cb
19 changed files with 476 additions and 353 deletions

2
.vscode/launch.json vendored
View File

@ -4,6 +4,8 @@
// Per altre informazioni, visitare: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "java",
"name": "Debug (Attach)",

View File

@ -4,6 +4,7 @@ FROM d4science/smartgears-distribution:4.0.0-SNAPSHOT-java$JAVA_VERSION-tomcat10
COPY ./docker/logback.xml /etc/
COPY ./docker/container.ini /etc/
COPY ./docker/devsec.gcubekey /tomcat/lib
COPY ./target/idm.war /tomcat/webapps/
EXPOSE 8080

View File

@ -42,14 +42,16 @@ OPTSTRING=":sn:p:d:j:?h"
while getopts $OPTSTRING opt; do
# echo "Option -${opt} was triggered, Argument: ${OPTARG}"
case "${opt}" in
s) COMPILE=false && echo "compile $COMPILE" ;;
n) NAME=${OPTARG} ;;
p) PORT=${OPTARG} ;;
d) DEBUG=true
s) COMPILE=false && echo "compile $COMPILE" ;;
n) NAME=${OPTARG} ;;
p) PORT=${OPTARG} ;;
d)
DEBUG=true
DEBUG_PORT=${OPTARG}
echo "debug enabled, port $DEBUG_PORT"
;;
j) if [[ ${accepted_java_versions[@]} =~ ${OPTARG} ]]; then
j)
if [[ ${accepted_java_versions[@]} =~ ${OPTARG} ]]; then
java_version=${OPTARG}
else
echo "Invalid java version" && echo "accepted version are: ${accepted_java_versions[@]}" && exit 1
@ -57,10 +59,10 @@ while getopts $OPTSTRING opt; do
;;
h) Help && exit 0 ;;
:) # matched when an option that is expected to have an argument is passed without one
if [ ${OPTARG} = "d" ]; then
if [ ${OPTARG} = "d" ]; then
DEBUG=true
echo "debug enabled, port $DEBUG_PORT"
else
else
# matched when an option that is expected to have an argument is passed without one
echo "Option -${OPTARG} requires an argument."
exit 1
@ -73,7 +75,7 @@ while getopts $OPTSTRING opt; do
esac
done
if [ $COMPILE = true ]; then
if [ $COMPILE = true ]; then
mvn clean package
else
echo "skipping mvn package"

3
docker/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
container*.ini
!container.default.ini
*.gcubekey

View File

@ -20,6 +20,7 @@ location = pisa
factory = org.gcube.smartgears.security.defaults.DefaultAuthorizationProviderFactory
factory.endpoint = https://accounts.dev.d4science.org/auth/realms/d4science/protocol/openid-connect/token
credentials.class = org.gcube.smartgears.security.SimpleCredentials
#credentials.clientID = node-whn-test-uno-d-d4s.d4science.org
credentials.clientID = alfredo-idm-service-dev
credentials.secret = 979bd3bc-5cc4-11ec-bf63-0242ac130002
credentials.clientID =
credentials.secret =

View File

@ -11,9 +11,9 @@
<servlet-name>idm</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>org.gcube.service.idm.rest</param-value>
</init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>org.gcube.service.idm.rest</param-value>
</init-param>
</servlet>
<servlet-mapping>

11
pom.xml
View File

@ -262,6 +262,17 @@ java.lang.NoClassDefFoundError: org/apache/http/ssl/TrustStrategy
</exclusions>
</dependency>
<!--
<dependency>
<groupId>org.gcube.resources.discovery</groupId>
<artifactId>ic-client</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.gcube.core</groupId>
<artifactId>common-scope</artifactId>
<scope>provided</scope>
</dependency> -->
</dependencies>
<build>

View File

@ -8,17 +8,16 @@ public class KeycloackApiClient {
public String clientIdContext;
public String context;
public static String getClientIdContext(String context) {
public static String encodeClientIdContext(String context) {
return context.replace("/", "%2F");
}
public KeycloackApiClient(Keycloak kclient, String realmName, String context) {
this.clientIdContext = getClientIdContext(context);
this.clientIdContext = encodeClientIdContext(context);
this.context = context;
this.kclient = kclient;
this.realmName = realmName;
// ClientsResource clients = kclient.realm(realmName).clients().get*
// clients.get(context);
}
}

View File

@ -1,124 +0,0 @@
package org.gcube.keycloack;
import java.io.InputStream;
import java.net.URL;
import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry;
import java.util.Properties;
import jakarta.ws.rs.InternalServerErrorException;
import org.gcube.common.authorization.utils.secret.JWTSecret;
import org.gcube.common.keycloak.DefaultKeycloakClient;
import org.gcube.common.keycloak.KeycloakClientException;
import org.gcube.common.keycloak.KeycloakClientFactory;
import org.gcube.common.keycloak.model.TokenResponse;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.gcube.common.authorization.utils.secret.Secret;
/***
* from gcat implementation
*
*/
public class KeycloackClientGcatFactory {
private static final Logger logger = LoggerFactory.getLogger(KeycloackClientGcatFactory.class);
public static final String CATALOGUE_NAME = "IDM";
protected static final String CLIENT_ID_SECRET_FILENAME = "config.properties";
protected static final String CLIENT_ID_PROPERTY_NAME = "clientId";
public String context;
public String clientId;
public String clientSecret;
public DefaultKeycloakClient gcubeKeycloakClient;
// Reads the property file and extracts the keycloack configuration params
protected static Entry<String, String> getClientIdAndClientSecret(String context) {
try {
Properties properties = new Properties();
ClassLoader classLoader = KeycloackClientGcatFactory.class.getClassLoader();
URL url = classLoader.getResource(CLIENT_ID_SECRET_FILENAME);
logger.trace("Going to read {} at {}", CLIENT_ID_SECRET_FILENAME, url.toString());
InputStream input = classLoader.getResourceAsStream(CLIENT_ID_SECRET_FILENAME);
properties.load(input);
String clientId = "IDM";
if (properties.containsKey(CLIENT_ID_PROPERTY_NAME)) {
clientId = properties.getProperty(CLIENT_ID_PROPERTY_NAME);
}
int index = context.indexOf('/', 1);
String root = context.substring(0, index == -1 ? context.length() : index);
String clientSecret = properties.getProperty(root);
SimpleEntry<String, String> entry = new SimpleEntry<String, String>(clientId, clientSecret);
return entry;
} catch (Exception e) {
throw new InternalServerErrorException(
"Unable to retrieve Application Token for context "
/* + SecretManagerProvider.instance.get().getContext() */,
e);
}
}
// TODO: VERIFICARE
public URL getRealmBaseURL() throws KeycloakClientException {
return this.gcubeKeycloakClient.getRealmBaseURL(this.context);
}
public URL getRealmBaseURL(String realm) throws KeycloakClientException {
return this.gcubeKeycloakClient.getRealmBaseURL(this.context, realm);
}
public URL getServerURL() {
try {
return this.getRealmBaseURL();
} catch (KeycloakClientException e) {
// That should be almost impossible
logger.warn("Cannot create base URL", e);
return null;
}
}
public String getClientid() {
return clientId;
}
// TODO: serve? implementare
public String getPassword() {
return null;
}
// TODO: VERIFICARE
public String getRealm() {
return this.context;
}
public KeycloackClientGcatFactory(String context) {
this.context = context;
Entry<String, String> params = getClientIdAndClientSecret(context);
this.clientId = params.getKey();
this.clientSecret = params.getKey();
this.gcubeKeycloakClient = new DefaultKeycloakClient();
}
private static TokenResponse getJWTAccessToken() throws Exception {
String context = SecretManagerProvider.get().getContext();
Entry<String, String> entry = getClientIdAndClientSecret(context);
TokenResponse tr = KeycloakClientFactory.newInstance().queryUMAToken(context, entry.getKey(), entry.getValue(),
context, null);
return tr;
}
public static Secret getCatalogueSecret() throws Exception {
TokenResponse tr = getJWTAccessToken();
Secret secret = new JWTSecret(tr.getAccessToken());
return secret;
}
}

View File

@ -1,169 +0,0 @@
package org.gcube.keycloack;
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
import java.util.Iterator;
import java.util.List;
import org.gcube.common.encryption.encrypter.StringEncrypter;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
import org.gcube.smartgears.ContextProvider;
import org.gcube.smartgears.context.application.ApplicationContext;
import org.keycloak.OAuth2Constants;
import org.keycloak.admin.client.Keycloak;
import org.keycloak.admin.client.KeycloakBuilder;
// import org.keycloak.OAuth2Constants;
// import org.keycloak.admin.client.Keycloak;
// import org.keycloak.admin.client.KeycloakBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class KeycloakClientFactory {
private static final Logger logger = LoggerFactory.getLogger(KeycloakClientFactory.class);
private final static String RUNTIME_RESOURCE_NAME = "IAM";
private final static String CATEGORY = "Service";
// the singleton obj
private static KeycloakClientFactory singleton = new KeycloakClientFactory();
// properties that it contains
private String keycloakURL;
private String realm;
private String clientid;
private String password;
/**
* Private constructor
*/
private KeycloakClientFactory() {
logger.info("Building KeycloakAPICredentials object");
lookupPropertiesFromIs();
logger.info("KeycloakAPICredentials object built");
}
/**
* Read the properties from the infrastructure
*/
private void lookupPropertiesFromIs() {
logger.info("Starting creating KeycloakAPICredentials");
// String ctx = SecretManagerProvider.instance.get().getContext();
// TODO: verificare che sia contesto corretto
ApplicationContext ctx = ContextProvider.get();
logger.info("Discovering liferay user's credentials in context "
+ ctx.container().configuration().infrastructure());
try {
List<ServiceEndpoint> resources = getConfigurationFromIS();
if (resources.size() == 0) {
logger.error("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME + " and Category "
+ CATEGORY + " in this scope.");
throw new Exception("There is no Runtime Resource having name " + RUNTIME_RESOURCE_NAME
+ " and Category " + CATEGORY + " in this scope.");
} else {
for (ServiceEndpoint res : resources) {
Iterator<AccessPoint> accessPointIterator = res.profile().accessPoints().iterator();
while (accessPointIterator.hasNext()) {
ServiceEndpoint.AccessPoint accessPoint = (ServiceEndpoint.AccessPoint) accessPointIterator
.next();
if (accessPoint.name().equals("d4science")) {
keycloakURL = accessPoint.address();
realm = accessPoint.name();
clientid = accessPoint.username();
password = StringEncrypter.getEncrypter().decrypt(accessPoint.password());
logger.info("Found accesspoint URL = " + keycloakURL);
}
}
}
}
} catch (Exception e) {
logger.error("Unable to retrieve such service endpoint information!", e);
return;
// }finally{
// if(oldContext != null)
// ScopeProvider.instance.set(oldContext);
}
logger.info("Bean built " + toString());
}
/**
* Retrieve endpoints information from IS for DB
*
* @return list of endpoints for ckan database
* @throws Exception
*/
private List<ServiceEndpoint> getConfigurationFromIS() throws Exception {
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '" + RUNTIME_RESOURCE_NAME + "'");
query.addCondition("$resource/Profile/Category/text() eq '" + CATEGORY + "'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
List<ServiceEndpoint> toReturn = client.submit(query);
return toReturn;
}
public static KeycloakClientFactory getSingleton() {
if (singleton == null)
singleton = new KeycloakClientFactory();
return singleton;
}
public String getServerURL() {
return keycloakURL;
}
public String getClientid() {
return clientid;
}
public String getPassword() {
return password;
}
public String getRealm() {
return realm;
}
public KeycloackApiClient createtKeycloakInstance(String context) {
return defaultKeycloackInstance(context);
// // String clientIdContext = KeycloackUtils.getClientIdContext(context);
// String realm = this.getRealm();
// Keycloak keycloak = KeycloakBuilder.builder()
// .serverUrl(this.getServerURL())
// .realm(realm)
// .grantType(OAuth2Constants.CLIENT_CREDENTIALS)
// .clientId(this.getClientid()) //
// .clientSecret(this.getPassword()).build();
// return
}
public KeycloackApiClient defaultKeycloackInstance(String context) {
String serverUrl = "https://accounts.dev.d4science.org/auth";
String realm = "d4science";
String clientId = "id.d4science.org";
String client_secret = "09c26f24-3c65-4039-9fa0-e5cc4f4032cd";
Keycloak kclient = KeycloakBuilder.builder()
.serverUrl(serverUrl)
.realm(realm)
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(clientId) //
.clientSecret(client_secret).build();
return new KeycloackApiClient(kclient, realm, context);
}
}

View File

@ -0,0 +1,56 @@
package org.gcube.keycloack;
import org.keycloak.OAuth2Constants;
public class KeycloakServerConfig {
private String serverUrl;
private String realm;
private String clientId;
private String clientSecret;
private String grantType = OAuth2Constants.CLIENT_CREDENTIALS;
public String getServerUrl() {
return serverUrl;
}
public String getRealm() {
return realm;
}
public String getClientId() {
return clientId;
}
public String getClientSecret() {
return clientSecret;
}
public String getGrantType() {
return grantType;
}
public KeycloakServerConfig(String serverUrl, String realm, String clientId, String clientSecret) {
this.serverUrl = serverUrl;
this.realm = realm;
this.clientId = clientId;
this.clientSecret = clientSecret;
}
public KeycloakServerConfig(String serverUrl, String realm, String clientId, String clientSecret,
String grantType) {
this(serverUrl, realm, clientId, clientSecret);
this.grantType = grantType;
}
//TODO: REMOVE
static KeycloakServerConfig getTestConfig(){
String serverUrl = "https://accounts.dev.d4science.org/auth";
String realm = "d4science";
String clientId = "id.d4science.org";
String clientSecret = "09c26f24-3c65-4039-9fa0-e5cc4f4032cd";
return new KeycloakServerConfig(serverUrl, realm, clientId, clientSecret);
}
}

View File

@ -0,0 +1,162 @@
package org.gcube.keycloack;
import java.util.List;
import org.gcube.common.encryption.encrypter.StringEncrypter;
import org.gcube.common.resources.gcore.ServiceEndpoint;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.service.idm.is.client.InfrastrctureServiceClient;
import org.gcube.smartgears.ContextProvider;
import org.gcube.smartgears.context.application.ApplicationContext;
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.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 REALM_D4S = "d4science";
private final static boolean IS_ROOT_SERVICE = true;
// the singleton obj
private static KkClientFactory singleton = new KkClientFactory();
/**
* 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
*/
private KeycloakServerConfig config_keycloak;
public static KkClientFactory getSingleton() {
if (singleton == null)
singleton = new KkClientFactory();
return singleton;
}
/**
* Private constructor
* obtains the is_config_keycloak from IS
*/
private KkClientFactory() {
logger.info("Building KeycloakAPICredentials object");
try {
if (this.config_keycloak == null)
setIsKeycloackInstance();
if (this.config_keycloak == null)
setTestKeycloackInstance();
} catch (Exception e) {
logger.error("error obtaining IAM configuration from IS {} ", e);
}
logger.info("KeycloakAPICredentials object built {} - {}", config_keycloak.getServerUrl(), config_keycloak.getRealm() );
}
public void setTestKeycloackInstance() {
this.config_keycloak = KeycloakServerConfig.getTestConfig();
}
public void setIsKeycloackInstance() throws Exception {
this.config_keycloak = lookupPropertiesFromIs(RUNTIME_RESOURCE_NAME, CATEGORY, REALM_D4S, IS_ROOT_SERVICE);
}
public static String encodeClientIdContext(String context) {
return context.replace("/", "%2F");
}
public KeycloackApiClient createtKeycloakInstance(String context) {
return keycloackInstanceFromConfig(this.config_keycloak, context);
}
public static KeycloackApiClient keycloackInstanceFromConfig(KeycloakServerConfig config, String context) {
Keycloak kclient = KeycloakBuilder.builder()
.serverUrl(config.getServerUrl())
.realm(config.getRealm())
.grantType(config.getGrantType())
.clientId(config.getClientId()) //
.clientSecret(config.getClientSecret()).build();
return new KeycloackApiClient(kclient, config.getRealm(), context);
}
public RealmResource getKKRealmForCurrentContext() {
String ctx = SecretManagerProvider.get().getContext();
return getKKRealmForContext(ctx);
}
public RealmResource getKKRealmForContext(String ctx) {
logger.info("Searching client for contex");
KeycloackApiClient keycloackApiClient = createtKeycloakInstance(ctx);
RealmResource realm = keycloackApiClient.kclient.realm(keycloackApiClient.realmName);
return realm;
}
public ClientResource getKKClientForCurrentContext() {
String ctx = SecretManagerProvider.get().getContext();
return getKKClientForContext(ctx);
}
public ClientResource getKKClientForContext(String ctx) {
logger.info("Searching client for contex");
RealmResource realm = getKKRealmForContext(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);
}
/**
* Read the properties from the infrastructure
*
* @throws Exception
*/
private KeycloakServerConfig lookupPropertiesFromIs(String resource_name, String category, String accessPointName, boolean root_service)
throws Exception {
logger.info("Starting creating KeycloakAPICredentials");
ServiceEndpoint.AccessPoint accessPoint = InfrastrctureServiceClient.getAccesspointFromIS(resource_name,
category, accessPointName, root_service);
if (accessPoint == null) {
String error_log = "Unable to retrieve service endpoint " + accessPointName;
logger.error(error_log);
throw new NotFoundException(error_log);
}
String keycloakURL = accessPoint.address();
String realm = accessPoint.name();
String clientId = accessPoint.username();
String clientSecret = StringEncrypter.getEncrypter().decrypt(accessPoint.password());
KeycloakServerConfig config = new KeycloakServerConfig(keycloakURL, realm, clientId, clientSecret);
logger.info("Found accesspoint URL = " + keycloakURL);
return config;
}
}

View File

@ -0,0 +1,18 @@
KKRolesClient.list
KeycloakClientFactory.getKKClientForContext();
String ctx = SecretManagerProvider.get().getContext();
RealmResource realm = getKKRealmForContext();
KeycloackApiClient keycloackApiClient = KeycloakClientFactory.getSingleton().createtKeycloakInstance(ctx).clientIdContext;
List<ClientRepresentation> clients = realm.clients().findByClientId(keycloackApiClient.clientIdContext);
getUserByEmail
RealmResource realm = KeycloakClientFactory.getKKRealmForContext();
String ctx = SecretManagerProvider.get().getContext();
KeycloakClientFactory factory = KeycloakClientFactory.getSingleton()
new KeycloakClientFactory()
lookupPropertiesFromIs();

View File

@ -0,0 +1,20 @@
package org.gcube.service.idm.controller;
import java.util.List;
import org.gcube.keycloack.KkClientFactory;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.representations.idm.RoleRepresentation;
import org.slf4j.LoggerFactory;
public class KKRolesClient {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(KKRolesClient.class);
public static List<RoleRepresentation> getRoles() {
logger.info("Searching users for context");
ClientResource client = KkClientFactory.getSingleton().getKKClientForCurrentContext();
List<RoleRepresentation> roles = client.roles().list();
return roles;
}
}

View File

@ -4,7 +4,7 @@ import java.util.List;
import org.gcube.common.security.providers.SecretManagerProvider;
import org.gcube.keycloack.KeycloackApiClient;
import org.gcube.keycloack.KeycloakClientFactory;
import org.gcube.keycloack.KkClientFactory;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.representations.idm.ClientRepresentation;
@ -14,44 +14,11 @@ import org.slf4j.LoggerFactory;
public class KKUserClient {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(KKUserClient.class);
// TODO: Move to KK CLIENTE
public static ClientResource getKKClientForContext() {
logger.info("Searching client for contex");
RealmResource realm = getKKRealmForContext();
String ctx = SecretManagerProvider.get().getContext();
KeycloackApiClient keycloackApiClient = KeycloakClientFactory.getSingleton()
.createtKeycloakInstance(ctx);
List<ClientRepresentation> clients = realm.clients().findByClientId(keycloackApiClient.clientIdContext);
String id = "";
for (ClientRepresentation client : clients) {
logger.info("found client =" + client.getClientId());
logger.info("found client id=" + client.getId());
id = client.getId();
}
ClientResource client = realm.clients().get(id);
return client;
}
// TODO: Move to KK CLIENTE
public static RealmResource getKKRealmForContext() {
logger.info("Searching client for contex");
String ctx = SecretManagerProvider.get().getContext();
KeycloackApiClient keycloackApiClient = KeycloakClientFactory.getSingleton()
.createtKeycloakInstance(ctx);
RealmResource realm = keycloackApiClient.kclient.realm(keycloackApiClient.realmName);
return realm;
}
public static List<UserRepresentation> getUserByEmail(String email) {
logger.info("Searching user by email: {}", email);
RealmResource realm = getKKRealmForContext();
RealmResource realm = KkClientFactory.getSingleton().getKKRealmForCurrentContext();
List<UserRepresentation> users = realm.users()
.searchByEmail(email, true);
return users;
@ -60,7 +27,7 @@ public class KKUserClient {
public static List<UserRepresentation> getUserByUsername(String username) {
logger.info("Searching user by username: {}", username);
RealmResource realm = getKKRealmForContext();
RealmResource realm = KkClientFactory.getSingleton().getKKRealmForCurrentContext();
List<UserRepresentation> users = realm.users()
.search(username, true);
return users;
@ -68,18 +35,29 @@ public class KKUserClient {
public static List<UserRepresentation> searchUsersByRole(String roleName, Integer firstResult, Integer maxResults) {
logger.info("Searching users by role: {}", roleName);
ClientResource client = getKKClientForContext();
ClientResource client = KkClientFactory.getSingleton().getKKClientForCurrentContext();
List<UserRepresentation> users = client.roles().get(roleName)
.getUserMembers(firstResult, maxResults);
return users;
}
public static List<UserRepresentation> searchRealmUsers(Integer firstResult, Integer maxResults) {
RealmResource realm = getKKRealmForContext();
public static List<UserRepresentation> users(Integer firstResult, Integer maxResults) {
RealmResource realm = KkClientFactory.getSingleton().getKKRealmForCurrentContext();
List<UserRepresentation> users = realm.users()
.list(firstResult, maxResults);
return users;
}
public static List<ClientRepresentation> clients() {
RealmResource realm = KkClientFactory.getSingleton().getKKRealmForCurrentContext();
String ctx = SecretManagerProvider.get().getContext();
KeycloackApiClient keycloackApiClient = KkClientFactory.getSingleton()
.createtKeycloakInstance(ctx);
List<ClientRepresentation> clients = realm.clients().findByClientId(keycloackApiClient.clientIdContext);
return clients;
}
}

View File

@ -0,0 +1,96 @@
package org.gcube.service.idm.is.client;
import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
import java.util.List;
import org.gcube.common.resources.gcore.ServiceEndpoint;
// import org.gcube.common.scope.api.ScopeProvider;
import org.gcube.common.security.AuthorizedTasks;
import org.gcube.resources.discovery.client.api.DiscoveryClient;
import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
import org.gcube.smartgears.ContextProvider;
import org.gcube.smartgears.context.application.ApplicationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.gcube.common.security.secrets.Secret;
public class InfrastrctureServiceClient {
private static final Logger logger = LoggerFactory.getLogger(InfrastrctureServiceClient.class);
/**
* Retrieve endpoints information from IS for DB
*
* @return list of endpoints for ckan database
* @throws Throwable
*/
public static List<ServiceEndpoint> getEndopintsFromIS(String resource_name, String category,
boolean root_service) {
SimpleQuery query = queryFor(ServiceEndpoint.class);
query.addCondition("$resource/Profile/Name/text() eq '" + resource_name + "'");
query.addCondition("$resource/Profile/Category/text() eq '" + category + "'");
DiscoveryClient<ServiceEndpoint> client = clientFor(ServiceEndpoint.class);
ApplicationContext ctx = ContextProvider.get();
String infra_context = "/" + ctx.container().configuration().infrastructure();
Secret secret = ctx.container().authorizationProvider().getSecretForContext(infra_context);
List<ServiceEndpoint> endpoints = null;
try {
if (root_service) {
endpoints = AuthorizedTasks.executeSafely(() -> {
// esegui la query
List<ServiceEndpoint> toReturn = client.submit(query);
return toReturn;
}, secret);
} else {
endpoints = client.submit(query);
}
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return endpoints;
}
/**
* @param resource_name
* @param category
* @param accessPointName
* @return
* @throws Exception
*/
public static ServiceEndpoint.AccessPoint getAccesspointFromIS(String resource_name, String category,
String accessPointName, boolean root_service) throws Exception {
List<ServiceEndpoint> resources = getEndopintsFromIS(resource_name, category, root_service);
if (resources.size() == 0) {
logger.error("There is no Runtime Resource having name " + resource_name + " and Category "
+ category + " in this scope.");
return null;
}
for (ServiceEndpoint res : resources) {
ServiceEndpoint.AccessPoint accessPoint = res.profile().accessPoints().stream()
.filter(ap -> ap.name().equals(accessPointName))
.findFirst().orElse(null);
if (accessPoint != null) {
return accessPoint;
}
}
String error_log = "Unable to retrieve service endpoint " + accessPointName;
logger.error(error_log);
return null;
}
}

View File

@ -0,0 +1,66 @@
package org.gcube.service.idm.rest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gcube.service.idm.IdMManager;
import org.gcube.service.idm.controller.KKRolesClient;
import org.gcube.service.idm.controller.KKUserClient;
import org.gcube.service.idm.serializers.ContextSerializator;
import org.gcube.service.rest.ResponseBean;
import org.gcube.service.rest.ResponseBeanPaginated;
import org.gcube.smartgears.annotations.ManagedBy;
import org.keycloak.representations.idm.RoleRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.validation.constraints.Min;
import jakarta.ws.rs.DefaultValue;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
@ManagedBy(IdMManager.class)
@Path("roles")
public class RolesAPI {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(RolesAPI.class);
@GET
@Path("/")
@Produces({ "application/json;charset=UTF-8", "application/vnd.api+json" })
public Response roles() {
Status status = Status.OK;
ResponseBean responseBean = new ResponseBean();;
try {
List<RoleRepresentation> roles = KKRolesClient.getRoles();
responseBean.setResult(roles);
responseBean.setSuccess(true);
ObjectMapper objectMapper = ContextSerializator.getSerializer();
String jsonData = objectMapper.writeValueAsString(responseBean);
return Response.ok(jsonData).build();
} catch (JsonProcessingException e) {
e.printStackTrace();
return Response.serverError().build();
} catch (Exception e) {
logger.error("Unable to retrieve users with the requested role", e);
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
}
}

View File

@ -92,6 +92,7 @@ public class UsersSocialAPI {
responseBean.setMessage(e.getMessage());
status = Status.INTERNAL_SERVER_ERROR;
return Response.status(status).entity(responseBean).build();
}
}
@ -108,7 +109,7 @@ public class UsersSocialAPI {
try {
List<UserRepresentation> users = KKUserClient.searchRealmUsers(firstResult, maxResults);
List<UserRepresentation> users = KKUserClient.users(firstResult, maxResults);
if (users != null) {
for (UserRepresentation user : users) {
usernamesAndFullnames.put(user.getUsername(), user.getEmail());
@ -277,7 +278,7 @@ public class UsersSocialAPI {
ResponseBean responseBean = new ResponseBean();
List<String> usernames = new ArrayList<String>();
try {
List<UserRepresentation> users = KKUserClient.searchRealmUsers(firstResult, maxResults);
List<UserRepresentation> users = KKUserClient.users(firstResult, maxResults);
if (users != null) {
for (UserRepresentation user : users) {
usernames.add(user.getUsername());

View File

@ -38,7 +38,7 @@ public class KeycloakTestService {
private final static Logger logger = LoggerFactory.getLogger(KeycloakTestService.class);
public static String getClientIdContext(String context) {
public static String encodeClientIdContext(String context) {
return context.replace("/", "%2F");
}
@ -93,7 +93,7 @@ public class KeycloakTestService {
private static List<UserRepresentation> searchByRole(Keycloak kclient, String krealm, String clientIdContext,
String roleName) {
clientIdContext = getClientIdContext(clientIdContext);
clientIdContext = encodeClientIdContext(clientIdContext);
logger.info("Searching by role: {}", roleName);