diff --git a/source/java/org/alfresco/web/app/servlet/BaseServlet.java b/source/java/org/alfresco/web/app/servlet/BaseServlet.java index 518e2cbde3..541e4c4a15 100644 --- a/source/java/org/alfresco/web/app/servlet/BaseServlet.java +++ b/source/java/org/alfresco/web/app/servlet/BaseServlet.java @@ -19,6 +19,7 @@ package org.alfresco.web.app.servlet; import java.io.IOException; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -47,6 +48,7 @@ import org.alfresco.service.namespace.NamespaceService; import org.springframework.extensions.surf.util.URLDecoder; import org.alfresco.web.app.Application; import org.alfresco.web.bean.LoginBean; +import org.alfresco.web.bean.LoginOutcomeBean; import org.alfresco.web.bean.repository.Repository; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -163,32 +165,40 @@ public abstract class BaseServlet extends HttpServlet * once the user has successfully completed the authentication process. */ public static void redirectToLoginPage(HttpServletRequest req, HttpServletResponse res, ServletContext sc) - throws IOException + throws IOException { // authentication failed - so end servlet execution and redirect to login page - res.sendRedirect(req.getContextPath() + FACES_SERVLET + Application.getLoginPage(sc)); - - // save the full requested URL so the login page knows where to redirect too later + StringBuilder redirectURL = new StringBuilder(1024).append(req.getContextPath()).append(FACES_SERVLET).append( + Application.getLoginPage(sc)); + + // Pass the full requested URL as a parameter so the login page knows where to redirect to later String uri = req.getRequestURI(); - String url = uri; - if (req.getQueryString() != null && req.getQueryString().length() != 0) + + // if we find a JSF servlet reference in the URI then we need to check if the rest of the + // JSP specified is valid for a redirect operation after Login has occured. + int jspIndex; + if (uri.indexOf(req.getContextPath() + FACES_SERVLET) == -1 + || uri.length() > (jspIndex = uri.indexOf(BaseServlet.FACES_SERVLET) + BaseServlet.FACES_SERVLET.length()) + && BaseServlet.validRedirectJSP(uri.substring(jspIndex))) { - url += "?" + req.getQueryString(); - } - if (uri.indexOf(req.getContextPath() + FACES_SERVLET) != -1) - { - // if we find a JSF servlet reference in the URI then we need to check if the rest of the - // JSP specified is valid for a redirect operation after Login has occured. - int jspIndex = uri.indexOf(BaseServlet.FACES_SERVLET) + BaseServlet.FACES_SERVLET.length(); - if (uri.length() > jspIndex && BaseServlet.validRedirectJSP(uri.substring(jspIndex))) + if (redirectURL.indexOf("?") == -1) { - req.getSession().setAttribute(LoginBean.LOGIN_REDIRECT_KEY, url); + redirectURL.append('?'); } + else + { + redirectURL.append('&'); + } + redirectURL.append(LoginOutcomeBean.PARAM_REDIRECT_URL); + redirectURL.append('='); + String url = uri; + if (req.getQueryString() != null && req.getQueryString().length() != 0) + { + url += "?" + req.getQueryString(); + } + redirectURL.append(URLEncoder.encode(url, "UTF-8")); } - else - { - req.getSession().setAttribute(LoginBean.LOGIN_REDIRECT_KEY, url); - } + res.sendRedirect(redirectURL.toString()); } /** diff --git a/source/java/org/alfresco/web/bean/LoginBean.java b/source/java/org/alfresco/web/bean/LoginBean.java index fbc231f4cb..41bee76088 100644 --- a/source/java/org/alfresco/web/bean/LoginBean.java +++ b/source/java/org/alfresco/web/bean/LoginBean.java @@ -323,17 +323,18 @@ public class LoginBean implements Serializable // the app to continue without redirecting to the login page Application.setCurrentUser(fc, user); + // Programatically retrieve the LoginOutcomeBean from JSF + LoginOutcomeBean loginOutcomeBean = (LoginOutcomeBean) fc.getApplication().createValueBinding( + "#{LoginOutcomeBean}").getValue(fc); + // if a redirect URL has been provided then use that // this allows servlets etc. to provide a URL to return too after a successful login - String redirectURL = (String)session.get(LOGIN_REDIRECT_KEY); - if (redirectURL != null) + String redirectURL = loginOutcomeBean.getRedirectURL(); + if (redirectURL != null && redirectURL.length() > 0) { if (logger.isDebugEnabled()) logger.debug("Redirect URL found: " + redirectURL); - - // remove redirect URL from session - session.remove(LOGIN_REDIRECT_KEY); - + try { fc.getExternalContext().redirect(redirectURL); @@ -472,7 +473,6 @@ public class LoginBean implements Serializable public static final String MSG_PASSWORD_LENGTH = "login_err_password_length"; public static final String MSG_USER_ERR = "user_err_user_name"; - public static final String LOGIN_REDIRECT_KEY = "_alfRedirect"; public static final String LOGIN_EXTERNAL_AUTH = "_alfExternalAuth"; public static final String LOGIN_NOPERMISSIONS = "_alfNoPermissions"; diff --git a/source/java/org/alfresco/web/bean/LoginOutcomeBean.java b/source/java/org/alfresco/web/bean/LoginOutcomeBean.java new file mode 100644 index 0000000000..9d0c17bf62 --- /dev/null +++ b/source/java/org/alfresco/web/bean/LoginOutcomeBean.java @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2005-2010 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have received a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" + */ +package org.alfresco.web.bean; + +import java.io.Serializable; + +/** + * A request-scoped bean that is used to propagate the URL to redirect to after successful login. This is now done with + * request parameters rather than session-scoped beans so that tools such as MS Office, which do not propagate cookies + * to hyperlinks, can be used to open hyperlinks to protected documents (ALF-206). + * + * @author dward + */ +public class LoginOutcomeBean implements Serializable +{ + /** The name of the request parameter that provides the initial value of the {@link #redirectURL} property. */ + public static final String PARAM_REDIRECT_URL = "_alfRedirect"; + + private static final long serialVersionUID = -2575348340143674698L; + + /** The URL to redirect to after successful login. */ + private String redirectURL; + + /** + * Gets the URL to redirect to after successful login. + * + * @return the URL to redirect to after successful login + */ + public String getRedirectURL() + { + return redirectURL; + } + + /** + * Sets the URL to redirect to after successful login. + * + * @param redirectURL + * the URL to redirect to after successful login + */ + public void setRedirectURL(String redirectURL) + { + this.redirectURL = redirectURL; + } + +} diff --git a/source/java/org/alfresco/web/bean/users/EmailSpaceUsersDialog.java b/source/java/org/alfresco/web/bean/users/EmailSpaceUsersDialog.java index 060f3e8c11..07916258e3 100644 --- a/source/java/org/alfresco/web/bean/users/EmailSpaceUsersDialog.java +++ b/source/java/org/alfresco/web/bean/users/EmailSpaceUsersDialog.java @@ -33,6 +33,8 @@ import javax.faces.event.ActionEvent; import javax.transaction.UserTransaction; import org.alfresco.model.ContentModel; +import org.alfresco.repo.security.authentication.AuthenticationUtil; +import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork; import org.alfresco.service.cmr.repository.InvalidNodeRefException; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.security.AccessPermission; @@ -313,46 +315,53 @@ public class EmailSpaceUsersDialog extends BaseDialogBean implements IContextLis // Return all the permissions set against the current node for any authentication // instance (user/group), walking the parent space inheritance chain. // Then combine them into a single list for each authentication found. - String currentAuthority = Application.getCurrentUser(context).getUserName(); - Map> permissionMap = new HashMap>(8, 1.0f); - NodeRef spaceRef = getSpace().getNodeRef(); - while (spaceRef != null) + final String currentAuthority = Application.getCurrentUser(context).getUserName(); + Map> permissionMap = AuthenticationUtil.runAs(new RunAsWork>>() { - Set permissions = getPermissionService().getAllSetPermissions(spaceRef); - for (AccessPermission permission : permissions) + public Map> doWork() throws Exception { - // we are only interested in Allow and not Guest/Everyone/owner - if (permission.getAccessStatus() == AccessStatus.ALLOWED && - (permission.getAuthorityType() == AuthorityType.USER || - permission.getAuthorityType() == AuthorityType.GROUP)) + NodeRef spaceRef = getSpace().getNodeRef(); + Map> permissionMap = new HashMap>(8, 1.0f); + while (spaceRef != null) { - String authority = permission.getAuthority(); - - if (currentAuthority.equals(authority) == false) + Set permissions = getPermissionService().getAllSetPermissions(spaceRef); + for (AccessPermission permission : permissions) { - List userPermissions = permissionMap.get(authority); - if (userPermissions == null) + // we are only interested in Allow and not Guest/Everyone/owner + if (permission.getAccessStatus() == AccessStatus.ALLOWED && + (permission.getAuthorityType() == AuthorityType.USER || + permission.getAuthorityType() == AuthorityType.GROUP)) { - // create for first time - userPermissions = new ArrayList(4); - permissionMap.put(authority, userPermissions); + String authority = permission.getAuthority(); + + if (currentAuthority.equals(authority) == false) + { + List userPermissions = permissionMap.get(authority); + if (userPermissions == null) + { + // create for first time + userPermissions = new ArrayList(4); + permissionMap.put(authority, userPermissions); + } + // add the permission name for this authority + userPermissions.add(permission.getPermission()); + } } - // add the permission name for this authority - userPermissions.add(permission.getPermission()); + } + + // walk parent inheritance chain until root or no longer inherits + if (getPermissionService().getInheritParentPermissions(spaceRef)) + { + spaceRef = getNodeService().getPrimaryParent(spaceRef).getParentRef(); + } + else + { + spaceRef = null; } } - } - - // walk parent inheritance chain until root or no longer inherits - if (getPermissionService().getInheritParentPermissions(spaceRef)) - { - spaceRef = getNodeService().getPrimaryParent(spaceRef).getParentRef(); - } - else - { - spaceRef = null; - } - } + return permissionMap; + } + }, AuthenticationUtil.SYSTEM_USER_NAME); // create the structure as a linked list for fast insert/removal of items this.usersGroups = new LinkedList(); diff --git a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java index 290dfd66ee..f2d35e2b15 100644 --- a/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java +++ b/source/java/org/alfresco/web/bean/wcm/CreateWebContentWizard.java @@ -366,6 +366,23 @@ public class CreateWebContentWizard extends CreateContentWizard } } + // remove any locks created as a result of uploading files + final NodeRef[] uploadedFiles = this.filePickerBean.getUploadedFiles(); + if (uploadedFiles != null && uploadedFiles.length > 0) + { + for (NodeRef uploadedFile : uploadedFiles) + { + String path = AVMNodeConverter.ToAVMVersionPath(uploadedFile).getSecond(); + String storeId = AVMUtil.getStoreId(path); + String storePath = AVMUtil.getStoreRelativePath(path); + + if (logger.isDebugEnabled()) + logger.debug("Removing lock for uploaded file: " + path); + + this.getAvmLockingService().removeLock(storeId, storePath); + } + } + return super.cancel(); } diff --git a/source/java/org/alfresco/web/bean/wcm/FilePickerBean.java b/source/java/org/alfresco/web/bean/wcm/FilePickerBean.java index 33120f87a8..8325092353 100644 --- a/source/java/org/alfresco/web/bean/wcm/FilePickerBean.java +++ b/source/java/org/alfresco/web/bean/wcm/FilePickerBean.java @@ -112,10 +112,6 @@ public class FilePickerBean implements Serializable // cached reference to the public saved searches folder private NodeRef publicSearchesRef = null; - // initial current folder - the current folder path which the - // the file picker opens at when first selected in the form - private String initialCurrentPath = null; - public FilePickerBean() { } @@ -383,32 +379,20 @@ public class FilePickerBean implements Serializable AVMUtil.PathRelation.WEBAPP_RELATIVE); } - // if initial current path not set then set it to the current path - if (initialCurrentPath == null) - { - initialCurrentPath = currentPath; - - // insert '/' at end of initial current path if there isn't one - if (initialCurrentPath.charAt(initialCurrentPath.length() - 1) != '/') - { - initialCurrentPath = initialCurrentPath + "/"; - } - } - // if folder path restriction (relative path) is set, - // then calculate the absolute restriction path (in context of file - // picker's - // initial current path - the path at which it was opened the first time) - // and set file picker current path to that + // then calculate the absolute restriction path from the root + // of the webapp and set the current path to that if ((folderPathRestriction != null) && (folderPathRestriction.length() != 0)) { - currentPath = initialCurrentPath + folderPathRestriction; + currentPath = AVMUtil.getWebappPath(currentPath) + "/" + folderPathRestriction; } if (LOGGER.isDebugEnabled()) { LOGGER.debug(this + ".getFilePickerData(path = " + currentPath + + ", folderRestriction = " + + folderPathRestriction + ", selectableTypes = [" + StringUtils.join(selectableTypes, ",") + "], filterMimetypes = [" diff --git a/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java b/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java index e46d6865fa..6f59071137 100644 --- a/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java +++ b/source/java/org/alfresco/web/ui/repo/component/UIContentSelector.java @@ -43,7 +43,6 @@ import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.ui.common.Utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.lucene.queryParser.QueryParser; /** * Component for selecting content from the repository @@ -54,7 +53,7 @@ public class UIContentSelector extends UIInput { private final static Log logger = LogFactory.getLog(UIContentSelector.class); - private final static String ACTION_SEPARATOR = ";"; +// private final static String ACTION_SEPARATOR = ";"; private final static String ACTION_SEARCH = "0"; private final static String FIELD_CONTAINS = "_contains"; @@ -123,8 +122,8 @@ public class UIContentSelector extends UIInput */ public void decode(FacesContext context) { - Map requestMap = context.getExternalContext().getRequestParameterMap(); - Map valuesMap = context.getExternalContext().getRequestParameterValuesMap(); + Map requestMap = context.getExternalContext().getRequestParameterMap(); + Map valuesMap = context.getExternalContext().getRequestParameterValuesMap(); String fieldId = getHiddenFieldName(); String value = (String)requestMap.get(fieldId); @@ -356,7 +355,7 @@ public class UIContentSelector extends UIInput NamespaceService.CONTENT_MODEL_1_0_URI, "name")); query.append(nameAttr); - query.append(":*" + safeContains + "*"); + query.append(":\"*" + safeContains + "\"*"); } int maxResults = Application.getClientConfig(context).getSelectorsSearchMaxResults(); diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index 1ee8661de1..396f888143 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -260,6 +260,19 @@ + + + A request scoped bean that backs up the Login screen + + LoginOutcomeBean + org.alfresco.web.bean.LoginOutcomeBean + request + + redirectURL + #{param._alfRedirect} + + + The bean that holds navigation state. diff --git a/source/web/jsp/login.jsp b/source/web/jsp/login.jsp index 8d6314b1fc..7927b31a16 100644 --- a/source/web/jsp/login.jsp +++ b/source/web/jsp/login.jsp @@ -87,6 +87,9 @@ + <%-- Propagate the redirect URL parameter --%> + +