mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
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:
@@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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())
|
||||||
{
|
{
|
||||||
|
@@ -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)
|
||||||
|
@@ -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));
|
||||||
|
Reference in New Issue
Block a user