gcat/src/main/java/org/gcube/gcat/persistence/ckan/CKANUser.java

309 lines
8.6 KiB
Java

package org.gcube.gcat.persistence.ckan;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ws.rs.InternalServerErrorException;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response.Status;
import org.gcube.gcat.social.PortalUser;
import org.gcube.gcat.utils.ContextUtility;
import org.gcube.gcat.utils.RandomString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class CKANUser extends CKAN {
private static final Logger logger = LoggerFactory.getLogger(CKANUser.class);
/* 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";
public static final String ADD_USER_TO_GROUP = CKAN.CKAN_API_PATH + "member_create";
public static final String NAME = "name";
public static final String DISPLAY_NAME = "display_name";
public static final String FULL_NAME = "fullname";
public static final String ABOUT = "about";
public static final String EMAIL = "email";
public static final String PASSWORD = "password";
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();
}
}
protected PortalUser portalUser;
protected Role role;
public CKANUser() {
super();
LIST = USER_LIST;
CREATE = USER_CREATE;
READ = USER_SHOW;
UPDATE = USER_UPDATE;
PATCH = null;
DELETE = USER_DELETE;
PURGE = null;
}
public String create() {
RandomString randomString = new RandomString(12);
ObjectNode objectNode = mapper.createObjectNode();
objectNode.put(NAME, name);
objectNode.put(PASSWORD, randomString.nextString());
checkAndSetEMail(objectNode);
checkAndSetFullName(objectNode);
checkAndSetJobTitle(objectNode);
return create(getAsString(objectNode));
}
@Override
public void delete(boolean purge) {
this.delete();
}
/**
*
* @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;
}
protected void retrieve() {
setApiKey(CKANUtility.getSysAdminAPI());
try {
if(name==null || name.compareTo("")==0) {
setName(getCKANUsername());
}
read();
updateProfileIfNeeded();
} 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);
}
public void addToGroup(String groupName) throws WebApplicationException {
try {
ObjectNode objectNode = mapper.createObjectNode();
objectNode.put(ID_KEY, CKANGroup.getCKANGroupName(groupName));
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);
}
}
public PortalUser getPortalUser() {
if(portalUser==null) {
portalUser = new PortalUser();
}
return portalUser;
}
}