diff options
author | Maria Odea B. Ching <oching@apache.org> | 2008-10-05 12:50:36 +0000 |
---|---|---|
committer | Maria Odea B. Ching <oching@apache.org> | 2008-10-05 12:50:36 +0000 |
commit | 81027cf972f241dfa6f443c3992efcead70235bb (patch) | |
tree | f894f090b74291f9a074dc3df8eae2a8e3d5e976 | |
parent | fc2a235f39bfb8e50d0b8b4fa13b8a8e2a86d930 (diff) | |
download | archiva-81027cf972f241dfa6f443c3992efcead70235bb.tar.gz archiva-81027cf972f241dfa6f443c3992efcead70235bb.zip |
added test case for dav security
git-svn-id: https://svn.apache.org/repos/asf/archiva/branches/archiva-security-fix@701784 13f79535-47bb-0310-9956-ffa450edef68
6 files changed, 633 insertions, 159 deletions
diff --git a/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java b/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java index 4c07a0cf4..c03405425 100644 --- a/archiva-modules/archiva-web/archiva-security/src/main/java/org/apache/maven/archiva/security/ArchivaXworkUser.java +++ b/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-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java b/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java index 032f614fd..625768186 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/main/java/org/apache/maven/archiva/webdav/ArchivaDavResourceFactory.java +++ b/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<String> repositories = new ArrayList<String>(); 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-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java b/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java index badd20cb6..4446db1eb 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/java/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.java +++ b/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 <a href="mailto:joakime@apache.org">Joakim Erdfelt</a> * @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-modules/archiva-web/archiva-webdav/src/test/resources/WEB-INF/repository-servlet-security-test/web.xml b/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-modules/archiva-web/archiva-webdav/src/test/resources/WEB-INF/repository-servlet-security-test/web.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!-- + ~ 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. + --> + +<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> + + <display-name>Apache Archiva</display-name> + + <listener> + <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> + </listener> + + <context-param> + <param-name>contextClass</param-name> + <param-value>org.codehaus.plexus.spring.PlexusWebApplicationContext</param-value> + </context-param> + + <context-param> + <param-name>contextConfigLocation</param-name> + <param-value> + classpath*:/META-INF/plexus/components.xml + classpath*:/META-INF/spring-context.xml + target/test-classes/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml + </param-value> + </context-param> + +</web-app> diff --git a/archiva-modules/archiva-web/archiva-webdav/src/test/resources/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml b/archiva-modules/archiva-web/archiva-webdav/src/test/resources/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml index d7087095a..53e79073f 100644 --- a/archiva-modules/archiva-web/archiva-webdav/src/test/resources/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml +++ b/archiva-modules/archiva-web/archiva-webdav/src/test/resources/org/apache/maven/archiva/webdav/RepositoryServletSecurityTest.xml @@ -68,9 +68,12 @@ <role-hint>default</role-hint> <implementation>org.apache.maven.archiva.webdav.DefaultDavServerManager</implementation> <description>DefaultDavServerManager</description> - <configuration> - <provider-hint>proxied</provider-hint> - </configuration> + <requirements> + <requirement> + <role>org.apache.maven.archiva.webdav.DavServerComponent</role> + <role-hint>proxied</role-hint> + </requirement> + </requirements> </component> <component> @@ -99,174 +102,74 @@ <component> <role>org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers</role> <role-hint>default</role-hint> - <implementation>org.apache.maven.archiva.web.repository.StubRepositoryContentConsumers</implementation> + <implementation>org.apache.maven.archiva.webdav.StubRepositoryContentConsumers</implementation> </component> - - <!-- TODO: shouldn't need so many components just to use in-memory - is flaky since these are auto-generated --> + <component> <role>org.codehaus.plexus.redback.system.SecuritySystem</role> <role-hint>default</role-hint> <implementation>org.codehaus.plexus.redback.system.DefaultSecuritySystem</implementation> - <requirements> - <requirement> - <role>org.codehaus.plexus.redback.authentication.AuthenticationManager</role> - <field-name>authnManager</field-name> - </requirement> - <requirement> - <role>org.codehaus.plexus.redback.authorization.Authorizer</role> - <role-hint>rbac</role-hint> - <field-name>authorizer</field-name> - </requirement> - <requirement> - <role>org.codehaus.plexus.redback.users.UserManager</role> - <role-hint>memory</role-hint> - <field-name>userManager</field-name> - </requirement> - <requirement> - <role>org.codehaus.plexus.redback.keys.KeyManager</role> - <role-hint>memory</role-hint> - <field-name>keyManager</field-name> - </requirement> - <requirement> - <role>org.codehaus.plexus.redback.policy.UserSecurityPolicy</role> - <field-name>policy</field-name> - </requirement> - </requirements> </component> - - <component> - <role>org.codehaus.plexus.redback.authentication.Authenticator</role> - <role-hint>user-manager</role-hint> - <implementation>org.codehaus.plexus.redback.authentication.users.UserManagerAuthenticator</implementation> + + <component> + <role>org.apache.maven.archiva.webdav.ArchivaDavResourceFactory</role> + <implementation>org.apache.maven.archiva.webdav.ArchivaDavResourceFactory</implementation> <requirements> <requirement> - <role>org.codehaus.plexus.redback.users.UserManager</role> - <role-hint>memory</role-hint> - <field-name>userManager</field-name> + <role>org.apache.maven.archiva.configuration.ArchivaConfiguration</role> + <field-name>archivaConfiguration</field-name> </requirement> <requirement> - <role>org.codehaus.plexus.redback.policy.UserSecurityPolicy</role> - <field-name>securityPolicy</field-name> - </requirement> - </requirements> - </component> - - <component> - <role>org.codehaus.plexus.redback.authentication.Authenticator</role> - <role-hint>keystore</role-hint> - <implementation>org.codehaus.plexus.redback.authentication.keystore.KeyStoreAuthenticator</implementation> - <requirements> - <requirement> - <role>org.codehaus.plexus.redback.keys.KeyManager</role> - <role-hint>memory</role-hint> - <field-name>keystore</field-name> - </requirement> - <requirement> - <role>org.codehaus.plexus.redback.users.UserManager</role> - <role-hint>memory</role-hint> - <field-name>userManager</field-name> - </requirement> - </requirements> - </component> - - <component> - <role>org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator</role> - <role-hint>default</role-hint> - <implementation>org.codehaus.plexus.redback.authorization.rbac.evaluator.DefaultPermissionEvaluator - </implementation> - <requirements> - <requirement> - <role>org.codehaus.plexus.redback.users.UserManager</role> - <role-hint>memory</role-hint> - <field-name>userManager</field-name> - </requirement> - </requirements> - </component> - - <component> - <role>org.codehaus.plexus.redback.authorization.Authorizer</role> - <role-hint>rbac</role-hint> - <implementation>org.codehaus.plexus.redback.authorization.rbac.RbacAuthorizer</implementation> - <requirements> + <role>org.apache.maven.archiva.repository.RepositoryContentFactory</role> + <field-name>repositoryFactory</field-name> + </requirement> <requirement> - <role>org.codehaus.plexus.redback.rbac.RBACManager</role> - <role-hint>memory</role-hint> - <field-name>manager</field-name> + <role>org.apache.maven.archiva.repository.content.RepositoryRequest</role> + <field-name>repositoryRequest</field-name> </requirement> <requirement> - <role>org.codehaus.plexus.redback.users.UserManager</role> - <role-hint>memory</role-hint> - <field-name>userManager</field-name> + <role>org.apache.maven.archiva.proxy.RepositoryProxyConnectors</role> + <field-name>connectors</field-name> </requirement> <requirement> - <role>org.codehaus.plexus.redback.authorization.rbac.evaluator.PermissionEvaluator</role> - <role-hint>default</role-hint> - <field-name>evaluator</field-name> + <role>org.apache.maven.archiva.repository.metadata.MetadataTools</role> + <field-name>metadataTools</field-name> </requirement> - </requirements> - </component> - - <component> - <role>org.codehaus.plexus.redback.role.RoleManager</role> - <role-hint>default</role-hint> - <implementation>org.codehaus.plexus.redback.role.DefaultRoleManager</implementation> - <instantiation-strategy>singleton</instantiation-strategy> - <requirements> <requirement> - <role>org.codehaus.plexus.redback.role.merger.RoleModelMerger</role> - <role-hint>default</role-hint> - <field-name>modelMerger</field-name> + <role>org.apache.maven.archiva.security.ServletAuthenticator</role> + <field-name>servletAuth</field-name> </requirement> <requirement> - <role>org.codehaus.plexus.redback.role.validator.RoleModelValidator</role> - <role-hint>default</role-hint> - <field-name>modelValidator</field-name> + <role>org.apache.maven.archiva.webdav.util.MimeTypes</role> + <field-name>mimeTypes</field-name> </requirement> <requirement> - <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role> - <role-hint>default</role-hint> - <field-name>modelProcessor</field-name> + <role>org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator</role> + <role-hint>basic</role-hint> + <field-name>httpAuth</field-name> </requirement> <requirement> - <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role> + <role>org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers</role> <role-hint>default</role-hint> - <field-name>templateProcessor</field-name> </requirement> <requirement> - <role>org.codehaus.plexus.redback.rbac.RBACManager</role> - <role-hint>memory</role-hint> - <field-name>rbacManager</field-name> + <role>org.codehaus.plexus.digest.ChecksumFile</role> + <field-name>checksum</field-name> </requirement> <requirement> - <role>org.codehaus.plexus.PlexusContainer</role> - <field-name>container</field-name> + <role>org.codehaus.plexus.digest.Digester</role> + <role-hint>sha1</role-hint> + <field-name>digestSha1</field-name> </requirement> - </requirements> - </component> - - <component> - <role>org.codehaus.plexus.redback.role.processor.RoleModelProcessor</role> - <role-hint>default</role-hint> - <implementation>org.codehaus.plexus.redback.role.processor.DefaultRoleModelProcessor</implementation> - <requirements> <requirement> - <role>org.codehaus.plexus.redback.rbac.RBACManager</role> - <role-hint>memory</role-hint> - <field-name>rbacManager</field-name> + <role>org.codehaus.plexus.digest.Digester</role> + <role-hint>md5</role-hint> + <field-name>digestMd5</field-name> </requirement> - </requirements> - </component> - - <component> - <role>org.codehaus.plexus.redback.role.template.RoleTemplateProcessor</role> - <role-hint>default</role-hint> - <implementation>org.codehaus.plexus.redback.role.template.DefaultRoleTemplateProcessor</implementation> - <requirements> <requirement> - <role>org.codehaus.plexus.redback.rbac.RBACManager</role> - <role-hint>memory</role-hint> - <field-name>rbacManager</field-name> - </requirement> + <role>org.apache.maven.archiva.security.ArchivaXworkUser</role> + <field-name>archivaXworkUser</field-name> + </requirement> </requirements> </component> </components> @@ -205,6 +205,12 @@ <scope>test</scope> </dependency> <dependency> + <groupId>easymock</groupId> + <artifactId>easymockclassextension</artifactId> + <version>1.2</version> + <scope>test</scope> + </dependency> + <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl104-over-slf4j</artifactId> <scope>test</scope> |