diff --git a/README.md b/README.md
index c4f63e7..15ca1ba 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# gCube System - User Registration Hook
-This component is a Liferay 6.2.6 CE Hook which intercepts new user accounts creation and performs the related Workspace actions (on sHub and LDAP)
+This component is a Liferay 6.2.6 CE Hook which intercepts new user accounts creation and removal and performs the related Workspace actions (on sHub and LDAP)
* The source code is present in the src folder.
diff --git a/pom.xml b/pom.xml
index 091d93a..1a58d2c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,12 +15,12 @@
war
user-registration-hook Hook
2.0.0-SNAPSHOT
-
+
scm:git:https://code-repo.d4science.org/gCubeSystem/user-registration-hook.git
scm:git:https://code-repo.d4science.org/gCubeSystem/user-registration-hook.git
https://code-repo.d4science.org/gCubeSystem/user-registration-hook
-
+
6.2.5
6.2.10.12
/Users/massi/portal/liferay-portal-6.2-ce-ga6/deploy
@@ -39,8 +39,13 @@
-
+
+
+ org.gcube.core
+ common-encryption
+ provided
+
org.gcube.common
storagehub-client-library
diff --git a/src/main/java/org/gcube/portal/removeaccount/thread/RemoveUserFromJCR.java b/src/main/java/org/gcube/portal/removeaccount/thread/RemoveUserFromJCR.java
new file mode 100644
index 0000000..d72b6bd
--- /dev/null
+++ b/src/main/java/org/gcube/portal/removeaccount/thread/RemoveUserFromJCR.java
@@ -0,0 +1,79 @@
+package org.gcube.portal.removeaccount.thread;
+
+import static org.gcube.common.authorization.client.Constants.authorizationService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.gcube.common.authorization.library.provider.SecurityTokenProvider;
+import org.gcube.common.portal.PortalContext;
+import org.gcube.common.storagehub.client.dsl.StorageHubClient;
+import org.gcube.portal.usersaccount.Constants;
+import org.gcube.vomanagement.usermanagement.GroupManager;
+import org.gcube.vomanagement.usermanagement.RoleManager;
+import org.gcube.vomanagement.usermanagement.UserManager;
+import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager;
+import org.gcube.vomanagement.usermanagement.model.GCubeRole;
+import org.gcube.vomanagement.usermanagement.model.GCubeUser;
+
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
+
+/**
+ *
+ * @author Massimiliano Assante ISTI-CNR
+ *
+ */
+public class RemoveUserFromJCR {
+ private static Log _log = LogFactoryUtil.getLog(RemoveUserFromJCR.class);
+
+ private String username2Delete;
+ private GroupManager gm;
+ private UserManager uMan;
+ private RoleManager rm;
+
+ public RemoveUserFromJCR(String username2Delete, GroupManager gm, UserManager uMan) {
+ this.username2Delete = username2Delete;
+ this.gm = gm;
+ this.uMan = uMan;
+ this.rm = new LiferayRoleManager();
+ }
+
+ public boolean remove() {
+ try {
+ _log.debug("in RemoveUserFromJCR remove() for " + username2Delete );
+ //get the super user
+ String infraContext = "/"+PortalContext.getConfiguration().getInfrastructureName();
+ long groupId = gm.getGroupIdFromInfrastructureScope(infraContext);
+ long roleId = rm.getRoleId(Constants.AUTORISED_INFRA_ROLE, groupId);
+ List users = uMan.listUsersByGroupAndRole(groupId, roleId);
+ if (users.isEmpty()) {
+ _log.error("Cannot delete the user: there is no user having role " + Constants.AUTORISED_INFRA_ROLE + " on context: " + infraContext);
+ return false;
+ }
+ else {
+ GCubeUser theAdmin = users.get(0);
+ String adminUsername = theAdmin.getUsername();
+ String theAdminToken = PortalContext.getConfiguration().getCurrentUserToken(infraContext, adminUsername);
+ List theAdminRoles = rm.listRolesByUserAndGroup(theAdmin.getUserId(), groupId);
+ List rolesString = new ArrayList();
+ for (GCubeRole gCubeRole : theAdminRoles) {
+ rolesString.add(gCubeRole.getRoleName());
+ }
+ authorizationService().setTokenRoles(theAdminToken, rolesString);
+ SecurityTokenProvider.instance.set(theAdminToken);
+ _log.debug("Autorising drop workspace with infra manager token of " + theAdminToken);
+ StorageHubClient shc = new StorageHubClient();
+ _log.debug("BEFORE stohub.deleteUserAccount " + username2Delete);
+ shc.deleteUserAccount(username2Delete);
+ return true;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ _log.error("Could not delete " + username2Delete + " from JCR an error occurred on the service");
+ return false;
+ }
+ }
+
+
+}
diff --git a/src/main/java/org/gcube/portal/removeaccount/thread/RemovedUserAccountThread.java b/src/main/java/org/gcube/portal/removeaccount/thread/RemovedUserAccountThread.java
new file mode 100644
index 0000000..2e2aeee
--- /dev/null
+++ b/src/main/java/org/gcube/portal/removeaccount/thread/RemovedUserAccountThread.java
@@ -0,0 +1,61 @@
+package org.gcube.portal.removeaccount.thread;
+
+import java.util.List;
+
+import javax.portlet.PortletPreferences;
+
+import org.gcube.common.portal.PortalContext;
+import org.gcube.common.portal.mailing.EmailNotification;
+import org.gcube.portal.usersaccount.Constants;
+import org.gcube.vomanagement.usermanagement.GroupManager;
+import org.gcube.vomanagement.usermanagement.RoleManager;
+import org.gcube.vomanagement.usermanagement.UserManager;
+import org.gcube.vomanagement.usermanagement.exception.RoleRetrievalFault;
+import org.gcube.vomanagement.usermanagement.impl.LiferayGroupManager;
+import org.gcube.vomanagement.usermanagement.impl.LiferayRoleManager;
+import org.gcube.vomanagement.usermanagement.impl.LiferayUserManager;
+import org.gcube.vomanagement.usermanagement.model.GCubeUser;
+import org.gcube.vomanagement.usermanagement.model.GatewayRolesNames;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.liferay.portal.service.PortalPreferencesLocalServiceUtil;
+import com.liferay.portal.service.UserLocalServiceUtil;
+import com.liferay.portal.util.PortalUtil;
+
+
+/**
+ *
+ * @author Massimiliano Assante ISTI-CNR
+ *
+ */
+public class RemovedUserAccountThread implements Runnable {
+
+ private static final Logger _log = LoggerFactory.getLogger(RemovedUserAccountThread.class);
+
+ final String SUBJECT = "Removed account notification";
+
+ private String userName;
+ private GroupManager gm;
+ private UserManager uMan;
+
+ public RemovedUserAccountThread(long userId,String userName) {
+ super();
+ this.userName = userName;
+ this.uMan = new LiferayUserManager();
+ this.gm = new LiferayGroupManager();
+ }
+
+ @Override
+ public void run() {
+ try {
+ _log.info("Trying to remove user " + userName + " from JCR first, using storageHub with role: "+Constants.AUTORISED_INFRA_ROLE);
+ RemoveUserFromJCR rmJCR = new RemoveUserFromJCR(userName, gm, uMan);
+ boolean result = rmJCR.remove();
+ _log.info("The user " + userName + " has been removed from JCR with success? " + result);
+
+ } catch (Exception e) {
+ _log.error("An error occurred during user workspace removal: ", e);
+ }
+ }
+}
diff --git a/src/main/java/org/gcube/portal/removeaccount/thread/RemovedUserFromLDAPThread.java b/src/main/java/org/gcube/portal/removeaccount/thread/RemovedUserFromLDAPThread.java
new file mode 100644
index 0000000..2781581
--- /dev/null
+++ b/src/main/java/org/gcube/portal/removeaccount/thread/RemovedUserFromLDAPThread.java
@@ -0,0 +1,152 @@
+package org.gcube.portal.removeaccount.thread;
+
+import static org.gcube.resources.discovery.icclient.ICFactory.clientFor;
+import static org.gcube.resources.discovery.icclient.ICFactory.queryFor;
+
+import java.util.List;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+
+import org.gcube.common.encryption.encrypter.StringEncrypter;
+import org.gcube.common.portal.PortalContext;
+import org.gcube.common.resources.gcore.ServiceEndpoint;
+import org.gcube.common.resources.gcore.ServiceEndpoint.AccessPoint;
+import org.gcube.common.resources.gcore.ServiceEndpoint.Property;
+import org.gcube.common.resources.gcore.utils.Group;
+import org.gcube.common.scope.api.ScopeProvider;
+import org.gcube.resources.discovery.client.api.DiscoveryClient;
+import org.gcube.resources.discovery.client.queries.api.SimpleQuery;
+
+import com.liferay.portal.kernel.log.Log;
+import com.liferay.portal.kernel.log.LogFactoryUtil;
+
+/**
+ *
+ * @author Massimiliano Assante ISTI-CNR
+ *
+ */
+public class RemovedUserFromLDAPThread implements Runnable {
+ private static Log _log = LogFactoryUtil.getLog(RemovedUserFromLDAPThread.class);
+ private static final String LDAP_SERVER_NAME = "LDAPServer";
+ private static final String LDAP_SERVER_PRINCPAL_NAME = "ldapPrincipal";
+ private static final String USER_CONTEXT = ",ou=People,o=D4Science,ou=Organizations,dc=d4science,dc=org";
+
+ private String portalName;
+ private String ldapUrl;
+ private String principal;
+ private String ldapPassword;
+
+ private String username2Delete;
+
+ public RemovedUserFromLDAPThread(String username2Delete) {
+ this.username2Delete = username2Delete;
+ }
+
+
+ @SuppressWarnings("deprecation")
+ @Override
+ public void run() {
+ portalName = PortalContext.getPortalInstanceName();
+
+ PortalContext context = PortalContext.getConfiguration();
+ String scope = "/" + context.getInfrastructureName();
+ ScopeProvider.instance.set(scope);
+
+ SimpleQuery query = queryFor(ServiceEndpoint.class);
+ query.addCondition("$resource/Profile/Category/text() eq 'Portal'");
+ query.addCondition("$resource/Profile/Name/text() eq '" + portalName + "'");
+
+ DiscoveryClient client = clientFor(ServiceEndpoint.class);
+
+ List list = client.submit(query);
+ if (list == null || list.isEmpty()) {
+ _log.error("Could not find any Service endpoint registred in the infrastructure for this portal: " + portalName);
+ }
+ else if (list.size() > 1) {
+ _log.warn("Found more than one Service endpoint registred in the infrastructure for this portal: " + portalName);
+ }
+ else {
+ for (ServiceEndpoint res : list) {
+ Group apGroup = res.profile().accessPoints();
+ AccessPoint[] accessPoints = (AccessPoint[]) apGroup.toArray(new AccessPoint[apGroup.size()]);
+ for (int i = 0; i < accessPoints.length; i++) {
+ if (accessPoints[i].name().compareTo(LDAP_SERVER_NAME) == 0) {
+ _log.info("Found credentials for " + LDAP_SERVER_NAME);
+ AccessPoint found = accessPoints[i];
+ ldapUrl = found.address();
+ String encrPassword = found.password();
+ try {
+ ldapPassword = StringEncrypter.getEncrypter().decrypt( encrPassword);
+ } catch (Exception e) {
+ _log.error("Something went wrong while decrypting password for " + LDAP_SERVER_NAME);
+ e.printStackTrace();
+ }
+ Group propGroup = found.properties();
+ Property[] props = (Property[]) propGroup.toArray(new Property[propGroup.size()]);
+ for (int j = 0; j < props.length; j++) {
+ if (props[j].name().compareTo(LDAP_SERVER_PRINCPAL_NAME) == 0) {
+ _log.info("\tFound properties of " + LDAP_SERVER_PRINCPAL_NAME);
+ String encrValue = props[j].value();
+ try {
+ principal = StringEncrypter.getEncrypter().decrypt(encrValue);
+ } catch (Exception e) {
+ _log.error("Something went wrong while decrypting value for " + LDAP_SERVER_PRINCPAL_NAME);
+ e.printStackTrace();
+ }
+ }
+ }
+
+ }
+ }
+ }
+ _log.debug("Got LDAP connection info from IS Resource ...");
+ /*************** */
+ _log.debug("Initializing LDAP connection ...");
+
+ Properties env = new Properties();
+ env.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
+ env.put(Context.PROVIDER_URL, ldapUrl);
+ env.put(Context.SECURITY_PRINCIPAL, principal);
+ env.put(Context.SECURITY_CREDENTIALS, ldapPassword);
+
+ try {
+ Context ctx = new InitialContext(env);
+ String userCtx2Delete = getSubContext(username2Delete);
+ // Remove the binding
+ _log.debug("***** trying delete userCtx=" + userCtx2Delete);
+ ctx.unbind(userCtx2Delete);
+ // Check that it is gone
+ Object obj = null;
+ try {
+ obj = ctx.lookup(userCtx2Delete);
+ } catch (NameNotFoundException ne) {
+ _log.info("unbind successful for "+userCtx2Delete);
+ return;
+ }
+ _log.error("unbind failed; object still there: " + obj);
+ // Close the context when we're done
+ ctx.close();
+ } catch (NamingException e) {
+ _log.error("Something went Wrong during LDAP remove user");
+ e.printStackTrace();
+ } catch (Exception es) {
+ _log.error("Something went Wrong during LDAP remove user in retrieving Liferay Organization");
+ es.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ *
+ * @param username
+ * @return the single user subContext
+ */
+ private String getSubContext(String username) {
+ return "uid="+username+USER_CONTEXT;
+ }
+
+}
diff --git a/src/main/java/org/gcube/portal/usersaccount/Constants.java b/src/main/java/org/gcube/portal/usersaccount/Constants.java
new file mode 100644
index 0000000..93bfecc
--- /dev/null
+++ b/src/main/java/org/gcube/portal/usersaccount/Constants.java
@@ -0,0 +1,7 @@
+package org.gcube.portal.usersaccount;
+
+public class Constants {
+ public static final String AUTORISED_INFRA_ROLE = "Infrastructure-Manager";
+ public static final String USERNAME_PREFERENCE_KEY = "admin.reserved.screen.names";
+
+}
diff --git a/src/main/java/org/gcube/portal/usersaccount/MyCreateUserAccountListener.java b/src/main/java/org/gcube/portal/usersaccount/MyCreateUserAccountListener.java
index d1c519c..513e46f 100644
--- a/src/main/java/org/gcube/portal/usersaccount/MyCreateUserAccountListener.java
+++ b/src/main/java/org/gcube/portal/usersaccount/MyCreateUserAccountListener.java
@@ -1,6 +1,8 @@
package org.gcube.portal.usersaccount;
import org.gcube.portal.notifications.thread.NewUserAccountNotificationThread;
+import org.gcube.portal.removeaccount.thread.RemovedUserAccountThread;
+import org.gcube.portal.removeaccount.thread.RemovedUserFromLDAPThread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -20,16 +22,38 @@ import com.liferay.portal.model.User;
public class MyCreateUserAccountListener extends BaseModelListener {
private static final Logger _log = LoggerFactory.getLogger(MyCreateUserAccountListener.class);
final String SUBJECT = "New user account notification";
-
- @Override
- public void onAfterCreate(User user) throws ModelListenerException {
- _log.info("onAfterCreate NewUserAccount listener for: " + user.getScreenName() + " / " + user.getFullName());
- Thread emailManagersThread = new Thread(new NewUserAccountNotificationThread(user.getScreenName(), user.getFullName(), user.getEmailAddress()));
- emailManagersThread.start();
-
- Thread WorkspaceAccountCreationThread = new Thread(new WorkspaceCreateAccountThread(user.getScreenName(), user.getFullName(), user.getEmailAddress()));
- WorkspaceAccountCreationThread.start();
- }
-
+ @Override
+ public void onAfterCreate(User user) throws ModelListenerException {
+ _log.info("onAfterCreate NewUserAccount listener for: " + user.getScreenName() + " / " + user.getFullName());
+ Thread emailManagersThread = new Thread(new NewUserAccountNotificationThread(user.getScreenName(), user.getFullName(), user.getEmailAddress()));
+ emailManagersThread.start();
+
+ Thread WorkspaceAccountCreationThread = new Thread(new WorkspaceCreateAccountThread(user.getScreenName(), user.getFullName(), user.getEmailAddress()));
+ WorkspaceAccountCreationThread.start();
+ }
+
+ @Override
+ public void onBeforeRemove(User user) throws ModelListenerException {
+ _log.info("onBeforeRemove userAccount listener for: " + user.getScreenName() + " / " + user.getFullName());
+ String username2Delete = user.getScreenName();
+ _log.info("Trying to remove user from JCR and not notify infra-managers ...");
+ try {
+ Thread dropUserWorkspaceThread = new Thread(new RemovedUserAccountThread(user.getUserId(), username2Delete));
+ dropUserWorkspaceThread.start();
+ _log.info("Trying to remove user from LDAP ...");
+ Thread removeFromLDAPThread = new Thread(new RemovedUserFromLDAPThread(username2Delete));
+ removeFromLDAPThread.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ // @Override
+ // public void onAfterRemove(User user)
+
+
+
+
+
}
\ No newline at end of file