[MRM-747] Archiva should prevent re-deployment of released or non-snapshot versioned artifacts

o moved check for metadata support files to RepositoryRequest and added tests
o throw DavException error 409 immediately for released artifacts intead of a ReleaseArtifactAlreadyExistsException


git-svn-id: https://svn.apache.org/repos/asf/archiva/trunk@825449 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Maria Odea B. Ching 2009-10-15 09:40:40 +00:00
parent 7ecf7e1e88
commit fa22abb913
5 changed files with 139 additions and 74 deletions

View File

@ -133,6 +133,20 @@ public class RepositoryRequest
return ( ".sha1".equals( ext ) || ".md5".equals( ext ) || ".asc".equals( ext ) || ".pgp".equals( ext ) ); return ( ".sha1".equals( ext ) || ".md5".equals( ext ) || ".asc".equals( ext ) || ".pgp".equals( ext ) );
} }
public boolean isMetadataSupportFile( String requestedPath )
{
if( isSupportFile( requestedPath ) )
{
String basefilePath = StringUtils.substring( requestedPath, 0, requestedPath.lastIndexOf( '.' ) );
if( isMetadata( basefilePath ) )
{
return true;
}
}
return false;
}
/** /**
* <p> * <p>
* Tests the path to see if it conforms to the expectations of a default layout request. * Tests the path to see if it conforms to the expectations of a default layout request.

View File

@ -35,6 +35,16 @@ import java.io.File;
public class RepositoryRequestTest public class RepositoryRequestTest
extends AbstractRepositoryLayerTestCase extends AbstractRepositoryLayerTestCase
{ {
public void testInvalidRequestEmptyPath()
{
assertInvalidRequest( "" );
}
public void testInvalidRequestSlashOnly()
{
assertInvalidRequest( "//" );
}
public void testInvalidRequestNoArtifactId() public void testInvalidRequestNoArtifactId()
{ {
assertInvalidRequest( "groupId/jars/-1.0.jar" ); assertInvalidRequest( "groupId/jars/-1.0.jar" );
@ -237,6 +247,22 @@ public class RepositoryRequestTest
assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) ); assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) );
assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) ); assertFalse( repoRequest.isMetadata( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) );
} }
public void testIsMetadataSupprotFile()
{
assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml" ));
assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml" ));
assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml.sha1" ));
assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/maven-metadata.xml.md5" ));
assertFalse( repoRequest.isMetadataSupportFile( "test.maven-arch/poms/test-arch-2.0.3-SNAPSHOT.pom" ) );
assertFalse( repoRequest.isMetadataSupportFile( "test/maven-arch/test-arch/2.0.3-SNAPSHOT/test-arch-2.0.3-SNAPSHOT.jar" ) );
assertFalse( repoRequest.isMetadataSupportFile( "org/apache/archiva/archiva-api/1.0/archiva-api-1.0.xml.zip" ) );
assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz" ) );
assertFalse( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/derby-10.2.2.0-bin.tar.gz.pgp" ) );
assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.sha1" ) );
assertTrue( repoRequest.isMetadataSupportFile( "org/apache/derby/derby/10.2.2.0/maven-metadata.xml.md5" ) );
}
public void testIsDefault() public void testIsDefault()
{ {

View File

@ -200,17 +200,10 @@ public class ArchivaDavResourceFactory
return getResource( request, repoGroupConfig.getRepositories(), archivaLocator ); return getResource( request, repoGroupConfig.getRepositories(), archivaLocator );
} }
else else
{ {
try resource =
{ processRepositoryGroup( request, archivaLocator, repoGroupConfig.getRepositories(),
resource = activePrincipal, resourcesInAbsolutePath );
processRepositoryGroup( request, archivaLocator, repoGroupConfig.getRepositories(),
activePrincipal, resourcesInAbsolutePath );
}
catch ( ReleaseArtifactAlreadyExistsException e )
{
throw new DavException( HttpServletResponse.SC_CONFLICT );
}
} }
} }
else else
@ -232,15 +225,8 @@ public class ArchivaDavResourceFactory
} }
log.debug( "Managed repository '" + managedRepository.getId() + "' accessed by '" + activePrincipal + "'" ); log.debug( "Managed repository '" + managedRepository.getId() + "' accessed by '" + activePrincipal + "'" );
try resource = processRepository( request, archivaLocator, activePrincipal, managedRepository );
{
resource = processRepository( request, archivaLocator, activePrincipal, managedRepository );
}
catch ( ReleaseArtifactAlreadyExistsException e )
{
throw new DavException( HttpServletResponse.SC_CONFLICT, e );
}
String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() ); String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() );
resourcesInAbsolutePath.add( new File( managedRepository.getRepoRoot(), logicalResource ).getAbsolutePath() ); resourcesInAbsolutePath.add( new File( managedRepository.getRepoRoot(), logicalResource ).getAbsolutePath() );
@ -250,7 +236,7 @@ public class ArchivaDavResourceFactory
// MRM-872 : merge all available metadata // MRM-872 : merge all available metadata
// merge metadata only when requested via the repo group // merge metadata only when requested via the repo group
if ( ( repositoryRequest.isMetadata( requestedResource ) || ( requestedResource.endsWith( "metadata.xml.sha1" ) || requestedResource.endsWith( "metadata.xml.md5" ) ) ) && if ( ( repositoryRequest.isMetadata( requestedResource ) || repositoryRequest.isMetadataSupportFile( requestedResource ) ) &&
repoGroupConfig != null ) repoGroupConfig != null )
{ {
// this should only be at the project level not version level! // this should only be at the project level not version level!
@ -349,7 +335,7 @@ public class ArchivaDavResourceFactory
private DavResource processRepositoryGroup( final DavServletRequest request, private DavResource processRepositoryGroup( final DavServletRequest request,
ArchivaDavResourceLocator archivaLocator, List<String> repositories, ArchivaDavResourceLocator archivaLocator, List<String> repositories,
String activePrincipal, List<String> resourcesInAbsolutePath ) String activePrincipal, List<String> resourcesInAbsolutePath )
throws DavException, ReleaseArtifactAlreadyExistsException throws DavException
{ {
DavResource resource = null; DavResource resource = null;
List<DavException> storedExceptions = new ArrayList<DavException>(); List<DavException> storedExceptions = new ArrayList<DavException>();
@ -417,7 +403,7 @@ public class ArchivaDavResourceFactory
private DavResource processRepository( final DavServletRequest request, ArchivaDavResourceLocator archivaLocator, private DavResource processRepository( final DavServletRequest request, ArchivaDavResourceLocator archivaLocator,
String activePrincipal, ManagedRepositoryContent managedRepository ) String activePrincipal, ManagedRepositoryContent managedRepository )
throws DavException, ReleaseArtifactAlreadyExistsException throws DavException
{ {
DavResource resource = null; DavResource resource = null;
if ( isAuthorized( request, managedRepository.getId() ) ) if ( isAuthorized( request, managedRepository.getId() ) )
@ -507,21 +493,21 @@ public class ArchivaDavResourceFactory
try try
{ {
artifact = managedRepository.toArtifactReference( resourcePath ); artifact = managedRepository.toArtifactReference( resourcePath );
if ( !VersionUtil.isSnapshot( artifact.getVersion() ) )
{
// check if artifact already exists
if ( managedRepository.hasContent( artifact ) )
{
log.warn( "Overwriting released artifacts is not allowed." );
throw new DavException( HttpServletResponse.SC_CONFLICT,
"Overwriting released artifacts is not allowed." );
}
}
} }
catch ( LayoutException e ) catch ( LayoutException e )
{ {
throw new DavException( HttpServletResponse.SC_BAD_REQUEST, e ); log.warn( "Artifact path '" + resourcePath + "' is invalid." );
}
if ( !VersionUtil.isSnapshot( artifact.getVersion() ) )
{
// check if artifact already exists
if ( managedRepository.hasContent( artifact ) )
{
log.warn( "Overwriting released artifacts is not allowed." );
throw new ReleaseArtifactAlreadyExistsException( managedRepository.getId(),
"Overwriting released artifacts is not allowed." );
}
} }
} }

View File

@ -1,38 +0,0 @@
package org.apache.maven.archiva.webdav;
/*
* 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.
*/
/**
*/
public class ReleaseArtifactAlreadyExistsException
extends Exception
{
final private String repositoryName;
public ReleaseArtifactAlreadyExistsException( String repositoryName, String message )
{
this.repositoryName = repositoryName;
}
public String getRepositoryName()
{
return repositoryName;
}
}

View File

@ -63,7 +63,7 @@ public class RepositoryServletDeployTest
* *
* @throws Exception * @throws Exception
*/ */
public void testPreventOverwritingReleaseArtifacts() public void testReleaseArtifactsRedeploymentValidPath()
throws Exception throws Exception
{ {
setupCleanRepo( repoRootInternal ); setupCleanRepo( repoRootInternal );
@ -98,6 +98,76 @@ public class RepositoryServletDeployTest
assertResponseConflictError( response ); assertResponseConflictError( response );
} }
public void testReleaseArtifactsRedeploymentInvalidPath()
throws Exception
{
setupCleanRepo( repoRootInternal );
String putUrl = "http://machine.com/repository/internal/artifact.jar";
String metadataUrl = "http://machine.com/repository/internal/maven-metadata.xml";
String checksumUrl = "http://machine.com/repository/internal/artifact.jar.sha1";
InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
// verify that the file exists in resources-dir
assertNotNull( "artifact.jar inputstream", is );
// send request #1 and verify it's successful
WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
WebResponse response = sc.getResponse( request );
assertResponseCreated( response );
is = getClass().getResourceAsStream( "/artifact.jar.sha1" );
request = new PutMethodWebRequest( checksumUrl, is, "application/octet-stream" );
response = sc.getResponse( request );
assertResponseCreated( response );
is = getClass().getResourceAsStream( "/maven-metadata.xml" );
request = new PutMethodWebRequest( metadataUrl, is, "application/octet-stream" );
response = sc.getResponse( request );
assertResponseCreated( response );
// send request #2 and verify it's re-deployed
is = getClass().getResourceAsStream( "/artifact.jar" );
request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
response = sc.getResponse( request );
assertResponseNoContent( response );
}
public void testReleaseArtifactsRedeploymentArtifactIsSnapshot()
throws Exception
{
setupCleanRepo( repoRootInternal );
String putUrl = "http://machine.com/repository/internal/path/to/artifact/1.0-SNAPSHOT/artifact-1.0-SNAPSHOT.jar";
String metadataUrl = "http://machine.com/repository/internal/path/to/artifact/maven-metadata.xml";
String checksumUrl = "http://machine.com/repository/internal/path/to/artifact/1.0-SNAPSHOT/artifact-1.0-SNAPSHOT.jar.sha1";
InputStream is = getClass().getResourceAsStream( "/artifact.jar" );
// verify that the file exists in resources-dir
assertNotNull( "artifact.jar inputstream", is );
// send request #1 and verify it's successful
WebRequest request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
WebResponse response = sc.getResponse( request );
assertResponseCreated( response );
is = getClass().getResourceAsStream( "/artifact.jar.sha1" );
request = new PutMethodWebRequest( checksumUrl, is, "application/octet-stream" );
response = sc.getResponse( request );
assertResponseCreated( response );
is = getClass().getResourceAsStream( "/maven-metadata.xml" );
request = new PutMethodWebRequest( metadataUrl, is, "application/octet-stream" );
response = sc.getResponse( request );
assertResponseCreated( response );
// send request #2 and verify it's re-deployed
is = getClass().getResourceAsStream( "/artifact.jar" );
request = new PutMethodWebRequest( putUrl, is, "application/octet-stream" );
response = sc.getResponse( request );
assertResponseNoContent( response );
}
public void testMkColWithMissingParentCollectionFails() public void testMkColWithMissingParentCollectionFails()
throws Exception throws Exception
{ {
@ -115,6 +185,13 @@ public class RepositoryServletDeployTest
assertFalse(mkColLocalPath.exists()); assertFalse(mkColLocalPath.exists());
} }
protected void assertResponseNoContent( WebResponse response )
{
assertNotNull( "Should have recieved a response", response );
assertEquals( "Should have been a 204/NO CONTENT response code.", HttpServletResponse.SC_NO_CONTENT, response
.getResponseCode() );
}
protected void assertResponseCreated( WebResponse response ) protected void assertResponseCreated( WebResponse response )
{ {
assertNotNull( "Should have recieved a response", response ); assertNotNull( "Should have recieved a response", response );