Merged V3.4-BUG-FIX to HEAD

29484: Merged V3.4 to V3.4-BUG-FIX
      29426: ALF-9588: Merged PATCHES/V3.4.2 to V3.4
         29402: ALF-9637: Enable Share Advanced Search on properties containing a '-' in the prefix
      29469: ALF-8341: Merged missing fragment from ALF-6598
      29476: ALF-3061 Need to disable major/minor version radio buttons after [Upload File(s)]
      29483: ALF-9407: Escape quote characters in parameterized strings
   29488: Build Fix and correct fix for ALF-9632 "CMIS query fails if model name contains numbers" fix
      - Ensure CMIS query types are ISO9075 encoded
      - the user has to type them in encoded if encoding is required - the encoded look up name was in fact incorrect - not the lookup
   29561: Merge DEV/BELARUS/V3.4-BUG-FIX-2011_07_13 V3.4-BUG-FIX
      29422: ALF-7195 Add DisableAuditingInterceptor to NodeService and LockService.
   29572: ALF-9601 - Simultaneous deployment of the same web project to two file system targets on the same engine can cause some missing files in one of the targets.
   29578: Merged DEV/TEMPORARY to V3.4-BUG-FIX
      29334: ALF-7390 : Alfresco ftp server never binds to a single ip address
         Added default configuration for bindTo property for FTP server.
   29587: Merged V3.4 to V3.4-BUG-FIX
      29495: Merged DEV/TEMPORARY to V3.4
         29494: ALF-7701: Untranslated strings when Quickr module is installed: Task details page
            Global workflow messages were removed
      29502: ALF-8929: Merged DEV/TEMPORARY to V3.4
         29499: Rename dictionaryModelBootstrap beans for QuickR model and example model.
      29504: ALF-5895: Profile CSS tweaks for other languages (Kev reviewed)
      29519: Merged DEV/TEMPORARY to V3.4 (Reviewed by Kev)
         29510: ALF-9419: Share - Filename changes in "Upload new version" (with italian language set)
            Upload WebScript was modified for support locale as a request parameter.
         29518: ALF-9419: Share - Filename changes in "Upload new version" (with italian language set)
            ScriptUtils used for locale change.
      29520: ALF-9717: Possible workaround to PolicyTest taking so long to run
      - Set sun.net.client.defaultConnectTimeout and sun.net.client.defaultReadTimeout System properties so that hanging request for a DTD times out quickly
   29596: Merged DEV/TEMPORARY to V3.4-BUG-FIX
      29595: ALF-5046: DeclarativeWebScriptRegistry causes blow-out when loading system without content
         1. In org.alfresco.repo.web.scripts.RepoStore class added isContentPresent(NodeRef nodeRef) method.
         2. In org.alfresco.repo.web.scripts.RepoStore#getScriptDocumentPaths added check isContentPresent(nodeRef).
         3. In org.alfresco.repo.web.scripts.RepoStore#getDocumentPaths added check isContentPresent(nodeRef).
         4. In org.alfresco.repo.web.scripts.RepoStore#getAllDocumentPaths added check isContentPresent(nodeRef).
   29634: ALF-371 Alfresco Explorer: A change of a user's home folder now creates a new folder if it does not exist.
      If a home folder is shared, other users no longer find their home folder moving.
      However the content of the home folder must be manually moved.
   29637: ALF-9847 High level audit does not include initial node properties or changed path if node moved
   29685: Merged PATCHES/V3.4.1 to V3.4-BUG-FIX
      29682: ALF-9777: Merged V3.4-BUG-FIX to PATCHES/V3.4.1
         28188: Fix for ALF-731 - in a cluster environment (high availibility), when a node goes down, the users are asked to login
      29684: ALF-9777: Correction
   29686: ALF-2372 Revert action does not restore changes to document metadata
       Now uses VersionService.revert(...)
   29697: ALF-9886: Missing space in apostrophe-laden Italian translation
   - The world is safe once more
   29698: Merged V3.4 to V3.4-BUG-FIX
      29672: Merged PATCHES/V3.4.1 to V3.4
         29441: ALF-9876 / ALF-9579: Share external authentication fixes
         1. Share SSO filter makes touch requests in the name of the external user ID (remoteUser) for unauthenticated users
         2. Include WebScriptSSOAuthenticationFilter in external-filter-context.xml to allow cookie-based manual login failover (A Spring Surf patch is required to support this)
         3. On the repository tier, web client authentication will send a 401 response for an invalid remote user (with redirect to login page in HTML markup) so that Share SSO authenticator detects this as an authentication failure and redirects to the login page, thus allowing manual login failover.
         29454: ALF-9876 / ALF-9579: Share external authentication fixes
         4. Spring Surf / Spring webscripts jars (from Kevin Roast)
         29563: ALF-8607 / ALF-9596: Guarantee read consistency in AbstractNodeDAOImpl.getNodeRefStatus
         - Partly achieved by making EntityLookupCache.removeByKey() unconditionally cache removes
      29673: ALF-9530: Reverse merged V3.4-BUG-FIX revisions 29124 and 29109
      - Postgres service will continue to run as SYSTEM user on Windows. See bug for more details.
      29674: ALF-7993: Reversed changes to bitrock files made during removal of 32 bit linux support from the build, as requested by Bitrock (V3.4-BUG-FIX revision 26582)


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@29700 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2011-08-11 18:54:03 +00:00
parent 1b499b662a
commit 4ea611eec3
11 changed files with 187 additions and 142 deletions

View File

@@ -436,7 +436,30 @@ public final class AuthenticationHelper
}
return null;
}
/**
* Uses the remote user mapper, if one is configured, to extract a user ID from the request
*
* @param sc
* the servlet context
* @param httpRequest
* The HTTP request
* @return the user ID if a user has been externally authenticated or <code>null</code> otherwise.
*/
public static String getRemoteUser(final ServletContext sc, final HttpServletRequest httpRequest)
{
String userId = null;
// If the remote user mapper is configured, we may be able to map in an externally authenticated user
final WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
RemoteUserMapper remoteUserMapper = (RemoteUserMapper) wc.getBean(REMOTE_USER_MAPPER);
if (!(remoteUserMapper instanceof ActivateableBean) || ((ActivateableBean) remoteUserMapper).isActive())
{
userId = remoteUserMapper.getRemoteUser(httpRequest);
}
return userId;
}
/**
* Attempts to retrieve the User object stored in the current session.
*
@@ -450,16 +473,10 @@ public final class AuthenticationHelper
*/
public static User getUser(final ServletContext sc, final HttpServletRequest httpRequest, HttpServletResponse httpResponse)
{
String userId = null;
// If the remote user mapper is configured, we may be able to map in an externally authenticated user
final WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
RemoteUserMapper remoteUserMapper = (RemoteUserMapper) wc.getBean(REMOTE_USER_MAPPER);
if (!(remoteUserMapper instanceof ActivateableBean) || ((ActivateableBean) remoteUserMapper).isActive())
{
userId = remoteUserMapper.getRemoteUser(httpRequest);
}
String userId = getRemoteUser(sc, httpRequest);
final WebApplicationContext wc = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
HttpSession session = httpRequest.getSession();
User user = null;
@@ -513,9 +530,21 @@ public final class AuthenticationHelper
// If we have been authenticated by other means, just propagate through the user identity
AuthenticationComponent authenticationComponent = (AuthenticationComponent) wc
.getBean(AUTHENTICATION_COMPONENT);
authenticationComponent.setCurrentUser(userId);
AuthenticationService authenticationService = (AuthenticationService) wc.getBean(AUTHENTICATION_SERVICE);
user = setUser(sc, httpRequest, userId, authenticationService.getCurrentTicket(), true);
try
{
authenticationComponent.setCurrentUser(userId);
AuthenticationService authenticationService = (AuthenticationService) wc.getBean(AUTHENTICATION_SERVICE);
user = setUser(sc, httpRequest, userId, authenticationService.getCurrentTicket(), true);
}
catch (AuthenticationException authErr)
{
// Allow for an invalid external user ID to be indicated
session.removeAttribute(AUTHENTICATION_USER);
if (!Application.inPortalServer())
{
session.invalidate();
}
}
}
}
return user;

View File

@@ -19,6 +19,7 @@
package org.alfresco.web.app.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashSet;
@@ -264,7 +265,26 @@ public abstract class BaseServlet extends HttpServlet
}
redirectURL.append(URLEncoder.encode(url, "UTF-8"));
}
res.sendRedirect(redirectURL.toString());
// If external authentication isn't in use (e.g. proxied share authentication), it's safe to return a redirect to the client
if (AuthenticationHelper.getRemoteUser(sc, req) == null)
{
res.sendRedirect(redirectURL.toString());
}
// Otherwise, we must signal to the client with an unauthorized status code and rely on a browser refresh to do
// the redirect for failover login (as we do with NTLM, Kerberos)
else
{
res.setContentType("text/html; charset=UTF-8");
res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
final PrintWriter out = res.getWriter();
out.println("<html><head>");
out.println("<meta http-equiv=\"Refresh\" content=\"0; url=" + redirectURL + "\">");
out.println("</head><body><p>Please <a href=\"" + redirectURL + "\">log in</a>.</p>");
out.println("</body></html>");
out.close();
}
}
/**

View File

@@ -60,6 +60,11 @@ public class WebScriptSSOAuthenticationFilter extends BaseAuthenticationFilter i
private boolean isActive = true;
public WebScriptSSOAuthenticationFilter()
{
setUserAttributeName(AuthenticationHelper.AUTHENTICATION_USER);
}
/**
* @param container the container to set
*/
@@ -95,8 +100,6 @@ public class WebScriptSSOAuthenticationFilter extends BaseAuthenticationFilter i
public void doFilter(ServletContext context, ServletRequest sreq, ServletResponse sresp, FilterChain chain)
throws IOException, ServletException
{
setUserAttributeName(AuthenticationHelper.AUTHENTICATION_USER);
// Get the HTTP request/response
HttpServletRequest req = (HttpServletRequest)sreq;
HttpServletResponse res = (HttpServletResponse)sresp;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -799,39 +799,7 @@ public class CreateUserWizard extends BaseWizardBean
{
// create properties for Person type from submitted Form data
Map<QName, Serializable> props = new HashMap<QName, Serializable>(7, 1.0f);
props.put(ContentModel.PROP_USERNAME, this.userName);
props.put(ContentModel.PROP_FIRSTNAME, this.firstName);
props.put(ContentModel.PROP_LASTNAME, this.lastName);
NodeRef homeSpaceNodeRef;
if (this.homeSpaceLocation != null && this.homeSpaceName.length() != 0)
{
// create new
homeSpaceNodeRef = createHomeSpace(this.homeSpaceLocation.getId(), this.homeSpaceName, true);
}
else if (this.homeSpaceLocation != null)
{
// set to existing - first ensure it is NOT "User Homes" space!
if (this.defaultHomeSpaceRef.equals(this.homeSpaceLocation))
{
throw new AlfrescoRuntimeException(Application.getMessage(context, MSG_ERROR_NEWUSER_HOME_SPACE));
}
homeSpaceNodeRef = this.homeSpaceLocation;
setupHomeSpacePermissions(homeSpaceNodeRef);
}
else
{
// default to Company Home
homeSpaceNodeRef = getCompanyHomeSpace();
}
props.put(ContentModel.PROP_HOMEFOLDER, homeSpaceNodeRef);
props.put(ContentModel.PROP_EMAIL, this.email);
props.put(ContentModel.PROP_ORGID, this.companyId);
props.put(ContentModel.PROP_ORGANIZATION, this.organisation);
props.put(ContentModel.PROP_JOBTITLE, this.jobtitle);
props.put(ContentModel.PROP_LOCATION, this.location);
props.put(ContentModel.PROP_PRESENCEPROVIDER, this.presenceProvider);
props.put(ContentModel.PROP_PRESENCEUSERNAME, this.presenceUsername);
setPersonPropertiesAndCreateHomeSpaceIfNeeded(props, context);
// create the node to represent the Person
getPersonService().createPerson(props);
@@ -877,6 +845,47 @@ public class CreateUserWizard extends BaseWizardBean
return outcome;
}
protected void setPersonPropertiesAndCreateHomeSpaceIfNeeded(
Map<QName, Serializable> props, FacesContext context)
{
props.put(ContentModel.PROP_USERNAME, this.userName);
props.put(ContentModel.PROP_FIRSTNAME, this.firstName);
props.put(ContentModel.PROP_LASTNAME, this.lastName);
NodeRef homeSpaceNodeRef;
if (this.homeSpaceLocation != null && this.homeSpaceName.length() != 0)
{
// create new
props.put(ContentModel.PROP_HOME_FOLDER_PROVIDER, "userHomesHomeFolderProvider");
homeSpaceNodeRef = createHomeSpace(this.homeSpaceLocation.getId(), this.homeSpaceName, true);
}
else if (this.homeSpaceLocation != null)
{
// set to existing - first ensure it is NOT "User Homes" space!
if (this.defaultHomeSpaceRef.equals(this.homeSpaceLocation))
{
throw new AlfrescoRuntimeException(Application.getMessage(context, MSG_ERROR_NEWUSER_HOME_SPACE));
}
props.put(ContentModel.PROP_HOME_FOLDER_PROVIDER, "companyHomeFolderProvider"); // shared folder
homeSpaceNodeRef = this.homeSpaceLocation;
setupHomeSpacePermissions(homeSpaceNodeRef);
}
else
{
// default to Company Home
props.put(ContentModel.PROP_HOME_FOLDER_PROVIDER, "companyHomeFolderProvider"); // shared folder
homeSpaceNodeRef = getCompanyHomeSpace();
}
props.put(ContentModel.PROP_HOMEFOLDER, homeSpaceNodeRef);
props.put(ContentModel.PROP_EMAIL, this.email);
props.put(ContentModel.PROP_ORGID, this.companyId);
props.put(ContentModel.PROP_ORGANIZATION, this.organisation);
props.put(ContentModel.PROP_JOBTITLE, this.jobtitle);
props.put(ContentModel.PROP_LOCATION, this.location);
props.put(ContentModel.PROP_PRESENCEPROVIDER, this.presenceProvider);
props.put(ContentModel.PROP_PRESENCEUSERNAME, this.presenceUsername);
}
@Override
public boolean getFinishButtonDisabled()
{

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -24,7 +24,6 @@ import java.util.Map;
import javax.faces.context.FacesContext;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
@@ -118,86 +117,16 @@ public class EditUserWizard extends CreateUserWizard
// update the existing node in the repository
NodeRef nodeRef = properties.getPerson().getNodeRef();
// Note: The previous approach was to try a move the home folder if changed,
// but this was problematic as other users that shared the same folder
// moved too. We cannot tell if it is shared. Decided it is better to just
// create a new folder or reuse the folder pointed to just like the initial
// creation in CreateUserWizard. It is always possible to move the contents
// of the old home folder by hand later.
Map<QName, Serializable> props = this.getNodeService().getProperties(nodeRef);
props.put(ContentModel.PROP_USERNAME, this.userName);
props.put(ContentModel.PROP_FIRSTNAME, this.firstName);
props.put(ContentModel.PROP_LASTNAME, this.lastName);
setPersonPropertiesAndCreateHomeSpaceIfNeeded(props, context);
// calculate whether we need to move the old home space or create new
NodeRef newHomeFolderRef;
NodeRef oldHomeFolderRef = (NodeRef) this.getNodeService().getProperty(nodeRef, ContentModel.PROP_HOMEFOLDER);
boolean moveHomeSpace = false;
boolean renameHomeSpace = false;
if (oldHomeFolderRef != null && this.getNodeService().exists(oldHomeFolderRef) == true)
{
// the original home folder ref exists so may need moving if it has been changed
ChildAssociationRef childAssocRef = this.getNodeService().getPrimaryParent(oldHomeFolderRef);
NodeRef currentHomeSpaceLocation = childAssocRef.getParentRef();
if (this.homeSpaceName.length() != 0)
{
if (currentHomeSpaceLocation.equals(this.homeSpaceLocation) == false && oldHomeFolderRef.equals(this.homeSpaceLocation) == false
&& currentHomeSpaceLocation.equals(getCompanyHomeSpace()) == false && currentHomeSpaceLocation.equals(getDefaultHomeSpace()) == false)
{
moveHomeSpace = true;
}
String oldHomeSpaceName = Repository.getNameForNode(getNodeService(), oldHomeFolderRef);
if (oldHomeSpaceName.equals(this.homeSpaceName) == false && oldHomeFolderRef.equals(this.homeSpaceLocation) == false)
{
renameHomeSpace = true;
}
}
}
if (logger.isDebugEnabled())
logger.debug("Moving space: " + moveHomeSpace + " and renaming space: " + renameHomeSpace);
if (moveHomeSpace == false && renameHomeSpace == false)
{
if (this.homeSpaceLocation != null && this.homeSpaceName.length() != 0)
{
newHomeFolderRef = createHomeSpace(this.homeSpaceLocation.getId(), this.homeSpaceName, false);
}
else if (this.homeSpaceLocation != null)
{
// location selected but no home space name entered,
// so the home ref should be set to the newly selected space
newHomeFolderRef = this.homeSpaceLocation;
// set the permissions for this space so the user can access it
}
else
{
// nothing selected - use Company Home by default
newHomeFolderRef = getCompanyHomeSpace();
}
}
else
{
// either move, rename or both required
if (moveHomeSpace == true)
{
this.getNodeService()
.moveNode(oldHomeFolderRef, this.homeSpaceLocation, ContentModel.ASSOC_CONTAINS, this.getNodeService().getPrimaryParent(oldHomeFolderRef).getQName());
}
newHomeFolderRef = oldHomeFolderRef; // ref ID doesn't change
if (renameHomeSpace == true)
{
// change HomeSpace node name
this.getNodeService().setProperty(newHomeFolderRef, ContentModel.PROP_NAME, this.homeSpaceName);
}
}
props.put(ContentModel.PROP_HOMEFOLDER, newHomeFolderRef);
props.put(ContentModel.PROP_EMAIL, this.email);
props.put(ContentModel.PROP_ORGID, this.companyId);
props.put(ContentModel.PROP_ORGANIZATION, this.organisation);
props.put(ContentModel.PROP_JOBTITLE, this.jobtitle);
props.put(ContentModel.PROP_LOCATION, this.location);
props.put(ContentModel.PROP_PRESENCEPROVIDER, this.presenceProvider);
props.put(ContentModel.PROP_PRESENCEUSERNAME, this.presenceUsername);
// update the node that represents the Person
this.getNodeService().setProperties(nodeRef, props);
// TODO: RESET HomeSpace Ref found in top-level navigation bar!

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2010 Alfresco Software Limited.
* Copyright (C) 2005-2011 Alfresco Software Limited.
*
* This file is part of Alfresco
*
@@ -60,6 +60,7 @@ import org.apache.commons.logging.LogFactory;
import org.apache.commons.validator.EmailValidator;
/**
* @deprecated Replaced by CreateUserWizard.
* @author Kevin Roast
*/
public class NewUserWizard extends AbstractWizardBean

View File

@@ -21,7 +21,6 @@ package org.alfresco.web.ui.repo.component;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -650,20 +649,14 @@ public class UIActions extends SelfRenderingComponent
*/
private static String createUniqueId()
{
String guidString = GUID.generate();
byte[] guidBytes = null;
try
{
guidBytes = guidString.getBytes("ISO8859_1");
return "id_" + new BigInteger(GUID.generate().getBytes("8859_1")).toString(Character.MAX_RADIX);
}
catch (UnsupportedEncodingException e)
{
//probably unreachable block, so just in case
Charset defaultCharset = Charset.defaultCharset();
logger.warn("Can't get GUID bytes for encoding ISO8859_1, use default " + defaultCharset);
guidBytes = guidString.getBytes(defaultCharset);
throw new RuntimeException(e);
}
return "id_" + new BigInteger(guidBytes).toString(Character.MAX_RADIX);
}
// ------------------------------------------------------------------------------
@@ -680,6 +673,4 @@ public class UIActions extends SelfRenderingComponent
/** Vertical layout spacing */
private Integer verticalSpacing = null;
private static short id = 0;
}