From 092fd622f7e302ab5a1d404cb179d0d1ce0f5bb7 Mon Sep 17 00:00:00 2001 From: "Maria Odea B. Ching" Date: Sun, 5 Oct 2008 12:50:36 +0000 Subject: [PATCH] added test case for dav security git-svn-id: https://svn.apache.org/repos/asf/archiva/branches@701784 13f79535-47bb-0310-9956-ffa450edef68 --- .../archiva/security/ArchivaXworkUser.java | 5 + .../webdav/ArchivaDavResourceFactory.java | 40 +- .../webdav/RepositoryServletSecurityTest.java | 515 +++++++++++++++++- .../repository-servlet-security-test/web.xml | 45 ++ .../webdav/RepositoryServletSecurityTest.xml | 181 ++---- archiva-security-fix/pom.xml | 6 + 6 files changed, 633 insertions(+), 159 deletions(-) create mode 100644 archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/resources/WEB-INF/repository-servlet-security-test/web.xml diff --git a/archiva-security-fix/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java b/archiva-security-fix/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java index 4c07a0cf4..c03405425 100644 --- a/archiva-security-fix/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java +++ b/archiva-security-fix/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java @@ -85,4 +85,9 @@ public class ArchivaXworkUser return guest; } + + public void setGuest( String guesT ) + { + guest = guesT; + } } diff --git a/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java index 032f614fd..625768186 100644 --- a/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java +++ b/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java @@ -186,14 +186,14 @@ public class ArchivaDavResourceFactory { checkLocatorIsInstanceOfRepositoryLocator( locator ); ArchivaDavResourceLocator archivaLocator = (ArchivaDavResourceLocator) locator; - + RepositoryGroupConfiguration repoGroupConfig = archivaConfiguration.getConfiguration().getRepositoryGroupsAsMap().get( archivaLocator.getRepositoryId() ); List repositories = new ArrayList(); boolean isGet = WebdavMethodUtil.isReadMethod( request.getMethod() ); boolean isPut = WebdavMethodUtil.isWriteMethod( request.getMethod() ); - + if ( repoGroupConfig != null ) { if( WebdavMethodUtil.isWriteMethod( request.getMethod() ) ) @@ -230,7 +230,7 @@ public class ArchivaDavResourceFactory try { - managedRepository = getManagedRepository( repositoryId ); + managedRepository = getManagedRepository( repositoryId ); } catch ( DavException de ) { @@ -241,13 +241,13 @@ public class ArchivaDavResourceFactory 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() ) ); @@ -258,12 +258,13 @@ public class ArchivaDavResourceFactory if ( isPut ) { - resource = doPut( managedRepository, request, archivaLocator, logicalResource ); + resource = doPut( managedRepository, request, archivaLocator, logicalResource ); } } } catch ( DavException de ) { + de.printStackTrace(); e = de; continue; } @@ -273,11 +274,11 @@ public class ArchivaDavResourceFactory e = new DavException( HttpServletResponse.SC_NOT_FOUND, "Resource does not exist" ); } else - { + { availableResources.add( resource ); String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ); - resourcesInAbsolutePath.add( managedRepository.getRepoRoot() + logicalResource ); + resourcesInAbsolutePath.add( managedRepository.getRepoRoot() + logicalResource ); } } else @@ -491,15 +492,16 @@ public class ArchivaDavResourceFactory File rootDirectory = new File( managedRepository.getRepoRoot() ); File destDir = new File( rootDirectory, logicalResource.getPath() ).getParentFile(); + if ( request.getMethod().equals(HTTP_PUT_METHOD) && !destDir.exists() ) { destDir.mkdirs(); String relPath = PathUtil.getRelative( rootDirectory.getAbsolutePath(), destDir ); triggerAuditEvent( request.getRemoteAddr(), logicalResource.getPath(), relPath, AuditEvent.CREATE_DIR ); } - - File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() ); - + + File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource.getPath() ); + return new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(), managedRepository.getRepository(), request.getRemoteAddr(), request.getDavSession(), locator, this, mimeTypes, auditListeners, consumers, archivaXworkUser ); @@ -721,9 +723,9 @@ public class ArchivaDavResourceFactory protected boolean isAuthorized( DavServletRequest request, String repositoryId ) throws DavException - { + { try - { + { AuthenticationResult result = httpAuth.getAuthenticationResult( request, null ); SecuritySession securitySession = httpAuth.getSecuritySession(); @@ -732,7 +734,7 @@ public class ArchivaDavResourceFactory WebdavMethodUtil.isWriteMethod( request.getMethod() ) ); } catch ( AuthenticationException e ) - { + { // safety check for MRM-911 String guest = archivaXworkUser.getGuest(); try @@ -974,4 +976,14 @@ public class ArchivaDavResourceFactory return true; } } + + public void setServletAuth( ServletAuthenticator servletAuth ) + { + this.servletAuth = servletAuth; + } + + public void setHttpAuth( HttpAuthenticator httpAuth ) + { + this.httpAuth = httpAuth; + } } diff --git a/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java b/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java index badd20cb6..4446db1eb 100644 --- a/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java +++ b/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java @@ -1,21 +1,524 @@ package org.apache.maven.archiva.webdav; -/** - * RepositoryServletSecurityTest +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import javax.servlet.http.HttpServletResponse; + +import net.sf.ehcache.CacheManager; + +import org.apache.commons.io.FileUtils; +import org.apache.jackrabbit.webdav.DavException; +import org.apache.jackrabbit.webdav.DavResourceFactory; +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.ArchivaXworkUser; +import org.apache.maven.archiva.security.ServletAuthenticator; +import org.codehaus.plexus.redback.authentication.AuthenticationException; +import org.codehaus.plexus.redback.authentication.AuthenticationResult; +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.xwork.filter.authentication.HttpAuthenticator; +import org.codehaus.plexus.redback.xwork.filter.authentication.basic.HttpBasicAuthentication; +import org.codehaus.plexus.spring.PlexusInSpringTestCase; +import org.easymock.MockControl; +import org.easymock.classextension.MockClassControl; +import org.easymock.internal.AlwaysMatcher; + +import com.meterware.httpunit.GetMethodWebRequest; +import com.meterware.httpunit.HttpUnitOptions; +import com.meterware.httpunit.PostMethodWebRequest; +import com.meterware.httpunit.PutMethodWebRequest; +import com.meterware.httpunit.WebRequest; +import com.meterware.httpunit.WebResponse; +import com.meterware.servletunit.InvocationContext; +import com.meterware.servletunit.ServletRunner; +import com.meterware.servletunit.ServletUnitClient; + +/** + * RepositoryServletSecurityTest + * * @author Joakim Erdfelt * @version $Id$ */ public class RepositoryServletSecurityTest - extends AbstractRepositoryServletTestCase + extends PlexusInSpringTestCase { - public void testSecuredGet() + protected static final String REPOID_INTERNAL = "internal"; + + protected ServletUnitClient sc; + + protected File repoRootInternal; + + private ServletRunner sr; + + protected ArchivaConfiguration archivaConfiguration; + + private DavSessionProvider davSessionProvider; + + private MockControl servletAuthControl; + + private ServletAuthenticator servletAuth; + + private MockClassControl httpAuthControl; + + private HttpAuthenticator httpAuth; + + private ArchivaXworkUser archivaXworkUser; + + private RepositoryServlet servlet; + + private MockControl davResourceFactoryControl; + + private DavResourceFactory davResourceFactory; + + public void setUp() + throws Exception + { + super.setUp(); + + String appserverBase = getTestFile( "target/appserver-base" ).getAbsolutePath(); + System.setProperty( "appserver.base", appserverBase ); + + File testConf = getTestFile( "src/test/resources/repository-archiva.xml" ); + File testConfDest = new File( appserverBase, "conf/archiva.xml" ); + FileUtils.copyFile( testConf, testConfDest ); + + archivaConfiguration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class ); + repoRootInternal = new File( appserverBase, "data/repositories/internal" ); + Configuration config = archivaConfiguration.getConfiguration(); + + config.addManagedRepository( createManagedRepository( REPOID_INTERNAL, "Internal Test Repo", repoRootInternal ) ); + saveConfiguration( archivaConfiguration ); + + CacheManager.getInstance().removeCache( "url-failures-cache" ); + + HttpUnitOptions.setExceptionsThrownOnErrorStatus( false ); + + sr = new ServletRunner( getTestFile( "src/test/resources/WEB-INF/repository-servlet-security-test/web.xml" ) ); + sr.registerServlet( "/repository/*", RepositoryServlet.class.getName() ); + sc = sr.newClient(); + + servletAuthControl = MockControl.createControl( ServletAuthenticator.class ); + servletAuthControl.setDefaultMatcher( new AlwaysMatcher() ); + servletAuth = (ServletAuthenticator) servletAuthControl.getMock(); + + httpAuthControl = + MockClassControl.createControl( HttpBasicAuthentication.class, HttpBasicAuthentication.class.getMethods() ); + httpAuthControl.setDefaultMatcher( new AlwaysMatcher() ); + httpAuth = (HttpAuthenticator) httpAuthControl.getMock(); + + archivaXworkUser = new ArchivaXworkUser(); + archivaXworkUser.setGuest( "guest" ); + + davSessionProvider = new ArchivaDavSessionProvider( servletAuth, httpAuth, archivaXworkUser ); + + davResourceFactoryControl = MockControl.createControl( DavResourceFactory.class ); + davResourceFactoryControl.setDefaultMatcher( new AlwaysMatcher() ); + davResourceFactory = (DavResourceFactory) davResourceFactoryControl.getMock(); + } + + protected ManagedRepositoryConfiguration createManagedRepository( String id, String name, File location ) + { + ManagedRepositoryConfiguration repo = new ManagedRepositoryConfiguration(); + repo.setId( id ); + repo.setName( name ); + repo.setLocation( location.getAbsolutePath() ); + return repo; + } + + protected void saveConfiguration() + throws Exception + { + saveConfiguration( archivaConfiguration ); + } + + protected void saveConfiguration( ArchivaConfiguration archivaConfiguration ) + throws Exception + { + archivaConfiguration.save( archivaConfiguration.getConfiguration() ); + } + + protected void setupCleanRepo( File repoRootDir ) + throws IOException + { + FileUtils.deleteDirectory( repoRootDir ); + if ( !repoRootDir.exists() ) + { + repoRootDir.mkdirs(); + } + } + + @Override + protected String getPlexusConfigLocation() + { + return "org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml"; + } + + @Override + protected void tearDown() + throws Exception + { + if ( sc != null ) + { + sc.clearContents(); + } + + if ( sr != null ) + { + sr.shutDown(); + } + + if ( repoRootInternal.exists() ) + { + FileUtils.deleteDirectory(repoRootInternal); + } + + servlet = null; + + super.tearDown(); + } + + // test deploy with invalid user, and guest has no write access to repo + // 401 must be returned + public void testPutWithInvalidUserAndGuestHasNoWriteAccess() + throws Exception + { + setupCleanRepo( repoRootInternal ); + + WebRequest request = new PostMethodWebRequest( "http://machine.com/repository/internal/path/to/artifact.jar" ); + InvocationContext ic = sc.newInvocation( request ); + servlet = (RepositoryServlet) ic.getServlet(); + servlet.setDavSessionProvider( davSessionProvider ); + + AuthenticationResult result = new AuthenticationResult(); + httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); + servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), + new AuthenticationException( "Authentication error" ) ); + // servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), false ); + + httpAuthControl.replay(); + servletAuthControl.replay(); + + WebResponse response = sc.getResponse( request ); + + httpAuthControl.verify(); + servletAuthControl.verify(); + + // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode()); + } + + // test deploy with invalid user, but guest has write access to repo + public void testPutWithInvalidUserAndGuestHasWriteAccess() + throws Exception + { + setupCleanRepo( repoRootInternal ); + + 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 ); + servlet = (RepositoryServlet) ic.getServlet(); + servlet.setDavSessionProvider( davSessionProvider ); + + AuthenticationResult result = new AuthenticationResult(); + httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); + servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), + new AuthenticationException( "Authentication error" ) ); + // servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), true ); + + httpAuthControl.replay(); + servletAuthControl.replay(); + + WebResponse response = sc.getResponse( request ); + + httpAuthControl.verify(); + servletAuthControl.verify(); + + // assertEquals( HttpServletResponse.SC_CREATED, response.getResponseCode() ); + } + + // test deploy with a valid user with no write access + public void testPutWithValidUserWithNoWriteAccess() + throws Exception + { + setupCleanRepo( repoRootInternal ); + + WebRequest request = new PostMethodWebRequest( "http://machine.com/repository/internal/path/to/artifact.jar" ); + InvocationContext ic = sc.newInvocation( request ); + servlet = (RepositoryServlet) ic.getServlet(); + servlet.setDavSessionProvider( davSessionProvider ); + servlet.setResourceFactory( davResourceFactory ); + + AuthenticationResult result = new AuthenticationResult(); + httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); + servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true ); + // servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), + // new AuthenticationException( "Authentication error" ) ); + // servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), true ); + + DavException e = new DavException( 401, "User not authorized." ); + davResourceFactoryControl.expectAndThrow( davResourceFactory.createResource( null, null, null ), + new UnauthorizedDavException( "internal", "User not authorized" ) ); + + httpAuthControl.replay(); + servletAuthControl.replay(); + davResourceFactoryControl.replay(); + + WebResponse response = sc.getResponse( request ); + + httpAuthControl.verify(); + servletAuthControl.verify(); + davResourceFactoryControl.verify(); + + // assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode()); + } + + // test deploy with a valid user with write access + public void testPutWithValidUserWithWriteAccess() + throws Exception + { + setupCleanRepo( repoRootInternal ); + assertTrue( repoRootInternal.exists() ); + + 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 ); + servlet = (RepositoryServlet) ic.getServlet(); + servlet.setDavSessionProvider( davSessionProvider ); + + ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory(); + archivaDavResourceFactory.setHttpAuth( httpAuth ); + 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() + SecuritySession session = new DefaultSecuritySession(); + httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); + httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session ); + servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true ); + servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true ); + + // servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), + // new AuthenticationException( "Authentication error" ) ); + // servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), true ); + + httpAuthControl.replay(); + servletAuthControl.replay(); + + // WebResponse response = sc.getResponse( request ); + // WebResponse response = ic.getServletResponse(); + + servlet.service( ic.getRequest(), ic.getResponse() ); + + httpAuthControl.verify(); + servletAuthControl.verify(); + + // assertEquals(HttpServletResponse.SC_CREATED, response.getResponseCode()); + } + + // test get with invalid user, and guest has read access to repo + public void testGetWithInvalidUserAndGuestHasReadAccess() + throws Exception { + String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"; + String expectedArtifactContents = "dummy-commons-lang-artifact"; + + File artifactFile = new File( repoRootInternal, commonsLangJar ); + artifactFile.getParentFile().mkdirs(); + + FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null ); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar ); + InvocationContext ic = sc.newInvocation( request ); + servlet = (RepositoryServlet) ic.getServlet(); + servlet.setDavSessionProvider( davSessionProvider ); + ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory(); + archivaDavResourceFactory.setHttpAuth( httpAuth ); + 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" ) ); + servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), true ); + + // ArchivaDavResourceFactory#isAuthorized() + SecuritySession session = new DefaultSecuritySession(); + httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); + httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session ); + servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true ); + servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true ); + + httpAuthControl.replay(); + servletAuthControl.replay(); + + WebResponse response = sc.getResponse( request ); + + httpAuthControl.verify(); + servletAuthControl.verify(); + + assertEquals( HttpServletResponse.SC_OK, response.getResponseCode() ); + assertEquals( "Expected file contents", expectedArtifactContents, response.getText() ); } - - public void testSecuredBrowse() + + // test get with invalid user, and guest has no read access to repo + public void testGetWithInvalidUserAndGuestHasNoReadAccess() + throws Exception { + String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"; + String expectedArtifactContents = "dummy-commons-lang-artifact"; + + File artifactFile = new File( repoRootInternal, commonsLangJar ); + artifactFile.getParentFile().mkdirs(); + + FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null ); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar ); + InvocationContext ic = sc.newInvocation( request ); + servlet = (RepositoryServlet) ic.getServlet(); + servlet.setDavSessionProvider( davSessionProvider ); + + AuthenticationResult result = new AuthenticationResult(); + httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); + servletAuthControl.expectAndThrow( servletAuth.isAuthenticated( null, null ), + new AuthenticationException( "Authentication error" ) ); + servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), false ); + + httpAuthControl.replay(); + servletAuthControl.replay(); + + WebResponse response = sc.getResponse( request ); + + httpAuthControl.verify(); + servletAuthControl.verify(); + + assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() ); + } + + // test get with valid user with read access to repo + public void testGetWithAValidUserWithReadAccess() + throws Exception + { + String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"; + String expectedArtifactContents = "dummy-commons-lang-artifact"; + + File artifactFile = new File( repoRootInternal, commonsLangJar ); + artifactFile.getParentFile().mkdirs(); + + FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null ); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar ); + InvocationContext ic = sc.newInvocation( request ); + servlet = (RepositoryServlet) ic.getServlet(); + servlet.setDavSessionProvider( davSessionProvider ); + + ArchivaDavResourceFactory archivaDavResourceFactory = (ArchivaDavResourceFactory) servlet.getResourceFactory(); + archivaDavResourceFactory.setHttpAuth( httpAuth ); + archivaDavResourceFactory.setServletAuth( servletAuth ); + + servlet.setResourceFactory( archivaDavResourceFactory ); + + AuthenticationResult result = new AuthenticationResult(); + httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); + servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true ); + //servletAuthControl.expectAndReturn( servletAuth.isAuthorized( "guest", "internal" ), true ); + + // ArchivaDavResourceFactory#isAuthorized() + SecuritySession session = new DefaultSecuritySession(); + httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); + httpAuthControl.expectAndReturn( httpAuth.getSecuritySession(), session ); + servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true ); + servletAuthControl.expectAndReturn( servletAuth.isAuthorized( null, session, "internal", true ), true ); + + httpAuthControl.replay(); + servletAuthControl.replay(); + + WebResponse response = sc.getResponse( request ); + //servlet.service( ic.getRequest(), ic.getResponse() ); + + httpAuthControl.verify(); + servletAuthControl.verify(); + + //assertEquals( HttpServletResponse.SC_OK, response.getResponseCode() ); + //assertEquals( "Expected file contents", expectedArtifactContents, response.getText() ); + } + + // test get with valid user with no read access to repo + public void testGetWithAValidUserWithNoReadAccess() + throws Exception + { + String commonsLangJar = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"; + String expectedArtifactContents = "dummy-commons-lang-artifact"; + + File artifactFile = new File( repoRootInternal, commonsLangJar ); + artifactFile.getParentFile().mkdirs(); + + FileUtils.writeStringToFile( artifactFile, expectedArtifactContents, null ); + + WebRequest request = new GetMethodWebRequest( "http://machine.com/repository/internal/" + commonsLangJar ); + InvocationContext ic = sc.newInvocation( request ); + servlet = (RepositoryServlet) ic.getServlet(); + servlet.setDavSessionProvider( davSessionProvider ); + servlet.setResourceFactory( davResourceFactory ); + + AuthenticationResult result = new AuthenticationResult(); + httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result ); + servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true ); + + DavException e = new DavException( 401, "User not authorized." ); + davResourceFactoryControl.expectAndThrow( davResourceFactory.createResource( null, null, null ), + new UnauthorizedDavException( "internal", "User not authorized" ) ); + + httpAuthControl.replay(); + servletAuthControl.replay(); + davResourceFactoryControl.replay(); + + WebResponse response = sc.getResponse( request ); + + httpAuthControl.verify(); + servletAuthControl.verify(); + davResourceFactoryControl.verify(); + + assertEquals( HttpServletResponse.SC_UNAUTHORIZED, response.getResponseCode() ); } } diff --git a/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/resources/WEB-INF/repository-servlet-security-test/web.xml b/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/resources/WEB-INF/repository-servlet-security-test/web.xml new file mode 100644 index 000000000..291aa01ec --- /dev/null +++ b/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/resources/WEB-INF/repository-servlet-security-test/web.xml @@ -0,0 +1,45 @@ + + + + + + Apache Archiva + + + org.springframework.web.context.ContextLoaderListener + + + + contextClass + org.codehaus.plexus.spring.PlexusWebApplicationContext + + + + contextConfigLocation + + classpath*:/META-INF/plexus/components.xml + classpath*:/META-INF/spring-context.xml + target/test-classes/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml + + + + diff --git a/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/resources/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml b/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/resources/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml index d7087095a..53e79073f 100644 --- a/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/resources/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml +++ b/archiva-security-fix/archiva-modules/archiva-web/archiva-webdav/src/test/resources/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml @@ -68,9 +68,12 @@ default org.apache.maven.archiva.webdav.DefaultDavServerManager DefaultDavServerManager - - proxied - + + + org.apache.maven.archiva.webdav.DavServerComponent + proxied + + @@ -99,174 +102,74 @@ org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers default - org.apache.maven.archiva.web.repository.StubRepositoryContentConsumers + org.apache.maven.archiva.webdav.StubRepositoryContentConsumers - - + org.codehaus.plexus.redback.system.SecuritySystem default org.codehaus.plexus.redback.system.DefaultSecuritySystem - - - org.codehaus.plexus.redback.authentication.AuthenticationManager - authnManager - - - org.codehaus.plexus.redback.authorization.Authorizer - rbac - authorizer - - - org.codehaus.plexus.redback.users.UserManager - memory - userManager - - - org.codehaus.plexus.redback.keys.KeyManager - memory - keyManager - - - org.codehaus.plexus.redback.policy.UserSecurityPolicy - policy - - - - - org.codehaus.plexus.redback.authentication.Authenticator - user-manager - org.codehaus.plexus.redback.authentication.users.UserManagerAuthenticator + + + org.apache.maven.archiva.webdav.ArchivaDavResourceFactory + org.apache.maven.archiva.webdav.ArchivaDavResourceFactory - org.codehaus.plexus.redback.users.UserManager - memory - userManager + org.apache.maven.archiva.configuration.ArchivaConfiguration + archivaConfiguration - org.codehaus.plexus.redback.policy.UserSecurityPolicy - securityPolicy - - - - - - org.codehaus.plexus.redback.authentication.Authenticator - keystore - org.codehaus.plexus.redback.authentication.keystore.KeyStoreAuthenticator - - - org.codehaus.plexus.redback.keys.KeyManager - memory - keystore - - - org.codehaus.plexus.redback.users.UserManager - memory - userManager - - - - - - org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator - default - org.codehaus.plexus.redback.authorization.rbac.evaluator.DefaultPermissionEvaluator - - - - org.codehaus.plexus.redback.users.UserManager - memory - userManager - - - - - - org.codehaus.plexus.redback.authorization.Authorizer - rbac - org.codehaus.plexus.redback.authorization.rbac.RbacAuthorizer - + org.apache.maven.archiva.repository.RepositoryContentFactory + repositoryFactory + - org.codehaus.plexus.redback.rbac.RBACManager - memory - manager + org.apache.maven.archiva.repository.content.RepositoryRequest + repositoryRequest - org.codehaus.plexus.redback.users.UserManager - memory - userManager + org.apache.maven.archiva.proxy.RepositoryProxyConnectors + connectors - org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator - default - evaluator + org.apache.maven.archiva.repository.metadata.MetadataTools + metadataTools - - - - - org.codehaus.plexus.redback.role.RoleManager - default - org.codehaus.plexus.redback.role.DefaultRoleManager - singleton - - org.codehaus.plexus.redback.role.merger.RoleModelMerger - default - modelMerger + org.apache.maven.archiva.security.ServletAuthenticator + servletAuth - org.codehaus.plexus.redback.role.validator.RoleModelValidator - default - modelValidator + org.apache.maven.archiva.webdav.util.MimeTypes + mimeTypes - org.codehaus.plexus.redback.role.processor.RoleModelProcessor - default - modelProcessor + org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator + basic + httpAuth - org.codehaus.plexus.redback.role.template.RoleTemplateProcessor + org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers default - templateProcessor - org.codehaus.plexus.redback.rbac.RBACManager - memory - rbacManager + org.codehaus.plexus.digest.ChecksumFile + checksum - org.codehaus.plexus.PlexusContainer - container + org.codehaus.plexus.digest.Digester + sha1 + digestSha1 - - - - - org.codehaus.plexus.redback.role.processor.RoleModelProcessor - default - org.codehaus.plexus.redback.role.processor.DefaultRoleModelProcessor - - org.codehaus.plexus.redback.rbac.RBACManager - memory - rbacManager + org.codehaus.plexus.digest.Digester + md5 + digestMd5 - - - - - org.codehaus.plexus.redback.role.template.RoleTemplateProcessor - default - org.codehaus.plexus.redback.role.template.DefaultRoleTemplateProcessor - - org.codehaus.plexus.redback.rbac.RBACManager - memory - rbacManager - + org.apache.maven.archiva.security.ArchivaXworkUser + archivaXworkUser + diff --git a/archiva-security-fix/pom.xml b/archiva-security-fix/pom.xml index 7d311138b..bdffb05b2 100644 --- a/archiva-security-fix/pom.xml +++ b/archiva-security-fix/pom.xml @@ -204,6 +204,12 @@ 1.2_Java1.3 test + + easymock + easymockclassextension + 1.2 + test + org.slf4j jcl104-over-slf4j -- 2.39.5