ckan-util-library/src/main/java/org/gcube/datacatalogue/ckanutillibrary/CKanUtilsImpl.java

323 lines
10 KiB
Java

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<CkanOrganization> getOrganizationsByUser(String username) {
logger.debug("Requested organizations for user " + username);
List<String> organizationIds = getOrganizationsIds();
String userId = getUserIdByUsername(username);
// list to return
List<CkanOrganization> toReturn = new ArrayList<CkanOrganization>();
// 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<String, List<ROLES_IN_ORGANIZATION>> getGroupsAndRolesByUser(
String username, List<ROLES_IN_ORGANIZATION> rolesToMatch) {
logger.debug("Requested roles the user " + username + " has into its organizations");
logger.debug("Roles to check are " + rolesToMatch);
Map<String, List<ROLES_IN_ORGANIZATION>> toReturn = new HashMap<String, List<ROLES_IN_ORGANIZATION>>();
try{
// get id from the user
String userId = getUserIdByUsername(username);
// use the above method to require the list of user's organizations
List<CkanOrganization> 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<ROLES_IN_ORGANIZATION> rolesIntoOrg = new ArrayList<ROLES_IN_ORGANIZATION>();
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<String> getOrganizationsIds(){
logger.debug("Request organization ids");
List<String> toReturn = new ArrayList<String>();
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<String> getOrganizationsNamesByUser(String username) {
List<CkanOrganization> orgs = getOrganizationsByUser(username);
List<String> orgsName = new ArrayList<String>();
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<CkanLicense> licenses = client.getLicenseList();
for (CkanLicense ckanLicense : licenses) {
if(ckanLicense.getTitle().equals(chosenLicense))
return ckanLicense.getId();
}
return null;
}
@Override
public List<String> getLicenseTitles() {
logger.info("Request for CKAN licenses");
// get the url and the api key of the user
String ckanPortalUrl = getCatalogueUrl();
List<String> result = new ArrayList<String>();
CkanClient client = new CkanClient(ckanPortalUrl);
//retrieve the list of available licenses
List<CkanLicense> licenses = client.getLicenseList();
for (CkanLicense ckanLicense : licenses) {
result.add(ckanLicense.getTitle());
logger.debug("License is " + ckanLicense.getTitle() + " and id " + ckanLicense.getId());
}
return result;
}
}