Introduce user and session nodes.
authorMathieu Baudier <mbaudier@argeo.org>
Sat, 28 Nov 2020 11:52:58 +0000 (12:52 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Sat, 28 Nov 2020 11:52:58 +0000 (12:52 +0100)
org.argeo.entity.api/src/org/argeo/entity/EntityType.java
org.argeo.entity.api/src/org/argeo/entity/entity.cnd
org.argeo.suite.core/src/org/argeo/suite/SuiteUtils.java [new file with mode: 0644]
org.argeo.suite.core/src/org/argeo/suite/core/SuiteMaintenanceService.java
org.argeo.suite.ui/src/org/argeo/suite/ui/AdminEntryArea.java
org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteApp.java
org.argeo.suite.ui/src/org/argeo/suite/ui/SuiteUi.java

index 408b142c35fe4230b5782c2680a44d0faacfc86e..732c9b17139f76a881e0299e2b8040930ef171d8 100644 (file)
@@ -22,6 +22,10 @@ public enum EntityType implements JcrName {
                return "entity";
        }
 
+       public String basePath() {
+               return '/' + name();
+       }
+
        @Override
        public String getNamespace() {
                return namespace();
index 85da6506de449c819d0b484f8e61384a1e82138d..cd6952a589e75d8cd6a294ed779812459331d982 100644 (file)
@@ -74,7 +74,10 @@ mixin
 mixin
 - ldap:sn (String)
 - ldap:givenName (String)
+- ldap:mail (String) *
 
 [entity:user] > entity:person
+mixin
+- ldap:distinguishedName (String)
 - ldap:uid (String)
 
diff --git a/org.argeo.suite.core/src/org/argeo/suite/SuiteUtils.java b/org.argeo.suite.core/src/org/argeo/suite/SuiteUtils.java
new file mode 100644 (file)
index 0000000..f264bdf
--- /dev/null
@@ -0,0 +1,82 @@
+package org.argeo.suite;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.security.Privilege;
+import javax.naming.ldap.LdapName;
+
+import org.argeo.cms.auth.CmsSession;
+import org.argeo.entity.EntityType;
+import org.argeo.jcr.JcrException;
+import org.argeo.jcr.JcrUtils;
+import org.argeo.naming.LdapAttrs;
+
+/** Utilities around the Argeo Suite APIs. */
+public class SuiteUtils {
+
+       public static String getUserNodePath(LdapName userDn) {
+               String uid = userDn.getRdn(userDn.size() - 1).getValue().toString();
+               return EntityType.user.basePath() + '/' + uid;
+       }
+
+       public static Node getOrCreateUserNode(Session adminSession, LdapName userDn) {
+               try {
+                       Node usersBase = adminSession.getNode(EntityType.user.basePath());
+                       String uid = userDn.getRdn(userDn.size() - 1).getValue().toString();
+                       Node userNode;
+                       if (!usersBase.hasNode(uid)) {
+                               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);
+                               adminSession.save();
+                       } else {
+                               userNode = usersBase.getNode(uid);
+                       }
+                       return userNode;
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot create user node for " + userDn, e);
+               }
+       }
+
+       public static Node getOrCreateSessionDir(Session adminSession, CmsSession cmsSession) {
+               try {
+                       LdapName 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);
+//                     }
+                       String cmsSessionUuid = cmsSession.getUuid().toString();
+                       Node userDir;
+                       if (!userNode.hasNode(cmsSessionUuid)) {
+                               userDir = userNode.addNode(cmsSessionUuid, NodeType.NT_UNSTRUCTURED);
+                               userDir.addMixin(NodeType.MIX_CREATED);
+                               adminSession.save();
+                               JcrUtils.addPrivilege(adminSession, userDir.getPath(), cmsSession.getUserDn().toString(),
+                                               Privilege.JCR_ALL);
+                       } else {
+                               userDir = userNode.getNode(cmsSessionUuid);
+                       }
+                       return userDir;
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot create session dir for " + cmsSession, e);
+               }
+       }
+
+       /** Singleton. */
+       private SuiteUtils() {
+
+       }
+
+}
index 91f20433c5379fc8c24fe7084a48fe7c246df5d0..db6ac913422a5118db5428dbef8fa0b6966ef5bd 100644 (file)
@@ -2,9 +2,15 @@ package org.argeo.suite.core;
 
 import java.io.IOException;
 
+import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
+import javax.jcr.nodetype.NodeType;
+import javax.jcr.security.Privilege;
 
+import org.argeo.api.NodeConstants;
+import org.argeo.entity.EntityType;
+import org.argeo.jcr.JcrUtils;
 import org.argeo.maintenance.AbstractMaintenanceService;
 
 /** Initialises an Argeo Suite backend. */
@@ -13,14 +19,20 @@ public class SuiteMaintenanceService extends AbstractMaintenanceService {
        @Override
        public boolean prepareJcrTree(Session adminSession) throws RepositoryException, IOException {
                boolean modified = false;
-//             Node rootNode = adminSession.getRootNode();
-//             if (!rootNode.hasNode(EntityNames.TERM)) {
-//                     rootNode.addNode(EntityNames.TERM, EntityType.typologies.get());
-//                     modified = true;
-//             }
-//             if (modified)
-//                     adminSession.save();
+               Node rootNode = adminSession.getRootNode();
+               if (!rootNode.hasNode(EntityType.user.name())) {
+                       rootNode.addNode(EntityType.user.name(), NodeType.NT_UNSTRUCTURED);
+                       modified = true;
+               }
+               if (modified)
+                       adminSession.save();
                return modified;
        }
 
+       @Override
+       public void configurePrivileges(Session adminSession) throws RepositoryException {
+               JcrUtils.addPrivilege(adminSession, EntityType.user.basePath(), NodeConstants.ROLE_USER_ADMIN,
+                               Privilege.JCR_ALL);
+       }
+
 }
index 0e7d2d87d600fc49de998e6fe583ab48b5c7d462..170bf83ea19e397d8893a4e061d4a04d71d0e626 100644 (file)
@@ -5,6 +5,7 @@ import java.util.Set;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 
+import org.argeo.api.NodeConstants;
 import org.argeo.cms.CmsUserManager;
 import org.argeo.cms.ui.CmsTheme;
 import org.argeo.cms.ui.CmsUiProvider;
@@ -14,6 +15,7 @@ import org.argeo.entity.EntityType;
 import org.argeo.jcr.Jcr;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.naming.LdapAttrs;
+import org.argeo.suite.SuiteRole;
 import org.eclipse.jface.viewers.ColumnLabelProvider;
 import org.eclipse.jface.viewers.DoubleClickEvent;
 import org.eclipse.jface.viewers.IDoubleClickListener;
@@ -105,9 +107,9 @@ public class AdminEntryArea implements CmsUiProvider {
                        public void doubleClick(DoubleClickEvent event) {
                                User user = (User) usersViewer.getStructuredSelection().getFirstElement();
                                if (user != null) {
-                                       Node userNode = getOrCreateUserNode(user, context);
+//                                     Node userNode = getOrCreateUserNode(user, context);
                                        CmsView.getCmsView(parent).sendEvent(SuiteEvent.openNewPart.topic(),
-                                                       SuiteEvent.eventProperties(userNode));
+                                                       SuiteEvent.eventProperties(user));
                                }
 
                        }
@@ -116,9 +118,9 @@ public class AdminEntryArea implements CmsUiProvider {
                        public void selectionChanged(SelectionChangedEvent event) {
                                User user = (User) usersViewer.getStructuredSelection().getFirstElement();
                                if (user != null) {
-                                       Node userNode = getOrCreateUserNode(user, context);
+//                                     Node userNode = getOrCreateUserNode(user, context);
                                        CmsView.getCmsView(parent).sendEvent(SuiteEvent.refreshPart.topic(),
-                                                       SuiteEvent.eventProperties(userNode));
+                                                       SuiteEvent.eventProperties(user));
                                        deleteItem.setEnabled(true);
                                } else {
                                        deleteItem.setEnabled(false);
@@ -132,11 +134,11 @@ public class AdminEntryArea implements CmsUiProvider {
                return usersViewer.getTable();
        }
 
-       private Node getOrCreateUserNode(User user, Node context) {
-               return JcrUtils.mkdirs(Jcr.getSession(context),
-                               "/" + EntityType.user.name() + "/" + getUserProperty(user, LdapAttrs.uid.name()),
-                               EntityType.user.get());
-       }
+//     private Node getOrCreateUserNode(User user, Node context) {
+//             return JcrUtils.mkdirs(Jcr.getSession(context),
+//                             "/" + EntityType.user.name() + "/" + getUserProperty(user, LdapAttrs.uid.name()),
+//                             EntityType.user.get());
+//     }
 
        private String getUserProperty(Object element, String key) {
                Object value = ((User) element).getProperties().get(key);
@@ -148,8 +150,7 @@ public class AdminEntryArea implements CmsUiProvider {
                @Override
                public Object[] getElements(Object inputElement) {
                        CmsUserManager cum = (CmsUserManager) inputElement;
-                       String baseGroup = "cn=apaf-coworker,cn=groups,cn=accounts,dc=id,dc=argeo,dc=pro";
-                       Set<User> users = cum.listUsersInGroup(baseGroup, null);
+                       Set<User> users = cum.listUsersInGroup(SuiteRole.coworker.dn(), null);
                        return users.toArray();
                }
 
index 80ebd6e8cf16bdfcdecac84d97161864eb3e5bd9..db8a8dc17e0d589d01d2ae0de04580bfe0e7744d 100644 (file)
@@ -15,11 +15,14 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.api.NodeUtils;
 import org.argeo.cms.CmsUserManager;
+import org.argeo.cms.auth.CmsSession;
 import org.argeo.cms.ui.AbstractCmsApp;
 import org.argeo.cms.ui.CmsTheme;
 import org.argeo.cms.ui.CmsUiProvider;
@@ -31,14 +34,15 @@ import org.argeo.entity.EntityConstants;
 import org.argeo.entity.EntityNames;
 import org.argeo.entity.EntityType;
 import org.argeo.jcr.Jcr;
-import org.argeo.jcr.JcrUtils;
 import org.argeo.suite.RankedObject;
+import org.argeo.suite.SuiteUtils;
 import org.argeo.util.LangUtils;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.widgets.Composite;
 import org.osgi.framework.Constants;
 import org.osgi.service.event.Event;
 import org.osgi.service.event.EventHandler;
+import org.osgi.service.useradmin.User;
 
 /** The Argeo Suite App. */
 public class SuiteApp extends AbstractCmsApp implements EventHandler {
@@ -125,25 +129,32 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                                ui.logout();
                                ui.refreshBelowHeader(false);
                                refreshPart(findUiProvider(LOGIN_SCREEN_PID), ui.getBelowHeader(), context);
+                               ui.layout(true, true);
                        } else {
-                               try {
-                                       if (ui.getUserHome() == null)
-                                               ui.initSessions(getRepository());
-                                       context = ui.getUserHome();
-
-                               } catch (RepositoryException e) {
-                                       e.printStackTrace();
+                               if (ui.getUserDir() == null) {
+                                       CmsSession cmsSession = cmsView.getCmsSession();
+                                       Session adminSession = null;
+                                       try {
+                                               adminSession = NodeUtils.openDataAdminSession(getRepository(), null);
+                                               Node userDir = SuiteUtils.getOrCreateSessionDir(adminSession, cmsSession);
+                                               ui.initSessions(getRepository(), userDir.getPath());
+                                       } finally {
+                                               Jcr.logout(adminSession);
+                                       }
                                }
-                               ui.refreshBelowHeader(true);
+                               context = stateToNode(ui, state);
+                               if (context == null)
+                                       context = ui.getUserDir();
 
+                               ui.refreshBelowHeader(true);
                                for (String key : layersByPid.keySet()) {
                                        SuiteLayer layer = layersByPid.get(key).get();
                                        ui.addLayer(key, layer);
                                }
                                refreshPart(findUiProvider(LEAD_PANE_PID), ui.getLeadPane(), context);
+                               ui.layout(true, true);
+                               setState(parent, state);
                        }
-                       ui.layout(true, true);
-                       setState(parent, state);
                } catch (Exception e) {
                        CmsFeedback.show("Unexpected exception", e);
                }
@@ -201,7 +212,7 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                        }
 
                        if (types.size() == 0)
-                               throw new IllegalArgumentException("No component found for " + context);
+                               throw new IllegalArgumentException("No type found for " + context);
                        String type = types.iterator().next();
                        if (!byType.containsKey(type))
                                throw new IllegalArgumentException("No component found for " + context + " with type " + type);
@@ -213,46 +224,93 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
 
        @Override
        public void setState(Composite parent, String state) {
-               CmsView cmsView = CmsView.getCmsView(parent);
-               if(cmsView.isAnonymous())
+               if (state == null || !state.startsWith("/"))
                        return;
-               // for the time being we systematically open a session, in order to make sure
-               // that home is initialised
-               Session session = null;
-               try {
-                       if (state != null && state.startsWith("/")) {
-                               String path = state.substring(1);
-                               String workspace;
-                               if (path.equals("")) {
-                                       workspace = null;
-                                       path = "/";
-                               } else {
-                                       int index = path.indexOf('/');
-                                       if (index == 0) {
-                                               log.error("Cannot interpret " + state);
-                                               cmsView.navigateTo("~");
-                                               return;
-                                       } else if (index > 0) {
-                                               workspace = path.substring(0, index);
-                                               path = path.substring(index);
-                                       } else {// index<0, assuming root node
-                                               workspace = path;
-                                               path = "/";
-                                       }
-                               }
-                               session = cmsView.doAs(() -> Jcr.login(getRepository(), workspace));
+               SuiteUi suiteUi = (SuiteUi) parent;
+               Node node = stateToNode(suiteUi, state);
+               if (node == null) {
+                       suiteUi.getCmsView().navigateTo("~");
+               } else {
+                       suiteUi.getCmsView().sendEvent(SuiteEvent.switchLayer.topic(), SuiteEvent.eventProperties(node));
+                       suiteUi.getCmsView().sendEvent(SuiteEvent.refreshPart.topic(), SuiteEvent.eventProperties(node));
+               }
+
+//             CmsView cmsView = CmsView.getCmsView(parent);
+//             if (cmsView.isAnonymous())
+//                     return;
+//             Session session = null;
+//             try {
+//                     if (state != null && state.startsWith("/")) {
+//                             String path = state.substring(1);
+//                             String workspace;
+//                             if (path.equals("")) {
+//                                     workspace = null;
+//                                     path = "/";
+//                             } else {
+//                                     int index = path.indexOf('/');
+//                                     if (index == 0) {
+//                                             log.error("Cannot interpret " + state);
+//                                             cmsView.navigateTo("~");
+//                                             return;
+//                                     } else if (index > 0) {
+//                                             workspace = path.substring(0, index);
+//                                             path = path.substring(index);
+//                                     } else {// index<0, assuming root node
+//                                             workspace = path;
+//                                             path = "/";
+//                                     }
+//                             }
+//                             session = cmsView.doAs(() -> Jcr.login(getRepository(), workspace));
+//
+//                             Node node = session.getNode(path);
+//
+//                             cmsView.sendEvent(SuiteEvent.switchLayer.topic(), SuiteEvent.eventProperties(node));
+//                             cmsView.sendEvent(SuiteEvent.refreshPart.topic(), SuiteEvent.eventProperties(node));
+//                     }
+//             } catch (RepositoryException e) {
+//                     log.error("Cannot load state " + state, e);
+//                     cmsView.navigateTo("~");
+//             } finally {
+//                     JcrUtils.logoutQuietly(session);
+//             }
+       }
+
+       private String nodeToState(Node node) {
+               return '/' + Jcr.getWorkspaceName(node) + Jcr.getPath(node);
+       }
 
-                               Node node = session.getNode(path);
+       private Node stateToNode(SuiteUi suiteUi, String state) {
+               if (suiteUi == null)
+                       return null;
+               if (state == null)
+                       return null;
 
-                               cmsView.sendEvent(SuiteEvent.switchLayer.topic(), SuiteEvent.eventProperties(node));
-                               cmsView.sendEvent(SuiteEvent.refreshPart.topic(), SuiteEvent.eventProperties(node));
+               String path = state.substring(1);
+               String workspace;
+               if (path.equals("")) {
+                       workspace = null;
+                       path = "/";
+               } else {
+                       int index = path.indexOf('/');
+                       if (index == 0) {
+                               log.error("Cannot interpret " + state);
+//                             cmsView.navigateTo("~");
+                               return null;
+                       } else if (index > 0) {
+                               workspace = path.substring(0, index);
+                               path = path.substring(index);
+                       } else {// index<0, assuming root node
+                               workspace = path;
+                               path = "/";
                        }
-               } catch (RepositoryException e) {
-                       log.error("Cannot load state " + state, e);
-                       cmsView.navigateTo("~");
-               } finally {
-                       JcrUtils.logoutQuietly(session);
                }
+//             session = cmsView.doAs(() -> Jcr.login(getRepository(), workspace));
+
+               Session session = suiteUi.getSession(workspace);
+               if (session == null)
+                       return null;
+               Node node = Jcr.getNode(session, path);
+               return node;
        }
 
        /*
@@ -268,16 +326,12 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                        String currentLayerId = ui.getCurrentLayerId();
                        SuiteLayer currentLayer = currentLayerId != null ? layersByPid.get(currentLayerId).get() : null;
                        if (isTopic(event, SuiteEvent.refreshPart)) {
-                               String nodePath = get(event, SuiteEvent.NODE_PATH);
-                               String workspace = get(event, SuiteEvent.WORKSPACE);
-                               Node node = Jcr.getNode(ui.getSession(workspace), nodePath);
+                               Node node = getNode(ui, event);
                                CmsUiProvider uiProvider = findByType(uiProvidersByType, node);
                                currentLayer.view(uiProvider, ui.getCurrentWorkArea(), node);
                                ui.getCmsView().stateChanged(nodeToState(node), Jcr.getTitle(node));
                        } else if (isTopic(event, SuiteEvent.openNewPart)) {
-                               String nodePath = get(event, SuiteEvent.NODE_PATH);
-                               String workspace = get(event, SuiteEvent.WORKSPACE);
-                               Node node = Jcr.getNode(ui.getSession(workspace), nodePath);
+                               Node node = getNode(ui, event);
                                CmsUiProvider uiProvider = findByType(uiProvidersByType, node);
                                currentLayer.open(uiProvider, ui.getCurrentWorkArea(), node);
                                ui.getCmsView().stateChanged(nodeToState(node), Jcr.getTitle(node));
@@ -286,10 +340,8 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
                                if (layerId != null) {
                                        ui.switchToLayer(layerId, Jcr.getRootNode(ui.getSession(null)));
                                } else {
-                                       String nodePath = get(event, SuiteEvent.NODE_PATH);
-                                       String workspace = get(event, SuiteEvent.WORKSPACE);
-                                       if (nodePath != null) {
-                                               Node node = Jcr.getNode(ui.getSession(workspace), nodePath);
+                                       Node node = getNode(ui, event);
+                                       if (node != null) {
                                                SuiteLayer layer = findByType(layersByType, node);
                                                ui.switchToLayer(layer, node);
                                        }
@@ -302,8 +354,42 @@ public class SuiteApp extends AbstractCmsApp implements EventHandler {
 
        }
 
-       private String nodeToState(Node node) {
-               return '/' + Jcr.getWorkspaceName(node) + Jcr.getPath(node);
+       private Node getNode(SuiteUi ui, Event event) {
+               String nodePath = get(event, SuiteEvent.NODE_PATH);
+               String workspaceName = get(event, SuiteEvent.WORKSPACE);
+               Session session = ui.getSession(workspaceName);
+               Node node;
+               if (nodePath == null) {
+                       // look for a user
+                       String username = get(event, SuiteEvent.USERNAME);
+                       if (username == null)
+                               return null;
+                       User user = cmsUserManager.getUser(username);
+                       if (user == null)
+                               return null;
+                       LdapName userDn;
+                       try {
+                               userDn = new LdapName(user.getName());
+                       } catch (InvalidNameException e) {
+                               throw new IllegalArgumentException("Badly formatted username", e);
+                       }
+                       String userNodePath = SuiteUtils.getUserNodePath(userDn);
+                       if (Jcr.itemExists(session, userNodePath))
+                               node = Jcr.getNode(session, userNodePath);
+                       else {
+                               Session adminSession = null;
+                               try {
+                                       adminSession = NodeUtils.openDataAdminSession(getRepository(), workspaceName);
+                                       SuiteUtils.getOrCreateUserNode(adminSession, userDn);
+                               } finally {
+                                       Jcr.logout(adminSession);
+                               }
+                               node = Jcr.getNode(session, userNodePath);
+                       }
+               } else {
+                       node = Jcr.getNode(session, nodePath);
+               }
+               return node;
        }
 
        private SuiteUi getRelatedUi(Event event) {
index 1231d9262efda834e893a75f6a4dd81b670f79af..cad5a9b994e093dce57c08c18dc147e630f54686 100644 (file)
@@ -11,7 +11,6 @@ import javax.jcr.Session;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.api.NodeConstants;
-import org.argeo.api.NodeUtils;
 import org.argeo.cms.ui.CmsView;
 import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.jcr.Jcr;
@@ -29,8 +28,8 @@ class SuiteUi extends Composite {
        private Composite dynamicArea;
 
        private Session sysSession;
-       private Session homeSession;
-       private Node userHome;
+//     private Session homeSession;
+       private Node userDir;
 
        private Map<String, SuiteLayer> layers = new HashMap<>();
        private Map<String, Composite> workAreas = new HashMap<>();
@@ -105,7 +104,7 @@ class SuiteUi extends Composite {
                }
                if (context == null) {
                        if (!cmsView.isAnonymous())
-                               context = userHome;
+                               context = userDir;
                }
                Composite toShow = getLayer(layerId, context);
                currentLayerId = layerId;
@@ -152,9 +151,9 @@ class SuiteUi extends Composite {
        }
 
        synchronized void logout() {
-               userHome = null;
+               userDir = null;
                Jcr.logout(sysSession);
-               Jcr.logout(homeSession);
+//             Jcr.logout(homeSession);
                currentLayerId = null;
                workAreas.clear();
        }
@@ -179,18 +178,18 @@ class SuiteUi extends Composite {
 //             return sysSession;
 //     }
 //
-       synchronized void initSessions(Repository repository) throws RepositoryException {
+       synchronized void initSessions(Repository repository, String userDirPath) throws RepositoryException {
                this.sysSession = repository.login();
-               this.homeSession = repository.login(NodeConstants.HOME_WORKSPACE);
-               userHome = NodeUtils.getUserHome(homeSession);
+//             this.homeSession = repository.login(NodeConstants.HOME_WORKSPACE);
+               userDir = sysSession.getNode(userDirPath);
                addDisposeListener((e) -> {
                        Jcr.logout(sysSession);
-                       Jcr.logout(homeSession);
+//                     Jcr.logout(homeSession);
                });
        }
 
-       Node getUserHome() {
-               return userHome;
+       Node getUserDir() {
+               return userDir;
        }
 
        Session getSysSession() {
@@ -202,8 +201,8 @@ class SuiteUi extends Composite {
                        return sysSession;
                if (NodeConstants.SYS_WORKSPACE.equals(workspaceName))
                        return sysSession;
-               else if (NodeConstants.HOME_WORKSPACE.equals(workspaceName))
-                       return homeSession;
+//             else if (NodeConstants.HOME_WORKSPACE.equals(workspaceName))
+//                     return homeSession;
                else
                        throw new IllegalArgumentException("Unknown workspace " + workspaceName);
        }