From 3317ddd4c71b91d1d77348e3b966db12cb0e5d9c Mon Sep 17 00:00:00 2001 From: Massimiliano Assante Date: Mon, 20 Jul 2020 11:57:43 +0200 Subject: [PATCH] modifications for the new IAM --- .../portal/ldapexport/LDAPExportService.java | 2 +- .../org/gcube/portal/ldapexport/LDAPSync.java | 178 ++++++++++++------ 2 files changed, 126 insertions(+), 54 deletions(-) diff --git a/src/main/java/org/gcube/portal/ldapexport/LDAPExportService.java b/src/main/java/org/gcube/portal/ldapexport/LDAPExportService.java index b30f0e3..968980e 100644 --- a/src/main/java/org/gcube/portal/ldapexport/LDAPExportService.java +++ b/src/main/java/org/gcube/portal/ldapexport/LDAPExportService.java @@ -36,7 +36,7 @@ public class LDAPExportService extends HttpServlet { private static final String LDAP_SERVER_FILTER_NAME = "filter"; private static final String LDAP_SERVER_PRINCPAL_NAME = "ldapPrincipal"; - private static final int LDAP_MINUTES_DELAY = 10; + private static final int LDAP_MINUTES_DELAY = 60; private String portalName; private String ldapUrl; diff --git a/src/main/java/org/gcube/portal/ldapexport/LDAPSync.java b/src/main/java/org/gcube/portal/ldapexport/LDAPSync.java index abd2e9b..2958963 100644 --- a/src/main/java/org/gcube/portal/ldapexport/LDAPSync.java +++ b/src/main/java/org/gcube/portal/ldapexport/LDAPSync.java @@ -37,22 +37,25 @@ public class LDAPSync implements Runnable { private static final String LDAP_ORG_FILTER = "(objectClass=organizationalUnit)"; private static final String LDAP_GROUP_FILTER = "(objectClass=posixGroup)"; private static final String USER_CONTEXT = ",ou=People,o=D4Science,ou=Organizations,dc=d4science,dc=org"; + private static final String GROUPS_OU = "ou=Groups,o=D4Science,ou=Organizations,dc=d4science,dc=org"; private static final String DEFAULT_GID_NUMBER = "1000"; private static final String SSH_PUBLIC_KEY_ATTR = "SSH-public-key"; - + private static LiferayGroupManager GM; + 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; + GM = new LiferayGroupManager(); _log.info("Starting LDAPSync over " + ldapUrl); } @@ -105,7 +108,7 @@ public class LDAPSync implements Runnable { //update the users list exportSingleUsers(ctx, env, users); - + //crate or update the whole list of organizations (objectClass=organizationalUnit, ou="+orgName+",dc=d4science,dc=org) and groups ( objectClass=top and POSIXGroup) updateGroups(ctx, rootVO); } catch (NamingException e) { @@ -132,7 +135,7 @@ public class LDAPSync implements Runnable { Attribute description = new BasicAttribute("description"); description.add("Where to find users"); attributes.put(description); - // private static final String USER_CONTEXT = ","; + ctx.createSubcontext("ou=Organizations,dc=d4science,dc=org", attributes); _log.info("organizationalUnit \"ou=Organizations,dc=d4science,dc=org\" created"); @@ -152,6 +155,14 @@ public class LDAPSync implements Runnable { description.add("People Org Unit"); ctx.createSubcontext("ou=People,o=D4Science,ou=Organizations,dc=d4science,dc=org", attributes); _log.info("organizationalUnit \"ou=People,o=D4Science,ou=Organizations,dc=d4science,dc=org\" created"); + + attributes = new BasicAttributes(); + objectClass = new BasicAttribute("objectClass"); + objectClass.add("organizationalUnit"); + attributes.put(objectClass); + description.add("Groups Org Unit"); + ctx.createSubcontext(GROUPS_OU, attributes); + _log.info("organizationalUnit \"ou=Groups,o=D4Science,ou=Organizations,dc=d4science,dc=org\" created"); } else _log.info("ou=Organizations,dc=d4science,dc=org already present, skip"); @@ -164,40 +175,87 @@ public class LDAPSync implements Runnable { * @throws NamingException * @throws SystemException */ - private void updateGroups(DirContext ctx, GCubeGroup root) throws NamingException, SystemException { - String subCtx = getOrgSubContext(root.getGroupName()); - if (!checkIfLDAPOrganizationalUnitExists(ctx, subCtx)) - createOrganizationalUnit(ctx, subCtx); + private void updateGroups(DirContext ctx, GCubeGroup root) throws Exception { + String subCtx = getGroupContext(root.getGroupName()); + //first we create the groups + if (!checkIfLDAPGroupExists(ctx, subCtx)) { + createGroup(ctx, subCtx, root, true); + } for (GCubeGroup vo : root.getChildren()) { - String orgSubCtx = "ou="+vo.getGroupName()+","+subCtx; - if (!checkIfLDAPOrganizationalUnitExists(ctx, orgSubCtx)) - createOrganizationalUnit(ctx, orgSubCtx); + String orgSubCtx = getGroupContext(vo.getGroupName()); + if (!checkIfLDAPGroupExists(ctx, orgSubCtx)) + createGroup(ctx, orgSubCtx, vo, false); for (GCubeGroup vre : vo.getChildren()) { - String vreSubCtx = "cn="+vre.getGroupName()+","+orgSubCtx; + String vreSubCtx = getGroupContext(vre.getGroupName()); if (!checkIfLDAPGroupExists(ctx, vreSubCtx)) - createGroupVRE(ctx, vreSubCtx, vre.getGroupName()); + createGroup(ctx, vreSubCtx, vre, false); + } + } + _log.debug("updateUsersInGroup: groups created waiting for adding users and member"); + //the we add/update the users + updateUsersInGroup(ctx, subCtx, root); + for (GCubeGroup vo : root.getChildren()) { + String orgSubCtx = getGroupContext(vo.getGroupName()); + updateUsersInGroup(ctx, orgSubCtx, vo); + for (GCubeGroup vre : vo.getChildren()) { + String vreSubCtx = getGroupContext(vre.getGroupName()); //update the list of users in such VRE updateUsersInGroup(ctx, vreSubCtx, vre); } } _log.debug("LDAP Groups Sync Completed OK!"); } + /** + * + * @param ctx + * @param groupSubctx + * @return true if exists + */ + private boolean checkIfLDAPGroupExists(DirContext ctx, String groupSubctx) { + SearchControls ctls = new SearchControls(); + ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); + NamingEnumeration answer; + try { + answer = ctx.search(groupSubctx, LDAP_GROUP_FILTER, ctls); + } catch (NamingException e) { + _log.debug("not found in LDAP (will add it): Group: " + groupSubctx); + return false; + } + boolean toReturn = answer.hasMoreElements(); + _log.debug("Group: " + groupSubctx + " exists? " + toReturn); + return toReturn; + } + /** * * @param ctx * @param vreSubCtx - * @param vre + * @param group * @throws NamingException * @throws SystemException */ - private void updateUsersInGroup(DirContext ctx, String vreSubCtx, GCubeGroup vre) throws NamingException, SystemException { - _log.debug("updateUsersInGroup: " + vre.getGroupName() ); + private void updateUsersInGroup(DirContext ctx, String vreSubCtx, GCubeGroup group) throws NamingException, SystemException { + _log.debug("updateUsersInGroup: " + group.getGroupName()); List users = new ArrayList<>(); try { - users = UserLocalServiceUtil.getGroupUsers(vre.getGroupId()); + users = UserLocalServiceUtil.getGroupUsers(group.getGroupId()); } catch (Exception e) { - _log.error("Could not retrieve members of vre: " + vre.getGroupName() + " having groupid: "+vre.getGroupId(), e); + _log.error("Could not retrieve members of group: " + group.getGroupName() + " having groupid: "+group.getGroupId(), e); } + //set the children, if any + if (group.getChildren() != null) { + _log.debug("Adding member e.g. cn=env.Name Iterating children of " + group.getGroupName()); + for (GCubeGroup g : group.getChildren()) { + Attribute member = new BasicAttribute("member"); + member.add(getGroupContext(g.getGroupName())); + Attributes attributes2 = new BasicAttributes(); + attributes2.put(member); + ctx.modifyAttributes(vreSubCtx, DirContext.ADD_ATTRIBUTE, attributes2); + _log.debug("Added Child env. as member: " + getGroupContext(g.getGroupName())); + + } + } + _log.info("Adding users as members to: " + getGroupContext(group.getGroupName())); for (User userObj : users) { String user = userObj.getScreenName(); try { @@ -206,14 +264,14 @@ public class LDAPSync implements Runnable { Attributes attributes = new BasicAttributes(); attributes.put(memberUid); ctx.modifyAttributes(vreSubCtx, DirContext.ADD_ATTRIBUTE, attributes); - _log.info("Adding user as memberUid: " + user ); - + _log.debug("Adding user as memberUid: " + user ); + Attribute member = new BasicAttribute("member"); member.add(getSubContext(user)); Attributes attributes2 = new BasicAttributes(); attributes2.put(member); ctx.modifyAttributes(vreSubCtx, DirContext.ADD_ATTRIBUTE, attributes2); - _log.info("Adding user as memberUid: " + user ); + _log.debug("Added user as member: " + user ); } catch (javax.naming.directory.AttributeInUseException ex) { _log.trace("Not adding already existing user: " + user); @@ -228,7 +286,7 @@ public class LDAPSync implements Runnable { String lastName = "NoLastNameEntered"; if (user.getLastName() != null && user.getLastName().compareTo("") != 0) lastName = user.getLastName(); - + _log.debug("Trying read sshPublicKey for " + user.getScreenName()); String sshPublicKey = new LiferayUserManager().readCustomAttr(user.getUserId(), SSH_PUBLIC_KEY_ATTR).toString(); if (user.getFirstName() != null && user.getFirstName().compareTo("") != 0) @@ -263,34 +321,67 @@ public class LDAPSync implements Runnable { * * @param ctx * @param subContext - * @param vreName + * @param d4sContextName e.g, devsec or devVRE * @throws NamingException */ - private void createGroupVRE(DirContext ctx, String subContext, String vreName) throws NamingException { + private void createGroup(DirContext ctx, String subContext, GCubeGroup d4sContext, boolean isRoot) throws Exception { + + _log.debug("in createGroup: " + d4sContext.getGroupName() + " isRoot?"+isRoot); + Attributes attributes = new BasicAttributes(); Attribute objectClass = new BasicAttribute("objectClass"); objectClass.add("top"); objectClass.add("groupofnames"); objectClass.add("posixGroup"); - //objectClass.add("nestedGroup"); + if (!isRoot) + objectClass.add("nsMemberOf"); attributes.put(objectClass); Attribute cn = new BasicAttribute("cn"); - cn.add(vreName); + cn.add(d4sContext.getGroupName()); attributes.put(cn); - Attribute gidNumber = new BasicAttribute("gidNumber"); - gidNumber.add(String.valueOf(getRandomPOSIXidentifier())); - attributes.put(gidNumber); + + // //set the parent, if any + // if (d4sContext.getParentGroupId() >= 0) { + // _log.debug("this context " + d4sContext.getGroupName() + " has a parent " ); + // GCubeGroup parent = GM.getGroup(d4sContext.getParentGroupId()); + // _log.debug("parent= " + parent.getGroupName() ); + // Attribute memberOf = new BasicAttribute("memberOf"); + // String memberOfContext = getGroupContext(parent.getGroupName()); + // memberOf.add(memberOfContext); + // _log.info("Added parent group memberOf: " + memberOfContext); + // attributes.put(memberOf); + // } + + // Attribute gidNumber = new BasicAttribute("gidNumber"); + // gidNumber.add(String.valueOf(getRandomPOSIXidentifier())); + // attributes.put(gidNumber); ctx.createSubcontext(subContext, attributes); - _log.info("Added " + subContext); + _log.info("Added Group: " + subContext); + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } } private String getOrgSubContext(String orgName) { return "ou="+orgName+",dc=d4science,dc=org"; } + + private String getGroupContext(String groupName) { + return "cn="+groupName+","+GROUPS_OU; + } + + + + + + /** * * @param ctx @@ -311,26 +402,7 @@ public class LDAPSync implements Runnable { _log.debug("Organization: " + orgSubctx + " exists? " + toReturn); return toReturn; } - /** - * - * @param ctx - * @param groupSubctx - * @return true if exists - */ - private boolean checkIfLDAPGroupExists(DirContext ctx, String groupSubctx) { - SearchControls ctls = new SearchControls(); - ctls.setSearchScope(SearchControls.SUBTREE_SCOPE); - NamingEnumeration answer; - try { - answer = ctx.search(groupSubctx, LDAP_GROUP_FILTER, ctls); - } catch (NamingException e) { - _log.debug("not found in LDAP (will add it): Group: " + groupSubctx); - return false; - } - boolean toReturn = answer.hasMoreElements(); - _log.debug("Group: " + groupSubctx + " exists? " + toReturn); - return toReturn; - } + /** * * @param username @@ -390,7 +462,7 @@ public class LDAPSync implements Runnable { Attribute homeDirectory = new BasicAttribute("homeDirectory"); Attribute shell = new BasicAttribute("loginShell"); Attribute sshPublicKeyAttr = new BasicAttribute("sshPublicKey"); - + givenName.add(name); cn.add(fullName); @@ -401,7 +473,7 @@ public class LDAPSync implements Runnable { homeDirectory.add("/home/"+username); shell.add("/bin/bash"); sshPublicKeyAttr.add(sshPublicKey); - + attributes.put(givenName); attributes.put(cn); attributes.put(sn);