Other functionalities added to manage the correspondence between ckan and liferay roles map

git-svn-id: https://svn.d4science.research-infrastructures.eu/gcube/trunk/data-catalogue/ckan-util-library@129120 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
Costantino Perciante 2016-06-14 15:05:24 +00:00
parent 7f13048bde
commit 5c8605f1dc
7 changed files with 125 additions and 66 deletions

View File

@ -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();

View File

@ -4,8 +4,8 @@ import java.util.List;
import java.util.Map;
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.RolesIntoOrganization;
import eu.trentorise.opendata.jackan.model.CkanOrganization;
@ -16,9 +16,9 @@ import eu.trentorise.opendata.jackan.model.CkanOrganization;
public interface CKanUtilsInterface {
/**
* Retrieve the API_KEY given the username .
* Retrieve the API_KEY given the username (only if it is active).
* @param username
* @return an API_KEY string
* @return an API_KEY string on success, null otherwise
*/
public String getApiKeyFromUser(String username);
@ -44,13 +44,13 @@ public interface CKanUtilsInterface {
public List<String> getOrganizationsNamesByUser(String username);
/**
* Given a username and a list of roles to be matched, find the organizations to who the user
* belongs and the role(s) he has in them.
* Given a username and a list of roles to be matched, find the organizations in which the user has these roles.
* If the user is a sysadmin, for every organization in the map, the role will be present as well.
* @param username
* @param rolesToMatch
* @return
*/
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);
/**
* Return the ckan catalogue url in this scope.
@ -131,4 +131,20 @@ public interface CKanUtilsInterface {
* @return The url of the dataset on success, null otherwise
*/
public String getUrlFromDatasetIdOrName(String username, String datasetIdOrName);
/**
* Check if this user is a sysadmin
* @param username
* @return true on success, false otherwise
*/
public boolean isSysAdmin(String username);
/**
* Check if this role is present for this user in that organization. If it is not present we need to add it.
* @param username
* @param organizationName
* @param correspondentRoleToCheck
*/
void checkRole(String username, String organizationName,
RolesIntoOrganization correspondentRoleToCheck);
}

View File

@ -0,0 +1,12 @@
package org.gcube.datacatalogue.ckanutillibrary.models;
/**
* These roles are present in liferay and are a one to one map with the ones into ckan.
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public enum CkanRolesIntoLiferay {
CATALOG_MEMBER,
CATALOG_EDITOR,
CATALOG_ADMIN,
CATALOG_SYSADMIN
}

View File

@ -1,11 +0,0 @@
package org.gcube.datacatalogue.ckanutillibrary.models;
/**
* Roles that user can have into the group table
* @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it)
*
*/
public enum ROLES_IN_ORGANIZATION{
editor, admin, member
}

View File

@ -0,0 +1,12 @@
package org.gcube.datacatalogue.ckanutillibrary.models;
/**
* Roles that user can have into the member table (the sys_admin is into the user table)
* @author Costantino Perciante at ISTI-CNR (costantino.perciante@isti.cnr.it)
*/
public enum RolesIntoOrganization{
MEMBER,
EDITOR,
ADMIN,
SYSADMIN
}

View File

@ -5,6 +5,6 @@ package org.gcube.datacatalogue.ckanutillibrary.models;
* @author Costantino Perciante at ISTI-CNR
* (costantino.perciante@isti.cnr.it)
*/
public enum STATE{
deleted, active
public enum State{
DELETED, ACTIVE
}

View File

@ -5,7 +5,7 @@ import java.util.List;
import java.util.Map;
import org.gcube.datacatalogue.ckanutillibrary.models.CKanUserWrapper;
import org.gcube.datacatalogue.ckanutillibrary.models.ROLES_IN_ORGANIZATION;
import org.gcube.datacatalogue.ckanutillibrary.models.RolesIntoOrganization;
import org.slf4j.LoggerFactory;
import eu.trentorise.opendata.jackan.CheckedCkanClient;
@ -68,11 +68,11 @@ public class TestCKanLib {
logger.debug("Testing getGroupsAndRolesByUser");
String username = "francescomangiacrapa";
List<ROLES_IN_ORGANIZATION> rolesToMatch = new ArrayList<ROLES_IN_ORGANIZATION>();
rolesToMatch.add(ROLES_IN_ORGANIZATION.admin);
rolesToMatch.add(ROLES_IN_ORGANIZATION.member);
rolesToMatch.add(ROLES_IN_ORGANIZATION.editor);
Map<String, List<ROLES_IN_ORGANIZATION>> map = instance.getGroupsAndRolesByUser(username, rolesToMatch);
List<RolesIntoOrganization> rolesToMatch = new ArrayList<RolesIntoOrganization>();
rolesToMatch.add(RolesIntoOrganization.ADMIN);
rolesToMatch.add(RolesIntoOrganization.MEMBER);
rolesToMatch.add(RolesIntoOrganization.EDITOR);
Map<String, List<RolesIntoOrganization>> map = instance.getGroupsAndRolesByUser(username, rolesToMatch);
System.out.println("organizations for user " + username + " are " + map);
}