X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.cms.ui%2Fsrc%2Forg%2Fargeo%2Fcms%2Fui%2FAbstractCmsEntryPoint.java;h=2cd86ce08edc115300b1e9cda9d0309b4d8626bc;hb=92b77a90db637e71a7ccbc76fc12bad6ba4a289a;hp=bea7117a6c6e3737e8fb1aec82797164f0462ba1;hpb=7864616a19aefc440239c1c8854c6b3969be7af0;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/AbstractCmsEntryPoint.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/AbstractCmsEntryPoint.java index bea7117a6..2cd86ce08 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/AbstractCmsEntryPoint.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/AbstractCmsEntryPoint.java @@ -1,5 +1,8 @@ package org.argeo.cms.ui; +import static org.argeo.naming.SharedSecret.X_SHARED_SECRET; + +import java.io.IOException; import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Map; @@ -12,6 +15,8 @@ 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.UnsupportedCallbackException; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import javax.servlet.http.HttpServletRequest; @@ -20,11 +25,13 @@ 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.HttpRequestCallback; import org.argeo.cms.auth.HttpRequestCallbackHandler; import org.argeo.eclipse.ui.specific.UiContext; import org.argeo.jcr.JcrUtils; +import org.argeo.naming.AuthPassword; +import org.argeo.naming.SharedSecret; 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; @@ -55,7 +62,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 @@ -71,19 +77,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_ANONYMOUS); - 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); @@ -109,8 +116,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() { + UiContext.setData(CmsView.KEY, this); + Subject.doAs(getSubject(), new PrivilegedAction() { @Override public Void run() { try { @@ -133,17 +140,17 @@ 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 { - if (!session.hasPermission(defaultPath, "read")) { - String userId = session.getUserID(); - if (userId.equals(NodeConstants.ROLE_ANONYMOUS)) - // TODO throw a special exception - throw new CmsException("Login required"); - else - throw new CmsException("Unauthorized"); - } - return session.getNode(defaultPath); - } +// private Node getDefaultNode(Session session) throws RepositoryException { +// if (!session.hasPermission(defaultPath, "read")) { +// String userId = session.getUserID(); +// if (userId.equals(NodeConstants.ROLE_ANONYMOUS)) +// // TODO throw a special exception +// throw new CmsException("Login required"); +// else +// throw new CmsException("Unauthorized"); +// } +// return session.getNode(defaultPath); +// } protected String getBaseTitle() { return factoryProperties.get(WebClient.PAGE_TITLE); @@ -162,9 +169,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 @@ -183,11 +198,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() { + // 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() { @Override public Void run() { @@ -210,7 +232,6 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement } }); - } @Override @@ -221,7 +242,7 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement } protected synchronized void doRefresh() { - Subject.doAs(loginContext.getSubject(), new PrivilegedAction() { + Subject.doAs(getSubject(), new PrivilegedAction() { @Override public Void run() { refresh(); @@ -234,8 +255,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 = ""; @@ -243,25 +264,54 @@ 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 { - node = getDefaultNode(session); - page = state; + newNodePath = defaultPath; + prefix = state; + + } + + // auth + int colonIndex = prefix.indexOf('$'); + if (colonIndex > 0) { + SharedSecret token = new SharedSecret(new AuthPassword(X_SHARED_SECRET + '$' + prefix)) { + + @Override + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + super.handle(callbacks); + // handle HTTP context + for (Callback callback : callbacks) { + if (callback instanceof HttpRequestCallback) { + ((HttpRequestCallback) callback).setRequest(UiContext.getHttpRequest()); + ((HttpRequestCallback) callback).setResponse(UiContext.getHttpResponse()); + } + } + } + }; + LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, token); + lc.login(); + authChange(lc);// sets the node as well + // } else { + // // TODO check consistency + // } + } else { + Node newNode = null; + if (session.nodeExists(newNodePath)) + newNode = session.getNode(newNodePath); + else { +// throw new CmsException("Data " + newNodePath + " does not exist"); + newNode = null; + } + 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) { @@ -278,7 +328,7 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement private String publishMetaData(Node node) throws RepositoryException { // Title String title; - if (node.isNodeType(NodeType.MIX_TITLE) && node.hasProperty(Property.JCR_TITLE)) + if (node != null && node.isNodeType(NodeType.MIX_TITLE) && node.hasProperty(Property.JCR_TITLE)) title = node.getProperty(Property.JCR_TITLE).getString() + " - " + getBaseTitle(); else title = getBaseTitle(); @@ -288,6 +338,8 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement return null; StringBuilder js = new StringBuilder(); + if (title == null) + title = ""; title = title.replace("'", "\\'");// sanitize js.append("document.title = '" + title + "';"); jsExecutor.execute(js.toString()); @@ -331,7 +383,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