|
|
|
@ -20,9 +20,9 @@ import net.htmlparser.jericho.Source;
|
|
|
|
|
import org.gcube.common.encryption.StringEncrypter;
|
|
|
|
|
import org.gcube.common.scope.api.ScopeProvider;
|
|
|
|
|
import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper;
|
|
|
|
|
import org.gcube.datacatalogue.ckanutillibrary.models.ROLES_IN_ORGANIZATION;
|
|
|
|
|
import org.gcube.datacatalogue.ckanutillibrary.models.ResourceBean;
|
|
|
|
|
import org.gcube.datacatalogue.ckanutillibrary.models.STATE;
|
|
|
|
|
import org.gcube.datacatalogue.ckanutillibrary.models.RolesIntoOrganization;
|
|
|
|
|
import org.gcube.datacatalogue.ckanutillibrary.models.State;
|
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
|
@ -40,6 +40,7 @@ import eu.trentorise.opendata.jackan.model.CkanOrganization;
|
|
|
|
|
import eu.trentorise.opendata.jackan.model.CkanPair;
|
|
|
|
|
import eu.trentorise.opendata.jackan.model.CkanResource;
|
|
|
|
|
import eu.trentorise.opendata.jackan.model.CkanTag;
|
|
|
|
|
import eu.trentorise.opendata.jackan.model.CkanUser;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This is the Ckan Utils implementation class.
|
|
|
|
@ -64,7 +65,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
String currentScope = ScopeProvider.instance.get();
|
|
|
|
|
|
|
|
|
|
try{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ScopeProvider.instance.set(scope);
|
|
|
|
|
CKanRunningCluster runningInstance = new CKanRunningCluster(scope);
|
|
|
|
|
CKAN_DB_URL = runningInstance.getDatabaseHosts().get(0);
|
|
|
|
@ -72,7 +73,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
CKAN_DB_USER = runningInstance.getDataBaseUser();
|
|
|
|
|
CKAN_DB_PASSWORD = StringEncrypter.getEncrypter().decrypt(runningInstance.getDataBasePassword());
|
|
|
|
|
logger.debug("Plain password first 3 chars are " + CKAN_DB_PASSWORD.substring(0, 3));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CKAN_DB_PORT = runningInstance.getDatabasePorts().get(0);
|
|
|
|
|
CKAN_CATALOGUE_URL = runningInstance.getDataCatalogueUrl().get(0);
|
|
|
|
|
|
|
|
|
@ -80,7 +81,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
Class.forName("org.postgresql.Driver");
|
|
|
|
|
connection = DriverManager.getConnection(
|
|
|
|
|
"jdbc:postgresql://" + CKAN_DB_URL + ":" + CKAN_DB_PORT + "/" + CKAN_DB_NAME, CKAN_DB_USER, CKAN_DB_PASSWORD);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}catch(Exception e){
|
|
|
|
|
logger.error("Error while trying to connect to ckan database/catalogue ", e);
|
|
|
|
|
}finally{
|
|
|
|
@ -93,16 +94,17 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String getApiKeyFromUser(String username) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// in order to avoid errors, the username is always converted
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug("Request api key for user = " + username);
|
|
|
|
|
String apiToReturn = null;
|
|
|
|
|
try{
|
|
|
|
|
String query = "SELECT \"apikey\" FROM \"user\" WHERE \"name\"=?";
|
|
|
|
|
String query = "SELECT \"apikey\" FROM \"user\" WHERE \"name\"=? and \"state\"=?;";
|
|
|
|
|
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
|
|
|
|
preparedStatement.setString(1, ckanUsername);
|
|
|
|
|
preparedStatement.setString(2, State.ACTIVE.toString());
|
|
|
|
|
|
|
|
|
|
ResultSet rs = preparedStatement.executeQuery();
|
|
|
|
|
while (rs.next()) {
|
|
|
|
@ -122,14 +124,16 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
logger.debug("Request user whose api key is = " + apiKey);
|
|
|
|
|
CKanUserWrapper user = new CKanUserWrapper();
|
|
|
|
|
try{
|
|
|
|
|
String query = "SELECT * FROM \"user\" WHERE \"apikey\"=?;";
|
|
|
|
|
String query = "SELECT * FROM \"user\" WHERE \"apikey\"=? and \"state\"=?;";
|
|
|
|
|
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
|
|
|
|
preparedStatement.setString(1, apiKey);
|
|
|
|
|
preparedStatement.setString(2, State.ACTIVE.toString());
|
|
|
|
|
|
|
|
|
|
ResultSet rs = preparedStatement.executeQuery();
|
|
|
|
|
while (rs.next()) {
|
|
|
|
|
|
|
|
|
|
// check if it is active
|
|
|
|
|
if(STATE.deleted.equals(rs.getString("state")))
|
|
|
|
|
if(State.DELETED.equals(rs.getString("state")))
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
user.setId(rs.getString("id"));
|
|
|
|
@ -155,10 +159,10 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
public List<CkanOrganization> getOrganizationsByUser(String username) {
|
|
|
|
|
|
|
|
|
|
logger.debug("Requested organizations for user " + username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// in order to avoid errors, the username is always converted
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<String> organizationIds = getOrganizationsIds();
|
|
|
|
|
String userId = getUserIdByUsername(ckanUsername);
|
|
|
|
|
|
|
|
|
@ -171,12 +175,12 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
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\"=?; ";
|
|
|
|
|
String query = "SELECT * FROM \"member\" WHERE \"table_id\"=? and \"group_id\"=? and \"table_name\"=? and \"state\"=?;";
|
|
|
|
|
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
|
|
|
|
preparedStatement.setString(1, userId);
|
|
|
|
|
preparedStatement.setString(2, orgId);
|
|
|
|
|
preparedStatement.setString(3, "user");
|
|
|
|
|
|
|
|
|
|
preparedStatement.setString(4, State.ACTIVE.toString());
|
|
|
|
|
ResultSet rs = preparedStatement.executeQuery();
|
|
|
|
|
while (rs.next()) {
|
|
|
|
|
// the role within the organization doesn't matter
|
|
|
|
@ -193,16 +197,23 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Map<String, List<ROLES_IN_ORGANIZATION>> getGroupsAndRolesByUser(
|
|
|
|
|
String username, List<ROLES_IN_ORGANIZATION> rolesToMatch) {
|
|
|
|
|
public Map<String, List<RolesIntoOrganization>> getGroupsAndRolesByUser(
|
|
|
|
|
String username, List<RolesIntoOrganization> 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>>();
|
|
|
|
|
Map<String, List<RolesIntoOrganization>> toReturn = new HashMap<String, List<RolesIntoOrganization>>();
|
|
|
|
|
|
|
|
|
|
// in order to avoid errors, the username is always converted
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// retrieve the user and if it is a sys_admin, for every organizations will be created in the map, add also
|
|
|
|
|
// the sys_admin role
|
|
|
|
|
boolean isSysAdmin = false;
|
|
|
|
|
if(rolesToMatch.contains(RolesIntoOrganization.SYSADMIN)){
|
|
|
|
|
isSysAdmin = isSysAdmin(ckanUsername);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try{
|
|
|
|
|
|
|
|
|
|
// get id from the user
|
|
|
|
@ -217,23 +228,27 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
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\"=?;";
|
|
|
|
|
String query = "SELECT * FROM \"member\" WHERE \"table_id\"=? and \"group_id\"=? and \"table_name\"=? and \"state\"=?;";
|
|
|
|
|
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
|
|
|
|
preparedStatement.setString(1, userId);
|
|
|
|
|
preparedStatement.setString(2, orgId);
|
|
|
|
|
preparedStatement.setString(3, "user");
|
|
|
|
|
preparedStatement.setString(4, "active");
|
|
|
|
|
ResultSet rs = preparedStatement.executeQuery();
|
|
|
|
|
|
|
|
|
|
// prepare the data to put into the hashmap
|
|
|
|
|
List<ROLES_IN_ORGANIZATION> rolesIntoOrg = new ArrayList<ROLES_IN_ORGANIZATION>();
|
|
|
|
|
List<RolesIntoOrganization> rolesIntoOrg = new ArrayList<RolesIntoOrganization>();
|
|
|
|
|
|
|
|
|
|
if(isSysAdmin)
|
|
|
|
|
rolesIntoOrg.add(RolesIntoOrganization.SYSADMIN);
|
|
|
|
|
|
|
|
|
|
while(rs.next()){
|
|
|
|
|
|
|
|
|
|
// check
|
|
|
|
|
String role = rs.getString("capacity");
|
|
|
|
|
if(rolesToMatch.contains(ROLES_IN_ORGANIZATION.valueOf(role))){
|
|
|
|
|
if(rolesToMatch.contains(RolesIntoOrganization.valueOf(role))){
|
|
|
|
|
|
|
|
|
|
rolesIntoOrg.add(ROLES_IN_ORGANIZATION.valueOf(role));
|
|
|
|
|
rolesIntoOrg.add(RolesIntoOrganization.valueOf(role));
|
|
|
|
|
logger.debug("User " + ckanUsername + " has role " + role + " into organization " + ckanOrganization.getName());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -255,7 +270,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
*/
|
|
|
|
|
private String getUserIdByUsername(String username) {
|
|
|
|
|
logger.debug("Request user id whose username is = " + username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// in order to avoid errors, the username is always converted
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
|
|
|
|
|
|
|
|
@ -264,7 +279,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
String query = "SELECT \"id\" FROM \"user\" WHERE \"name\"=? and \"state\"=?;";
|
|
|
|
|
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
|
|
|
|
preparedStatement.setString(1, ckanUsername);
|
|
|
|
|
preparedStatement.setString(2, STATE.active.toString());
|
|
|
|
|
preparedStatement.setString(2, State.ACTIVE.toString());
|
|
|
|
|
ResultSet rs = preparedStatement.executeQuery();
|
|
|
|
|
while (rs.next()) {
|
|
|
|
|
userId = rs.getString("id");
|
|
|
|
@ -290,7 +305,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
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());
|
|
|
|
|
preparedStatement.setString(2, State.ACTIVE.toString());
|
|
|
|
|
ResultSet rs = preparedStatement.executeQuery();
|
|
|
|
|
while (rs.next()) {
|
|
|
|
|
toReturn.add(rs.getString("id"));
|
|
|
|
@ -314,12 +329,12 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<String> getOrganizationsNamesByUser(String username) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug("Requested organizations for user " + username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// in order to avoid errors, the username is always converted
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<CkanOrganization> orgs = getOrganizationsByUser(ckanUsername);
|
|
|
|
|
List<String> orgsName = new ArrayList<String>();
|
|
|
|
|
for (CkanOrganization ckanOrganization : orgs) {
|
|
|
|
@ -380,10 +395,10 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
String pathSetPrivate = "/api/3/action/bulk_update_private";
|
|
|
|
|
String pathSetPublic = "/api/3/action/bulk_update_public";
|
|
|
|
|
String token = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// in order to avoid errors, the username is always converted
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(ckanUsername == null || ckanUsername.isEmpty()){
|
|
|
|
|
logger.error("The owner parameter is mandatory");
|
|
|
|
|
return false;
|
|
|
|
@ -454,7 +469,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
* @param URLName
|
|
|
|
|
* @return
|
|
|
|
|
*/
|
|
|
|
|
private static boolean exists(String URLName){
|
|
|
|
|
private static boolean resourceExists(String URLName){
|
|
|
|
|
try {
|
|
|
|
|
HttpURLConnection.setFollowRedirects(true);
|
|
|
|
|
HttpURLConnection con = (HttpURLConnection) new URL(URLName).openConnection();
|
|
|
|
@ -474,14 +489,14 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
logger.debug("Request to add a resource described by this bean " + resourceBean);
|
|
|
|
|
|
|
|
|
|
try{
|
|
|
|
|
if(exists(resourceBean.getUrl())){
|
|
|
|
|
if(resourceExists(resourceBean.getUrl())){
|
|
|
|
|
|
|
|
|
|
// retrieve ckan's catalog url
|
|
|
|
|
String ckanPortalUrl = getCatalogueUrl();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// in order to avoid errors, the username is always converted
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(resourceBean.getOwner());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// retrieve the api key for this user
|
|
|
|
|
String apiKey = getApiKeyFromUser(ckanUsername);
|
|
|
|
|
|
|
|
|
@ -520,7 +535,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
public boolean deleteResourceFromDataset(String username, String resourceId) {
|
|
|
|
|
|
|
|
|
|
logger.error("Request to delete a resource with id " + resourceId + " coming by user " + username);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// in order to avoid errors, the username is always converted
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
|
|
|
|
|
|
|
|
@ -562,7 +577,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
List<ResourceBean> resources, boolean setPublic) {
|
|
|
|
|
|
|
|
|
|
logger.debug("Request for dataset creation");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// in order to avoid errors, the username is always converted
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
|
|
|
|
|
|
|
|
@ -664,7 +679,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
res = client.createDataset(dataset);
|
|
|
|
|
|
|
|
|
|
if(res != null){
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
logger.debug("Dataset with name " + res.getName() + " has been created. Setting visibility");
|
|
|
|
|
|
|
|
|
|
// set visibility
|
|
|
|
@ -684,7 +699,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
logger.error("Error while creating the dataset, probably it already exists.", e);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -692,7 +707,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
public String getUrlFromDatasetIdOrName(String username, String datasetIdOrName) {
|
|
|
|
|
|
|
|
|
|
logger.debug("Request coming for dataset url of dataset with name/id " + datasetIdOrName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
|
|
|
|
|
|
|
|
|
// the url of the dataset looks like "getCatalogueUrl() + /dataset/ + dataset name"
|
|
|
|
@ -708,7 +723,7 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Ckan username has _ instead of . (that is, costantino.perciante -> costantino_perciante)
|
|
|
|
|
* @param owner
|
|
|
|
@ -717,7 +732,22 @@ public class CKanUtilsImpl implements CKanUtilsInterface{
|
|
|
|
|
private static String fromOwnerToCKanOwner(String owner){
|
|
|
|
|
return owner.replaceAll("\\.", "_");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void checkRole(String username, String organizationName,
|
|
|
|
|
RolesIntoOrganization correspondentRoleToCheck) {
|
|
|
|
|
// TODO it must be defined
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isSysAdmin(String username) {
|
|
|
|
|
// in order to avoid errors, the username is always converted
|
|
|
|
|
String ckanUsername = fromOwnerToCKanOwner(username);
|
|
|
|
|
CheckedCkanClient checkedClient = new CheckedCkanClient(getCatalogueUrl(), getApiKeyFromUser(ckanUsername));
|
|
|
|
|
CkanUser user = checkedClient.getUser(getUserIdByUsername(ckanUsername));
|
|
|
|
|
return user.isSysadmin();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
protected void finalize() throws Throwable {
|
|
|
|
|
super.finalize();
|
|
|
|
|