diff --git a/src/main/java/org/gcube/portal/social/networking/liferay/ws/KeycloakAPICredentials.java b/src/main/java/org/gcube/portal/social/networking/liferay/ws/KeycloakAPICredentials.java new file mode 100644 index 0000000..7e73a83 --- /dev/null +++ b/src/main/java/org/gcube/portal/social/networking/liferay/ws/KeycloakAPICredentials.java @@ -0,0 +1,143 @@ +package org.gcube.portal.social.networking.liferay.ws; + +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 java.util.Map; + +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.common.resources.gcore.ServiceEndpoint.Property; +import org.gcube.common.scope.api.ScopeProvider; +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; + + + +public class KeycloakAPICredentials { + + private static final Logger logger = LoggerFactory.getLogger(KeycloakAPICredentials.class); + + // the singleton obj + private static KeycloakAPICredentials singleton = new KeycloakAPICredentials(); + + // properties that it contains + private String keycloakURL; + private String realm; + private String clientid; + private String password; + + + // Service endpoint properties + private final static String RUNTIME_RESOURCE_NAME = "IAM"; + private final static String CATEGORY = "Service"; + + /** + * Private constructor + */ + private KeycloakAPICredentials() { + 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 oldContext = ScopeProvider.instance.get(); + ApplicationContext ctx = ContextProvider.get(); // get this info from SmartGears + ScopeProvider.instance.set("/"+ctx.container().configuration().infrastructure()); + logger.info("Discovering liferay user's credentials in context " + ctx.container().configuration().infrastructure()); + + try{ + List 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 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.description(); + 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 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 client = clientFor(ServiceEndpoint.class); + List toReturn = client.submit(query); + return toReturn; + + } + + public static KeycloakAPICredentials getSingleton() { + if (singleton == null) + singleton = new KeycloakAPICredentials(); + return singleton; + } + + public String getServerURL() { + return keycloakURL; + } + + public String getClientid() { + return clientid; + } + + public String getPassword() { + return password; + } + + public String getRealm() { + return realm; + } + + @Override + public String toString() { + return "KeycloakAPICredentials [keycloakURL=" + keycloakURL + ", realm=" + realm + ", clientid=" + clientid + + ", password=**************]"; + } + + +} diff --git a/src/main/java/org/gcube/portal/social/networking/liferay/ws/LiferayJSONWsCredentials.java b/src/main/java/org/gcube/portal/social/networking/liferay/ws/LiferayJSONWsCredentials.java index 6543a30..288094c 100644 --- a/src/main/java/org/gcube/portal/social/networking/liferay/ws/LiferayJSONWsCredentials.java +++ b/src/main/java/org/gcube/portal/social/networking/liferay/ws/LiferayJSONWsCredentials.java @@ -7,7 +7,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import org.gcube.common.encryption.StringEncrypter; +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.common.resources.gcore.ServiceEndpoint.Property; diff --git a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Users.java b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Users.java index 598754e..c0f062e 100644 --- a/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Users.java +++ b/src/main/java/org/gcube/portal/social/networking/ws/methods/v2/Users.java @@ -24,6 +24,7 @@ import org.gcube.common.scope.impl.ScopeBean; import org.gcube.common.scope.impl.ScopeBean.Type; import org.gcube.portal.social.networking.caches.UsersCache; import org.gcube.portal.social.networking.liferay.ws.GroupManagerWSBuilder; +import org.gcube.portal.social.networking.liferay.ws.KeycloakAPICredentials; import org.gcube.portal.social.networking.liferay.ws.RoleManagerWSBuilder; import org.gcube.portal.social.networking.liferay.ws.UserManagerWSBuilder; import org.gcube.portal.social.networking.ws.outputs.ResponseBean; @@ -477,13 +478,6 @@ public class Users { return Response.status(status).entity(responseBean).build(); } - - private static final String REALM_NAME = "d4science"; - private static final String clientId = "id.d4science.org"; - private static final String SERVER_URL = "https://accounts.dev.d4science.org/auth"; - private static final String client_secret = "09c26f24-3c65-4039-9fa0-e5cc4f4032cd"; - - /** * @pathExample /get-usernames-by-role?role-name=VRE-Manager * @param roleName the role name @@ -506,19 +500,22 @@ public class Users { Status status = Status.OK; String context = ScopeProvider.instance.get(); + KeycloakAPICredentials apiService = KeycloakAPICredentials.getSingleton(); + Keycloak keycloak; + keycloak = KeycloakBuilder.builder() - .serverUrl(SERVER_URL) - .realm("d4science") + .serverUrl(apiService.getServerURL()) + .realm(apiService.getRealm()) .grantType(OAuth2Constants.CLIENT_CREDENTIALS) - .clientId(clientId) // - .clientSecret(client_secret).build(); + .clientId(apiService.getClientid()) // + .clientSecret(apiService.getPassword()).build(); List usernames = new ArrayList(); try { - List users = searchByRole(keycloak, context, roleName); + List users = searchByRole(keycloak, apiService.getRealm(), context, roleName); if(users != null){ for (UserRepresentation user : users) { usernames.add(user.getUsername()); @@ -531,57 +528,15 @@ public class Users { responseBean.setMessage(e.getMessage()); status = Status.INTERNAL_SERVER_ERROR; } - - // try{ - // GroupManager groupManager = GroupManagerWSBuilder.getInstance().getGroupManager(); - // RoleManager roleManager = RoleManagerWSBuilder.getInstance().getRoleManager(); - // long roleId = roleManager.getRoleIdByName(roleName); - // if(roleId > 0){ - // UserManager userManager = UserManagerWSBuilder.getInstance().getUserManager(); - // List users = null; - // long groupId = groupManager.getGroupIdFromInfrastructureScope(context); - // // first check if for any reason this is a global role, then (if result is null or exception arises) check for site role - // // Global role's users are retrieved much faster - // try{ - // if(GLOBAL_ROLES_ALLOWED_BY_LOCAL_CALL_METHOD.contains(roleName)){ - // // TODO inconsistent value can be returned - // users = userManager.listUsersByGlobalRole(roleId); - // } - // }catch(Exception globalExp){ - // logger.warn("Failed while checking for global role... trying with local one", globalExp); - // } - // - // if(users == null || users.isEmpty()){ - // logger.debug("User list is still null/empty, checking for local information"); - // users = userManager.listUsersByGroupAndRole(groupId, roleId); - // } - // - // if(users != null){ - // for (GCubeUser gCubeUser : users) { - // usernames.add(gCubeUser.getUsername()); - // } - // } - // responseBean.setResult(usernames); - // responseBean.setSuccess(true); - // }else{ - // responseBean.setMessage("No role exists whit such a name"); - // status = Status.BAD_REQUEST; - // } - // }catch(Exception e){ - // logger.error("Unable to retrieve user's usernames", e); - // responseBean.setMessage(e.getMessage()); - // status = Status.INTERNAL_SERVER_ERROR; - // } - return Response.status(status).entity(responseBean).build(); } - private static List searchByRole(Keycloak keycloak, String context, String roleName) { + private static List searchByRole(Keycloak keycloak, String realmName, String context, String roleName) { logger.info("Searching by role: {}", roleName); String clientIdContext = context.replace("/", "%2F") ; - List clients = keycloak.realm(REALM_NAME) + List clients = keycloak.realm(realmName) .clients().findByClientId(clientIdContext); String id = ""; @@ -591,7 +546,7 @@ public class Users { id =client.getId(); } - List users = keycloak.realm(REALM_NAME) + List users = keycloak.realm(realmName) .clients() .get(id).roles().get(roleName) .getUserMembers(0, 100000);