Fix creating new user profile structure for existing users
[gpl/argeo-suite.git] / org.argeo.app.core / src / org / argeo / app / core / SuiteUtils.java
index 6453b88b4c2c2d12133a1dd94923a818a668b0e1..f225064158ac6728486de7805764070e04936c2b 100644 (file)
@@ -1,10 +1,10 @@
 package org.argeo.app.core;
 
 import java.util.HashSet;
-import java.util.Optional;
 import java.util.Set;
 
 import javax.jcr.Node;
+import javax.jcr.NodeIterator;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
@@ -13,8 +13,8 @@ import javax.security.auth.x500.X500Principal;
 import javax.xml.namespace.QName;
 
 import org.argeo.api.acr.Content;
-import org.argeo.api.acr.ldap.LdapAttrs;
-import org.argeo.api.acr.ldap.LdapObjs;
+import org.argeo.api.acr.ldap.LdapAttr;
+import org.argeo.api.acr.ldap.LdapObj;
 import org.argeo.api.cms.CmsConstants;
 import org.argeo.api.cms.CmsSession;
 import org.argeo.app.api.EntityType;
@@ -24,14 +24,16 @@ import org.argeo.jcr.JcrUtils;
 
 /** Utilities around the Argeo Suite APIs. */
 public class SuiteUtils {
-       @Deprecated
+       public final static String USER_STATE_NODE_NAME = "state";
+       public final static String USER_DEVICES_NODE_NAME = "devices";
+       public final static String USER_SESSIONS_NODE_NAME = "sessions";
+
        public static String getUserNodePath(String userDn) {
                String uid = RoleNameUtils.getLastRdnValue(userDn);
                return EntityType.user.basePath() + '/' + uid;
        }
 
-       @Deprecated
-       private static Node getOrCreateUserNode(Session adminSession, String userDn) {
+       public static Node getOrCreateUserNode(Session adminSession, String userDn) {
                try {
                        Node usersBase = adminSession.getNode(EntityType.user.basePath());
                        String uid = RoleNameUtils.getLastRdnValue(userDn);
@@ -40,8 +42,27 @@ public class SuiteUtils {
                                userNode = usersBase.addNode(uid, NodeType.NT_UNSTRUCTURED);
                                userNode.addMixin(EntityType.user.get());
                                userNode.addMixin(NodeType.MIX_CREATED);
-                               userNode.setProperty(LdapAttrs.distinguishedName.property(), userDn.toString());
-                               userNode.setProperty(LdapAttrs.uid.property(), uid);
+                               userNode.setProperty(LdapAttr.distinguishedName.get(), userDn.toString());
+                               userNode.setProperty(LdapAttr.uid.get(), uid);
+                       } else {
+                               userNode = usersBase.getNode(uid);
+                       }
+
+                       if (!userNode.hasNode(USER_SESSIONS_NODE_NAME)) {
+                               // Migrate existing user node
+                               Node sessionsNode = userNode.addNode(USER_SESSIONS_NODE_NAME, NodeType.NT_UNSTRUCTURED);
+                               oldSessions: for (NodeIterator nit = userNode.getNodes(); nit.hasNext();) {
+                                       Node child = nit.nextNode();
+                                       if (USER_SESSIONS_NODE_NAME.equals(child.getName()) || child.getName().startsWith("rep:")
+                                                       || child.getName().startsWith("jcr:"))
+                                               continue oldSessions;
+                                       Node target = sessionsNode.addNode(child.getName());
+                                       JcrUtils.copy(child, target);
+                               }
+
+                               Node userStateNode = userNode.addNode(USER_STATE_NODE_NAME, NodeType.NT_UNSTRUCTURED);
+                               Node userDevicesNode = userNode.addNode(USER_DEVICES_NODE_NAME, NodeType.NT_UNSTRUCTURED);
+
                                adminSession.save();
 //                             JackrabbitSecurityUtils.denyPrivilege(adminSession, userNode.getPath(), SuiteRole.coworker.dn(),
 //                                             Privilege.JCR_READ);
@@ -49,8 +70,9 @@ public class SuiteUtils {
                                                Privilege.JCR_READ);
                                JcrUtils.addPrivilege(adminSession, userNode.getPath(), CmsConstants.ROLE_USER_ADMIN,
                                                Privilege.JCR_ALL);
-                       } else {
-                               userNode = usersBase.getNode(uid);
+
+                               JcrUtils.addPrivilege(adminSession, userStateNode.getPath(), userDn, Privilege.JCR_ALL);
+                               JcrUtils.addPrivilege(adminSession, userDevicesNode.getPath(), userDn, Privilege.JCR_ALL);
                        }
                        return userNode;
                } catch (RepositoryException e) {
@@ -58,41 +80,30 @@ public class SuiteUtils {
                }
        }
 
-       @Deprecated
        public static Node getCmsSessionNode(Session session, CmsSession cmsSession) {
                try {
-                       return session.getNode(getUserNodePath(cmsSession.getUserDn()) + '/' + cmsSession.getUuid().toString());
+                       return session.getNode(getUserNodePath(cmsSession.getUserDn()) + '/' + USER_SESSIONS_NODE_NAME + '/'
+                                       + cmsSession.getUuid().toString());
                } catch (RepositoryException e) {
                        throw new JcrException("Cannot get session dir for " + cmsSession, e);
                }
        }
 
-       @Deprecated
        public static Node getOrCreateCmsSessionNode(Session adminSession, CmsSession cmsSession) {
                try {
                        String userDn = cmsSession.getUserDn();
-//                     String uid = userDn.get(userDn.size() - 1);
                        Node userNode = getOrCreateUserNode(adminSession, userDn);
-//                     if (!usersBase.hasNode(uid)) {
-//                             userNode = usersBase.addNode(uid, NodeType.NT_UNSTRUCTURED);
-//                             userNode.addMixin(EntityType.user.get());
-//                             userNode.addMixin(NodeType.MIX_CREATED);
-//                             usersBase.setProperty(LdapAttrs.uid.property(), uid);
-//                             usersBase.setProperty(LdapAttrs.distinguishedName.property(), userDn.toString());
-//                             adminSession.save();
-//                     } else {
-//                             userNode = usersBase.getNode(uid);
-//                     }
+                       Node sessionsNode = userNode.getNode(USER_SESSIONS_NODE_NAME);
                        String cmsSessionUuid = cmsSession.getUuid().toString();
                        Node cmsSessionNode;
-                       if (!userNode.hasNode(cmsSessionUuid)) {
-                               cmsSessionNode = userNode.addNode(cmsSessionUuid, NodeType.NT_UNSTRUCTURED);
+                       if (!sessionsNode.hasNode(cmsSessionUuid)) {
+                               cmsSessionNode = sessionsNode.addNode(cmsSessionUuid, NodeType.NT_UNSTRUCTURED);
                                cmsSessionNode.addMixin(NodeType.MIX_CREATED);
                                adminSession.save();
                                JcrUtils.addPrivilege(adminSession, cmsSessionNode.getPath(), cmsSession.getUserRole(),
                                                Privilege.JCR_ALL);
                        } else {
-                               cmsSessionNode = userNode.getNode(cmsSessionUuid);
+                               cmsSessionNode = sessionsNode.getNode(cmsSessionUuid);
                        }
                        return cmsSessionNode;
                } catch (RepositoryException e) {
@@ -121,20 +132,20 @@ public class SuiteUtils {
        }
 
        synchronized static public long findNextId(Content hierarchyUnit, QName cclass) {
-               if (!hierarchyUnit.hasContentClass(LdapObjs.posixGroup.qName())) 
+               if (!hierarchyUnit.hasContentClass(LdapObj.posixGroup.qName()))
                        throw new IllegalArgumentException(hierarchyUnit + " is not a POSIX group");
-               
-               long min = hierarchyUnit.get(LdapAttrs.gidNumber.qName(), Long.class).orElseThrow();
+
+               long min = hierarchyUnit.get(LdapAttr.gidNumber.qName(), Long.class).orElseThrow();
                long currentMax = 0l;
                for (Content childHu : hierarchyUnit) {
-                       if (!childHu.hasContentClass(LdapObjs.organizationalUnit.qName()))
+                       if (!childHu.hasContentClass(LdapObj.organizationalUnit.qName()))
                                continue;
                        // FIXME filter out functional hierarchy unit
                        for (Content role : childHu) {
                                if (role.hasContentClass(cclass)) {
 
-                                       if (LdapObjs.posixAccount.qName().equals(cclass)) {
-                                               Long id = role.get(LdapAttrs.uidNumber.qName(), Long.class).orElseThrow();
+                                       if (LdapObj.posixAccount.qName().equals(cclass)) {
+                                               Long id = role.get(LdapAttr.uidNumber.qName(), Long.class).orElseThrow();
                                                if (id > currentMax)
                                                        currentMax = id;
                                        }