mirror of https://github.com/apache/archiva.git
[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:
parent
7ecf7e1e88
commit
fa22abb913
|
@ -133,6 +133,20 @@ public class RepositoryRequest
|
|||
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>
|
||||
* Tests the path to see if it conforms to the expectations of a default layout request.
|
||||
|
|
|
@ -35,6 +35,16 @@ import java.io.File;
|
|||
public class RepositoryRequestTest
|
||||
extends AbstractRepositoryLayerTestCase
|
||||
{
|
||||
public void testInvalidRequestEmptyPath()
|
||||
{
|
||||
assertInvalidRequest( "" );
|
||||
}
|
||||
|
||||
public void testInvalidRequestSlashOnly()
|
||||
{
|
||||
assertInvalidRequest( "//" );
|
||||
}
|
||||
|
||||
public void testInvalidRequestNoArtifactId()
|
||||
{
|
||||
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/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()
|
||||
{
|
||||
|
|
|
@ -200,17 +200,10 @@ public class ArchivaDavResourceFactory
|
|||
return getResource( request, repoGroupConfig.getRepositories(), archivaLocator );
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
resource =
|
||||
processRepositoryGroup( request, archivaLocator, repoGroupConfig.getRepositories(),
|
||||
activePrincipal, resourcesInAbsolutePath );
|
||||
}
|
||||
catch ( ReleaseArtifactAlreadyExistsException e )
|
||||
{
|
||||
throw new DavException( HttpServletResponse.SC_CONFLICT );
|
||||
}
|
||||
{
|
||||
resource =
|
||||
processRepositoryGroup( request, archivaLocator, repoGroupConfig.getRepositories(),
|
||||
activePrincipal, resourcesInAbsolutePath );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -232,15 +225,8 @@ public class ArchivaDavResourceFactory
|
|||
}
|
||||
|
||||
log.debug( "Managed repository '" + managedRepository.getId() + "' accessed by '" + activePrincipal + "'" );
|
||||
|
||||
try
|
||||
{
|
||||
resource = processRepository( request, archivaLocator, activePrincipal, managedRepository );
|
||||
}
|
||||
catch ( ReleaseArtifactAlreadyExistsException e )
|
||||
{
|
||||
throw new DavException( HttpServletResponse.SC_CONFLICT, e );
|
||||
}
|
||||
|
||||
resource = processRepository( request, archivaLocator, activePrincipal, managedRepository );
|
||||
|
||||
String logicalResource = RepositoryPathUtil.getLogicalResource( locator.getResourcePath() );
|
||||
resourcesInAbsolutePath.add( new File( managedRepository.getRepoRoot(), logicalResource ).getAbsolutePath() );
|
||||
|
@ -250,7 +236,7 @@ public class ArchivaDavResourceFactory
|
|||
|
||||
// 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" ) ) ) &&
|
||||
if ( ( repositoryRequest.isMetadata( requestedResource ) || repositoryRequest.isMetadataSupportFile( requestedResource ) ) &&
|
||||
repoGroupConfig != null )
|
||||
{
|
||||
// this should only be at the project level not version level!
|
||||
|
@ -349,7 +335,7 @@ public class ArchivaDavResourceFactory
|
|||
private DavResource processRepositoryGroup( final DavServletRequest request,
|
||||
ArchivaDavResourceLocator archivaLocator, List<String> repositories,
|
||||
String activePrincipal, List<String> resourcesInAbsolutePath )
|
||||
throws DavException, ReleaseArtifactAlreadyExistsException
|
||||
throws DavException
|
||||
{
|
||||
DavResource resource = null;
|
||||
List<DavException> storedExceptions = new ArrayList<DavException>();
|
||||
|
@ -417,7 +403,7 @@ public class ArchivaDavResourceFactory
|
|||
|
||||
private DavResource processRepository( final DavServletRequest request, ArchivaDavResourceLocator archivaLocator,
|
||||
String activePrincipal, ManagedRepositoryContent managedRepository )
|
||||
throws DavException, ReleaseArtifactAlreadyExistsException
|
||||
throws DavException
|
||||
{
|
||||
DavResource resource = null;
|
||||
if ( isAuthorized( request, managedRepository.getId() ) )
|
||||
|
@ -507,21 +493,21 @@ public class ArchivaDavResourceFactory
|
|||
try
|
||||
{
|
||||
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 )
|
||||
{
|
||||
throw new DavException( HttpServletResponse.SC_BAD_REQUEST, e );
|
||||
}
|
||||
|
||||
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." );
|
||||
}
|
||||
log.warn( "Artifact path '" + resourcePath + "' is invalid." );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -63,7 +63,7 @@ public class RepositoryServletDeployTest
|
|||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public void testPreventOverwritingReleaseArtifacts()
|
||||
public void testReleaseArtifactsRedeploymentValidPath()
|
||||
throws Exception
|
||||
{
|
||||
setupCleanRepo( repoRootInternal );
|
||||
|
@ -98,6 +98,76 @@ public class RepositoryServletDeployTest
|
|||
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()
|
||||
throws Exception
|
||||
{
|
||||
|
@ -115,6 +185,13 @@ public class RepositoryServletDeployTest
|
|||
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 )
|
||||
{
|
||||
assertNotNull( "Should have recieved a response", response );
|
||||
|
|
Loading…
Reference in New Issue