Start making theming separate
[lgpl/argeo-commons.git] / org.argeo.cms.ui / src / org / argeo / cms / ui / AbstractCmsEntryPoint.java
index 22a2ba3e1dbec9f6c74fe922b822c9845eb0256d..43906fae73e7914aaa0797d06aa7746e76da93ad 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.cms.ui;
 
+import java.io.IOException;
 import java.security.PrivilegedAction;
 import java.util.HashMap;
 import java.util.Map;
@@ -12,6 +13,11 @@ import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.nodetype.NodeType;
 import javax.security.auth.Subject;
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 import javax.servlet.http.HttpServletRequest;
@@ -19,11 +25,11 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.argeo.cms.CmsException;
+import org.argeo.cms.auth.CurrentUser;
 import org.argeo.cms.auth.HttpRequestCallbackHandler;
 import org.argeo.eclipse.ui.specific.UiContext;
 import org.argeo.jcr.JcrUtils;
 import org.argeo.node.NodeConstants;
-import org.argeo.node.security.NodeAuthenticated;
 import org.eclipse.rap.rwt.RWT;
 import org.eclipse.rap.rwt.application.AbstractEntryPoint;
 import org.eclipse.rap.rwt.client.WebClient;
@@ -54,7 +60,6 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
        private Node node;
        private String nodePath;// useful when changing auth
        private String state;
-       private String page;
        private Throwable exception;
 
        // Client services
@@ -70,19 +75,20 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
                // subject = new Subject();
 
                // Initial login
+               LoginContext lc;
                try {
-                       loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER,
+                       lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER,
                                        new HttpRequestCallbackHandler(UiContext.getHttpRequest(), UiContext.getHttpResponse()));
-                       loginContext.login();
+                       lc.login();
                } catch (LoginException e) {
                        try {
-                               loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER);
-                               loginContext.login();
+                               lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS);
+                               lc.login();
                        } catch (LoginException e1) {
                                throw new CmsException("Cannot log in as anonymous", e1);
                        }
                }
-               authChange(loginContext);
+               authChange(lc);
 
                jsExecutor = RWT.getClient().getService(JavaScriptExecutor.class);
                browserNavigation = RWT.getClient().getService(BrowserNavigation.class);
@@ -108,8 +114,8 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
 
        @Override
        protected final void createContents(final Composite parent) {
-               UiContext.setData(NodeAuthenticated.KEY, this);
-               Subject.doAs(loginContext.getSubject(), new PrivilegedAction<Void>() {
+               UiContext.setData(CmsView.KEY, this);
+               Subject.doAs(getSubject(), new PrivilegedAction<Void>() {
                        @Override
                        public Void run() {
                                try {
@@ -132,7 +138,7 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
         * The node to return when no node was found (for authenticated users and
         * anonymous)
         */
-       protected Node getDefaultNode(Session session) throws RepositoryException {
+       private Node getDefaultNode(Session session) throws RepositoryException {
                if (!session.hasPermission(defaultPath, "read")) {
                        String userId = session.getUserID();
                        if (userId.equals(NodeConstants.ROLE_ANONYMOUS))
@@ -161,9 +167,17 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
        // return subject;
        // }
 
+       // @Override
+       // public LoginContext getLoginContext() {
+       // return loginContext;
+       // }
+       protected Subject getSubject() {
+               return loginContext.getSubject();
+       }
+
        @Override
-       public LoginContext getLoginContext() {
-               return loginContext;
+       public boolean isAnonymous() {
+               return CurrentUser.isAnonymous(getSubject());
        }
 
        @Override
@@ -171,8 +185,9 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
                if (loginContext == null)
                        throw new CmsException("Login context should not be null");
                try {
+                       CurrentUser.logoutCmsSession(loginContext.getSubject());
                        loginContext.logout();
-                       LoginContext anonymousLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER);
+                       LoginContext anonymousLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS);
                        anonymousLc.login();
                        authChange(anonymousLc);
                } catch (LoginException e) {
@@ -181,11 +196,18 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
        }
 
        @Override
-       public synchronized void authChange(LoginContext loginContext) {
-               if (loginContext == null)
+       public synchronized void authChange(LoginContext lc) {
+               if (lc == null)
                        throw new CmsException("Login context cannot be null");
-               this.loginContext = loginContext;
-               Subject.doAs(loginContext.getSubject(), new PrivilegedAction<Void>() {
+               // logout previous login context
+               if (this.loginContext != null)
+                       try {
+                               this.loginContext.logout();
+                       } catch (LoginException e1) {
+                               log.warn("Could not log out: " + e1);
+                       }
+               this.loginContext = lc;
+               Subject.doAs(getSubject(), new PrivilegedAction<Void>() {
 
                        @Override
                        public Void run() {
@@ -208,7 +230,6 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
                        }
 
                });
-
        }
 
        @Override
@@ -219,7 +240,7 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
        }
 
        protected synchronized void doRefresh() {
-               Subject.doAs(loginContext.getSubject(), new PrivilegedAction<Void>() {
+               Subject.doAs(getSubject(), new PrivilegedAction<Void>() {
                        @Override
                        public Void run() {
                                refresh();
@@ -232,8 +253,8 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
        protected synchronized String setState(String newState) {
                String previousState = this.state;
 
-               Node node = null;
-               page = null;
+               String newNodePath = null;
+               String prefix = null;
                this.state = newState;
                if (newState.equals("~"))
                        this.state = "";
@@ -241,25 +262,53 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
                try {
                        int firstSlash = state.indexOf('/');
                        if (firstSlash == 0) {
-                               node = session.getNode(state);
-                               page = "";
+                               newNodePath = state;
+                               prefix = "";
                        } else if (firstSlash > 0) {
-                               String prefix = state.substring(0, firstSlash);
-                               String path = state.substring(firstSlash);
-                               if (session.nodeExists(path))
-                                       node = session.getNode(path);
-                               else
-                                       throw new CmsException("Data " + path + " does not exist");
-                               page = prefix;
+                               prefix = state.substring(0, firstSlash);
+                               newNodePath = state.substring(firstSlash);
+                       } else {
+                               newNodePath = defaultPath;
+                               prefix = state;
+
+                       }
+
+                       // auth
+                       int colonIndex = prefix.indexOf(':');
+                       if (colonIndex > 0) {
+                               String user = prefix.substring(0, colonIndex);
+                               // if (isAnonymous()) {
+                               String token = prefix.substring(colonIndex + 1);
+                               LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, new CallbackHandler() {
+
+                                       @Override
+                                       public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
+                                               for (Callback callback : callbacks) {
+                                                       if (callback instanceof NameCallback)
+                                                               ((NameCallback) callback).setName(user);
+                                                       else if (callback instanceof PasswordCallback)
+                                                               ((PasswordCallback) callback).setPassword(token.toCharArray());
+                                               }
+
+                                       }
+                               });
+                               lc.login();
+                               authChange(lc);// sets the node as well
+                               // } else {
+                               // // TODO check consistency
+                               // }
                        } else {
-                               node = getDefaultNode(session);
-                               page = state;
+                               Node newNode = null;
+                               if (session.nodeExists(newNodePath))
+                                       newNode = session.getNode(newNodePath);
+                               else
+                                       throw new CmsException("Data " + newNodePath + " does not exist");
+                               setNode(newNode);
                        }
-                       setNode(node);
-                       String title = publishMetaData(node);
+                       String title = publishMetaData(getNode());
 
                        if (log.isTraceEnabled())
-                               log.trace("node=" + node + ", state=" + state + " (page=" + page + ")");
+                               log.trace("node=" + newNodePath + ", state=" + state + " (prefix=" + prefix + ")");
 
                        return title;
                } catch (Exception e) {
@@ -329,7 +378,7 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement
                @Override
                public void navigated(BrowserNavigationEvent event) {
                        setState(event.getState());
-                       refresh();
+                       doRefresh();
                }
        }
 }
\ No newline at end of file