2018-12-04 12:06:22 +01:00
|
|
|
package org.gcube.gcat.persistence.ckan;
|
|
|
|
|
2019-09-12 14:26:24 +02:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
2019-02-27 17:36:09 +01:00
|
|
|
import javax.ws.rs.InternalServerErrorException;
|
|
|
|
import javax.ws.rs.WebApplicationException;
|
2019-09-12 14:26:24 +02:00
|
|
|
import javax.ws.rs.core.Response.Status;
|
2019-02-27 17:36:09 +01:00
|
|
|
|
2019-09-12 14:26:24 +02:00
|
|
|
import org.gcube.gcat.social.PortalUser;
|
|
|
|
import org.gcube.gcat.utils.ContextUtility;
|
2018-12-04 12:06:22 +01:00
|
|
|
import org.gcube.gcat.utils.RandomString;
|
2019-09-12 14:26:24 +02:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
2018-12-04 12:06:22 +01:00
|
|
|
|
|
|
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
|
|
*/
|
|
|
|
public class CKANUser extends CKAN {
|
|
|
|
|
2019-09-12 14:26:24 +02:00
|
|
|
private static final Logger logger = LoggerFactory.getLogger(CKANUser.class);
|
|
|
|
|
2018-12-04 12:06:22 +01:00
|
|
|
/* User Paths */
|
|
|
|
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.get.user_list
|
|
|
|
public static final String USER_LIST = CKAN.CKAN_API_PATH + "user_list";
|
|
|
|
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.create.user_create
|
|
|
|
public static final String USER_CREATE = CKAN.CKAN_API_PATH + "user_create";
|
|
|
|
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.get.user_show
|
|
|
|
public static final String USER_SHOW = CKAN.CKAN_API_PATH + "user_show";
|
|
|
|
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.update.user_update
|
|
|
|
public static final String USER_UPDATE = CKAN.CKAN_API_PATH + "user_update";
|
|
|
|
// see http://docs.ckan.org/en/latest/api/#ckan.logic.action.delete.user_delete
|
|
|
|
public static final String USER_DELETE = CKAN.CKAN_API_PATH + "user_delete";
|
|
|
|
|
2019-02-27 17:36:09 +01:00
|
|
|
public static final String ADD_USER_TO_GROUP = CKAN.CKAN_API_PATH + "member_create";
|
2018-12-04 12:06:22 +01:00
|
|
|
|
2019-09-12 14:26:24 +02:00
|
|
|
public static final String NAME = "name";
|
2019-09-12 16:05:45 +02:00
|
|
|
public static final String DISPLAY_NAME = "display_name";
|
|
|
|
public static final String FULL_NAME = "fullname";
|
|
|
|
public static final String ABOUT = "about";
|
2019-09-12 14:26:24 +02:00
|
|
|
public static final String EMAIL = "email";
|
|
|
|
public static final String PASSWORD = "password";
|
|
|
|
|
2019-09-12 16:05:45 +02:00
|
|
|
|
2019-09-12 14:26:24 +02:00
|
|
|
private static final String API_KEY = "apikey";
|
|
|
|
|
|
|
|
public enum Role {
|
|
|
|
MEMBER("Catalogue-Member", "member"),
|
|
|
|
EDITOR("Catalogue-Editor", "editor"),
|
|
|
|
ADMIN("Catalogue-Admin", "admin");
|
|
|
|
|
|
|
|
private final String portalRole;
|
|
|
|
private final String ckanRole;
|
|
|
|
|
|
|
|
Role(String portalRole, String ckanRole) {
|
|
|
|
this.portalRole = portalRole;
|
|
|
|
this.ckanRole = ckanRole;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getPortalRole() {
|
|
|
|
return portalRole;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getCkanRole() {
|
|
|
|
return ckanRole;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static final Map<String, Role> ROLE_BY_PORTAL_ROLE;
|
|
|
|
protected static final Map<String, Role> ROLE_BY_CKAN_ROLE;
|
|
|
|
|
|
|
|
static {
|
|
|
|
ROLE_BY_PORTAL_ROLE = new HashMap<String, Role>();
|
|
|
|
|
|
|
|
// null or empty string identify a member
|
|
|
|
ROLE_BY_PORTAL_ROLE.put(null, MEMBER);
|
|
|
|
ROLE_BY_PORTAL_ROLE.put("", MEMBER);
|
|
|
|
|
|
|
|
ROLE_BY_CKAN_ROLE = new HashMap<String, Role>();
|
|
|
|
|
|
|
|
for(Role role : Role.values()) {
|
|
|
|
ROLE_BY_PORTAL_ROLE.put(role.getPortalRole(), role);
|
|
|
|
ROLE_BY_CKAN_ROLE.put(role.getCkanRole(), role);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Role getRoleFromPortalRole(String portalRole) {
|
|
|
|
return ROLE_BY_PORTAL_ROLE.get(portalRole);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getCkanRoleFromPortalRole(String portalRole) {
|
|
|
|
return getRoleFromPortalRole(portalRole).getCkanRole();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static Role getRoleFromCkanRole(String ckanRole) {
|
|
|
|
return ROLE_BY_CKAN_ROLE.get(ckanRole);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getPortalRoleFromCkanRole(String ckanRole) {
|
|
|
|
return getRoleFromCkanRole(ckanRole).getPortalRole();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static final InheritableThreadLocal<CKANUser> currentCkanUser = new InheritableThreadLocal<CKANUser>() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected CKANUser initialValue() {
|
|
|
|
CKANUser ckanUser = new CKANUser();
|
|
|
|
ckanUser.retrieve();
|
|
|
|
return ckanUser;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
public static CKANUser getCurrentCKANUser() {
|
|
|
|
return currentCkanUser.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected PortalUser portalUser;
|
|
|
|
protected Role role;
|
|
|
|
|
2018-12-04 12:06:22 +01:00
|
|
|
public CKANUser() {
|
|
|
|
super();
|
|
|
|
LIST = USER_LIST;
|
|
|
|
CREATE = USER_CREATE;
|
|
|
|
READ = USER_SHOW;
|
|
|
|
UPDATE = USER_UPDATE;
|
|
|
|
PATCH = null;
|
|
|
|
DELETE = USER_DELETE;
|
|
|
|
PURGE = null;
|
|
|
|
}
|
|
|
|
|
2019-09-12 14:26:24 +02:00
|
|
|
|
2018-12-04 12:06:22 +01:00
|
|
|
|
|
|
|
public String create() {
|
|
|
|
RandomString randomString = new RandomString(12);
|
|
|
|
ObjectNode objectNode = mapper.createObjectNode();
|
|
|
|
objectNode.put(NAME, name);
|
|
|
|
objectNode.put(PASSWORD, randomString.nextString());
|
2019-09-12 16:05:45 +02:00
|
|
|
checkAndSetEMail(objectNode);
|
|
|
|
checkAndSetFullName(objectNode);
|
|
|
|
checkAndSetJobTitle(objectNode);
|
2018-12-04 12:06:22 +01:00
|
|
|
return create(getAsString(objectNode));
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void delete(boolean purge) {
|
|
|
|
this.delete();
|
|
|
|
}
|
|
|
|
|
2019-09-12 16:05:45 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param objectNode
|
|
|
|
* @return true if the display name and the full name has been updated in objectNode
|
|
|
|
*/
|
|
|
|
private boolean checkAndSetJobTitle(ObjectNode objectNode) {
|
|
|
|
String portalJobTitle = getPortalUser().getJobTitle();
|
|
|
|
|
|
|
|
String ckanJobTitle = "";
|
|
|
|
if(objectNode.has(ABOUT)) {
|
|
|
|
ckanJobTitle = objectNode.get(ABOUT).asText();
|
|
|
|
}
|
|
|
|
if(portalJobTitle.compareTo(ckanJobTitle)!=0){
|
|
|
|
objectNode = (ObjectNode) result;
|
|
|
|
objectNode.put(ABOUT, portalJobTitle);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param objectNode
|
|
|
|
* @return true if the display name and the full name has been updated in objectNode
|
|
|
|
*/
|
|
|
|
private boolean checkAndSetFullName(ObjectNode objectNode) {
|
|
|
|
String portalFullname = getPortalUser().getFullName();
|
|
|
|
|
|
|
|
String ckanFullname = "";
|
|
|
|
if(objectNode.has(FULL_NAME)) {
|
|
|
|
ckanFullname = objectNode.get(FULL_NAME).asText();
|
|
|
|
}
|
|
|
|
if(portalFullname.compareTo(ckanFullname)!=0){
|
|
|
|
objectNode = (ObjectNode) result;
|
|
|
|
objectNode.put(FULL_NAME, portalFullname);
|
|
|
|
objectNode.put(DISPLAY_NAME, portalFullname);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param objectNode
|
|
|
|
* @return true if the display name and the full name has been updated
|
|
|
|
*/
|
|
|
|
private boolean checkAndSetEMail(ObjectNode objectNode) {
|
|
|
|
String portalEmail = getPortalUser().getEMail();
|
|
|
|
|
|
|
|
String ckanEmail = "";
|
|
|
|
if(objectNode.has(EMAIL)) {
|
|
|
|
ckanEmail = objectNode.get(EMAIL).asText();
|
|
|
|
}
|
|
|
|
if(portalEmail.compareTo(ckanEmail)!=0){
|
|
|
|
objectNode = (ObjectNode) result;
|
|
|
|
objectNode.put(EMAIL, portalEmail);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the user profile on CKAN if the got got informations differs from the portal information
|
|
|
|
* @return true if the profile information has been updated
|
|
|
|
*/
|
|
|
|
protected boolean updateProfileIfNeeded() {
|
|
|
|
ObjectNode objectNode = (ObjectNode) result;
|
|
|
|
boolean toBeUpdated = false;
|
|
|
|
|
|
|
|
toBeUpdated = checkAndSetEMail(objectNode) || toBeUpdated;
|
|
|
|
toBeUpdated = checkAndSetFullName(objectNode) || toBeUpdated;
|
|
|
|
toBeUpdated = checkAndSetJobTitle(objectNode) || toBeUpdated;
|
|
|
|
|
|
|
|
if(toBeUpdated) {
|
|
|
|
update(getAsString(objectNode));
|
|
|
|
}
|
|
|
|
return toBeUpdated;
|
|
|
|
}
|
2019-02-27 17:36:09 +01:00
|
|
|
|
2019-09-12 14:26:24 +02:00
|
|
|
private void retrieve() {
|
|
|
|
setApiKey(CKANUtility.getSysAdminAPI());
|
|
|
|
try {
|
|
|
|
if(name==null || name.compareTo("")==0) {
|
|
|
|
setName(getCKANUsername());
|
|
|
|
}
|
|
|
|
read();
|
2019-09-12 16:05:45 +02:00
|
|
|
updateProfileIfNeeded();
|
2019-09-12 14:26:24 +02:00
|
|
|
} catch(WebApplicationException e) {
|
|
|
|
if(e.getResponse().getStatusInfo() == Status.NOT_FOUND) {
|
|
|
|
create();
|
|
|
|
}else {
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
addUserToOrganization();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void parseResult() {
|
|
|
|
name = result.get(NAME).asText();
|
|
|
|
apiKey = result.get(API_KEY).asText();
|
|
|
|
}
|
|
|
|
|
|
|
|
protected static String getCKANUsername(String username){
|
|
|
|
if(username == null)
|
|
|
|
return null;
|
|
|
|
return username.trim().replaceAll("\\.", "_");
|
|
|
|
}
|
|
|
|
|
|
|
|
public static String getCKANUsername() {
|
|
|
|
return getCKANUsername(ContextUtility.getUsername());
|
|
|
|
}
|
|
|
|
|
|
|
|
public String read() {
|
|
|
|
String ret = super.read();
|
|
|
|
parseResult();
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void addUserToOrganization(String organizationName, String ckanUsername, String role) {
|
|
|
|
logger.trace("Going to add user {} to organization {} with role {}", ckanUsername, organizationName, role);
|
|
|
|
CKANOrganization ckanOrganization = new CKANOrganization();
|
|
|
|
ckanOrganization.setApiKey(CKANUtility.getSysAdminAPI());
|
|
|
|
ckanOrganization.setName(organizationName);
|
|
|
|
ckanOrganization.addUserToOrganisation(ckanUsername, role);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Role getRole() {
|
|
|
|
if(role==null) {
|
|
|
|
role = Role.MEMBER;
|
|
|
|
List<String> roles = getPortalUser().getRoles();
|
|
|
|
for(String portalRole : roles){
|
|
|
|
Role gotRole = Role.getRoleFromPortalRole(portalRole);
|
|
|
|
if(gotRole!=null && gotRole.ordinal()>role.ordinal()){
|
|
|
|
role = gotRole;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return role;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addUserToOrganization(String organizationName) {
|
|
|
|
addUserToOrganization(organizationName, name, getRole().getCkanRole());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addUserToOrganization() {
|
|
|
|
String organizationName = CKANOrganization.getCKANOrganizationName();
|
|
|
|
addUserToOrganization(organizationName);
|
|
|
|
}
|
|
|
|
|
2019-02-27 17:36:09 +01:00
|
|
|
public void addToGroup(String groupName) throws WebApplicationException {
|
|
|
|
try {
|
|
|
|
ObjectNode objectNode = mapper.createObjectNode();
|
2019-09-12 16:05:45 +02:00
|
|
|
objectNode.put(ID_KEY, CKANGroup.getCKANGroupName(groupName));
|
2019-02-27 17:36:09 +01:00
|
|
|
objectNode.put("object", name);
|
|
|
|
objectNode.put("object_type", "user");
|
|
|
|
objectNode.put("capacity", "member");
|
|
|
|
sendPostRequest(ADD_USER_TO_GROUP, getAsString(objectNode));
|
|
|
|
}catch (WebApplicationException e) {
|
|
|
|
throw e;
|
|
|
|
}catch (Exception e) {
|
|
|
|
throw new InternalServerErrorException(e);
|
|
|
|
}
|
|
|
|
}
|
2019-09-12 14:26:24 +02:00
|
|
|
|
|
|
|
public PortalUser getPortalUser() {
|
|
|
|
if(portalUser==null) {
|
|
|
|
portalUser = new PortalUser();
|
|
|
|
}
|
|
|
|
return portalUser;
|
|
|
|
}
|
|
|
|
|
2018-12-04 12:06:22 +01:00
|
|
|
}
|