package org.gcube.datacatalogue.ckanutillibrary.db; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import org.gcube.datacatalogue.ckanutillibrary.shared.RolesCkanGroupOrOrg; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // TODO: Auto-generated Javadoc /** * The Class DBCaller. * * @author Francesco Mangiacrapa at ISTI-CNR Pisa (Italy) * Jun 1, 2020 */ public class DBCaller { private static final Logger LOG = LoggerFactory.getLogger(DBCaller.class); private String CKAN_DB_URL; private Integer CKAN_DB_PORT; private String CKAN_DB_NAME; private String CKAN_DB_USER; private String CKAN_DB_PASSWORD; /** * Instantiates a new DB caller. */ public DBCaller() { } /** * Instantiates a new DB caller. * * @param cKAN_DB_URL the c KA N D B URL * @param cKAN_DB_PORT the c KA N D B PORT * @param cKAN_DB_NAME the c KA N D B NAME * @param cKAN_DB_USER the c KA N D B USER * @param cKAN_DB_PASSWORD the c KA N D B PASSWORD */ public DBCaller(String cKAN_DB_URL, Integer cKAN_DB_PORT, String cKAN_DB_NAME, String cKAN_DB_USER, String cKAN_DB_PASSWORD) { CKAN_DB_URL = cKAN_DB_URL; CKAN_DB_PORT = cKAN_DB_PORT; CKAN_DB_NAME = cKAN_DB_NAME; CKAN_DB_USER = cKAN_DB_USER; CKAN_DB_PASSWORD = cKAN_DB_PASSWORD; } /** * Retrieve connection from the pool. * * @return a connection available within the pool * @throws SQLException the SQL exception * @throws ClassNotFoundException the class not found exception */ private Connection getConnection() throws SQLException, ClassNotFoundException{ LOG.trace("CONNECTION REQUEST"); // create db connection Class.forName("org.postgresql.Driver"); String dbBaseConnectionURL = String.format("jdbc:postgresql://%s", CKAN_DB_URL); if(CKAN_DB_PORT!=null) dbBaseConnectionURL+=":" + CKAN_DB_PORT; dbBaseConnectionURL+="/" + CKAN_DB_NAME; LOG.debug("DB CONNECTION URL: "+dbBaseConnectionURL); Connection connection = DriverManager.getConnection(dbBaseConnectionURL, CKAN_DB_USER, CKAN_DB_PASSWORD); // Connection connection = DriverManager.getConnection( // "jdbc:postgresql://" + CKAN_DB_URL + ":" + CKAN_DB_PORT + "/" + CKAN_DB_NAME, CKAN_DB_USER, CKAN_DB_PASSWORD); return connection; } /** * Retrieve the map (groups id, capacity) with the groups to which the user belongs by querying directly the database. * * @param username the username * @return the groups by user from DB */ public Map getGroupsByUserFromDB(String username){ checkNotNull(username); LOG.debug("Get groups by user called"); //couples (groups id, capacity) of the user in the group Map toReturn = new HashMap(); Connection connection = null; try{ String userId = getUserIdForUsername(username); connection = getConnection(); String joinQuery = "SELECT \"group_id\",\"capacity\" FROM \"public\".\"member\" " + "JOIN \"public\".\"group\" ON \"member\".\"group_id\" = \"group\".\"id\" where \"table_id\"=?" + " and \"table_name\"='user' and \"member\".\"state\"='active' and \"group\".\"state\"='active' and \"group\".\"is_organization\"=?;"; LOG.debug("Performing query: "+joinQuery); PreparedStatement preparedStatement = connection.prepareStatement(joinQuery); preparedStatement.setString(1, userId); preparedStatement.setBoolean(2, false); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { toReturn.put(rs.getString("group_id"), RolesCkanGroupOrOrg.convertFromCapacity(rs.getString("capacity"))); } }catch(Exception e){ LOG.error("Failed to retrieve the groups to whom the user belongs. Error is " + e.getMessage()); return null; }finally{ closeConnection(connection); } return toReturn; } /** * Gets the user id for username. * * @param username the username * @return the user id for username */ private String getUserIdForUsername(String username) { LOG.debug("Get user id for username called"); Connection connection = null; String userId = null; try{ connection = getConnection(); String selQuery = "SELECT \"id\" FROM \"public\".\"user\" WHERE \"name\"=?;"; LOG.info("Performing query: "+selQuery); PreparedStatement preparedStatement = connection.prepareStatement(selQuery); preparedStatement.setString(1, username); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { userId = rs.getString("id"); break; } LOG.debug("For username "+username+" returning the user id: "+userId); return userId; }catch(Exception e){ LOG.error("Failed to retrieve the user id for username:"+username+". Error is " + e.getMessage()); return null; }finally{ closeConnection(connection); } } /** * Retrieve the map (organisation id, capacity) with the organisations to which the user belongs by querying directly the database. * * @param username the username * @return the organizations by user from DB */ public Map getOrganizationsByUserFromDB(String username){ LOG.debug("Get organisations by user called"); checkNotNull(username); Map toReturn = new HashMap(); Connection connection = null; try{ String userId = getUserIdForUsername(username); connection = getConnection(); ResultSet rs; String joinQuery = "SELECT \"group_id\",\"capacity\" FROM \"public\".\"member\" " + "JOIN \"public\".\"group\" ON \"member\".\"group_id\" = \"group\".\"id\" where \"table_id\"=?" + " and \"table_name\"='user' and \"member\".\"state\"='active' and \"group\".\"state\"='active' and \"group\".\"is_organization\"=?;"; PreparedStatement preparedStatement = connection.prepareStatement(joinQuery); preparedStatement.setString(1, userId); preparedStatement.setBoolean(2, true); rs = preparedStatement.executeQuery(); while (rs.next()) { toReturn.put(rs.getString("group_id"), RolesCkanGroupOrOrg.convertFromCapacity(rs.getString("capacity"))); } }catch(Exception e){ LOG.error("Failed to retrieve the groups to whom the user belongs. Error is " + e.getMessage()); return null; }finally{ closeConnection(connection); } return toReturn; } /** * Gets the api key from username. * * @param username the username * @param state the state * @return the api key from username */ public String getApiKeyFromUsername(String username, String state) { LOG.debug("Request api key for user = " + username); // checks checkNotNull(username); checkArgument(!username.isEmpty()); // the connection Connection connection = null; String apiToReturn = null; try{ connection = getConnection(); String query = "SELECT \"apikey\" FROM \"user\" WHERE \"name\"=? and \"state\"=?;"; PreparedStatement preparedStatement = connection.prepareStatement(query); preparedStatement.setString(1, username); preparedStatement.setString(2, state); ResultSet rs = preparedStatement.executeQuery(); while (rs.next()) { apiToReturn = rs.getString("apikey"); LOG.debug("Api key "+apiToReturn.substring(0,10)+" MASKED-TOKEN retrieved for user " + username); break; } return apiToReturn; }catch(Exception e){ LOG.error("Unable to retrieve key for user " + username, e); }finally{ closeConnection(connection); } return null; } /** * Tries to close a connection. * * @param connection the connection */ private void closeConnection(Connection connection){ if(connection != null){ try{ connection.close(); LOG.trace("CONNECTION CLOSED"); }catch(Exception e){ LOG.error("Unable to close this connection ", e); } } } }