]> source.dussan.org Git - archiva.git/commitdiff
clean up the webdav interface to make the code more readable
authorBrett Porter <brett@apache.org>
Thu, 19 Mar 2009 06:10:38 +0000 (06:10 +0000)
committerBrett Porter <brett@apache.org>
Thu, 19 Mar 2009 06:10:38 +0000 (06:10 +0000)
in addition, webdav now honours the delete operation separately to upload
improved the HTTP error responses for misconfiguration (500) vs not found on groups

git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@755845 13f79535-47bb-0310-9956-ffa450edef68

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

index 1b533d30fb0b4c01667241c9b92ea900a88d783c..40d7a796a10b04fa30f65fadcfa560468236168c 100644 (file)
@@ -62,27 +62,19 @@ public class ArchivaServletAuthenticator
     }
 
     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 @@ public class ArchivaServletAuthenticator
         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 )
             {
index 5488f139d837009dbda1a937b21ef51449611385..ea9cc0d667ebbe3b764a9612ea3d5ee6a49992dc 100644 (file)
@@ -59,7 +59,7 @@ public interface ServletAuthenticator
      * @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 @@ public interface ServletAuthenticator
      * @return
      * @throws UnauthorizedException
      */
-    public boolean isAuthorized( String principal, String repoId, boolean isWriteRequest )
+    public boolean isAuthorized( String principal, String repoId, String permission )
         throws UnauthorizedException;
 }
index 19e36929a45e909284379b917693d4b7ae204dd3..89f72848a8bc47e9e16ab5abdbf228fba14acc64 100644 (file)
@@ -27,7 +27,7 @@ import org.codehaus.plexus.redback.authorization.UnauthorizedException;
 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 @@ import org.easymock.MockControl;
  */
 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 @@ public class ArchivaServletAuthenticatorTest
         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 );
     }
 }
index 091489761024e374fd2346faa045bf2107de9cc1..1480645b8ffc1af4d9e1ff1d45678d40cdb27d06 100644 (file)
@@ -38,6 +38,7 @@ import org.apache.commons.codec.binary.Base64;
 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 @@ public class RssFeedServlet
                 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;
                 }
index 54fb20e500c41521dd60d237cae1914edaaba740..96effbba6edbbe4e9a85fbdc2c80d5c6df5dbae5 100644 (file)
@@ -91,7 +91,7 @@ import org.slf4j.LoggerFactory;
  */
 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 @@ public class ArchivaDavResourceFactory
      */
     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 @@ public class ArchivaDavResourceFactory
      * @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 ) )
+
+                // 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() )
+                    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 ) )
+        DavException storedException = null;
+
+        for ( String repositoryId : repositories )
         {
-            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 );
+            ManagedRepositoryContent managedRepository = null;
+
+            try
+            {
+                managedRepository = repositoryFactory.getManagedRepositoryContent( repositoryId );
+            }
+            catch ( RepositoryNotFoundException e )
+            {
+                throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
+            }
+            catch ( RepositoryException e )
+            {
+                throw new DavException( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e );
+            }
+
+            try
+            {
+                DavResource resource1 =
+                    processRepository( locator, request, archivaLocator, readMethod, activePrincipal, repositoryId,
+                                       managedRepository );
+                if ( resource == null )
+                {
+                    resource = resource1;
+                }
+
+                String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() );
+                resourcesInAbsolutePath.add( managedRepository.getRepoRoot() + logicalResource );
+            }
+            catch ( DavException e )
+            {
+                storedException = e;
+            }
         }
-        resource.addLockManager(lockManager);
-        return resource;
-    }
 
-    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( "/" ) )
+        if ( resource == null )
         {
-            if ( ! resourceFile.isDirectory() )
+            if ( storedException != null )
+            {
+                throw storedException;
+            }
+            else
             {
-                //force a resource not found 
-                return null;
+                throw new DavException( HttpServletResponse.SC_NOT_FOUND );
             }
         }
+        return resource;
+    }
 
-        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() )
+    private DavResource processRepository( final DavResourceLocator locator, final DavServletRequest request,
+                                           ArchivaDavResourceLocator archivaLocator, boolean readMethod,
+                                           String activePrincipal, String repositoryId,
+                                           ManagedRepositoryContent managedRepository )
+        throws DavException
+    {
+        DavResource resource = null;
+        if ( isAuthorized( request, repositoryId ) )
         {
-            boolean previouslyExisted = resourceFile.exists();
+            LogicalResource logicalResource =
+                new LogicalResource( RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ) );
 
-            // At this point the incoming request can either be in default or
-            // legacy layout format.
-            boolean fromProxy = fetchContentFromProxies( managedRepository, request, logicalResource );
+            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 );
 
-            try
+            if ( readMethod )
             {
-                // 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 );
-            }
-            catch ( LayoutException e )
-            {
-                if ( previouslyExisted )
+                if ( archivaLocator.getHref( false ).endsWith( "/" ) && !resourceFile.isDirectory() )
                 {
-                    return resource;
+                    // force a resource not found
+                    throw new DavException( HttpServletResponse.SC_NOT_FOUND, "Resource does not exist" );
                 }
-                throw new DavException( HttpServletResponse.SC_NOT_FOUND, e );
-            }
+                else
+                {
+                    if ( !resource.isCollection() )
+                    {
+                        boolean previouslyExisted = resourceFile.exists();
 
-            // Attempt to fetch the resource from any defined proxy.
-            if ( fromProxy )
-            {
-                String repositoryId = locator.getRepositoryId();
-                String event = ( previouslyExisted ? AuditEvent.MODIFY_FILE : AuditEvent.CREATE_FILE ) + PROXIED_SUFFIX;
-                triggerAuditEvent( request.getRemoteAddr(), repositoryId, logicalResource.getPath(), event,
-                                   activePrincipal );
-            }
+                        // Attempt to fetch the resource from any defined proxy.
+                        boolean fromProxy = fetchContentFromProxies( managedRepository, request, logicalResource );
 
-            if ( !resourceFile.exists() )
-            {
-                resource = null;
+                        // 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" );
+                        }
+                    }
+                }
             }
-            else
+
+            if ( request.getMethod().equals( HTTP_PUT_METHOD ) )
             {
-                resource =
-                    new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(),
-                                            managedRepository.getRepository(), request.getRemoteAddr(),
-                                            activePrincipal, request.getDavSession(), locator, this, mimeTypes,
-                                            auditListeners, consumers );
+                /*
+                 * 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;
     }
 
-    private DavResource doPut( ManagedRepositoryContent managedRepository, DavServletRequest request,
-                               ArchivaDavResourceLocator locator, LogicalResource logicalResource )
+    public DavResource createResource( final DavResourceLocator locator, final DavSession davSession )
         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 );
+        ArchivaDavResourceLocator archivaLocator = checkLocatorIsInstanceOfRepositoryLocator( locator );
 
-        if ( request.getMethod().equals(HTTP_PUT_METHOD) && !destDir.exists() )
+        ManagedRepositoryContent managedRepository;
+        try
         {
-            destDir.mkdirs();
-            String relPath = PathUtil.getRelative( rootDirectory.getAbsolutePath(), destDir );
-            triggerAuditEvent( request.getRemoteAddr(), logicalResource.getPath(), relPath, AuditEvent.CREATE_DIR,
-                               activePrincipal );
+            managedRepository = repositoryFactory.getManagedRepositoryContent( archivaLocator.getRepositoryId() );
         }
-        
-        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 );
+        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 @@ public class ArchivaDavResourceFactory
         // 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 @@ public class ArchivaDavResourceFactory
             }
             finally
             {
-                if (reader != null)
+                if ( reader != null )
                 {
                     reader.close();
                 }
@@ -676,44 +689,38 @@ public class ArchivaDavResourceFactory
             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 @@ public class ArchivaDavResourceFactory
 
     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 @@ public class ArchivaDavResourceFactory
         }
     }
 
-    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 @@ public class ArchivaDavResourceFactory
         // 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 @@ public class ArchivaDavResourceFactory
         }
 
         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 @@ public class ArchivaDavResourceFactory
         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 @@ public class ArchivaDavResourceFactory
     {
         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 @@ public class ArchivaDavResourceFactory
         }
         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 @@ public class ArchivaDavResourceFactory
 
     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;
index 6157f1cb80b0b67d75045cfa007d8a27877952e5..a5c447e8df7d93848d7056d8373b79a7b16139a2 100644 (file)
@@ -66,16 +66,15 @@ public class ArchivaDavSessionProvider
         }
         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;
                 }
             }
index 4bb3a140a05dacb7f90a018647003e09b112f625..47bd88d1573756c15a349e8407b1b99a68ac6d86 100644 (file)
@@ -59,8 +59,6 @@ import org.joda.time.format.ISODateTimeFormat;
 public class ArchivaVirtualDavResource
     implements DavResource
 {
-    public static final String HIDDEN_PATH_PREFIX = ".";
-    
     private static final String COMPLIANCE_CLASS = "1";
 
     private ArchivaDavResourceLocator locator;
index 9d488f7b6d61bca1a0fabdbc6cd1936129f7d77d..fad10e294be28687298492e55f54e4ebf9673a04 100644 (file)
@@ -20,13 +20,15 @@ package org.apache.maven.archiva.webdav.util;
  */
 
 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 @@ public class WebdavMethodUtil
         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 ) );
     }
 }
index 7f7b724b8e3fa405100802809eda9ca7ac6969bd..fe1a6be639bdf24dd4caad7c649713ede4dc3a10 100644 (file)
@@ -97,6 +97,13 @@ public abstract class AbstractRepositoryServletTestCase
             .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();
index 370b30ff6cfc195ff2759ed2e7a58258307a174d..c03e36ff238c08f19063e4386d6908f3f122dafc 100644 (file)
@@ -360,13 +360,14 @@ public class ArchivaDavSessionProviderTest extends TestCase
             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;
index 4ea71a929d98731be801aed229c84a4fc8e5fb45..0f1b8ab6adaf1519cafc8f894b93c7476ecf7757 100644 (file)
@@ -26,7 +26,7 @@ public class MockServletAuthenticator
     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;
index 47a94a9e36f55c89aed66df2e24093986c8b4343..13b8fc871841e49fe5a9bc0944ac5732af8d1692 100644 (file)
@@ -193,7 +193,7 @@ public class RepositoryServletRepositoryGroupTest
         WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/" + REPO_GROUP_WITH_INVALID_REPOS + "/" + resourceName );
         WebResponse response = sc.getResponse( request );
         
-        assertResponseNotFound( response );
+        assertResponseInternalServerError( response );
     }
     
     /*
index 4d29198a67c15c176d2c88ff3fb7308d4f01f4b8..f5a33ff49d992c01d9280c8aa3d8259f5ddf7f9e 100644 (file)
@@ -32,6 +32,7 @@ import org.apache.jackrabbit.webdav.DavSessionProvider;
 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
 import org.apache.maven.archiva.configuration.Configuration;
 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
+import org.apache.maven.archiva.security.ArchivaRoleConstants;
 import org.apache.maven.archiva.security.ArchivaXworkUser;
 import org.apache.maven.archiva.security.ServletAuthenticator;
 import org.codehaus.plexus.redback.authentication.AuthenticationException;
@@ -56,9 +57,7 @@ import com.meterware.servletunit.ServletRunner;
 import com.meterware.servletunit.ServletUnitClient;
 
 /**
- * RepositoryServletSecurityTest
- * 
- * Test the flow of the authentication and authorization checks. This does not necessarily
+ * RepositoryServletSecurityTest Test the flow of the authentication and authorization checks. This does not necessarily
  * perform redback security checking.
  * 
  * @version $Id$
@@ -87,7 +86,7 @@ public class RepositoryServletSecurityTest
     private HttpAuthenticator httpAuth;
 
     private RepositoryServlet servlet;
-    
+
     public void setUp()
         throws Exception
     {
@@ -126,7 +125,7 @@ public class RepositoryServletSecurityTest
 
         ArchivaXworkUser archivaXworkUser = (ArchivaXworkUser) lookup( ArchivaXworkUser.class );
 
-        davSessionProvider = new ArchivaDavSessionProvider( servletAuth, httpAuth, archivaXworkUser );      
+        davSessionProvider = new ArchivaDavSessionProvider( servletAuth, httpAuth, archivaXworkUser );
     }
 
     protected ManagedRepositoryConfiguration createManagedRepository( String id, String name, File location )
@@ -182,11 +181,11 @@ public class RepositoryServletSecurityTest
 
         if ( repoRootInternal.exists() )
         {
-            FileUtils.deleteDirectory(repoRootInternal);
+            FileUtils.deleteDirectory( repoRootInternal );
         }
 
         servlet = null;
-        
+
         super.tearDown();
     }
 
@@ -209,21 +208,21 @@ public class RepositoryServletSecurityTest
         AuthenticationResult result = new AuthenticationResult();
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
-                           new AuthenticationException( "Authentication error" ) );
-        
-        servletAuth.isAuthorized( "guest", "internal", true );        
+                                           new AuthenticationException( "Authentication error" ) );
+
+        servletAuth.isAuthorized( "guest", "internal", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
         servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
         servletAuthControl.setThrowable( new UnauthorizedException( "'guest' has no write access to repository" ) );
 
         httpAuthControl.replay();
         servletAuthControl.replay();
-        
+
         servlet.service( ic.getRequest(), ic.getResponse() );
-        
+
         httpAuthControl.verify();
         servletAuthControl.verify();
 
-        //assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
+        // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
     }
 
     // test deploy with invalid user, but guest has write access to repo
@@ -247,30 +246,30 @@ public class RepositoryServletSecurityTest
         archivaDavResourceFactory.setServletAuth( servletAuth );
 
         servlet.setResourceFactory( archivaDavResourceFactory );
-        
+
         AuthenticationResult result = new AuthenticationResult();
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
                                            new AuthenticationException( "Authentication error" ) );
-        
-        servletAuth.isAuthorized( "guest", "internal", true );
+
+        servletAuth.isAuthorized( "guest", "internal", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
         servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
         servletAuthControl.setReturnValue( true );
-                
-     // ArchivaDavResourceFactory#isAuthorized()
+
+        // ArchivaDavResourceFactory#isAuthorized()
         SecuritySession session = new DefaultSecuritySession();
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
-        httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true) ), session );
+        httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
         servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, result ),
                                            new AuthenticationException( "Authentication error" ) );
-        
+
         httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), null );
-        
+
         // check if guest has write access
-        servletAuth.isAuthorized( "guest", "internal", true );
+        servletAuth.isAuthorized( "guest", "internal", ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD );
         servletAuthControl.setMatcher( MockControl.EQUALS_MATCHER );
         servletAuthControl.setReturnValue( true );
-        
+
         httpAuthControl.replay();
         servletAuthControl.replay();
 
@@ -291,13 +290,13 @@ public class RepositoryServletSecurityTest
         String putUrl = "http://machine.com/repository/internal/path/to/artifact.jar";
         InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
         assertNotNull( "artifact.jar inputstream", is );
-        
+
         WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
-        
-        InvocationContext ic = sc.newInvocation( request ); 
+
+        InvocationContext ic = sc.newInvocation( request );
         servlet = (RepositoryServlet) ic.getServlet();
         servlet.setDavSessionProvider( davSessionProvider );
-        
+
         ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
         archivaDavResourceFactory.setHttpAuth( httpAuth );
         archivaDavResourceFactory.setServletAuth( servletAuth );
@@ -306,23 +305,26 @@ public class RepositoryServletSecurityTest
         AuthenticationResult result = new AuthenticationResult();
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
-        
-     // ArchivaDavResourceFactory#isAuthorized()
+
+        // ArchivaDavResourceFactory#isAuthorized()
         SecuritySession session = new DefaultSecuritySession();
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
+        httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
-        servletAuthControl.expectAndThrow( servletAuth.isAuthorized( null, session, "internal", true ),
+        servletAuthControl.expectAndThrow(
+                                           servletAuth.isAuthorized( null, session, "internal",
+                                                                     ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
                                            new UnauthorizedException( "User not authorized" ) );
-                
+
         httpAuthControl.replay();
         servletAuthControl.replay();
-        
+
         servlet.service( ic.getRequest(), ic.getResponse() );
 
         httpAuthControl.verify();
         servletAuthControl.verify();
-        
+
         // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode());
     }
 
@@ -359,7 +361,10 @@ public class RepositoryServletSecurityTest
         httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
         httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
-        servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true );
+        servletAuthControl.expectAndReturn(
+                                            servletAuth.isAuthorized( null, session, "internal",
+                                                                      ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
+                                            true );
 
         httpAuthControl.replay();
         servletAuthControl.replay();
@@ -388,7 +393,7 @@ public class RepositoryServletSecurityTest
         InvocationContext ic = sc.newInvocation( request );
         servlet = (RepositoryServlet) ic.getServlet();
         servlet.setDavSessionProvider( davSessionProvider );
-        
+
         ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory();
         archivaDavResourceFactory.setHttpAuth( httpAuth );
         archivaDavResourceFactory.setServletAuth( servletAuth );
@@ -399,15 +404,21 @@ public class RepositoryServletSecurityTest
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
                                            new AuthenticationException( "Authentication error" ) );
-        servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", false ), true );
-        
-     // ArchivaDavResourceFactory#isAuthorized()
+        servletAuthControl.expectAndReturn(
+                                            servletAuth.isAuthorized( "guest", "internal",
+                                                                      ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS ),
+                                            true );
+
+        // ArchivaDavResourceFactory#isAuthorized()
         SecuritySession session = new DefaultSecuritySession();
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
         httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), null );
         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
-        servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true );
+        servletAuthControl.expectAndReturn(
+                                            servletAuth.isAuthorized( null, session, "internal",
+                                                                      ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
+                                            true );
 
         httpAuthControl.replay();
         servletAuthControl.replay();
@@ -442,7 +453,10 @@ public class RepositoryServletSecurityTest
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ),
                                            new AuthenticationException( "Authentication error" ) );
-        servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal", false ), false );
+        servletAuthControl.expectAndReturn(
+                                            servletAuth.isAuthorized( "guest", "internal",
+                                                                      ArchivaRoleConstants.OPERATION_REPOSITORY_ACCESS ),
+                                            false );
 
         httpAuthControl.replay();
         servletAuthControl.replay();
@@ -477,24 +491,27 @@ public class RepositoryServletSecurityTest
         archivaDavResourceFactory.setServletAuth( servletAuth );
 
         servlet.setResourceFactory( archivaDavResourceFactory );
-        
+
         AuthenticationResult result = new AuthenticationResult();
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
-        
-     // ArchivaDavResourceFactory#isAuthorized()
+
+        // ArchivaDavResourceFactory#isAuthorized()
         SecuritySession session = new DefaultSecuritySession();
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
         httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
-        servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true );
-        
+        servletAuthControl.expectAndReturn(
+                                            servletAuth.isAuthorized( null, session, "internal",
+                                                                      ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
+                                            true );
+
         httpAuthControl.replay();
         servletAuthControl.replay();
 
         WebResponse response = sc.getResponse( request );
-        
+
         httpAuthControl.verify();
         servletAuthControl.verify();
 
@@ -524,27 +541,30 @@ public class RepositoryServletSecurityTest
         archivaDavResourceFactory.setServletAuth( servletAuth );
 
         servlet.setResourceFactory( archivaDavResourceFactory );
-        
+
         AuthenticationResult result = new AuthenticationResult();
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
 
-     // ArchivaDavResourceFactory#isAuthorized()
+        // ArchivaDavResourceFactory#isAuthorized()
         SecuritySession session = new DefaultSecuritySession();
         httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
         httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
+        httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
         servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
-        servletAuthControl.expectAndThrow( servletAuth.isAuthorized( null, session, "internal", true ),
+        servletAuthControl.expectAndThrow(
+                                           servletAuth.isAuthorized( null, session, "internal",
+                                                                     ArchivaRoleConstants.OPERATION_REPOSITORY_UPLOAD ),
                                            new UnauthorizedException( "User not authorized to read repository." ) );
-        
+
         httpAuthControl.replay();
         servletAuthControl.replay();
-        
+
         WebResponse response = sc.getResponse( request );
 
         httpAuthControl.verify();
         servletAuthControl.verify();
-        
+
         assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() );
     }
 }