package org.gcube.datacatalogue.ckanutillibrary; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.gcube.common.encryption.StringEncrypter; import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper; import org.gcube.datacatalogue.ckanutillibrary.models.ROLES_IN_ORGANIZATION; import org.gcube.datacatalogue.ckanutillibrary.models.STATE; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.trentorise.opendata.jackan.CkanClient; import eu.trentorise.opendata.jackan.model.CkanLicense; import eu.trentorise.opendata.jackan.model.CkanOrganization; /** * This is the Ckan Utils implementation class. * @author Costantino Perciante at ISTI-CNR * (costantino.perciante@isti.cnr.it) * */ public class CKanUtilsImpl implements CKanUtilsInterface{ private static final Logger logger = LoggerFactory.getLogger(CKanUtilsImpl.class); private String CKAN_CATALOGUE_URL; private String CKAN_DB_NAME; private String CKAN_DB_USER; private String CKAN_DB_PASSWORD; private Integer CKAN_DB_PORT; // Connection to the db private static Connection connection; public CKanUtilsImpl(String scope) throws Exception{ CKanRunningCluster runningInstance = new CKanRunningCluster(scope); CKAN_CATALOGUE_URL = runningInstance.getHosts().get(0); CKAN_DB_NAME = runningInstance.getDataBaseName(); CKAN_DB_USER = runningInstance.getDataBaseUser(); CKAN_DB_PASSWORD = StringEncrypter.getEncrypter().decrypt(runningInstance.getDataBasePassword(), scope); CKAN_DB_PORT = runningInstance.getPorts().get(0); // create db connection Class.forName("org.postgresql.Driver"); connection = DriverManager.getConnection( "jdbc:postgresql://" + CKAN_CATALOGUE_URL + ":" + CKAN_DB_PORT + "/" + CKAN_DB_NAME, CKAN_DB_USER, CKAN_DB_PASSWORD); } @Override public String getApiKeyFromUser(String username) { logger.debug("Request api key for user = " + username); String apiToReturn = null; try{ String query = "SELECT \"apikey\" FROM \"user\" WHERE \"name\"=?"; PreparedStatement preparedStatement = connection.prepareStatement(query); preparedStatement.setString(1, username); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { apiToReturn = rs.getString("apikey"); break; } }catch(Exception e){ logger.error("Unable to retrieve key for user " + username, e); } logger.debug("Api key retrieved for user " + username); return apiToReturn; } @Override public CKanUserWrapper getUserFromApiKey(String apiKey) { logger.debug("Request user whose api key is = " + apiKey); CKanUserWrapper user = new CKanUserWrapper(); try{ String query = "SELECT * FROM \"user\" WHERE \"apikey\"=?;"; PreparedStatement preparedStatement = connection.prepareStatement(query); preparedStatement.setString(1, apiKey); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { // check if it is active if(STATE.deleted.equals(rs.getString("state"))) break; user.setId(rs.getString("id")); user.setName(rs.getString("name")); user.setApiKey(apiKey); user.setCreationTimestamp(rs.getTimestamp("created").getTime()); user.setAbout(rs.getString("about")); user.setOpenId(rs.getString("openid")); user.setFullName(rs.getString("fullname")); user.setEmail(rs.getString("email")); user.setAdmin(rs.getBoolean("sysadmin")); break; } }catch(Exception e){ logger.error("Unable to retrieve user with api key " + apiKey); } logger.debug("User retrieved"); return user; } @Override public List getOrganizationsByUser(String username) { logger.debug("Requested organizations for user " + username); List organizationIds = getOrganizationsIds(); String userId = getUserIdByUsername(username); // list to return List toReturn = new ArrayList(); // get the CkanClient to retrieve the organization from the id CkanClient client = new CkanClient("https://ckan-d-d4s.d4science.org"); try{ // for each org id, check if the user is included for (String orgId : organizationIds) { String query = "SELECT * FROM \"member\" WHERE \"table_id\"=? and \"group_id\"=? and \"table_name\"=?; "; PreparedStatement preparedStatement = connection.prepareStatement(query); preparedStatement.setString(1, userId); preparedStatement.setString(2, orgId); preparedStatement.setString(3, "user"); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { // the role within the organization doesn't matter logger.debug("User " + username + " belongs to organization with id " + orgId); toReturn.add(client.getOrganization(orgId)); } } }catch(Exception e){ logger.error("Unable to get user's organizations", e); } return toReturn; } @Override public Map> getGroupsAndRolesByUser( String username, List rolesToMatch) { logger.debug("Requested roles the user " + username + " has into its organizations"); logger.debug("Roles to check are " + rolesToMatch); Map> toReturn = new HashMap>(); try{ // get id from the user String userId = getUserIdByUsername(username); // use the above method to require the list of user's organizations List usersOrganizations = getOrganizationsByUser(username); for (CkanOrganization ckanOrganization : usersOrganizations) { // get the org id String orgId = ckanOrganization.getId(); // go to the member table, that says which role has this user into the org String query = "SELECT * FROM \"member\" WHERE \"table_id\"=? and \"group_id\"=? and \"table_name\"=?;"; PreparedStatement preparedStatement = connection.prepareStatement(query); preparedStatement.setString(1, userId); preparedStatement.setString(2, orgId); preparedStatement.setString(3, "user"); ResultSet rs = preparedStatement.executeQuery(); // prepare the data to put into the hashmap List rolesIntoOrg = new ArrayList(); while(rs.next()){ // check String role = rs.getString("capacity"); if(rolesToMatch.contains(ROLES_IN_ORGANIZATION.valueOf(role))){ rolesIntoOrg.add(ROLES_IN_ORGANIZATION.valueOf(role)); System.out.println("User " + username + " has role " + role + " into organization " + ckanOrganization.getName()); } } if(!rolesIntoOrg.isEmpty()) toReturn.put(orgId, rolesIntoOrg); } }catch(Exception e){ logger.error("Unable to analyze user's roles", e); } return toReturn; } /** * Returns the user id given his username * @param username * @return the id on success, null otherwise */ private String getUserIdByUsername(String username) { logger.debug("Request user id whose username is = " + username); String userId = null; try{ String query = "SELECT \"id\" FROM \"user\" WHERE \"name\"=? and \"state\"=?;"; PreparedStatement preparedStatement = connection.prepareStatement(query); preparedStatement.setString(1, username); preparedStatement.setString(2, STATE.active.toString()); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { userId = rs.getString("id"); break; } }catch(Exception e){ logger.error("Unable to retrieve user with name " + username); } logger.debug("User id retrieved"); return userId; } /** * Retrieve the list of organizations ids * @return */ private List getOrganizationsIds(){ logger.debug("Request organization ids"); List toReturn = new ArrayList(); try{ String query = "SELECT \"id\" FROM \"group\" WHERE \"is_organization\"=? and \"state\"=?;"; PreparedStatement preparedStatement = connection.prepareStatement(query); preparedStatement.setBoolean(1, true); preparedStatement.setString(2, STATE.active.toString()); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { toReturn.add(rs.getString("id")); } }catch(Exception e){ logger.error("Unable to retrieve list of organization ids"); } logger.debug("Organizations' ids retrieved"); return toReturn; } @Override protected void finalize() throws Throwable { super.finalize(); logger.debug("Closing connection on finalize()"); connection.close(); } @Override public String getCatalogueUrl() { return "https://" + CKAN_CATALOGUE_URL; } @Override public List getOrganizationsNamesByUser(String username) { List orgs = getOrganizationsByUser(username); List orgsName = new ArrayList(); for (CkanOrganization ckanOrganization : orgs) { orgsName.add(ckanOrganization.getName()); logger.debug("Organization name is " + ckanOrganization.getName()); } return orgsName; } @Override public String findLicenseIdByLicense(String chosenLicense) { logger.debug("Requested license id"); String ckanPortalUrl = getCatalogueUrl(); CkanClient client = new CkanClient(ckanPortalUrl); //retrieve the list of available licenses List licenses = client.getLicenseList(); for (CkanLicense ckanLicense : licenses) { if(ckanLicense.getTitle().equals(chosenLicense)) return ckanLicense.getId(); } return null; } @Override public List getLicenseTitles() { logger.info("Request for CKAN licenses"); // get the url and the api key of the user String ckanPortalUrl = getCatalogueUrl(); List result = new ArrayList(); CkanClient client = new CkanClient(ckanPortalUrl); //retrieve the list of available licenses List licenses = client.getLicenseList(); for (CkanLicense ckanLicense : licenses) { result.add(ckanLicense.getTitle()); logger.debug("License is " + ckanLicense.getTitle() + " and id " + ckanLicense.getId()); } return result; } }