From: Mathieu Baudier Date: Sat, 1 Oct 2016 19:03:17 +0000 (+0000) Subject: Change webdav and remoting URLs X-Git-Tag: argeo-commons-2.1.48~4 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=54cba9d97464302cbcfad9d8a57cb23a17bdddb7;p=lgpl%2Fargeo-commons.git Change webdav and remoting URLs git-svn-id: https://svn.argeo.org/commons/trunk@9235 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- diff --git a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java index 1f572b304..8b19b51a9 100644 --- a/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java +++ b/org.argeo.cms.ui.workbench/src/org/argeo/cms/ui/workbench/internal/jcr/commands/AddRemoteRepository.java @@ -114,7 +114,7 @@ public class AddRemoteRepository extends AbstractHandler implements setMessage("Login to remote repository", IMessageProvider.NONE); name = createLT(composite, "Name", "remoteRepository"); uri = createLT(composite, "URI", - "http://localhost:7070/data/jcr/node"); + "http://localhost:7070/jcr/node"); username = createLT(composite, "User", ""); password = createLP(composite, "Password"); diff --git a/org.argeo.cms.ui/src/org/argeo/cms/util/CmsUtils.java b/org.argeo.cms.ui/src/org/argeo/cms/util/CmsUtils.java index 108dd3a95..27f83807f 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/util/CmsUtils.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/util/CmsUtils.java @@ -4,17 +4,11 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; -import javax.jcr.Item; import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.Repository; import javax.jcr.RepositoryException; -import javax.jcr.Session; import javax.servlet.http.HttpServletRequest; import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.cms.CmsException; import org.argeo.cms.ui.CmsConstants; import org.argeo.cms.ui.CmsView; @@ -22,6 +16,7 @@ import org.argeo.eclipse.ui.specific.UiContext; import org.argeo.jcr.JcrUtils; import org.argeo.node.NodeAuthenticated; import org.argeo.node.NodeConstants; +import org.argeo.node.NodeUtils; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.service.ResourceManager; import org.eclipse.swt.SWT; @@ -39,7 +34,7 @@ import org.eclipse.swt.widgets.Widget; /** Static utilities for the CMS framework. */ public class CmsUtils implements CmsConstants { - private final static Log log = LogFactory.getLog(CmsUtils.class); + // private final static Log log = LogFactory.getLog(CmsUtils.class); /** * The CMS view related to this display, or null if none is available from @@ -73,33 +68,40 @@ public class CmsUtils implements CmsConstants { } } - // FIXME - private final static String PATH_DATA = "/data"; - private final static String WEBDAV_PUBLIC = PATH_DATA + "/public"; - private final static String WEBDAV_PRIVATE = PATH_DATA + "/files"; + // private final static String PATH_DATA = "/data"; + // private final static String WEBDAV_PUBLIC = PATH_DATA + "/public"; + // private final static String WEBDAV_PRIVATE = PATH_DATA + "/files"; + /** A path in the node repository */ public static String getDataPath(Node node) throws RepositoryException { - assert node != null; - String userId = node.getSession().getUserID(); - if (log.isTraceEnabled()) - log.trace(userId + " : " + node.getPath()); - StringBuilder buf = new StringBuilder(); - boolean isAnonymous = userId.equalsIgnoreCase(NodeConstants.ROLE_ANONYMOUS); - if (isAnonymous) - buf.append(WEBDAV_PUBLIC); - else - buf.append(WEBDAV_PRIVATE); - Session session = node.getSession(); - Repository repository = session.getRepository(); - String cn; - if (repository.isSingleValueDescriptor(NodeConstants.CN)) { - cn = repository.getDescriptor(NodeConstants.CN); - } else { - log.warn("No cn defined in repository, using " + NodeConstants.NODE); - cn = NodeConstants.NODE; - } - return buf.append('/').append(cn).append('/').append(session.getWorkspace().getName()).append(node.getPath()) - .toString(); + return getDataPath(NodeConstants.NODE, node); + } + + public static String getDataPath(String cn, Node node) throws RepositoryException { + return NodeUtils.getDataPath(cn, node); + // assert node != null; + // String userId = node.getSession().getUserID(); + // if (log.isTraceEnabled()) + // log.trace(userId + " : " + node.getPath()); + // StringBuilder buf = new StringBuilder(); + // boolean isAnonymous = + // userId.equalsIgnoreCase(NodeConstants.ROLE_ANONYMOUS); + // if (isAnonymous) + // buf.append(WEBDAV_PUBLIC); + // else + // buf.append(WEBDAV_PRIVATE); + // Session session = node.getSession(); + // Repository repository = session.getRepository(); + // String cn; + // if (repository.isSingleValueDescriptor(NodeConstants.CN)) { + // cn = repository.getDescriptor(NodeConstants.CN); + // } else { + // log.warn("No cn defined in repository, using " + NodeConstants.NODE); + // cn = NodeConstants.NODE; + // } + // return + // buf.append('/').append(cn).append('/').append(session.getWorkspace().getName()).append(node.getPath()) + // .toString(); } // // public static String getCanonicalUrl(Node node, HttpServletRequest @@ -164,25 +166,27 @@ public class CmsUtils implements CmsConstants { table.setData(CmsConstants.ITEM_HEIGHT, height); } - /** @return the path or null if not instrumented */ - public static String getDataPath(Widget widget) { - // JCR item - Object data = widget.getData(); - if (data != null && data instanceof Item) { - try { - return ((Item) data).getPath(); - } catch (RepositoryException e) { - throw new CmsException("Cannot find data path of " + data + " for " + widget); - } - } - - // JCR path - data = widget.getData(Property.JCR_PATH); - if (data != null) - return data.toString(); - - return null; - } + // /** @return the path or null if not instrumented */ + // @Deprecated + // public static String getDataPath(Widget widget) { + // // JCR item + // Object data = widget.getData(); + // if (data != null && data instanceof Item) { + // try { + // return ((Item) data).getPath(); + // } catch (RepositoryException e) { + // throw new CmsException("Cannot find data path of " + data + " for " + + // widget); + // } + // } + // + // // JCR path + // data = widget.getData(Property.JCR_PATH); + // if (data != null) + // return data.toString(); + // + // return null; + // } /** Dispose all children of a Composite */ public static void clear(Composite composite) { diff --git a/org.argeo.cms/src/org/argeo/cms/auth/HttpLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/HttpLoginModule.java index 71aec68c8..9a07e3c20 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/HttpLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/HttpLoginModule.java @@ -135,6 +135,7 @@ public class HttpLoginModule implements LoginModule, AuthConstants { if (log.isTraceEnabled()) log.trace("Added " + request.getServletPath() + " to " + cmsSession + " (" + request.getRequestURI() + ")"); + httpSession.setAttribute(HttpContext.REMOTE_USER, authorization.getName()); httpSession.setAttribute(HttpContext.AUTHORIZATION, authorization); } } @@ -170,7 +171,7 @@ public class HttpLoginModule implements LoginModule, AuthConstants { } if (srs.size() == 0) - throw new CmsException("No CMS web sesison found for http session " + httpSessionId); + throw new CmsException("No CMS web session found for http session " + httpSessionId); else if (srs.size() > 1) throw new CmsException(srs.size() + " CMS web sessions found for http session " + httpSessionId); diff --git a/org.argeo.cms/src/org/argeo/cms/internal/auth/KernelLoginModule.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/KernelLoginModule.java deleted file mode 100644 index b042b3f9f..000000000 --- a/org.argeo.cms/src/org/argeo/cms/internal/auth/KernelLoginModule.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.argeo.cms.internal.auth; - -public class KernelLoginModule {//implements LoginModule { -// private Subject subject; -// -// @Override -// public void initialize(Subject subject, CallbackHandler callbackHandler, -// Map sharedState, Map options) { -// this.subject = subject; -// } -// -// @Override -// public boolean login() throws LoginException { -// // TODO check permission at code level ? -// return true; -// } -// -// @Override -// public boolean commit() throws LoginException { -// // Check that kernel has been logged in w/ certificate -// // Name -// Set names = subject.getPrincipals(X500Principal.class); -// if (names.isEmpty() || names.size() > 1) { -// // throw new LoginException("Kernel must have been named"); -// // TODO set not hardened -// subject.getPrincipals().add( -// new X500Principal(AuthConstants.ROLE_KERNEL)); -// } else { -// X500Principal name = names.iterator().next(); -// if (!AuthConstants.ROLE_KERNEL.equals(name.getName())) -// throw new LoginException("Kernel must be named " -// + AuthConstants.ROLE_KERNEL); -// // Private certificate -// Set privateCerts = subject -// .getPrivateCredentials(X500PrivateCredential.class); -// X500PrivateCredential privateCert = null; -// for (X500PrivateCredential pCert : privateCerts) { -// if (pCert.getCertificate().getSubjectX500Principal() -// .equals(name)) { -// privateCert = pCert; -// } -// } -// if (privateCert == null) -// throw new LoginException( -// "Kernel must have a private certificate"); -// // Certificate path -// Set certPaths = subject -// .getPublicCredentials(CertPath.class); -// CertPath certPath = null; -// for (CertPath cPath : certPaths) { -// if (cPath.getCertificates().get(0) -// .equals(privateCert.getCertificate())) { -// certPath = cPath; -// } -// } -// if (certPath == null) -// throw new LoginException("Kernel must have a certificate path"); -// } -// Set principals = subject.getPrincipals(); -// // Add admin roles -// -// // Add data access roles -// principals.add(new AdminPrincipal(SecurityConstants.ADMIN_ID)); -// -// return true; -// } -// -// @Override -// public boolean abort() throws LoginException { -// return true; -// } -// -// @Override -// public boolean logout() throws LoginException { -// // clear everything -// subject.getPrincipals().clear(); -// subject.getPublicCredentials().clear(); -// subject.getPrivateCredentials().clear(); -// return true; -// } - -} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/DataHttp.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/DataHttp.java index a1507a591..469dfd2a7 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/DataHttp.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/DataHttp.java @@ -22,6 +22,7 @@ import javax.security.auth.login.LoginException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import org.apache.commons.codec.binary.Base64; import org.apache.commons.logging.Log; @@ -81,8 +82,8 @@ class DataHttp implements KernelConstants { void registerRepositoryServlets(String alias, Repository repository) { try { - registerWebdavServlet(alias, repository, true); - registerWebdavServlet(alias, repository, false); + registerWebdavServlet(alias, repository); + // registerWebdavServlet(alias, repository, false); registerRemotingServlet(alias, repository, true); registerRemotingServlet(alias, repository, false); if (log.isDebugEnabled()) @@ -94,8 +95,8 @@ class DataHttp implements KernelConstants { void unregisterRepositoryServlets(String alias) { try { - httpService.unregister(webdavPath(alias, true)); - httpService.unregister(webdavPath(alias, false)); + httpService.unregister(webdavPath(alias)); + // httpService.unregister(webdavPath(alias, false)); httpService.unregister(remotingPath(alias, true)); httpService.unregister(remotingPath(alias, false)); if (log.isDebugEnabled()) @@ -105,14 +106,13 @@ class DataHttp implements KernelConstants { } } - void registerWebdavServlet(String alias, Repository repository, boolean anonymous) - throws NamespaceException, ServletException { + void registerWebdavServlet(String alias, Repository repository) throws NamespaceException, ServletException { WebdavServlet webdavServlet = new WebdavServlet(repository, sessionProvider); - String path = webdavPath(alias, anonymous); + String path = webdavPath(alias); Properties ip = new Properties(); ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_CONFIG, WEBDAV_CONFIG); ip.setProperty(WebdavServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, path); - httpService.registerServlet(path, webdavServlet, ip, new DataHttpContext(anonymous)); + httpService.registerServlet(path, webdavServlet, ip, new DataHttpContext()); } void registerRemotingServlet(String alias, Repository repository, boolean anonymous) @@ -126,16 +126,17 @@ class DataHttp implements KernelConstants { ip.setProperty(RemotingServlet.INIT_PARAM_HOME, KernelUtils.getOsgiInstanceDir() + "/tmp/jackrabbit"); ip.setProperty(RemotingServlet.INIT_PARAM_TMP_DIRECTORY, "remoting"); ip.setProperty(RemotingServlet.INIT_PARAM_PROTECTED_HANDLERS_CONFIG, DEFAULT_PROTECTED_HANDLERS); - httpService.registerServlet(path, remotingServlet, ip, new DataHttpContext(anonymous)); + httpService.registerServlet(path, remotingServlet, ip, new RemotingHttpContext(anonymous)); } - private String webdavPath(String alias, boolean anonymous) { - String pathPrefix = anonymous ? WEBDAV_PUBLIC : WEBDAV_PRIVATE; - return pathPrefix + "/" + alias; + private String webdavPath(String alias) { + return NodeConstants.PATH_DATA + "/" + alias; + // String pathPrefix = anonymous ? WEBDAV_PUBLIC : WEBDAV_PRIVATE; + // return pathPrefix + "/" + alias; } private String remotingPath(String alias, boolean anonymous) { - String pathPrefix = anonymous ? REMOTING_PUBLIC : REMOTING_PRIVATE; + String pathPrefix = anonymous ? NodeConstants.PATH_JCR_PUB : NodeConstants.PATH_JCR; return pathPrefix + "/" + alias; } @@ -181,9 +182,87 @@ class DataHttp implements KernelConstants { } private class DataHttpContext implements HttpContext { + // private final boolean anonymous; + + DataHttpContext() { + // this.anonymous = anonymous; + } + + @Override + public boolean handleSecurity(final HttpServletRequest request, HttpServletResponse response) + throws IOException { + + // optimization + HttpSession httpSession = request.getSession(); + Object remoteUser = httpSession.getAttribute(REMOTE_USER); + Object authorization = httpSession.getAttribute(AUTHORIZATION); + if (remoteUser != null && authorization != null) { + request.setAttribute(REMOTE_USER, remoteUser); + request.setAttribute(AUTHORIZATION, authorization); + return true; + } + + // if (anonymous) { + // Subject subject = KernelUtils.anonymousLogin(); + // Authorization authorization = + // subject.getPrivateCredentials(Authorization.class).iterator().next(); + // request.setAttribute(REMOTE_USER, NodeConstants.ROLE_ANONYMOUS); + // request.setAttribute(AUTHORIZATION, authorization); + // return true; + // } + + // if (log.isTraceEnabled()) + // KernelUtils.logRequestHeaders(log, request); + try { + new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, new HttpRequestCallbackHandler(request)).login(); + return true; + } catch (CredentialNotFoundException e) { + Subject subject = KernelUtils.anonymousLogin(); + authorization = subject.getPrivateCredentials(Authorization.class).iterator().next(); + request.setAttribute(REMOTE_USER, NodeConstants.ROLE_ANONYMOUS); + request.setAttribute(AUTHORIZATION, authorization); + httpSession.setAttribute(REMOTE_USER, NodeConstants.ROLE_ANONYMOUS); + httpSession.setAttribute(AUTHORIZATION, authorization); + return true; + // CallbackHandler token = basicAuth(request); + // if (token != null) { + // try { + // LoginContext lc = new + // LoginContext(NodeConstants.LOGIN_CONTEXT_USER, token); + // lc.login(); + // // Note: this is impossible to reliably clear the + // // authorization header when access from a browser. + // return true; + // } catch (LoginException e1) { + // throw new CmsException("Could not login", e1); + // } + // } else { + // String path = request.getServletPath(); + // if (path.startsWith(REMOTING_PRIVATE)) + // requestBasicAuth(request, response); + // return false; + // } + } catch (LoginException e) { + throw new CmsException("Could not login", e); + } + } + + @Override + public URL getResource(String name) { + return KernelUtils.getBundleContext(DataHttp.class).getBundle().getResource(name); + } + + @Override + public String getMimeType(String name) { + return null; + } + + } + + private class RemotingHttpContext implements HttpContext { private final boolean anonymous; - DataHttpContext(boolean anonymous) { + RemotingHttpContext(boolean anonymous) { this.anonymous = anonymous; } @@ -217,9 +296,7 @@ class DataHttp implements KernelConstants { throw new CmsException("Could not login", e1); } } else { - String path = request.getServletPath(); - if (path.startsWith(REMOTING_PRIVATE)) - requestBasicAuth(request, response); + requestBasicAuth(request, response); return false; } } catch (LoginException e) { diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java index b0dd2c6b2..5fc138d4d 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java @@ -16,18 +16,18 @@ public interface KernelConstants { String DEPLOY_CONFIG_PATH = KernelConstants.DIR_NODE + '/' + NodeConstants.DEPLOY_BASEDN + ".ldif"; // Security - String DEFAULT_SECURITY_KEY = "argeo"; +// String DEFAULT_SECURITY_KEY = "argeo"; String JAAS_CONFIG = "/org/argeo/cms/internal/kernel/jaas.cfg"; - String LOGIN_CONTEXT_KERNEL = "KERNEL"; - String LOGIN_CONTEXT_HARDENED_KERNEL = "HARDENED_KERNEL"; +// String LOGIN_CONTEXT_KERNEL = "KERNEL"; +// String LOGIN_CONTEXT_HARDENED_KERNEL = "HARDENED_KERNEL"; // DAV String WEBDAV_CONFIG = "/org/argeo/cms/internal/kernel/webdav-config.xml"; - String PATH_DATA = "/data"; - String WEBDAV_PUBLIC = PATH_DATA + "/public"; - String WEBDAV_PRIVATE = PATH_DATA + "/files"; - String REMOTING_PUBLIC = PATH_DATA + "/pub"; - String REMOTING_PRIVATE = PATH_DATA + "/jcr"; + // String PATH_DATA = "/data"; + // String WEBDAV_PUBLIC = PATH_DATA + "/public"; + // String WEBDAV_PRIVATE = PATH_DATA + "/files"; + // String REMOTING_PUBLIC = PATH_DATA + "/pub"; + // String REMOTING_PRIVATE = PATH_DATA + "/jcr"; // RWT / RAP String PATH_WORKBENCH = "/ui"; diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java index 909b1faff..e0eb371b1 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java @@ -2,10 +2,8 @@ package org.argeo.cms.internal.kernel; import java.io.File; import java.io.IOException; -import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.security.PrivilegedAction; @@ -15,7 +13,6 @@ import java.util.Hashtable; import java.util.Properties; import java.util.TreeSet; -import javax.jcr.Node; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; @@ -210,67 +207,7 @@ class KernelUtils implements KernelConstants { } } - // DATA - public static StringBuilder getServerBaseUrl(HttpServletRequest request) { - try { - URL url = new URL(request.getRequestURL().toString()); - StringBuilder buf = new StringBuilder(); - buf.append(url.getProtocol()).append("://").append(url.getHost()); - if (url.getPort() != -1) - buf.append(':').append(url.getPort()); - return buf; - } catch (MalformedURLException e) { - throw new CmsException("Cannot extract server base URL from " + request.getRequestURL(), e); - } - } - - public static String getDataUrl(Node node, HttpServletRequest request) throws RepositoryException { - try { - StringBuilder buf = getServerBaseUrl(request); - buf.append(getDataPath(node)); - return new URL(buf.toString()).toString(); - } catch (MalformedURLException e) { - throw new CmsException("Cannot build data URL for " + node, e); - } - } - - public static String getDataPath(Node node) throws RepositoryException { - assert node != null; - String userId = node.getSession().getUserID(); -// if (log.isTraceEnabled()) -// log.trace(userId + " : " + node.getPath()); - StringBuilder buf = new StringBuilder(); - boolean isAnonymous = userId.equalsIgnoreCase(NodeConstants.ROLE_ANONYMOUS); - if (isAnonymous) - buf.append(WEBDAV_PUBLIC); - else - buf.append(WEBDAV_PRIVATE); - Session session = node.getSession(); - Repository repository = session.getRepository(); - String cn; - if (repository.isSingleValueDescriptor(NodeConstants.CN)) { - cn = repository.getDescriptor(NodeConstants.CN); - } else { -// log.warn("No cn defined in repository, using " + NodeConstants.NODE); - cn = NodeConstants.NODE; - } - return buf.append('/').append(cn).append('/').append(session.getWorkspace().getName()).append(node.getPath()) - .toString(); - } - - public static String getCanonicalUrl(Node node, HttpServletRequest request) throws RepositoryException { - try { - StringBuilder buf = getServerBaseUrl(request); - buf.append('/').append('!').append(node.getPath()); - return new URL(buf.toString()).toString(); - } catch (MalformedURLException e) { - throw new CmsException("Cannot build data URL for " + node, e); - } - // return request.getRequestURL().append('!').append(node.getPath()) - // .toString(); - } - private KernelUtils() { } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeHttp.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeHttp.java index abaadb0b1..f17e15797 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeHttp.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeHttp.java @@ -7,6 +7,8 @@ import static org.argeo.cms.CmsTypes.CMS_IMAGE; import java.io.IOException; import java.io.PrintWriter; +import java.net.MalformedURLException; +import java.net.URL; import java.security.PrivilegedExceptionAction; import java.security.cert.X509Certificate; import java.util.Calendar; @@ -31,6 +33,7 @@ import org.apache.commons.logging.LogFactory; import org.argeo.cms.CmsException; import org.argeo.jcr.JcrUtils; import org.argeo.node.NodeConstants; +import org.argeo.node.NodeUtils; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.service.http.HttpService; @@ -115,8 +118,8 @@ class NodeHttp implements KernelConstants { @Override public Session run() throws Exception { - Collection> srs = bc.getServiceReferences(Repository.class, "(" - + NodeConstants.CN + "=" + NodeConstants.NODE + ")"); + Collection> srs = bc.getServiceReferences(Repository.class, + "(" + NodeConstants.CN + "=" + NodeConstants.NODE + ")"); Repository repository = bc.getService(srs.iterator().next()); return repository.login(); } @@ -127,13 +130,13 @@ class NodeHttp implements KernelConstants { String desc = node.hasProperty(JCR_DESCRIPTION) ? node.getProperty(JCR_DESCRIPTION).getString() : null; Calendar lastUpdate = node.hasProperty(JCR_LAST_MODIFIED) ? node.getProperty(JCR_LAST_MODIFIED).getDate() : null; - String url = KernelUtils.getCanonicalUrl(node, request); + String url = getCanonicalUrl(node, request); String imgUrl = null; loop: for (NodeIterator it = node.getNodes(); it.hasNext();) { // Takes the first found cms:image Node child = it.nextNode(); if (child.isNodeType(CMS_IMAGE)) { - imgUrl = KernelUtils.getDataUrl(child, request); + imgUrl = getDataUrl(child, request); break loop; } } @@ -207,6 +210,71 @@ class NodeHttp implements KernelConstants { } buf.append(""); } + + // DATA + private StringBuilder getServerBaseUrl(HttpServletRequest request) { + try { + URL url = new URL(request.getRequestURL().toString()); + StringBuilder buf = new StringBuilder(); + buf.append(url.getProtocol()).append("://").append(url.getHost()); + if (url.getPort() != -1) + buf.append(':').append(url.getPort()); + return buf; + } catch (MalformedURLException e) { + throw new CmsException("Cannot extract server base URL from " + request.getRequestURL(), e); + } + } + + private String getDataUrl(Node node, HttpServletRequest request) throws RepositoryException { + try { + StringBuilder buf = getServerBaseUrl(request); + buf.append(NodeUtils.getDataPath(NodeConstants.NODE, node)); + return new URL(buf.toString()).toString(); + } catch (MalformedURLException e) { + throw new CmsException("Cannot build data URL for " + node, e); + } + } + + // public static String getDataPath(Node node) throws + // RepositoryException { + // assert node != null; + // String userId = node.getSession().getUserID(); + //// if (log.isTraceEnabled()) + //// log.trace(userId + " : " + node.getPath()); + // StringBuilder buf = new StringBuilder(); + // boolean isAnonymous = + // userId.equalsIgnoreCase(NodeConstants.ROLE_ANONYMOUS); + // if (isAnonymous) + // buf.append(WEBDAV_PUBLIC); + // else + // buf.append(WEBDAV_PRIVATE); + // Session session = node.getSession(); + // Repository repository = session.getRepository(); + // String cn; + // if (repository.isSingleValueDescriptor(NodeConstants.CN)) { + // cn = repository.getDescriptor(NodeConstants.CN); + // } else { + //// log.warn("No cn defined in repository, using " + + // NodeConstants.NODE); + // cn = NodeConstants.NODE; + // } + // return + // buf.append('/').append(cn).append('/').append(session.getWorkspace().getName()).append(node.getPath()) + // .toString(); + // } + + private String getCanonicalUrl(Node node, HttpServletRequest request) throws RepositoryException { + try { + StringBuilder buf = getServerBaseUrl(request); + buf.append('/').append('!').append(node.getPath()); + return new URL(buf.toString()).toString(); + } catch (MalformedURLException e) { + throw new CmsException("Cannot build data URL for " + node, e); + } + // return request.getRequestURL().append('!').append(node.getPath()) + // .toString(); + } + } class RobotServlet extends HttpServlet { @@ -247,7 +315,7 @@ class NodeHttp implements KernelConstants { } // skip data - if (servletPath.startsWith(PATH_DATA)) { + if (servletPath.startsWith(NodeConstants.PATH_DATA)) { filterChain.doFilter(request, response); return; } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java index d887e92f8..6d216c651 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeSecurity.java @@ -3,25 +3,15 @@ package org.argeo.cms.internal.kernel; import static org.argeo.cms.internal.kernel.KernelUtils.getOsgiInstanceDir; import java.io.File; -import java.io.IOException; import java.net.URL; import java.security.KeyStore; import java.util.Arrays; 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.security.auth.x500.X500Principal; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.cms.CmsException; -import org.argeo.cms.auth.AuthConstants; /** Low-level kernel security */ @Deprecated @@ -34,7 +24,7 @@ class NodeSecurity implements KernelConstants { private final boolean firstInit; - private final Subject kernelSubject; + private Subject kernelSubject; private int securityLevel = STAGING; private final File keyStoreFile; @@ -52,60 +42,60 @@ class NodeSecurity implements KernelConstants { this.keyStoreFile = new File(KernelUtils.getOsgiInstanceDir(), "node.p12"); createKeyStoreIfNeeded(); - if (keyStoreFile.exists()) - this.kernelSubject = logInHardenedKernel(); - else - this.kernelSubject = logInKernel(); +// if (keyStoreFile.exists()) +// this.kernelSubject = logInHardenedKernel(); +// else +// this.kernelSubject = logInKernel(); } - private Subject logInKernel() { - final Subject kernelSubject = new Subject(); - try { - LoginContext kernelLc = new LoginContext(KernelConstants.LOGIN_CONTEXT_KERNEL, kernelSubject); - kernelLc.login(); - } catch (LoginException e) { - throw new CmsException("Cannot log in kernel", e); - } - return kernelSubject; - } - - private Subject logInHardenedKernel() { - final Subject kernelSubject = new Subject(); - createKeyStoreIfNeeded(); - - CallbackHandler cbHandler = new CallbackHandler() { - - @Override - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { - // alias -// ((NameCallback) callbacks[1]).setName(AuthConstants.ROLE_KERNEL); - // store pwd - ((PasswordCallback) callbacks[2]).setPassword("changeit".toCharArray()); - // key pwd - ((PasswordCallback) callbacks[3]).setPassword("changeit".toCharArray()); - } - }; - try { - LoginContext kernelLc = new LoginContext(KernelConstants.LOGIN_CONTEXT_HARDENED_KERNEL, kernelSubject, - cbHandler); - kernelLc.login(); - } catch (LoginException e) { - throw new CmsException("Cannot log in kernel", e); - } - return kernelSubject; - } - - void destroy() { - // Logout kernel - try { - LoginContext kernelLc = new LoginContext(KernelConstants.LOGIN_CONTEXT_KERNEL, kernelSubject); - kernelLc.logout(); - } catch (LoginException e) { - throw new CmsException("Cannot log out kernel", e); - } - - // Security.removeProvider(SECURITY_PROVIDER); - } +// private Subject logInKernel() { +// final Subject kernelSubject = new Subject(); +// try { +// LoginContext kernelLc = new LoginContext(KernelConstants.LOGIN_CONTEXT_KERNEL, kernelSubject); +// kernelLc.login(); +// } catch (LoginException e) { +// throw new CmsException("Cannot log in kernel", e); +// } +// return kernelSubject; +// } +// +// private Subject logInHardenedKernel() { +// final Subject kernelSubject = new Subject(); +// createKeyStoreIfNeeded(); +// +// CallbackHandler cbHandler = new CallbackHandler() { +// +// @Override +// public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { +// // alias +//// ((NameCallback) callbacks[1]).setName(AuthConstants.ROLE_KERNEL); +// // store pwd +// ((PasswordCallback) callbacks[2]).setPassword("changeit".toCharArray()); +// // key pwd +// ((PasswordCallback) callbacks[3]).setPassword("changeit".toCharArray()); +// } +// }; +// try { +// LoginContext kernelLc = new LoginContext(KernelConstants.LOGIN_CONTEXT_HARDENED_KERNEL, kernelSubject, +// cbHandler); +// kernelLc.login(); +// } catch (LoginException e) { +// throw new CmsException("Cannot log in kernel", e); +// } +// return kernelSubject; +// } + +// void destroy() { +// // Logout kernel +// try { +// LoginContext kernelLc = new LoginContext(KernelConstants.LOGIN_CONTEXT_KERNEL, kernelSubject); +// kernelLc.logout(); +// } catch (LoginException e) { +// throw new CmsException("Cannot log out kernel", e); +// } +// +// // Security.removeProvider(SECURITY_PROVIDER); +// } public Subject getKernelSubject() { return kernelSubject; diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/WebCmsSessionImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/WebCmsSessionImpl.java index b30b00323..cff723e13 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/WebCmsSessionImpl.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/WebCmsSessionImpl.java @@ -86,6 +86,7 @@ public class WebCmsSessionImpl implements WebCmsSession { public void cleanUp() { try { + httpSession.setAttribute(HttpContext.REMOTE_USER, null); httpSession.setAttribute(HttpContext.AUTHORIZATION, null); // httpSession.setMaxInactiveInterval(1); } catch (Exception e) { diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg b/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg index 269c9112b..4c7ebb328 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg @@ -17,14 +17,10 @@ SYSTEM { org.argeo.cms.auth.DataAdminLoginModule requisite; }; -KERNEL { - org.argeo.cms.internal.auth.KernelLoginModule requisite; -}; HARDENED_KERNEL { com.sun.security.auth.module.UnixLoginModule requisite; com.sun.security.auth.module.KeyStoreLoginModule requisite keyStoreURL="${osgi.instance.area}/node.p12" keyStoreType=PKCS12; - org.argeo.cms.internal.auth.KernelLoginModule requisite; }; KEYRING { diff --git a/org.argeo.node.api/src/org/argeo/node/NodeConstants.java b/org.argeo.node.api/src/org/argeo/node/NodeConstants.java index 889296112..2bba10cdc 100644 --- a/org.argeo.node.api/src/org/argeo/node/NodeConstants.java +++ b/org.argeo.node.api/src/org/argeo/node/NodeConstants.java @@ -69,6 +69,13 @@ public interface NodeConstants { String LOGIN_CONTEXT_ANONYMOUS = "ANONYMOUS"; String LOGIN_CONTEXT_DATA_ADMIN = "DATA_ADMIN"; String LOGIN_CONTEXT_SINGLE_USER = "SINGLE_USER"; + + /* + * PATHS + */ + String PATH_DATA = "/data"; + String PATH_JCR = "/jcr"; + String PATH_JCR_PUB = "/pub"; /* * FRAMEWORK PROPERTIES diff --git a/org.argeo.node.api/src/org/argeo/node/NodeUtils.java b/org.argeo.node.api/src/org/argeo/node/NodeUtils.java index b9281043d..7dd2ceb69 100644 --- a/org.argeo.node.api/src/org/argeo/node/NodeUtils.java +++ b/org.argeo.node.api/src/org/argeo/node/NodeUtils.java @@ -159,6 +159,13 @@ public class NodeUtils { return getUserHome(session, userID); } + public static String getDataPath(String cn, Node node) throws RepositoryException { + assert node != null; + StringBuilder buf = new StringBuilder(NodeConstants.PATH_DATA); + return buf.append('/').append(cn).append('/').append(node.getSession().getWorkspace().getName()) + .append(node.getPath()).toString(); + } + // public static Node getUserProfile(Session session, String username) { // try { // QueryObjectModelFactory qomf = session.getWorkspace()