package org.gcube.portal.ldapexport; import java.util.ArrayList; import java.util.List; import java.util.Properties; import javax.naming.Context; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; import javax.naming.directory.InitialDirContext; import javax.naming.directory.SearchControls; import javax.naming.directory.SearchResult; import org.gcube.common.portal.PortalContext; import org.gcube.portal.custom.communitymanager.OrganizationsUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.liferay.portal.kernel.cache.CacheRegistryUtil; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.exception.SystemException; import com.liferay.portal.model.Organization; import com.liferay.portal.model.User; import com.liferay.portal.service.OrganizationLocalServiceUtil; import com.liferay.portal.service.UserLocalServiceUtil; public class LDAPSync implements Runnable { private static final Logger _log = LoggerFactory.getLogger(LDAPSync.class); private String ldapUrl; private String filter; private String principal; private String pwd; public LDAPSync(String ldapUrl, String filter, String principal, String pwd) { this.ldapUrl = ldapUrl; this.filter = filter; this.principal = principal; this.pwd = pwd; _log.info("Starting LDAPSync over " + ldapUrl); } @Override public void run() { _log.debug("Reading Portal Users ..."); List users = null; try { users = getAllLiferayUsers(); _log.debug("\n\n\n ******** Read " + users.size() + " from LR DB\n\n"); } catch (Exception e1) { e1.printStackTrace(); } _log.debug("Initializing LDAP exporter ..."); 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, pwd); try { DirContext ctx = new InitialDirContext(env); _log.debug("Initiating LDAP Sync ..."); for (User user : users) { updateUserInLDAP(user.getScreenName(), user.getFirstName(), user.getLastName(), user.getFullName(), user.getEmailAddress(), "{SHA}"+user.getPassword(), ctx, filter); //_log.debug("Updated " + user.getScreenName()); } _log.debug("LDAP Sync cycle done"); } catch (NamingException e) { _log.error("Something went Wrong during LDAP Sync"); e.printStackTrace(); } if (! users.isEmpty()) _log.info("LDAP Sync Completed OK!"); else _log.warn("LDAP Sync cycle skipped this time"); } private String getSubContext(String username) { return "uid="+username+",ou=People,o=Liferay,ou=Organizations,dc=d4science,dc=org"; } private boolean checkIfLDAPUserExists(String username, DirContext ctx, String filter) { SearchControls ctls = new SearchControls(); ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); NamingEnumeration answer; try { answer = ctx.search(getSubContext(username), filter, ctls); } catch (NamingException e) { _log.info("user: " + username + " not found in LDAP, trying to export it"); return false; } return answer.hasMoreElements(); } /** * * @param username * @param name * @param lastName * @param email * @param passwd * @param ctx * @throws NamingException */ private void updateUserInLDAP(String username, String name, String lastName, String fullName, String email, String passwd, DirContext ctx, String filter) throws NamingException { Attributes attributes=new BasicAttributes(); Attribute objectClass=new BasicAttribute("objectClass"); objectClass.add("inetOrgPerson"); attributes.put(objectClass); //the main ldap server uses 'givenName' for the First name, 'cn' for "first name last name', 'sn' for the last name Attribute givenName = new BasicAttribute("givenName"); Attribute cn = new BasicAttribute("cn"); Attribute sn = new BasicAttribute("sn"); Attribute mail = new BasicAttribute("mail"); Attribute userPassword = new BasicAttribute("userPassword"); givenName.add(name); cn.add(fullName); sn.add(lastName); mail.add(email); userPassword.add(passwd); attributes.put(givenName); attributes.put(cn); attributes.put(sn); attributes.put(mail); attributes.put(userPassword); if (checkIfLDAPUserExists(username, ctx, filter)) { //_log.debug("User " + username + " already exists, replacing attributes"); ctx.modifyAttributes(getSubContext(username), DirContext.REPLACE_ATTRIBUTE, attributes); } else { ctx.createSubcontext(getSubContext(username),attributes); _log.debug("New User Found with uid=" + username + " created"); } } private List getAllLiferayUsers() { String infraName = PortalContext.getConfiguration().getInfrastructureName(); _log.info("TRY Reading non chached users belonging to: /" + infraName); List toReturn = new ArrayList(); Organization rootInfra; try { CacheRegistryUtil.clear(); rootInfra = OrganizationLocalServiceUtil.getOrganization(OrganizationsUtil.getCompany().getCompanyId(), infraName); toReturn = UserLocalServiceUtil.getOrganizationUsers(rootInfra.getOrganizationId()); } catch (PortalException | SystemException e) { _log.error("Error during LDAP Sync, could not retrieve users from LR DB: " + e.getMessage()); } return toReturn; } }