You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by br...@apache.org on 2009/03/19 07:10:38 UTC

svn commit: r755845 [1/2] - in /archiva/trunk/archiva-modules/archiva-web: archiva-security/src/main/java/org/apache/maven/archiva/security/ archiva-security/src/test/java/org/apache/maven/archiva/security/ archiva-webapp/src/main/java/org/apache/maven...

Author: brett
Date: Thu Mar 19 06:10:38 2009
New Revision: 755845

URL: http://svn.apache.org/viewvc?rev=755845&view=rev
Log:
clean up the webdav interface to make the code more readable
in addition, webdav now honours the delete operation separately to upload
improved the HTTP error responses for misconfiguration (500) vs not found on groups

Modified:
    archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java
    archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java
    archiva/trunk/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/ArchivaServletAuthenticatorTest.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/rss/RssFeedServlet.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaVirtualDavResource.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WebdavMethodUtil.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/AbstractRepositoryServletTestCase.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProviderTest.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/MockServletAuthenticator.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletRepositoryGroupTest.java
    archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaServletAuthenticator.java Thu Mar 19 06:10:38 2009
@@ -62,27 +62,19 @@
     }
 
     public boolean isAuthorized( HttpServletRequest request, SecuritySession securitySession, String repositoryId,
-                                 boolean isWriteRequest )
+                                 String permission )
         throws AuthorizationException, UnauthorizedException
     {
         // TODO: also check for permission to proxy the resource when MRM-579 is implemented
 
-        String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
-
-        if ( isWriteRequest )
-        {
-            permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
-        }
-
         AuthorizationResult authzResult = securitySystem.authorize( securitySession, permission, repositoryId );
 
         if ( !authzResult.isAuthorized() )
         {
             if ( authzResult.getException() != null )
             {
-                log.info( "Authorization Denied [ip=" + request.getRemoteAddr() + ",isWriteRequest=" + isWriteRequest +
-                    ",permission=" + permission + ",repo=" + repositoryId + "] : " +
-                    authzResult.getException().getMessage() );
+                log.info( "Authorization Denied [ip=" + request.getRemoteAddr() + ",permission=" + permission
+                    + ",repo=" + repositoryId + "] : " + authzResult.getException().getMessage() );
 
                 throw new UnauthorizedException( "Access denied for repository " + repositoryId );
             }
@@ -92,18 +84,11 @@
         return true;
     }
 
-    public boolean isAuthorized( String principal, String repoId, boolean isWriteRequest )
+    public boolean isAuthorized( String principal, String repoId, String permission )
         throws UnauthorizedException
     {
         try
         {
-            String permission = ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
-
-            if ( isWriteRequest )
-            {
-                permission = ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
-            }
-            
             User user = securitySystem.getUserManager().findUser( principal );
             if ( user == null )
             {

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ServletAuthenticator.java Thu Mar 19 06:10:38 2009
@@ -59,7 +59,7 @@
      * @throws UnauthorizedException
      */
     public boolean isAuthorized( HttpServletRequest request, SecuritySession securitySession, String repositoryId,
-        boolean isWriteRequest ) throws AuthorizationException, UnauthorizedException;
+        String permission ) throws AuthorizationException, UnauthorizedException;
     
     /**
      * Authorization check specific for user guest, which doesn't go through 
@@ -74,6 +74,6 @@
      * @return
      * @throws UnauthorizedException
      */
-    public boolean isAuthorized( String principal, String repoId, boolean isWriteRequest )
+    public boolean isAuthorized( String principal, String repoId, String permission )
         throws UnauthorizedException;
 }

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/ArchivaServletAuthenticatorTest.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/ArchivaServletAuthenticatorTest.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/ArchivaServletAuthenticatorTest.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-security/src/test/java/org/apache/maven/archiva/security/ArchivaServletAuthenticatorTest.java Thu Mar 19 06:10:38 2009
@@ -27,7 +27,7 @@
 import org.codehaus.plexus.redback.system.DefaultSecuritySession;
 import org.codehaus.plexus.redback.system.SecuritySession;
 import org.codehaus.plexus.redback.users.User;
-import org.codehaus.plexus.redback.users.UserManager; 
+import org.codehaus.plexus.redback.users.UserManager;
 
 import org.easymock.MockControl;
 
@@ -38,48 +38,48 @@
  */
 public class ArchivaServletAuthenticatorTest
     extends AbstractSecurityTest
-{    
+{
     private ServletAuthenticator servletAuth;
-    
+
     private MockControl httpServletRequestControl;
-    
+
     private HttpServletRequest request;
-    
+
     @Override
     public void setUp()
         throws Exception
     {
         super.setUp();
-        
-        servletAuth = ( ServletAuthenticator ) lookup( ServletAuthenticator.class, "default" );
-        
+
+        servletAuth = (ServletAuthenticator) lookup( ServletAuthenticator.class, "default" );
+
         httpServletRequestControl = MockControl.createControl( HttpServletRequest.class );
-        request = ( HttpServletRequest ) httpServletRequestControl.getMock();
-        
+        request = (HttpServletRequest) httpServletRequestControl.getMock();
+
         setupRepository( "corporate" );
     }
-    
+
     @Override
     protected String getPlexusConfigLocation()
     {
         return "org/apache/maven/archiva/security/ArchivaServletAuthenticatorTest.xml";
     }
-    
+
     protected void assignRepositoryManagerRole( String principal, String repoId )
         throws Exception
     {
         roleManager.assignTemplatedRole( ArchivaRoleConstants.TEMPLATE_REPOSITORY_MANAGER, repoId, principal );
     }
-    
+
     public void testIsAuthenticatedUserExists()
         throws Exception
     {
         AuthenticationResult result = new AuthenticationResult( true, "user", null );
         boolean isAuthenticated = servletAuth.isAuthenticated( request, result );
-        
+
         assertTrue( isAuthenticated );
     }
-    
+
     public void testIsAuthenticatedUserDoesNotExist()
         throws Exception
     {
@@ -92,132 +92,137 @@
         catch ( AuthenticationException e )
         {
             assertEquals( "User Credentials Invalid", e.getMessage() );
-        }        
+        }
     }
-    
+
     public void testIsAuthorizedUserHasWriteAccess()
         throws Exception
-    {   
+    {
         createUser( USER_ALPACA, "Al 'Archiva' Paca" );
-        
+
         assignRepositoryManagerRole( USER_ALPACA, "corporate" );
 
         UserManager userManager = securitySystem.getUserManager();
         User user = userManager.findUser( USER_ALPACA );
-        
+
         AuthenticationResult result = new AuthenticationResult( true, USER_ALPACA, null );
-        
+
         SecuritySession session = new DefaultSecuritySession( result, user );
-        boolean isAuthorized = servletAuth.isAuthorized( request, session, "corporate", true );
-                
+        boolean isAuthorized =
+            servletAuth.isAuthorized( request, session, "corporate", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
+
         assertTrue( isAuthorized );
     }
-    
+
     public void testIsAuthorizedUserHasNoWriteAccess()
         throws Exception
     {
         createUser( USER_ALPACA, "Al 'Archiva' Paca" );
-        
+
         assignRepositoryObserverRole( USER_ALPACA, "corporate" );
-    
+
         httpServletRequestControl.expectAndReturn( request.getRemoteAddr(), "192.168.111.111" );
-        
+
         UserManager userManager = securitySystem.getUserManager();
         User user = userManager.findUser( USER_ALPACA );
-        
+
         AuthenticationResult result = new AuthenticationResult( true, USER_ALPACA, null );
-        
+
         SecuritySession session = new DefaultSecuritySession( result, user );
-        
+
         httpServletRequestControl.replay();
-        
+
         try
         {
-            servletAuth.isAuthorized( request, session, "corporate", true );
-            fail( "UnauthorizedException should have been thrown." ); 
+            servletAuth.isAuthorized( request, session, "corporate", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
+            fail( "UnauthorizedException should have been thrown." );
         }
         catch ( UnauthorizedException e )
         {
             assertEquals( "Access denied for repository corporate", e.getMessage() );
         }
-    
+
         httpServletRequestControl.verify();
     }
-    
-    
+
     public void testIsAuthorizedUserHasReadAccess()
         throws Exception
-    { 
+    {
         createUser( USER_ALPACA, "Al 'Archiva' Paca" );
-        
+
         assignRepositoryObserverRole( USER_ALPACA, "corporate" );
-        
+
         UserManager userManager = securitySystem.getUserManager();
         User user = userManager.findUser( USER_ALPACA );
-        
+
         AuthenticationResult result = new AuthenticationResult( true, USER_ALPACA, null );
-        
+
         SecuritySession session = new DefaultSecuritySession( result, user );
-        boolean isAuthorized = servletAuth.isAuthorized( request, session, "corporate", false );
-                
-        assertTrue( isAuthorized );        
+        boolean isAuthorized =
+            servletAuth.isAuthorized( request, session, "corporate", ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
+
+        assertTrue( isAuthorized );
     }
-    
+
     public void testIsAuthorizedUserHasNoReadAccess()
         throws Exception
     {
         createUser( USER_ALPACA, "Al 'Archiva' Paca" );
-        
+
         UserManager userManager = securitySystem.getUserManager();
         User user = userManager.findUser( USER_ALPACA );
-        
+
         AuthenticationResult result = new AuthenticationResult( true, USER_ALPACA, null );
-        
+
         SecuritySession session = new DefaultSecuritySession( result, user );
         try
         {
-            servletAuth.isAuthorized( request, session, "corporate", false );
+            servletAuth.isAuthorized( request, session, "corporate", ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
             fail( "UnauthorizedException should have been thrown." );
         }
         catch ( UnauthorizedException e )
         {
             assertEquals( "Access denied for repository corporate", e.getMessage() );
-        }       
+        }
     }
-    
+
     public void testIsAuthorizedGuestUserHasWriteAccess()
         throws Exception
-    {   
-        assignRepositoryManagerRole( USER_GUEST, "corporate" );        
-        boolean isAuthorized = servletAuth.isAuthorized( USER_GUEST, "corporate", true );
-        
+    {
+        assignRepositoryManagerRole( USER_GUEST, "corporate" );
+        boolean isAuthorized =
+            servletAuth.isAuthorized( USER_GUEST, "corporate", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
+
         assertTrue( isAuthorized );
     }
-    
+
     public void testIsAuthorizedGuestUserHasNoWriteAccess()
         throws Exception
-    {   
+    {
         assignRepositoryObserverRole( USER_GUEST, "corporate" );
-        
-        boolean isAuthorized = servletAuth.isAuthorized( USER_GUEST, "corporate", true );
+
+        boolean isAuthorized =
+            servletAuth.isAuthorized( USER_GUEST, "corporate", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
         assertFalse( isAuthorized );
     }
-    
+
     public void testIsAuthorizedGuestUserHasReadAccess()
         throws Exception
     {
         assignRepositoryObserverRole( USER_GUEST, "corporate" );
-        
-        boolean isAuthorized = servletAuth.isAuthorized( USER_GUEST, "corporate", false );
-        
-        assertTrue( isAuthorized );        
+
+        boolean isAuthorized =
+            servletAuth.isAuthorized( USER_GUEST, "corporate", ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
+
+        assertTrue( isAuthorized );
     }
-    
+
     public void testIsAuthorizedGuestUserHasNoReadAccess()
         throws Exception
-    {                   
-        boolean isAuthorized = servletAuth.isAuthorized( USER_GUEST, "corporate", false );
-            
+    {
+        boolean isAuthorized =
+            servletAuth.isAuthorized( USER_GUEST, "corporate", ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS );
+
         assertFalse( isAuthorized );
     }
 }

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/rss/RssFeedServlet.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/rss/RssFeedServlet.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/rss/RssFeedServlet.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webapp/src/main/java/org/apache/maven/archiva/web/rss/RssFeedServlet.java Thu Mar 19 06:10:38 2009
@@ -38,6 +38,7 @@
 import org.apache.commons.lang.StringUtils;
 import org.apache.maven.archiva.database.ArchivaDatabaseException;
 import org.apache.maven.archiva.security.AccessDeniedException;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
 import org.apache.maven.archiva.security.ArchivaSecurityException;
 import org.apache.maven.archiva.security.PrincipalNotFoundException;
 import org.apache.maven.archiva.security.ServletAuthenticator;
@@ -293,8 +294,9 @@
                 AuthenticationResult result = httpAuth.getAuthenticationResult( req, null );
                 SecuritySession securitySession = httpAuth.getSecuritySession( req.getSession( true ) );
 
-                if ( servletAuth.isAuthenticated( req, result ) &&
-                    servletAuth.isAuthorized( req, securitySession, repoId, false ) )
+                if ( servletAuth.isAuthenticated( req, result )
+                    && servletAuth.isAuthorized( req, securitySession, repoId,
+                                                 ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS ) )
                 {
                     return true;
                 }

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java Thu Mar 19 06:10:38 2009
@@ -91,7 +91,7 @@
  */
 public class ArchivaDavResourceFactory
     implements DavResourceFactory, Auditable
-{   
+{
     private static final String PROXIED_SUFFIX = " (proxied)";
 
     private static final String HTTP_PUT_METHOD = "PUT";
@@ -148,16 +148,16 @@
      */
     private final LockManager lockManager = new SimpleLockManager();
 
-    /** 
-     * @plexus.requirement 
+    /**
+     * @plexus.requirement
      */
     private RepositoryContentConsumers consumers;
-    
+
     /**
      * @plexus.requirement
      */
     private ChecksumFile checksum;
-        
+
     /**
      * @plexus.requirement role-hint="sha1"
      */
@@ -167,342 +167,355 @@
      * @plexus.requirement role-hint="md5";
      */
     private Digester digestMd5;
-        
+
     public DavResource createResource( final DavResourceLocator locator, final DavServletRequest request,
                                        final DavServletResponse response )
         throws DavException
     {
-        checkLocatorIsInstanceOfRepositoryLocator( locator );
-        ArchivaDavResourceLocator archivaLocator = (ArchivaDavResourceLocator) locator;
-        
+        ArchivaDavResourceLocator archivaLocator = checkLocatorIsInstanceOfRepositoryLocator( locator );
+
         RepositoryGroupConfiguration repoGroupConfig =
             archivaConfiguration.getConfiguration().getRepositoryGroupsAsMap().get( archivaLocator.getRepositoryId() );
-        List<String> repositories = new ArrayList<String>();
 
-        boolean isGet = WebdavMethodUtil.isReadMethod( request.getMethod() );
-        boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
-        
+        String activePrincipal = getActivePrincipal( request );
+
+        List<String> resourcesInAbsolutePath = new ArrayList<String>();
+
+        boolean readMethod = WebdavMethodUtil.isReadMethod( request.getMethod() );
+        DavResource resource;
         if ( repoGroupConfig != null )
         {
-            if( WebdavMethodUtil.isWriteMethod( request.getMethod() ) )
+            if ( !readMethod )
             {
                 throw new DavException( HttpServletResponse.SC_METHOD_NOT_ALLOWED,
                                         "Write method not allowed for repository groups." );
             }
-            repositories.addAll( repoGroupConfig.getRepositories() );
 
             // handle browse requests for virtual repos
             if ( RepositoryPathUtil.getLogicalResource( archivaLocator.getOrigResourcePath() ).endsWith( "/" ) )
             {
-                return getResource( request, repositories, archivaLocator );
+                return getResource( request, repoGroupConfig.getRepositories(), archivaLocator );
+            }
+            else
+            {
+                resource =
+                    processRepositoryGroup( locator, request, archivaLocator, repoGroupConfig.getRepositories(),
+                                            activePrincipal, readMethod, resourcesInAbsolutePath );
             }
         }
         else
         {
-            repositories.add( archivaLocator.getRepositoryId() );
-        }
-
-        //MRM-419 - Windows Webdav support. Should not 404 if there is no content.
-        if (StringUtils.isEmpty(archivaLocator.getRepositoryId()))
-        {
-            throw new DavException(HttpServletResponse.SC_NO_CONTENT);
-        }
-
-        List<DavResource> availableResources = new ArrayList<DavResource>();
-        List<String> resourcesInAbsolutePath = new ArrayList<String>();
-        DavException e = null;
-        
-        for ( String repositoryId : repositories )
-        {
             ManagedRepositoryContent managedRepository = null;
 
             try
             {
-                managedRepository = getManagedRepository( repositoryId );                
+                managedRepository = repositoryFactory.getManagedRepositoryContent( archivaLocator.getRepositoryId() );
             }
-            catch ( DavException de )
+            catch ( RepositoryNotFoundException e )
             {
-                throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Invalid managed repository <" +
-                    repositoryId + ">" );
+                throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Invalid repository: "
+                    + archivaLocator.getRepositoryId() );
+            }
+            catch ( RepositoryException e )
+            {
+                throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
             }
-            
-            DavResource resource = null;
-            
-            if ( !locator.getResourcePath().startsWith( ArchivaDavResource.HIDDEN_PATH_PREFIX ) )
-            {                
-                if ( managedRepository != null )
-                {
-                    try
-                    {
-                        if( isAuthorized( request, repositoryId ) )
-                        {   
-                            LogicalResource logicalResource =
-                                new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) );
-
-                            if ( isGet )
-                            {
-                                resource = doGet( managedRepository, request, archivaLocator, logicalResource );
-                            }
-
-                            if ( isPut )
-                            {
-                                resource = doPut( managedRepository, request, archivaLocator, logicalResource );                                
-                            }
-                        }
-                    }
-                    catch ( DavException de ) 
-                    {                        
-                        e = de;
-                        continue;
-                    }
 
-                    if( resource == null )
-                    {
-                        e = new DavException( HttpServletResponse.SC_NOT_FOUND, "Resource does not exist" );
-                    }
-                    else
-                    {                           
-                        availableResources.add( resource );
+            resource =
+                processRepository( locator, request, archivaLocator, readMethod, activePrincipal,
+                                   archivaLocator.getRepositoryId(), managedRepository );
 
-                        String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() );
-                        resourcesInAbsolutePath.add( managedRepository.getRepoRoot() + logicalResource );                        
-                    }
-                }
-                else
-                {
-                    e = new DavException( HttpServletResponse.SC_NOT_FOUND, "Repository does not exist" );
-                }
-            }
-        }        
-        
-        if ( availableResources.isEmpty() )
-        {
-            throw e;
+            String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() );
+            resourcesInAbsolutePath.add( managedRepository.getRepoRoot() + logicalResource );
         }
-        
+
         String requestedResource = request.getRequestURI();
-        
+
         // MRM-872 : merge all available metadata
-        // merge metadata only when requested via the repo group        
-        if ( ( repositoryRequest.isMetadata( requestedResource ) || ( requestedResource.endsWith( "metadata.xml.sha1" ) || requestedResource.endsWith( "metadata.xml.md5" ) ) ) &&
-            repoGroupConfig != null )
-        {   
+        // merge metadata only when requested via the repo group
+        if ( ( repositoryRequest.isMetadata( requestedResource ) || ( requestedResource.endsWith( "metadata.xml.sha1" ) || requestedResource.endsWith( "metadata.xml.md5" ) ) )
+            && repoGroupConfig != null )
+        {
             // this should only be at the project level not version level!
-            if( isProjectReference( requestedResource ) )
+            if ( isProjectReference( requestedResource ) )
             {
                 String artifactId = StringUtils.substringBeforeLast( requestedResource.replace( '\\', '/' ), "/" );
                 artifactId = StringUtils.substringAfterLast( artifactId, "/" );
-                
-                ArchivaDavResource res = ( ArchivaDavResource ) availableResources.get( 0 );
-                String filePath = StringUtils.substringBeforeLast( res.getLocalResource().getAbsolutePath().replace( '\\', '/' ), "/" );                                
+
+                ArchivaDavResource res = (ArchivaDavResource) resource;
+                String filePath =
+                    StringUtils.substringBeforeLast( res.getLocalResource().getAbsolutePath().replace( '\\', '/' ), "/" );
                 filePath = filePath + "/maven-metadata-" + repoGroupConfig.getId() + ".xml";
-                
-                // for MRM-872 handle checksums of the merged metadata files 
-                if( repositoryRequest.isSupportFile( requestedResource ) )
-                {
-                    File metadataChecksum = new File( filePath + "." 
-                              + StringUtils.substringAfterLast( requestedResource, "." ) );                    
-                    if( metadataChecksum.exists() )
+
+                // for MRM-872 handle checksums of the merged metadata files
+                if ( repositoryRequest.isSupportFile( requestedResource ) )
+                {
+                    File metadataChecksum =
+                        new File( filePath + "." + StringUtils.substringAfterLast( requestedResource, "." ) );
+                    if ( metadataChecksum.exists() )
                     {
                         LogicalResource logicalResource =
                             new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) );
-                                        
-                        String activePrincipal = getActivePrincipal( request );
 
-                        ArchivaDavResource metadataChecksumResource =
+                        resource =
                             new ArchivaDavResource( metadataChecksum.getAbsolutePath(), logicalResource.getPath(),
                                                     null, request.getRemoteAddr(), activePrincipal,
                                                     request.getDavSession(), archivaLocator, this, mimeTypes,
                                                     auditListeners, consumers );
-                        availableResources.add( 0, metadataChecksumResource );
                     }
                 }
                 else
-                {   // merge the metadata of all repos under group
-                    ArchivaRepositoryMetadata mergedMetadata = new ArchivaRepositoryMetadata();
-                    for ( String resourceAbsPath : resourcesInAbsolutePath )    
-                    {   
+                {
+                    if ( resourcesInAbsolutePath != null && resourcesInAbsolutePath.size() > 1 )
+                    {
+                        // merge the metadata of all repos under group
+                        ArchivaRepositoryMetadata mergedMetadata = new ArchivaRepositoryMetadata();
+                        for ( String resourceAbsPath : resourcesInAbsolutePath )
+                        {
+                            try
+                            {
+                                File metadataFile = new File( resourceAbsPath );
+                                ArchivaRepositoryMetadata repoMetadata = RepositoryMetadataReader.read( metadataFile );
+                                mergedMetadata = RepositoryMetadataMerge.merge( mergedMetadata, repoMetadata );
+                            }
+                            catch ( RepositoryMetadataException r )
+                            {
+                                throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                                        "Error occurred while reading metadata file." );
+                            }
+                        }
+
                         try
-                        {   
-                            File metadataFile = new File( resourceAbsPath );
-                            ArchivaRepositoryMetadata repoMetadata = RepositoryMetadataReader.read( metadataFile );
-                            mergedMetadata = RepositoryMetadataMerge.merge( mergedMetadata, repoMetadata );
+                        {
+                            File resourceFile = writeMergedMetadataToFile( mergedMetadata, filePath );
+
+                            LogicalResource logicalResource =
+                                new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) );
+
+                            resource =
+                                new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(),
+                                                        null, request.getRemoteAddr(), activePrincipal,
+                                                        request.getDavSession(), archivaLocator, this, mimeTypes,
+                                                        auditListeners, consumers );
                         }
                         catch ( RepositoryMetadataException r )
                         {
                             throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-                                                    "Error occurred while reading metadata file." );
-                        }                
-                    }        
-                    
-                    try
-                    {   
-                        File resourceFile = writeMergedMetadataToFile( mergedMetadata, filePath );   
-                        
-                        LogicalResource logicalResource =
-                            new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) );
-                                        
-                        String activePrincipal = getActivePrincipal( request );
-
-                        ArchivaDavResource metadataResource =
-                            new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(), null,
-                                                    request.getRemoteAddr(), activePrincipal, request.getDavSession(),
-                                                    archivaLocator, this, mimeTypes, auditListeners, consumers );
-                        availableResources.add( 0, metadataResource );
-                    }
-                    catch ( RepositoryMetadataException r )
-                    {                
-                        throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-                                                "Error occurred while writing metadata file." );
-                    }
-                    catch ( IOException ie )
-                    {
-                        throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-                            "Error occurred while generating checksum files." );
-                    }
-                    catch ( DigesterException de )
-                    {
-                        throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-                            "Error occurred while generating checksum files." );
+                                                    "Error occurred while writing metadata file." );
+                        }
+                        catch ( IOException ie )
+                        {
+                            throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                                    "Error occurred while generating checksum files." );
+                        }
+                        catch ( DigesterException de )
+                        {
+                            throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                                    "Error occurred while generating checksum files." );
+                        }
                     }
                 }
             }
         }
-                
-        DavResource resource = availableResources.get( 0 );               
-        setHeaders(response, locator, resource );
+
+        setHeaders( response, locator, resource );
 
         // compatibility with MRM-440 to ensure browsing the repository works ok
-        if ( resource.isCollection() && !request.getRequestURI().endsWith("/" ) )
+        if ( resource.isCollection() && !request.getRequestURI().endsWith( "/" ) )
         {
             throw new BrowserRedirectException( resource.getHref() );
         }
-        resource.addLockManager(lockManager);
+        resource.addLockManager( lockManager );
         return resource;
     }
 
-    public DavResource createResource( final DavResourceLocator locator, final DavSession davSession )
+    private DavResource processRepositoryGroup( final DavResourceLocator locator, final DavServletRequest request,
+                                                ArchivaDavResourceLocator archivaLocator, List<String> repositories,
+                                                String activePrincipal, boolean readMethod,
+                                                List<String> resourcesInAbsolutePath )
         throws DavException
     {
-        checkLocatorIsInstanceOfRepositoryLocator( locator );
-        ArchivaDavResourceLocator archivaLocator = (ArchivaDavResourceLocator) locator;
-
         DavResource resource = null;
-        if ( !locator.getResourcePath().startsWith( ArchivaDavResource.HIDDEN_PATH_PREFIX ) )
-        {
-            ManagedRepositoryContent managedRepository = getManagedRepository( archivaLocator.getRepositoryId() );
-            String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() );
-            File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource );
-            resource =
-                new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource,
-                                        managedRepository.getRepository(), davSession, archivaLocator, this, mimeTypes,
-                                        auditListeners, consumers );
-        }
-        resource.addLockManager(lockManager);
-        return resource;
-    }
+        DavException storedException = null;
 
-    private DavResource doGet( ManagedRepositoryContent managedRepository, DavServletRequest request,
-                               ArchivaDavResourceLocator locator, LogicalResource logicalResource )
-        throws DavException
-    {
-        File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
-        
-        //MRM-893, dont send back a file when user intentionally wants a directory
-        if ( locator.getHref( false ).endsWith( "/" ) )
+        for ( String repositoryId : repositories )
         {
-            if ( ! resourceFile.isDirectory() )
-            {
-                //force a resource not found 
-                return null;
-            }
-        }
-
-        String activePrincipal = getActivePrincipal( request );
-
-        ArchivaDavResource resource =
-            new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(),
-                                    managedRepository.getRepository(), request.getRemoteAddr(), activePrincipal,
-                                    request.getDavSession(), locator, this, mimeTypes, auditListeners, consumers );
-
-        if ( !resource.isCollection() )
-        {
-            boolean previouslyExisted = resourceFile.exists();
-
-            // At this point the incoming request can either be in default or
-            // legacy layout format.
-            boolean fromProxy = fetchContentFromProxies( managedRepository, request, logicalResource );
+            ManagedRepositoryContent managedRepository = null;
 
             try
             {
-                // Perform an adjustment of the resource to the managed
-                // repository expected path.
-                String localResourcePath =
-                    repositoryRequest.toNativePath( logicalResource.getPath(), managedRepository );
-                resourceFile = new File( managedRepository.getRepoRoot(), localResourcePath );
+                managedRepository = repositoryFactory.getManagedRepositoryContent( repositoryId );
+            }
+            catch ( RepositoryNotFoundException e )
+            {
+                throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
             }
-            catch ( LayoutException e )
+            catch ( RepositoryException e )
+            {
+                throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
+            }
+
+            try
             {
-                if ( previouslyExisted )
+                DavResource resource1 =
+                    processRepository( locator, request, archivaLocator, readMethod, activePrincipal, repositoryId,
+                                       managedRepository );
+                if ( resource == null )
                 {
-                    return resource;
+                    resource = resource1;
                 }
-                throw new DavException( HttpServletResponse.SC_NOT_FOUND, e );
-            }
 
-            // Attempt to fetch the resource from any defined proxy.
-            if ( fromProxy )
+                String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() );
+                resourcesInAbsolutePath.add( managedRepository.getRepoRoot() + logicalResource );
+            }
+            catch ( DavException e )
             {
-                String repositoryId = locator.getRepositoryId();
-                String event = ( previouslyExisted ? AuditEvent.MODIFY_FILE : AuditEvent.CREATE_FILE ) + PROXIED_SUFFIX;
-                triggerAuditEvent( request.getRemoteAddr(), repositoryId, logicalResource.getPath(), event,
-                                   activePrincipal );
+                storedException = e;
             }
+        }
 
-            if ( !resourceFile.exists() )
+        if ( resource == null )
+        {
+            if ( storedException != null )
             {
-                resource = null;
+                throw storedException;
             }
             else
             {
-                resource =
-                    new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(),
-                                            managedRepository.getRepository(), request.getRemoteAddr(),
-                                            activePrincipal, request.getDavSession(), locator, this, mimeTypes,
-                                            auditListeners, consumers );
+                throw new DavException( HttpServletResponse.SC_NOT_FOUND );
             }
         }
         return resource;
     }
 
-    private DavResource doPut( ManagedRepositoryContent managedRepository, DavServletRequest request,
-                               ArchivaDavResourceLocator locator, LogicalResource logicalResource )
+    private DavResource processRepository( final DavResourceLocator locator, final DavServletRequest request,
+                                           ArchivaDavResourceLocator archivaLocator, boolean readMethod,
+                                           String activePrincipal, String repositoryId,
+                                           ManagedRepositoryContent managedRepository )
         throws DavException
     {
-        /*
-         * Create parent directories that don't exist when writing a file This actually makes this implementation not
-         * compliant to the WebDAV RFC - but we have enough knowledge about how the collection is being used to do this
-         * reasonably and some versions of Maven's WebDAV don't correctly create the collections themselves.
-         */
-
-        File rootDirectory = new File( managedRepository.getRepoRoot() );
-        File destDir = new File( rootDirectory, logicalResource.getPath() ).getParentFile();
-        
-        String activePrincipal = getActivePrincipal( request );
+        DavResource resource = null;
+        if ( isAuthorized( request, repositoryId ) )
+        {
+            LogicalResource logicalResource =
+                new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) );
+
+            File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
+            resource =
+                new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(),
+                                        managedRepository.getRepository(), request.getRemoteAddr(), activePrincipal,
+                                        request.getDavSession(), archivaLocator, this, mimeTypes, auditListeners,
+                                        consumers );
+
+            if ( readMethod )
+            {
+                if ( archivaLocator.getHref( false ).endsWith( "/" ) && !resourceFile.isDirectory() )
+                {
+                    // force a resource not found
+                    throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Resource does not exist" );
+                }
+                else
+                {
+                    if ( !resource.isCollection() )
+                    {
+                        boolean previouslyExisted = resourceFile.exists();
+
+                        // Attempt to fetch the resource from any defined proxy.
+                        boolean fromProxy = fetchContentFromProxies( managedRepository, request, logicalResource );
 
-        if ( request.getMethod().equals(HTTP_PUT_METHOD) && !destDir.exists() )
+                        // At this point the incoming request can either be in default or
+                        // legacy layout format.
+                        try
+                        {
+                            // Perform an adjustment of the resource to the managed
+                            // repository expected path.
+                            String localResourcePath =
+                                repositoryRequest.toNativePath( logicalResource.getPath(), managedRepository );
+                            resourceFile = new File( managedRepository.getRepoRoot(), localResourcePath );
+                            resource =
+                                new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(),
+                                                        managedRepository.getRepository(), request.getRemoteAddr(),
+                                                        activePrincipal, request.getDavSession(), archivaLocator, this,
+                                                        mimeTypes, auditListeners, consumers );
+                        }
+                        catch ( LayoutException e1 )
+                        {
+                            if ( !resourceFile.exists() )
+                            {
+                                throw new DavException( HttpServletResponse.SC_NOT_FOUND, e1 );
+                            }
+                        }
+
+                        if ( fromProxy )
+                        {
+                            String repositoryId1 = archivaLocator.getRepositoryId();
+                            String event =
+                                ( previouslyExisted ? AuditEvent.MODIFY_FILE : AuditEvent.CREATE_FILE )
+                                    + PROXIED_SUFFIX;
+                            triggerAuditEvent( request.getRemoteAddr(), repositoryId1, logicalResource.getPath(),
+                                               event, activePrincipal );
+                        }
+
+                        if ( !resourceFile.exists() )
+                        {
+                            throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Resource does not exist" );
+                        }
+                    }
+                }
+            }
+
+            if ( request.getMethod().equals( HTTP_PUT_METHOD ) )
+            {
+                /*
+                 * Create parent directories that don't exist when writing a file This actually makes this
+                 * implementation not compliant to the WebDAV RFC - but we have enough knowledge about how the
+                 * collection is being used to do this reasonably and some versions of Maven's WebDAV don't correctly
+                 * create the collections themselves.
+                 */
+
+                File rootDirectory = new File( managedRepository.getRepoRoot() );
+                File destDir = new File( rootDirectory, logicalResource.getPath() ).getParentFile();
+
+                if ( !destDir.exists() )
+                {
+                    destDir.mkdirs();
+                    String relPath = PathUtil.getRelative( rootDirectory.getAbsolutePath(), destDir );
+                    triggerAuditEvent( request.getRemoteAddr(), logicalResource.getPath(), relPath,
+                                       AuditEvent.CREATE_DIR, activePrincipal );
+                }
+            }
+        }
+        return resource;
+    }
+
+    public DavResource createResource( final DavResourceLocator locator, final DavSession davSession )
+        throws DavException
+    {
+        ArchivaDavResourceLocator archivaLocator = checkLocatorIsInstanceOfRepositoryLocator( locator );
+
+        ManagedRepositoryContent managedRepository;
+        try
         {
-            destDir.mkdirs();
-            String relPath = PathUtil.getRelative( rootDirectory.getAbsolutePath(), destDir );
-            triggerAuditEvent( request.getRemoteAddr(), logicalResource.getPath(), relPath, AuditEvent.CREATE_DIR,
-                               activePrincipal );
-        }
-        
-        File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );        
-                
-        return new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(),
-                                       managedRepository.getRepository(), request.getRemoteAddr(), activePrincipal,
-                                       request.getDavSession(), locator, this, mimeTypes, auditListeners, consumers );
+            managedRepository = repositoryFactory.getManagedRepositoryContent( archivaLocator.getRepositoryId() );
+        }
+        catch ( RepositoryNotFoundException e )
+        {
+            throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Invalid repository: "
+                + archivaLocator.getRepositoryId() );
+        }
+        catch ( RepositoryException e )
+        {
+            throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
+        }
+
+        String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() );
+        File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource );
+        DavResource resource =
+            new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource, managedRepository.getRepository(),
+                                    davSession, archivaLocator, this, mimeTypes, auditListeners, consumers );
+
+        resource.addLockManager( lockManager );
+        return resource;
     }
 
     private boolean fetchContentFromProxies( ManagedRepositoryContent managedRepository, DavServletRequest request,
@@ -519,7 +532,7 @@
         // Is it a Metadata resource?
         if ( repositoryRequest.isDefault( resource.getPath() ) && repositoryRequest.isMetadata( resource.getPath() ) )
         {
-            return connectors.fetchMetatadaFromProxies(managedRepository, resource.getPath()) != null;
+            return connectors.fetchMetatadaFromProxies( managedRepository, resource.getPath() ) != null;
         }
 
         // Not any of the above? Then it's gotta be an artifact reference.
@@ -596,7 +609,7 @@
             }
             finally
             {
-                if (reader != null)
+                if ( reader != null )
                 {
                     reader.close();
                 }
@@ -676,44 +689,38 @@
             response.addHeader( "Cache-Control", "no-cache" );
         }
 
-        //We need to specify this so connecting wagons can work correctly
-        response.addDateHeader("last-modified", resource.getModificationTime());
+        // We need to specify this so connecting wagons can work correctly
+        response.addDateHeader( "last-modified", resource.getModificationTime() );
 
         // TODO: [MRM-524] determine http caching options for other types of files (artifacts, sha1, md5, snapshots)
     }
 
-    private ManagedRepositoryContent getManagedRepository( String respositoryId )
+    private ArchivaDavResourceLocator checkLocatorIsInstanceOfRepositoryLocator( DavResourceLocator locator )
         throws DavException
     {
-        if ( respositoryId != null )
+        if ( !( locator instanceof ArchivaDavResourceLocator ) )
         {
-            try
-            {
-                return repositoryFactory.getManagedRepositoryContent( respositoryId );
-            }
-            catch ( RepositoryNotFoundException e )
-            {
-                throw new DavException( HttpServletResponse.SC_NOT_FOUND, e );
-            }
-            catch ( RepositoryException e )
-            {
-                throw new DavException( HttpServletResponse.SC_NOT_FOUND, e );
-            }
+            throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                    "Locator does not implement RepositoryLocator" );
         }
-        return null;
-    }
 
-    private void checkLocatorIsInstanceOfRepositoryLocator( DavResourceLocator locator )
-        throws DavException
-    {
-        if ( !( locator instanceof RepositoryLocator ) )
+        // Hidden paths
+        if ( locator.getResourcePath().startsWith( ArchivaDavResource.HIDDEN_PATH_PREFIX ) )
         {
-            throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-                                    "Locator does not implement RepositoryLocator" );
+            throw new DavException( HttpServletResponse.SC_NOT_FOUND );
+        }
+
+        ArchivaDavResourceLocator archivaLocator = (ArchivaDavResourceLocator) locator;
+
+        // MRM-419 - Windows Webdav support. Should not 404 if there is no content.
+        if ( StringUtils.isEmpty( archivaLocator.getRepositoryId() ) )
+        {
+            throw new DavException( HttpServletResponse.SC_NO_CONTENT );
         }
+        return archivaLocator;
     }
 
-    class LogicalResource
+    private static class LogicalResource
     {
         private String path;
 
@@ -735,36 +742,36 @@
 
     protected boolean isAuthorized( DavServletRequest request, String repositoryId )
         throws DavException
-    {   
+    {
         try
-        {     
+        {
             AuthenticationResult result = httpAuth.getAuthenticationResult( request, null );
             SecuritySession securitySession = httpAuth.getSecuritySession( request.getSession( true ) );
 
-            return servletAuth.isAuthenticated( request, result ) &&
-                servletAuth.isAuthorized( request, securitySession, repositoryId,
-                                          WebdavMethodUtil.isWriteMethod( request.getMethod() ) );
+            return servletAuth.isAuthenticated( request, result )
+                && servletAuth.isAuthorized( request, securitySession, repositoryId,
+                                             WebdavMethodUtil.getMethodPermission( request.getMethod() ) );
         }
         catch ( AuthenticationException e )
-        {            
-            boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
-            
-            // safety check for MRM-911            
+        {
+            // safety check for MRM-911
             String guest = UserManager.GUEST_USERNAME;
             try
             {
-                if( servletAuth.isAuthorized( guest, 
-                      ( ( ArchivaDavResourceLocator ) request.getRequestLocator() ).getRepositoryId(), isPut ) )
-                {   
+                if ( servletAuth.isAuthorized(
+                                               guest,
+                                               ( (ArchivaDavResourceLocator) request.getRequestLocator() ).getRepositoryId(),
+                                               WebdavMethodUtil.getMethodPermission( request.getMethod() ) ) )
+                {
                     return true;
                 }
             }
             catch ( UnauthorizedException ae )
             {
                 throw new UnauthorizedDavException( repositoryId,
-                        "You are not authenticated and authorized to access any repository." );
+                                                    "You are not authenticated and authorized to access any repository." );
             }
-                        
+
             throw new UnauthorizedDavException( repositoryId, "You are not authenticated" );
         }
         catch ( MustChangePasswordException e )
@@ -786,7 +793,8 @@
         }
     }
 
-    private DavResource getResource( DavServletRequest request, List<String> repositories, ArchivaDavResourceLocator locator )
+    private DavResource getResource( DavServletRequest request, List<String> repositories,
+                                     ArchivaDavResourceLocator locator )
         throws DavException
     {
         List<File> mergedRepositoryContents = new ArrayList<File>();
@@ -799,43 +807,67 @@
         // otherwise, prompt for authentication.
 
         String activePrincipal = getActivePrincipal( request );
-        
+
         boolean allow = isAllowedToContinue( request, repositories, activePrincipal );
 
-        if( allow )
+        if ( allow )
         {
-            boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
-            
-            for( String repository : repositories )
+            for ( String repository : repositories )
             {
-                // for prompted authentication
-                if( httpAuth.getSecuritySession( request.getSession( true ) ) != null )
+                ManagedRepositoryContent managedRepository = null;
+
+                try
                 {
-                    try
-                    {
-                        if( isAuthorized( request, repository ) )
-                        {
-                            getResource( locator, mergedRepositoryContents, logicalResource, repository );
-                        }
-                    }
-                    catch ( DavException e )
-                    {
-                        continue;
-                    }
+                    managedRepository = repositoryFactory.getManagedRepositoryContent( repository );
                 }
-                else
+                catch ( RepositoryNotFoundException e )
+                {
+                    throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                            "Invalid managed repository <" + repository + ">: " + e.getMessage() );
+                }
+                catch ( RepositoryException e )
+                {
+                    throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+                                            "Invalid managed repository <" + repository + ">: " + e.getMessage() );
+                }
+
+                File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
+                if ( resourceFile.exists() )
                 {
-                    // for the current user logged in
-                    try
+                    // for prompted authentication
+                    if ( httpAuth.getSecuritySession( request.getSession( true ) ) != null )
                     {
-                        if( servletAuth.isAuthorized( activePrincipal, repository, isPut ) )
+                        try
+                        {
+                            if ( isAuthorized( request, repository ) )
+                            {
+                                mergedRepositoryContents.add( resourceFile );
+                            }
+                        }
+                        catch ( DavException e )
                         {
-                            getResource( locator, mergedRepositoryContents, logicalResource, repository );
+                            // TODO: review exception handling
+                            log.debug( "Skipping repository '" + managedRepository + "' for user '" + activePrincipal
+                                + "': " + e.getMessage() );
                         }
                     }
-                    catch ( UnauthorizedException e )
+                    else
                     {
-                        continue;
+                        // for the current user logged in
+                        try
+                        {
+                            if ( servletAuth.isAuthorized( activePrincipal, repository,
+                                                           WebdavMethodUtil.getMethodPermission( request.getMethod() ) ) )
+                            {
+                                mergedRepositoryContents.add( resourceFile );
+                            }
+                        }
+                        catch ( UnauthorizedException e )
+                        {
+                            // TODO: review exception handling
+                            log.debug( "Skipping repository '" + managedRepository + "' for user '" + activePrincipal
+                                + "': " + e.getMessage() );
+                        }
                     }
                 }
             }
@@ -846,10 +878,11 @@
         }
 
         ArchivaVirtualDavResource resource =
-            new ArchivaVirtualDavResource( mergedRepositoryContents, logicalResource.getPath(), mimeTypes, locator, this );
+            new ArchivaVirtualDavResource( mergedRepositoryContents, logicalResource.getPath(), mimeTypes, locator,
+                                           this );
 
         // compatibility with MRM-440 to ensure browsing the repository group works ok
-        if ( resource.isCollection() && !request.getRequestURI().endsWith("/" ) )
+        if ( resource.isCollection() && !request.getRequestURI().endsWith( "/" ) )
         {
             throw new BrowserRedirectException( resource.getHref() );
         }
@@ -863,38 +896,9 @@
         return sessionUser != null ? sessionUser.getUsername() : UserManager.GUEST_USERNAME;
     }
 
-    private void getResource( ArchivaDavResourceLocator locator, List<File> mergedRepositoryContents,
-                              LogicalResource logicalResource, String repository )
-        throws DavException
-    {
-        ManagedRepositoryContent managedRepository = null;
-
-        try
-        {
-            managedRepository = getManagedRepository( repository );
-        }
-        catch ( DavException de )
-        {
-            throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Invalid managed repository <" +
-                repository + ">" );
-        }
-
-        if ( !locator.getResourcePath().startsWith( ArchivaVirtualDavResource.HIDDEN_PATH_PREFIX ) )
-        {
-            if( managedRepository != null )
-            {
-                File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() );
-                if( resourceFile.exists() )
-                {
-                    mergedRepositoryContents.add( resourceFile );
-                }
-            }
-        }
-    }
-
     /**
      * Check if the current user is authorized to access any of the repos
-     *
+     * 
      * @param request
      * @param repositories
      * @param activePrincipal
@@ -904,21 +908,20 @@
     {
         boolean allow = false;
 
-
         // if securitySession != null, it means that the user was prompted for authentication
-        if( httpAuth.getSecuritySession( request.getSession() ) != null )
+        if ( httpAuth.getSecuritySession( request.getSession() ) != null )
         {
-            for( String repository : repositories )
+            for ( String repository : repositories )
             {
                 try
                 {
-                    if( isAuthorized( request, repository ) )
+                    if ( isAuthorized( request, repository ) )
                     {
                         allow = true;
                         break;
                     }
                 }
-                catch( DavException e )
+                catch ( DavException e )
                 {
                     continue;
                 }
@@ -926,12 +929,12 @@
         }
         else
         {
-            boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
-            for( String repository : repositories )
+            for ( String repository : repositories )
             {
                 try
-                {   
-                    if( servletAuth.isAuthorized( activePrincipal, repository, isPut ) )
+                {
+                    if ( servletAuth.isAuthorized( activePrincipal, repository,
+                                                   WebdavMethodUtil.getMethodPermission( request.getMethod() ) ) )
                     {
                         allow = true;
                         break;
@@ -949,55 +952,55 @@
 
     private File writeMergedMetadataToFile( ArchivaRepositoryMetadata mergedMetadata, String outputFilename )
         throws RepositoryMetadataException, DigesterException, IOException
-    {  
-        File outputFile = new File( outputFilename );        
-        if( outputFile.exists() )
+    {
+        File outputFile = new File( outputFilename );
+        if ( outputFile.exists() )
         {
             FileUtils.deleteQuietly( outputFile );
         }
-        
+
         outputFile.getParentFile().mkdirs();
         RepositoryMetadataWriter.write( mergedMetadata, outputFile );
-        
+
         createChecksumFile( outputFilename, digestSha1 );
         createChecksumFile( outputFilename, digestMd5 );
-        
+
         return outputFile;
     }
-    
+
     private void createChecksumFile( String path, Digester digester )
         throws DigesterException, IOException
-    {   
-        File checksumFile = new File( path + digester.getFilenameExtension() );        
+    {
+        File checksumFile = new File( path + digester.getFilenameExtension() );
         if ( !checksumFile.exists() )
         {
             FileUtils.deleteQuietly( checksumFile );
-            checksum.createChecksum( new File( path ), digester );            
+            checksum.createChecksum( new File( path ), digester );
         }
         else if ( !checksumFile.isFile() )
         {
             log.error( "Checksum file is not a file." );
         }
     }
-    
+
     private boolean isProjectReference( String requestedResource )
-    {  
-       try
-       {           
-           metadataTools.toVersionedReference( requestedResource );           
-           return false;
-       }
-       catch ( RepositoryMetadataException re )
-       {
-           return true;
-       }
+    {
+        try
+        {
+            metadataTools.toVersionedReference( requestedResource );
+            return false;
+        }
+        catch ( RepositoryMetadataException re )
+        {
+            return true;
+        }
     }
-    
+
     public void setServletAuth( ServletAuthenticator servletAuth )
     {
         this.servletAuth = servletAuth;
     }
-    
+
     public void setHttpAuth( HttpAuthenticator httpAuth )
     {
         this.httpAuth = httpAuth;

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProvider.java Thu Mar 19 06:10:38 2009
@@ -66,16 +66,15 @@
         }
         catch ( AuthenticationException e )
         {   
-            boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() );
-            
             // safety check for MRM-911            
             String guest = UserManager.GUEST_USERNAME;
             try
             {
-                if( servletAuth.isAuthorized( guest, 
-                      ( ( ArchivaDavResourceLocator ) request.getRequestLocator() ).getRepositoryId(), isPut ) )
+                if ( servletAuth.isAuthorized( guest,
+                                               ( (ArchivaDavResourceLocator) request.getRequestLocator() ).getRepositoryId(),
+                                               WebdavMethodUtil.getMethodPermission( request.getMethod() ) ) )
                 {
-                    request.setDavSession(new ArchivaDavSession());
+                    request.setDavSession( new ArchivaDavSession() );
                     return true;
                 }
             }

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaVirtualDavResource.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaVirtualDavResource.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaVirtualDavResource.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaVirtualDavResource.java Thu Mar 19 06:10:38 2009
@@ -59,8 +59,6 @@
 public class ArchivaVirtualDavResource
     implements DavResource
 {
-    public static final String HIDDEN_PATH_PREFIX = ".";
-    
     private static final String COMPLIANCE_CLASS = "1";
 
     private ArchivaDavResourceLocator locator;

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WebdavMethodUtil.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WebdavMethodUtil.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WebdavMethodUtil.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/util/WebdavMethodUtil.java Thu Mar 19 06:10:38 2009
@@ -20,13 +20,15 @@
  */
 
 import org.apache.commons.lang.StringUtils;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 
 /**
- * WebdavMethodUtil 
- *
+ * WebdavMethodUtil
+ * 
  * @version $Id: WebdavMethodUtil.java 5412 2007-01-13 01:18:47Z joakime $
  */
 public class WebdavMethodUtil
@@ -43,23 +45,32 @@
         READ_METHODS.add( "REPORT" );
     }
 
-    public static boolean isReadMethod( String method )
+    public static String getMethodPermission( String method )
     {
         if ( StringUtils.isBlank( method ) )
         {
-            return false;
+            throw new IllegalArgumentException( "WebDAV method is empty" );
+        }
+        if ( READ_METHODS.contains( method.toUpperCase( Locale.US ) ) )
+        {
+            return ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS;
+        }
+        else if ( "DELETE".equals( method.toUpperCase( Locale.US ) ) )
+        {
+            return ArchivaRoleConstants.OPERATION_REPOSITORY_DELETE;
+        }
+        else
+        {
+            return ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD;
         }
-
-        return READ_METHODS.contains( method.toUpperCase() );
     }
 
-    public static boolean isWriteMethod( String method )
+    public static boolean isReadMethod( String method )
     {
         if ( StringUtils.isBlank( method ) )
         {
-            return false;
+            throw new IllegalArgumentException( "WebDAV method is empty" );
         }
-
-        return !READ_METHODS.contains( method.toUpperCase() );
+        return READ_METHODS.contains( method.toUpperCase( Locale.US ) );
     }
 }

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/AbstractRepositoryServletTestCase.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/AbstractRepositoryServletTestCase.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/AbstractRepositoryServletTestCase.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/AbstractRepositoryServletTestCase.java Thu Mar 19 06:10:38 2009
@@ -97,6 +97,13 @@
             .getResponseCode() );
     }
 
+    protected void assertResponseInternalServerError( WebResponse response )
+    {
+        assertNotNull( "Should have recieved a response", response );
+        Assert.assertEquals( "Should have been an 500/Internal Server Error response code.", HttpServletResponse.SC_INTERNAL_SERVER_ERROR, response
+            .getResponseCode() );
+    }
+
     protected ManagedRepositoryConfiguration createManagedRepository( String id, String name, File location )
     {
         ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration();

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProviderTest.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProviderTest.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProviderTest.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/ArchivaDavSessionProviderTest.java Thu Mar 19 06:10:38 2009
@@ -360,13 +360,14 @@
             return true;
         }
 
-        public boolean isAuthorized(HttpServletRequest arg0, SecuritySession arg1, String arg2, boolean arg3)
+        public boolean isAuthorized( HttpServletRequest request, SecuritySession securitySession, String repositoryId,
+                                     String permission )
             throws AuthorizationException, UnauthorizedException
         {
             return true;
         }
 
-        public boolean isAuthorized(String arg0, String arg1, boolean isWriteRequest)
+        public boolean isAuthorized( String principal, String repoId, String permission )
             throws UnauthorizedException
         {
             return true;

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/MockServletAuthenticator.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/MockServletAuthenticator.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/MockServletAuthenticator.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/MockServletAuthenticator.java Thu Mar 19 06:10:38 2009
@@ -26,7 +26,7 @@
     extends ArchivaServletAuthenticator
 {
     @Override
-    public boolean isAuthorized( String principal, String repoId, boolean isWriteRequest )
+    public boolean isAuthorized( String principal, String repoId, String permission )
         throws UnauthorizedException
     {
         return true;

Modified: archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletRepositoryGroupTest.java
URL: http://svn.apache.org/viewvc/archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletRepositoryGroupTest.java?rev=755845&r1=755844&r2=755845&view=diff
==============================================================================
--- archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletRepositoryGroupTest.java (original)
+++ archiva/trunk/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletRepositoryGroupTest.java Thu Mar 19 06:10:38 2009
@@ -193,7 +193,7 @@
         WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/" + REPO_GROUP_WITH_INVALID_REPOS + "/" + resourceName );
         WebResponse response = sc.getResponse( request );
         
-        assertResponseNotFound( response );
+        assertResponseInternalServerError( response );
     }
     
     /*