[MRM-1296] Audit Log Report

o log to database all artifact deployments done via webdav
o updated webdav tests to reflect changes
o updated format of artifact field value in audit logs for consistency between web upload & webdav deployments


git-svn-id: https://svn.apache.org/repos/asf/archiva/branches/MRM-1296@891067 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Maria Odea B. Ching 2009-12-15 23:21:39 +00:00
parent 56c76e7571
commit e5f4782097
10 changed files with 122 additions and 32 deletions

View File

@ -49,7 +49,7 @@ public class ArchivaAuditLogsConstraint
{
whereClause = whereClause + " && artifact.like(desiredArtifact)";
declParamsList.add( "String desiredArtifact" );
paramsList.add( desiredArtifact );
paramsList.add( desiredArtifact );
}
if ( desiredRepositoryId != null && !"".equals( desiredRepositoryId ) )

View File

@ -423,7 +423,7 @@ public class UploadAction
String msg = "Artifact \'" + groupId + ":" + artifactId + ":" + version +
"\' was successfully deployed to repository \'" + repositoryId + "\'";
triggerAuditEvent( repositoryId, groupId + ":" + artifactId + ":" + version, AuditEvent.UPLOAD_FILE );
triggerAuditEvent( repositoryId, artifactPath, AuditEvent.UPLOAD_FILE );
addActionMessage( msg );

View File

@ -160,11 +160,11 @@ public class ViewAuditLogReportAction
if ( groupId != null && !"".equals( groupId.trim() ) )
{
artifact = groupId + ( ( artifactId != null && !"".equals( artifactId.trim() ) ) ? ( ":" + artifactId + ":%" ) : ":%" );
artifact = groupId + ( ( artifactId != null && !"".equals( artifactId.trim() ) ) ? ( "/" + artifactId + "/%" ) : "%" );
}
else
{
artifact = ( artifactId != null && !"".equals( artifactId.trim() ) ) ? ( "%:" + artifactId + ":%" ) : "";
artifact = ( artifactId != null && !"".equals( artifactId.trim() ) ) ? ( "%" + artifactId + "%" ) : "";
}
Date startDateInDF = null;
@ -189,17 +189,14 @@ public class ViewAuditLogReportAction
}
else
{
endDateInDF = DateUtils.parseDate( endDate, datePatterns );
if( endDate.equals( startDate ) )
{
Calendar cal = Calendar.getInstance();
cal.setTime( endDateInDF );
cal.set( Calendar.HOUR, 23 );
cal.set( Calendar.MINUTE, 59 );
cal.set( Calendar.SECOND, 59 );
endDateInDF = cal.getTime();
}
endDateInDF = DateUtils.parseDate( endDate, datePatterns );
Calendar cal = Calendar.getInstance();
cal.setTime( endDateInDF );
cal.set( Calendar.HOUR, 23 );
cal.set( Calendar.MINUTE, 59 );
cal.set( Calendar.SECOND, 59 );
endDateInDF = cal.getTime();
}
range[0] = ( page - 1 ) * rowCount;

View File

@ -24,6 +24,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
@ -54,6 +55,8 @@ import org.apache.jackrabbit.webdav.property.DavPropertySet;
import org.apache.jackrabbit.webdav.property.DefaultDavProperty;
import org.apache.jackrabbit.webdav.property.ResourceType;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.database.ArchivaAuditLogsDao;
import org.apache.maven.archiva.model.ArchivaAuditLogs;
import org.apache.maven.archiva.repository.audit.AuditEvent;
import org.apache.maven.archiva.repository.audit.AuditListener;
import org.apache.maven.archiva.scheduled.ArchivaTaskScheduler;
@ -104,11 +107,13 @@ public class ArchivaDavResource
private ArchivaTaskScheduler scheduler;
private Logger log = LoggerFactory.getLogger( ArchivaDavResource.class );
private ArchivaAuditLogsDao auditLogsDao;
public ArchivaDavResource( String localResource, String logicalResource, ManagedRepositoryConfiguration repository,
DavSession session, ArchivaDavResourceLocator locator, DavResourceFactory factory,
MimeTypes mimeTypes, List<AuditListener> auditListeners,
ArchivaTaskScheduler scheduler )
ArchivaTaskScheduler scheduler, ArchivaAuditLogsDao auditLogsDao )
{
this.localResource = new File( localResource );
this.logicalResource = logicalResource;
@ -123,15 +128,16 @@ public class ArchivaDavResource
this.mimeTypes = mimeTypes;
this.auditListeners = auditListeners;
this.scheduler = scheduler;
this.auditLogsDao = auditLogsDao;
}
public ArchivaDavResource( String localResource, String logicalResource, ManagedRepositoryConfiguration repository,
String remoteAddr, String principal, DavSession session, ArchivaDavResourceLocator locator,
DavResourceFactory factory, MimeTypes mimeTypes, List<AuditListener> auditListeners,
ArchivaTaskScheduler scheduler )
ArchivaTaskScheduler scheduler, ArchivaAuditLogsDao auditLogsDao )
{
this( localResource, logicalResource, repository, session, locator, factory, mimeTypes, auditListeners,
scheduler );
scheduler, auditLogsDao );
this.remoteAddr = remoteAddr;
this.principal = principal;
@ -641,6 +647,27 @@ public class ArchivaDavResource
{
listener.auditEvent( event );
}
// identify as artifact deployment/upload
if( action.equals( AuditEvent.CREATE_FILE ) )
{
action = AuditEvent.UPLOAD_FILE;
}
String user = principal;
if( principal == null )
{
user = "guest";
}
ArchivaAuditLogs auditLogs = new ArchivaAuditLogs();
auditLogs.setArtifact( resource );
auditLogs.setEvent( action );
auditLogs.setEventDate( Calendar.getInstance().getTime() );
auditLogs.setRepositoryId( repositoryId );
auditLogs.setUsername( user );
auditLogsDao.saveAuditLogs( auditLogs );
}
private void queueRepositoryTask( File localFile )

View File

@ -43,6 +43,7 @@ import org.apache.maven.archiva.common.utils.PathUtil;
import org.apache.maven.archiva.common.utils.VersionUtil;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.RepositoryGroupConfiguration;
import org.apache.maven.archiva.database.ArchivaAuditLogsDao;
import org.apache.maven.archiva.model.ArchivaRepositoryMetadata;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.policies.ProxyDownloadException;
@ -168,6 +169,11 @@ public class ArchivaDavResourceFactory
* @plexus.requirement
*/
private ArchivaTaskScheduler scheduler;
/**
* @plexus.requirement role-hint="jdo"
*/
private ArchivaAuditLogsDao auditLogsDao;
public DavResource createResource( final DavResourceLocator locator, final DavServletRequest request,
final DavServletResponse response )
@ -264,7 +270,7 @@ public class ArchivaDavResourceFactory
new ArchivaDavResource( metadataChecksum.getAbsolutePath(), logicalResource.getPath(),
null, request.getRemoteAddr(), activePrincipal,
request.getDavSession(), archivaLocator, this, mimeTypes,
auditListeners, scheduler );
auditListeners, scheduler, auditLogsDao );
}
}
else
@ -299,7 +305,7 @@ public class ArchivaDavResourceFactory
new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(),
null, request.getRemoteAddr(), activePrincipal,
request.getDavSession(), archivaLocator, this, mimeTypes,
auditListeners, scheduler );
auditListeners, scheduler, auditLogsDao );
}
catch ( RepositoryMetadataException r )
{
@ -418,7 +424,7 @@ public class ArchivaDavResourceFactory
resource =
new ArchivaDavResource( resourceFile.getAbsolutePath(), path, managedRepository.getRepository(),
request.getRemoteAddr(), activePrincipal, request.getDavSession(),
archivaLocator, this, mimeTypes, auditListeners, scheduler );
archivaLocator, this, mimeTypes, auditListeners, scheduler, auditLogsDao );
if ( WebdavMethodUtil.isReadMethod( request.getMethod() ) )
{
@ -449,7 +455,7 @@ public class ArchivaDavResourceFactory
new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource.getPath(),
managedRepository.getRepository(), request.getRemoteAddr(),
activePrincipal, request.getDavSession(), archivaLocator, this,
mimeTypes, auditListeners, scheduler );
mimeTypes, auditListeners, scheduler, auditLogsDao );
}
catch ( LayoutException e )
{
@ -529,7 +535,7 @@ public class ArchivaDavResourceFactory
log.debug( "Creating destination directory '" + destDir.getName() + "' (current user '" +
activePrincipal + "')" );
triggerAuditEvent( request.getRemoteAddr(), logicalResource.getPath(), relPath,
triggerAuditEvent( request.getRemoteAddr(), managedRepository.getId(), relPath,
AuditEvent.CREATE_DIR, activePrincipal );
}
}
@ -565,7 +571,7 @@ public class ArchivaDavResourceFactory
File resourceFile = new File( managedRepository.getRepoRoot(), logicalResource );
DavResource resource =
new ArchivaDavResource( resourceFile.getAbsolutePath(), logicalResource, managedRepository.getRepository(),
davSession, archivaLocator, this, mimeTypes, auditListeners, scheduler );
davSession, archivaLocator, this, mimeTypes, auditListeners, scheduler, auditLogsDao );
resource.addLockManager( lockManager );
return resource;
@ -1093,4 +1099,9 @@ public class ArchivaDavResourceFactory
{
this.connectors = connectors;
}
public void setAuditLogsDao( ArchivaAuditLogsDao auditLogsDao )
{
this.auditLogsDao = auditLogsDao;
}
}

View File

@ -33,6 +33,8 @@ 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.configuration.RepositoryGroupConfiguration;
import org.apache.maven.archiva.database.ArchivaAuditLogsDao;
import org.apache.maven.archiva.model.ArchivaAuditLogs;
import org.apache.maven.archiva.proxy.DefaultRepositoryProxyConnectors;
import org.apache.maven.archiva.repository.ManagedRepositoryContent;
import org.apache.maven.archiva.repository.RepositoryContentFactory;
@ -81,6 +83,10 @@ public class ArchivaDavResourceFactoryTest
private MockControl repoContentFactoryControl;
private RepositoryContentFactory repoFactory;
private ArchivaAuditLogsDao auditLogsDao;
private MockControl auditLogsDaoControl;
public void setUp()
throws Exception
@ -96,6 +102,10 @@ public class ArchivaDavResourceFactoryTest
archivaConfigurationControl = MockControl.createControl( ArchivaConfiguration.class );
archivaConfiguration = (ArchivaConfiguration) archivaConfigurationControl.getMock();
auditLogsDaoControl = MockControl.createControl( ArchivaAuditLogsDao.class );
auditLogsDaoControl.setDefaultMatcher( MockControl.ALWAYS_MATCHER );
auditLogsDao = (ArchivaAuditLogsDao) auditLogsDaoControl.getMock();
config = new Configuration();
config.addManagedRepository( createManagedRepository( RELEASES_REPO, new File( getBasedir(),
@ -125,6 +135,7 @@ public class ArchivaDavResourceFactoryTest
resourceFactory.setRepositoryFactory( repoFactory );
resourceFactory.setRepositoryRequest( repoRequest );
resourceFactory.setConnectors( new OverridingRepositoryProxyConnectors() );
resourceFactory.setAuditLogsDao( auditLogsDao );
}
private ManagedRepositoryConfiguration createManagedRepository( String id, String location, String layout )
@ -392,7 +403,7 @@ public class ArchivaDavResourceFactoryTest
long date = 2039842134;
response.addDateHeader( "last-modified", date );
responseControl.setVoidCallable();
archivaConfigurationControl.replay();
repoContentFactoryControl.replay();
requestControl.replay();

View File

@ -20,7 +20,9 @@ package org.apache.maven.archiva.webdav;
*/
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.io.FileUtils;
import org.apache.jackrabbit.webdav.DavException;
@ -37,12 +39,15 @@ import org.apache.jackrabbit.webdav.lock.Scope;
import org.apache.jackrabbit.webdav.lock.SimpleLockManager;
import org.apache.jackrabbit.webdav.lock.Type;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.database.ArchivaAuditLogsDao;
import org.apache.maven.archiva.database.ArchivaDatabaseException;
import org.apache.maven.archiva.database.Constraint;
import org.apache.maven.archiva.database.ObjectNotFoundException;
import org.apache.maven.archiva.model.ArchivaAuditLogs;
import org.apache.maven.archiva.repository.audit.AuditListener;
import org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers;
import org.apache.maven.archiva.webdav.util.MimeTypes;
import org.codehaus.plexus.spring.PlexusInSpringTestCase;
import org.codehaus.plexus.spring.PlexusToSpringUtils;
import org.codehaus.plexus.taskqueue.execution.TaskQueueExecutor;
public class DavResourceTest
extends PlexusInSpringTestCase
@ -67,23 +72,27 @@ public class DavResourceTest
private ManagedRepositoryConfiguration repository = new ManagedRepositoryConfiguration();
private ArchivaAuditLogsDao auditLogsDao;
@Override
protected void setUp()
throws Exception
{
super.setUp();
session = new ArchivaDavSession();
auditLogsDao = new ArchivaAuditLogsDaoImpl();
mimeTypes = (MimeTypes) getApplicationContext().getBean( PlexusToSpringUtils.buildSpringId( MimeTypes.class ) );
baseDir = getTestFile( "target/DavResourceTest" );
baseDir.mkdirs();
myResource = new File( baseDir, "myresource.jar" );
assertTrue( "Could not create " + myResource.getAbsolutePath(), myResource.createNewFile() );
resourceFactory = new RootContextDavResourceFactory();
resourceLocator =
(ArchivaDavResourceLocator) new ArchivaDavLocatorFactory().createResourceLocator( "/", REPOPATH );
(ArchivaDavResourceLocator) new ArchivaDavLocatorFactory().createResourceLocator( "/", REPOPATH );
resource = getDavResource( resourceLocator.getHref( false ), myResource );
lockManager = new SimpleLockManager();
resource.addLockManager( lockManager );
resource.addLockManager( lockManager );
}
@Override
@ -98,7 +107,7 @@ public class DavResourceTest
private DavResource getDavResource( String logicalPath, File file )
{
return new ArchivaDavResource( file.getAbsolutePath(), logicalPath, repository, session, resourceLocator,
resourceFactory, mimeTypes, Collections.<AuditListener> emptyList(), null );
resourceFactory, mimeTypes, Collections.<AuditListener> emptyList(), null, auditLogsDao );
}
public void testDeleteNonExistantResourceShould404()
@ -305,7 +314,28 @@ public class DavResourceTest
{
return new ArchivaDavResource( baseDir.getAbsolutePath(), "/", repository, session, resourceLocator,
resourceFactory, mimeTypes, Collections.<AuditListener> emptyList(),
null );
null, auditLogsDao );
}
}
private class ArchivaAuditLogsDaoImpl
implements ArchivaAuditLogsDao
{
public List<ArchivaAuditLogs> queryAuditLogs( Constraint constraint )
throws ObjectNotFoundException, ArchivaDatabaseException
{
return new ArrayList<ArchivaAuditLogs>();
}
public ArchivaAuditLogs saveAuditLogs( ArchivaAuditLogs logs )
{
return new ArchivaAuditLogs();
}
public void deleteAuditLogs( ArchivaAuditLogs logs )
throws ArchivaDatabaseException
{
}
}
}

View File

@ -39,6 +39,7 @@ 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.users.User;
import org.codehaus.plexus.redback.users.memory.SimpleUser;
import org.codehaus.plexus.spring.PlexusInSpringTestCase;
import org.codehaus.redback.integration.filter.authentication.HttpAuthenticator;
@ -352,11 +353,14 @@ public class RepositoryServletSecurityTest
httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, null ), true );
User user = new SimpleUser();
user.setUsername( "admin" );
// ArchivaDavResourceFactory#isAuthorized()
SecuritySession session = new DefaultSecuritySession();
httpAuthControl.expectAndReturn( httpAuth.getAuthenticationResult( null, null ), result );
httpAuthControl.expectAndReturn( httpAuth.getSecuritySession( ic.getRequest().getSession( true ) ), session );
httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), new SimpleUser() );
httpAuthControl.expectAndReturn( httpAuth.getSessionUser( ic.getRequest().getSession() ), user );
servletAuthControl.expectAndReturn( servletAuth.isAuthenticated( null, result ), true );
servletAuthControl.expectAndReturn(
servletAuth.isAuthorized( null, session, "internal",

View File

@ -148,6 +148,11 @@
<role>org.apache.maven.archiva.scheduled.ArchivaTaskScheduler</role>
<field-name>scheduler</field-name>
</requirement>
<requirement>
<role>org.apache.maven.archiva.database.ArchivaAuditLogsDao</role>
<role-hint>jdo</role-hint>
<field-name>auditLogsDao</field-name>
</requirement>
</requirements>
</component>
<component>

View File

@ -160,6 +160,11 @@
<role>org.apache.maven.archiva.scheduled.ArchivaTaskScheduler</role>
<field-name>scheduler</field-name>
</requirement>
<requirement>
<role>org.apache.maven.archiva.database.ArchivaAuditLogsDao</role>
<role-hint>jdo</role-hint>
<field-name>auditLogsDao</field-name>
</requirement>
</requirements>
</component>
<component>