From 2c8233db8452c2ade520b5efeb2c584ea4d961cd Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Fri, 3 Feb 2006 10:56:47 +0000 Subject: [PATCH] Fix for AWC-488 - when a permissions "access is denied" occurs for content/externalaccess/template URL then the login page is now shown git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2290 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- .../web/app/servlet/AuthenticationFilter.java | 9 ++-- .../web/app/servlet/AuthenticationHelper.java | 10 +---- .../app/servlet/DownloadContentServlet.java | 23 ++++++++--- .../app/servlet/ExternalAccessServlet.java | 38 +++++++++++++++-- .../web/app/servlet/ServletHelper.java | 41 +++++++++++++------ .../app/servlet/TemplateContentServlet.java | 21 +++++++--- .../web/app/servlet/UploadFileServlet.java | 6 ++- 7 files changed, 111 insertions(+), 37 deletions(-) diff --git a/source/java/org/alfresco/web/app/servlet/AuthenticationFilter.java b/source/java/org/alfresco/web/app/servlet/AuthenticationFilter.java index 577c4f3e53..cd2e3f4cad 100644 --- a/source/java/org/alfresco/web/app/servlet/AuthenticationFilter.java +++ b/source/java/org/alfresco/web/app/servlet/AuthenticationFilter.java @@ -59,13 +59,14 @@ public class AuthenticationFilter implements Filter public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { - HttpServletRequest httpReq = (HttpServletRequest)req; + HttpServletRequest httpReq = (HttpServletRequest)req; + HttpServletResponse httpRes = (HttpServletResponse)res; // allow the login page to proceed if (httpReq.getRequestURI().endsWith(getLoginPage()) == false) { AuthenticationStatus status = - AuthenticationHelper.authenticate(this.context, httpReq, (HttpServletResponse)res, false); + AuthenticationHelper.authenticate(this.context, httpReq, httpRes, false); if (status == AuthenticationStatus.Success || status == AuthenticationStatus.Guest) { @@ -74,7 +75,9 @@ public class AuthenticationFilter implements Filter } else { - // failed to authenticate - save redirect URL for after login process + // authentication failed - so end servlet execution and redirect to login page + // also save the requested URL so the login page knows where to redirect too later + httpRes.sendRedirect(httpReq.getContextPath() + ServletHelper.FACES_SERVLET + Application.getLoginPage(context)); httpReq.getSession().setAttribute(LoginBean.LOGIN_REDIRECT_KEY, httpReq.getRequestURI()); } } diff --git a/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java b/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java index e91e675d14..2ee6504a52 100644 --- a/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java +++ b/source/java/org/alfresco/web/app/servlet/AuthenticationHelper.java @@ -38,7 +38,6 @@ import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.security.AuthenticationService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PersonService; -import org.alfresco.service.transaction.TransactionService; import org.alfresco.web.app.Application; import org.alfresco.web.app.portlet.AlfrescoFacesPortlet; import org.alfresco.web.bean.LoginBean; @@ -63,8 +62,6 @@ import org.springframework.web.context.support.WebApplicationContextUtils; */ public final class AuthenticationHelper { - public static final String FACES_SERVLET = "/faces"; - /** session variables */ public static final String AUTHENTICATION_USER = "_alfAuthTicket"; public static final String SESSION_USERNAME = "_alfLastUser"; @@ -194,9 +191,7 @@ public final class AuthenticationHelper } } - // no user/ticket found or session invalidated by user (logout) - redirect to login page - httpResponse.sendRedirect(httpRequest.getContextPath() + FACES_SERVLET + Application.getLoginPage(context)); - + // session invalidated - return to login screen return AuthenticationStatus.Failure; } else @@ -207,8 +202,7 @@ public final class AuthenticationHelper } catch (AuthenticationException authErr) { - // expired ticket - redirect to login page - httpResponse.sendRedirect(httpRequest.getContextPath() + FACES_SERVLET + Application.getLoginPage(context)); + // expired ticket return AuthenticationStatus.Failure; } diff --git a/source/java/org/alfresco/web/app/servlet/DownloadContentServlet.java b/source/java/org/alfresco/web/app/servlet/DownloadContentServlet.java index 18c8cf16cc..6f1f26fb0d 100644 --- a/source/java/org/alfresco/web/app/servlet/DownloadContentServlet.java +++ b/source/java/org/alfresco/web/app/servlet/DownloadContentServlet.java @@ -25,7 +25,6 @@ import java.text.MessageFormat; import java.util.StringTokenizer; import javax.servlet.ServletException; -import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -39,6 +38,8 @@ import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.MimetypeService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; import org.alfresco.web.app.Application; import org.alfresco.web.ui.common.Utils; @@ -141,7 +142,9 @@ public class DownloadContentServlet extends HttpServlet propertyQName = QName.createQName(property); } + // build noderef from the appropriate URL elements NodeRef nodeRef = new NodeRef(storeRef, id); + if (logger.isDebugEnabled()) { logger.debug("Found NodeRef: " + nodeRef.toString()); @@ -150,6 +153,20 @@ public class DownloadContentServlet extends HttpServlet logger.debug("With attachment mode: " + attachment); } + // get the services we need to retrieve the content + ServiceRegistry serviceRegistry = ServletHelper.getServiceRegistry(getServletContext()); + ContentService contentService = serviceRegistry.getContentService(); + PermissionService permissionService = serviceRegistry.getPermissionService(); + + // check that the user has at least READ_CONTENT access - else redirect to the login page + if (permissionService.hasPermission(nodeRef, PermissionService.READ_CONTENT) == AccessStatus.DENIED) + { + if (logger.isDebugEnabled()) + logger.debug("User does not have permissions to read content for NodeRef: " + nodeRef.toString()); + ServletHelper.redirectToLoginPage(req, res, getServletContext()); + return; + } + if (attachment == true) { // set header based on filename - will force a Save As from the browse if it doesn't recognise it @@ -160,10 +177,6 @@ public class DownloadContentServlet extends HttpServlet try { - // get the services we need to retrieve the content - ServiceRegistry serviceRegistry = ServletHelper.getServiceRegistry(getServletContext()); - ContentService contentService = serviceRegistry.getContentService(); - // get the content reader ContentReader reader = contentService.getReader(nodeRef, propertyQName); // ensure that it is safe to use diff --git a/source/java/org/alfresco/web/app/servlet/ExternalAccessServlet.java b/source/java/org/alfresco/web/app/servlet/ExternalAccessServlet.java index 5f0424c03c..78de84b79e 100644 --- a/source/java/org/alfresco/web/app/servlet/ExternalAccessServlet.java +++ b/source/java/org/alfresco/web/app/servlet/ExternalAccessServlet.java @@ -28,8 +28,11 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.alfresco.repo.webdav.WebDAVServlet; +import org.alfresco.service.ServiceRegistry; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.StoreRef; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.web.bean.BrowseBean; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -106,6 +109,10 @@ public class ExternalAccessServlet extends HttpServlet FacesContext fc = FacesHelper.getFacesContext(req, res, getServletContext()); BrowseBean browseBean = (BrowseBean)ServletHelper.getManagedBean(fc, "BrowseBean"); + // get services we need + ServiceRegistry serviceRegistry = ServletHelper.getServiceRegistry(getServletContext()); + PermissionService permissionService = serviceRegistry.getPermissionService(); + // setup is required for certain outcome requests if (OUTCOME_DOCDETAILS.equals(outcome)) { @@ -123,8 +130,16 @@ public class ExternalAccessServlet extends HttpServlet if (nodeRef != null) { + // check that the user has at least READ access - else redirect to the login page + if (permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED) + { + if (logger.isDebugEnabled()) + logger.debug("User does not have permissions to READ NodeRef: " + nodeRef.toString()); + ServletHelper.redirectToLoginPage(req, res, getServletContext()); + return; + } + // setup the Document on the browse bean - // TODO: the browse bean should accept a full NodeRef - not just an ID browseBean.setupContentAction(nodeRef.getId(), true); } @@ -148,8 +163,16 @@ public class ExternalAccessServlet extends HttpServlet if (nodeRef != null) { + // check that the user has at least READ access - else redirect to the login page + if (permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED) + { + if (logger.isDebugEnabled()) + logger.debug("User does not have permissions to READ NodeRef: " + nodeRef.toString()); + ServletHelper.redirectToLoginPage(req, res, getServletContext()); + return; + } + // setup the Space on the browse bean - // TODO: the browse bean should accept a full NodeRef - not just an ID browseBean.setupSpaceAction(nodeRef.getId(), true); } @@ -169,6 +192,15 @@ public class ExternalAccessServlet extends HttpServlet StoreRef storeRef = new StoreRef(args[0+offset], args[1+offset]); nodeRef = new NodeRef(storeRef, args[2+offset]); + // check that the user has at least READ access - else redirect to the login page + if (permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED) + { + if (logger.isDebugEnabled()) + logger.debug("User does not have permissions to READ NodeRef: " + nodeRef.toString()); + ServletHelper.redirectToLoginPage(req, res, getServletContext()); + return; + } + // this call sets up the current node Id, and updates or initialises the // breadcrumb component with the selected node as appropriate. browseBean.updateUILocation(nodeRef); @@ -187,7 +219,7 @@ public class ExternalAccessServlet extends HttpServlet // perform the forward to the page processed by the Faces servlet String viewId = fc.getViewRoot().getViewId(); - getServletContext().getRequestDispatcher(AuthenticationHelper.FACES_SERVLET + viewId).forward(req, res); + getServletContext().getRequestDispatcher(ServletHelper.FACES_SERVLET + viewId).forward(req, res); } /** diff --git a/source/java/org/alfresco/web/app/servlet/ServletHelper.java b/source/java/org/alfresco/web/app/servlet/ServletHelper.java index ff54d68d41..21d35d3ae8 100644 --- a/source/java/org/alfresco/web/app/servlet/ServletHelper.java +++ b/source/java/org/alfresco/web/app/servlet/ServletHelper.java @@ -49,6 +49,8 @@ import org.springframework.web.jsf.FacesContextUtils; */ public final class ServletHelper { + public static final String FACES_SERVLET = "/faces"; + /** an existing Ticket can be passed to most servlet for non-session based authentication */ private static final String ARG_TICKET = "ticket"; @@ -58,6 +60,13 @@ public final class ServletHelper private static Log logger = LogFactory.getLog(ServletHelper.class); + /** + * Private constructor + */ + private ServletHelper() + { + } + /** * Return the ServiceRegistry helper instance * @@ -71,13 +80,6 @@ public final class ServletHelper return (ServiceRegistry)wc.getBean(ServiceRegistry.SERVICE_REGISTRY); } - /** - * Private constructor - */ - private ServletHelper() - { - } - /** * Perform an authentication for the servlet request URI. Processing any "ticket" or * "guest" URL arguments. @@ -109,14 +111,26 @@ public final class ServletHelper } if (status == AuthenticationStatus.Failure) { - // authentication failed - no point returning the content as we haven't logged in yet - // so end servlet execution and save the URL so the login page knows what to do later - req.getSession().setAttribute(LoginBean.LOGIN_REDIRECT_KEY, req.getRequestURI() + (req.getQueryString() != null ? ("?" + req.getQueryString()) : "")); + // authentication failed - now need to display the login page to the user + redirectToLoginPage(req, res, sc); } return status; } + /** + * Redirect to the Login page - saving the current URL which can be redirected back later + * once the user has successfully completed the authentication process. + */ + public static void redirectToLoginPage(HttpServletRequest req, HttpServletResponse res, ServletContext sc) + throws IOException + { + // authentication failed - so end servlet execution and redirect to login page + // also save the requested URL so the login page knows where to redirect too later + res.sendRedirect(req.getContextPath() + FACES_SERVLET + Application.getLoginPage(sc)); + req.getSession().setAttribute(LoginBean.LOGIN_REDIRECT_KEY, req.getRequestURI()); + } + /** * Return a JSF managed bean reference. * @@ -153,7 +167,7 @@ public final class ServletHelper } if (logger.isDebugEnabled()) - logger.debug("Attempting to resolve webdav path to NodeRef: " + paths); + logger.debug("Attempting to resolve webdav path: " + paths); // get the company home node to start the search from NodeRef companyHome = new NodeRef(Repository.getStoreRef(), @@ -163,6 +177,9 @@ public final class ServletHelper FileFolderService ffs = (FileFolderService)wc.getBean("FileFolderService"); file = ffs.resolveNamePath(companyHome, paths); nodeRef = file.getNodeRef(); + + if (logger.isDebugEnabled()) + logger.debug("Resolved webdav path to NodeRef: " + nodeRef); } catch (UnsupportedEncodingException uee) { @@ -174,7 +191,7 @@ public final class ServletHelper catch (FileNotFoundException fne) { if (logger.isWarnEnabled()) - logger.debug("Failed to resolve webdav path", fne); + logger.warn("Failed to resolve webdav path", fne); nodeRef = null; } diff --git a/source/java/org/alfresco/web/app/servlet/TemplateContentServlet.java b/source/java/org/alfresco/web/app/servlet/TemplateContentServlet.java index 024b576a9e..107a35e0ec 100644 --- a/source/java/org/alfresco/web/app/servlet/TemplateContentServlet.java +++ b/source/java/org/alfresco/web/app/servlet/TemplateContentServlet.java @@ -38,6 +38,8 @@ import org.alfresco.service.cmr.repository.StoreRef; import org.alfresco.service.cmr.repository.TemplateException; import org.alfresco.service.cmr.repository.TemplateNode; import org.alfresco.service.cmr.repository.TemplateService; +import org.alfresco.service.cmr.security.AccessStatus; +import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.web.app.Application; import org.alfresco.web.ui.repo.component.template.DefaultModelHelper; import org.apache.commons.logging.Log; @@ -120,6 +122,20 @@ public class TemplateContentServlet extends HttpServlet templateRef = new NodeRef(storeRef, t.nextToken()); } + // get the services we need to retrieve the content + ServiceRegistry serviceRegistry = ServletHelper.getServiceRegistry(getServletContext()); + NodeService nodeService = serviceRegistry.getNodeService(); + TemplateService templateService = serviceRegistry.getTemplateService(); + PermissionService permissionService = serviceRegistry.getPermissionService(); + + // check that the user has at least READ access on any nodes - else redirect to the login page + if (permissionService.hasPermission(nodeRef, PermissionService.READ) == AccessStatus.DENIED || + (templateRef != null && permissionService.hasPermission(templateRef, PermissionService.READ) == AccessStatus.DENIED)) + { + ServletHelper.redirectToLoginPage(req, res, getServletContext()); + return; + } + String mimetype = MIMETYPE_HTML; if (req.getParameter(ARG_MIMETYPE) != null) { @@ -129,11 +145,6 @@ public class TemplateContentServlet extends HttpServlet try { - // get the services we need to retrieve the content - ServiceRegistry serviceRegistry = ServletHelper.getServiceRegistry(getServletContext()); - NodeService nodeService = serviceRegistry.getNodeService(); - TemplateService templateService = serviceRegistry.getTemplateService(); - UserTransaction txn = null; try { diff --git a/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java b/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java index 7a1abccb7b..f0edf9ac94 100644 --- a/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java +++ b/source/java/org/alfresco/web/app/servlet/UploadFileServlet.java @@ -59,7 +59,11 @@ public class UploadFileServlet extends HttpServlet try { - AuthenticationHelper.authenticate(getServletContext(), request, response, false); + AuthenticationStatus status = ServletHelper.servletAuthenticate(request, response, getServletContext()); + if (status == AuthenticationStatus.Failure) + { + return; + } if (isMultipart == false) {