Merged V1.4 to HEAD

svn merge svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@3987 svn://svn.alfresco.com:3691/alfresco/BRANCHES/V1.4@4133 .
   Removed LicenseComponent reference from projects\repository\source\java\org\alfresco\repo\descriptor\DescriptorServiceImpl.java


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@4135 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Derek Hulley
2006-10-17 22:42:59 +00:00
parent 2f1bdec345
commit 12fd56b191
5 changed files with 142 additions and 30 deletions

View File

@@ -16,6 +16,8 @@
*/ */
package org.alfresco.repo.webdav; package org.alfresco.repo.webdav;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.model.FileInfo;
import org.alfresco.service.cmr.model.FileNotFoundException; import org.alfresco.service.cmr.model.FileNotFoundException;
@@ -30,6 +32,7 @@ public class OptionsMethod extends WebDAVMethod
private static final String DAV_HEADER_CONTENT = "1,2"; private static final String DAV_HEADER_CONTENT = "1,2";
private static final String ALLOW_HEADER = "Allow"; private static final String ALLOW_HEADER = "Allow";
private static final String MS_HEADER = "MS-Author-Via"; private static final String MS_HEADER = "MS-Author-Via";
private static final String CONTENT_LENGTH = "Content-Length";
private static final String FILE_METHODS = "OPTIONS, GET, HEAD, POST, DELETE, PROPFIND, COPY, MOVE, LOCK, UNLOCK"; private static final String FILE_METHODS = "OPTIONS, GET, HEAD, POST, DELETE, PROPFIND, COPY, MOVE, LOCK, UNLOCK";
private static final String COLLECTION_METHODS = FILE_METHODS + ", PUT"; private static final String COLLECTION_METHODS = FILE_METHODS + ", PUT";
@@ -77,15 +80,24 @@ public class OptionsMethod extends WebDAVMethod
catch (FileNotFoundException e) catch (FileNotFoundException e)
{ {
// Do nothing; just default to a folder // Do nothing; just default to a folder
isFolder = true; isFolder = true;
} }
// Add the header to advertise the level of support the server has // Add the header to advertise the level of support the server has
m_response.addHeader(DAV_HEADER, DAV_HEADER_CONTENT); m_response.addHeader(DAV_HEADER, DAV_HEADER_CONTENT);
// Add the proprietary Microsoft header to make Microsoft clients behave // Add the proprietary Microsoft header to make Microsoft clients behave
m_response.addHeader(MS_HEADER, DAV_HEADER); m_response.addHeader(MS_HEADER, DAV_HEADER);
// Add the header to show what methods are allowed // Add the header to show what methods are allowed
m_response.addHeader(ALLOW_HEADER, isFolder ? COLLECTION_METHODS : FILE_METHODS); m_response.addHeader(ALLOW_HEADER, isFolder ? COLLECTION_METHODS : FILE_METHODS);
// Indicate no content
m_response.addHeader(CONTENT_LENGTH, "0");
} }
} }

View File

@@ -23,10 +23,13 @@ import java.util.Iterator;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.transaction.Status;
import javax.transaction.UserTransaction;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel; import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.permissions.AccessDeniedException; import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.transaction.TransactionUtil; import org.alfresco.repo.transaction.TransactionUtil;
@@ -113,28 +116,37 @@ public abstract class WebDAVMethod
public void execute() throws WebDAVServerException public void execute() throws WebDAVServerException
{ {
// Parse the HTTP headers // Parse the HTTP headers
parseRequestHeaders(); parseRequestHeaders();
// Parse the HTTP body // Parse the HTTP body
parseRequestBody();
TransactionWork<WebDAVServerException> executeWork = new TransactionWork<WebDAVServerException>() parseRequestBody();
{
public WebDAVServerException doWork() throws Exception // Run the method wrapped in a transaction
{
executeImpl(); TransactionService transactionService = getTransactionService();
return null; UserTransaction tx = transactionService.getUserTransaction( false);
}
};
try try
{ {
// Execute the method // Start the transaction
TransactionService transactionService = getTransactionService();
TransactionUtil.executeInUserTransaction(transactionService, executeWork); tx.begin();
// Run the WebDAV method
executeImpl();
// Commit the transaction
tx.commit();
tx = null;
} }
catch (AccessDeniedException e) catch (AccessDeniedException e)
{ {
// Return a forbidden status // Return a forbidden status
throw new WebDAVServerException(HttpServletResponse.SC_UNAUTHORIZED, e); throw new WebDAVServerException(HttpServletResponse.SC_UNAUTHORIZED, e);
} }
catch (Throwable e) catch (Throwable e)
@@ -147,9 +159,39 @@ public abstract class WebDAVMethod
else else
{ {
// Convert error to a server error // Convert error to a server error
throw new WebDAVServerException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); throw new WebDAVServerException(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
} }
} }
finally
{
if ( tx != null)
{
// Commit or rollback the transaction
try
{
// Commit or rollback the transaction
if ( tx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
{
// Transaction is marked for rollback
tx.rollback();
}
else
{
// Commit the transaction
tx.commit();
}
}
catch ( Exception ex)
{
throw new AlfrescoRuntimeException("Failed to end transaction", ex);
}
}
}
} }
/** /**

View File

@@ -97,6 +97,7 @@ public class WebDAVServlet extends HttpServlet
try try
{ {
// Create the appropriate WebDAV method for the request and execute it // Create the appropriate WebDAV method for the request and execute it
final WebDAVMethod method = createMethod(request, response); final WebDAVMethod method = createMethod(request, response);
if (method == null) if (method == null)
@@ -115,20 +116,14 @@ public class WebDAVServlet extends HttpServlet
logger.error("No root node for request"); logger.error("No root node for request");
// Return an error status // Return an error status
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return; return;
} }
// Execute the WebDAV request, wrapped in a transaction // Excecute the WebDAV request
TransactionWork<Object> methodWork = new TransactionWork<Object>()
{ method.execute();
public Object doWork() throws Exception
{
method.execute();
return null;
}
};
TransactionUtil.executeInUserTransaction(m_transactionService, methodWork);
} }
catch (Throwable e) catch (Throwable e)
{ {
@@ -139,13 +134,15 @@ public class WebDAVServlet extends HttpServlet
e = e.getCause(); e = e.getCause();
} }
} }
// Work out how to handle the error // Work out how to handle the error
if (e instanceof WebDAVServerException) if (e instanceof WebDAVServerException)
{ {
WebDAVServerException error = (WebDAVServerException) e; WebDAVServerException error = (WebDAVServerException) e;
if (error.getCause() != null) if (error.getCause() != null)
{ {
logger.error(INTERNAL_SERVER_ERROR, error.getCause()); logger.debug( "WebDAV " + request.getMethod() + " error: " + error.getCause().getMessage());
} }
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
@@ -166,7 +163,7 @@ public class WebDAVServlet extends HttpServlet
} }
else else
{ {
logger.error(INTERNAL_SERVER_ERROR, e); logger.debug( "WebDAV " + request.getMethod() + " error: " + e.getMessage());
if (response.isCommitted()) if (response.isCommitted())
{ {

View File

@@ -21,6 +21,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@@ -126,6 +127,10 @@ public class NTLMAuthenticationFilter implements Filter
private String m_srvName; private String m_srvName;
// In progress NTLM logons for clients that are not using cookies
private Hashtable<String, NTLMLogonDetails> m_logonDetailsTable;
/** /**
* Initialize the filter * Initialize the filter
* *
@@ -209,6 +214,10 @@ public class NTLMAuthenticationFilter implements Filter
if ( logger.isDebugEnabled() && m_allowGuest) if ( logger.isDebugEnabled() && m_allowGuest)
logger.debug("NTLM filter guest access allowed"); logger.debug("NTLM filter guest access allowed");
} }
// Create the NTLM logon details hash table for clients that are not using cookies
m_logonDetailsTable = new Hashtable<String, NTLMLogonDetails>();
} }
/** /**
@@ -320,6 +329,7 @@ public class NTLMAuthenticationFilter implements Filter
Type3NTLMMessage type3Msg = new Type3NTLMMessage(ntlmByts); Type3NTLMMessage type3Msg = new Type3NTLMMessage(ntlmByts);
processType3(type3Msg, req, resp, httpSess, chain); processType3(type3Msg, req, resp, httpSess, chain);
return;
} }
} }
@@ -445,8 +455,32 @@ public class NTLMAuthenticationFilter implements Filter
ntlmDetails = new NTLMLogonDetails(); ntlmDetails = new NTLMLogonDetails();
ntlmDetails.setType2Message( type2Msg); ntlmDetails.setType2Message( type2Msg);
ntlmDetails.setAuthenticationToken(authToken); ntlmDetails.setAuthenticationToken(authToken);
httpSess.setAttribute(NTLM_AUTH_DETAILS, ntlmDetails); // Check if the client supports cookies
if ( req.getCookies() != null)
{
// Client appears to support cookies so we can store the NTLM details in the session
httpSess.setAttribute(NTLM_AUTH_DETAILS, ntlmDetails);
}
else
{
// Client does not support cookies so store the NTLM details in the logon details table
StringBuilder keyStr = new StringBuilder();
keyStr.append( req.getRemoteHost());
keyStr.append( ":");
keyStr.append( req.getRemotePort());
m_logonDetailsTable.put( keyStr.toString(), ntlmDetails);
// DEBUG
if ( logger.isDebugEnabled())
logger.debug( "Storing NTLM details for " + keyStr.toString() + " in logon table");
}
// Debug // Debug
@@ -495,7 +529,30 @@ public class NTLMAuthenticationFilter implements Filter
ntlmDetails = (NTLMLogonDetails) httpSess.getAttribute(NTLM_AUTH_DETAILS); ntlmDetails = (NTLMLogonDetails) httpSess.getAttribute(NTLM_AUTH_DETAILS);
user = (WebDAVUser) httpSess.getAttribute(AUTHENTICATION_USER); user = (WebDAVUser) httpSess.getAttribute(AUTHENTICATION_USER);
} }
// Check if the NTLM details are null and the client is not using cookies. The NTLM details will have been
// stored in the logon table.
if ( ntlmDetails == null && req.getCookies() == null)
{
// Check if the NTLM details are in logon table
StringBuilder keyStr = new StringBuilder();
keyStr.append( req.getRemoteHost());
keyStr.append( ":");
keyStr.append( req.getRemotePort());
// Remove the NTLM details from the logon table
ntlmDetails = m_logonDetailsTable.remove( keyStr.toString());
// DEBUG
if ( logger.isDebugEnabled() && ntlmDetails != null)
logger.debug( "Retrieved NTLM details for " + keyStr.toString() + " from logon table");
}
// Get the NTLM logon details // Get the NTLM logon details
String userName = type3Msg.getUserName(); String userName = type3Msg.getUserName();
@@ -568,7 +625,7 @@ public class NTLMAuthenticationFilter implements Filter
} }
else else
{ {
// Cehck if we are using local MD4 password hashes or passthru authentication // Check if we are using local MD4 password hashes or passthru authentication
if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER) if ( m_authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
{ {
@@ -664,13 +721,16 @@ public class NTLMAuthenticationFilter implements Filter
tx.begin(); tx.begin();
// Get user details for the authenticated user // Get user details for the authenticated user
m_authComponent.setCurrentUser(userName.toLowerCase()); m_authComponent.setCurrentUser(userName.toLowerCase());
// The user name used may be a different case to the NTLM supplied user name, read the current // The user name used may be a different case to the NTLM supplied user name, read the current
// user and use that name // user and use that name
userName = m_authComponent.getCurrentUserName(); userName = m_authComponent.getCurrentUserName();
// Setup User object and Home space ID etc. // Setup User object and Home space ID etc.
NodeRef personNodeRef = m_personService.getPerson(userName); NodeRef personNodeRef = m_personService.getPerson(userName);
String currentTicket = m_authService.getCurrentTicket(); String currentTicket = m_authService.getCurrentTicket();
user = new WebDAVUser(userName, currentTicket, personNodeRef); user = new WebDAVUser(userName, currentTicket, personNodeRef);
@@ -678,7 +738,8 @@ public class NTLMAuthenticationFilter implements Filter
NodeRef homeSpaceRef = (NodeRef) m_nodeService.getProperty(personNodeRef, ContentModel.PROP_HOMEFOLDER); NodeRef homeSpaceRef = (NodeRef) m_nodeService.getProperty(personNodeRef, ContentModel.PROP_HOMEFOLDER);
user.setHomeNode(homeSpaceRef); user.setHomeNode(homeSpaceRef);
// commit // Commit the transaction
tx.commit(); tx.commit();
} }
catch (Throwable ex) catch (Throwable ex)

View File

@@ -593,7 +593,7 @@ public class CMLUtil
List<NodeRef> nodesToCopy = getNodeRefList(copy.getWhere_id(), copy.getWhere(), context); List<NodeRef> nodesToCopy = getNodeRefList(copy.getWhere_id(), copy.getWhere(), context);
for (NodeRef nodeToCopy : nodesToCopy) for (NodeRef nodeToCopy : nodesToCopy)
{ {
NodeRef newNodeRef = this.copyService.copy(nodeToCopy, destinationNodeRef, assocType, assocName, copyChildren); NodeRef newNodeRef = this.copyService.copyAndRename(nodeToCopy, destinationNodeRef, assocType, assocName, copyChildren);
// Create the result // Create the result
results.add(createResult(COPY, null, nodeToCopy, newNodeRef)); results.add(createResult(COPY, null, nodeToCopy, newNodeRef));