--- /dev/null
+package org.apache.maven.archiva.repository.audit;
+
+/*
+ * 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.
+ */
+
+/**
+ * AuditEvent
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public class AuditEvent
+{
+ public static final String CREATE_DIR = "Created Directory";
+
+ public static final String CREATE_FILE = "Created File";
+
+ public static final String REMOVE_DIR = "Removed Directory";
+
+ public static final String REMOVE_FILE = "Removed File";
+
+ public static final String MODIFY_FILE = "Modify File";
+
+ private String repositoryId;
+
+ private String userId;
+
+ private String remoteIP;
+
+ private String resource;
+
+ private String action;
+
+ public AuditEvent()
+ {
+ /* do nothing */
+ }
+
+ public AuditEvent( String repoId, String user, String resource, String action )
+ {
+ this.repositoryId = repoId;
+ this.userId = user;
+ this.resource = resource;
+ this.action = action;
+ }
+
+ public String getRepositoryId()
+ {
+ return repositoryId;
+ }
+
+ public void setRepositoryId( String repositoryId )
+ {
+ this.repositoryId = repositoryId;
+ }
+
+ public String getUserId()
+ {
+ return userId;
+ }
+
+ public void setUserId( String userId )
+ {
+ this.userId = userId;
+ }
+
+ public String getResource()
+ {
+ return resource;
+ }
+
+ public void setResource( String resource )
+ {
+ this.resource = resource;
+ }
+
+ public String getAction()
+ {
+ return action;
+ }
+
+ public void setAction( String action )
+ {
+ this.action = action;
+ }
+
+ public String getRemoteIP()
+ {
+ return remoteIP;
+ }
+
+ public void setRemoteIP( String remoteIP )
+ {
+ this.remoteIP = remoteIP;
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.repository.audit;
+
+/*
+ * 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.
+ */
+
+/**
+ * AuditListener
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface AuditListener
+{
+ /**
+ * Notification that an audit event occured.
+ *
+ * @param event the event details.
+ */
+ public void auditEvent( AuditEvent event );
+}
--- /dev/null
+package org.apache.maven.archiva.repository.audit;
+
+/*
+ * 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 org.apache.log4j.Logger;
+
+/**
+ * AuditLog - Audit Log.
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ *
+ * @plexus.component role="org.apache.maven.archiva.repository.audit.AuditListener"
+ * role-hint="logging"
+ */
+public class AuditLog
+ implements AuditListener
+{
+ public static final Logger logger = Logger.getLogger( "org.apache.archiva.AuditLog" );
+
+ private static final char DELIM = ' ';
+
+ /**
+ * Creates a log message in the following format ...
+ *
+ * "{repository_id} {user_id} {remote_ip} \"{resource}\" \"{action}\""
+ */
+ public void auditEvent( AuditEvent event )
+ {
+ StringBuffer msg = new StringBuffer();
+ msg.append( event.getRepositoryId() ).append( DELIM );
+ msg.append( event.getUserId() ).append( DELIM );
+ msg.append( event.getRemoteIP() ).append( DELIM );
+ msg.append( '\"' ).append( event.getResource() ).append( '\"' ).append( DELIM );
+ msg.append( '\"' ).append( event.getAction() ).append( '\"' );
+
+ logger.info( msg.toString() );
+ }
+}
--- /dev/null
+package org.apache.maven.archiva.repository.audit;
+
+/*
+ * 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.
+ */
+
+/**
+ * Auditable
+ *
+ * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
+ * @version $Id$
+ */
+public interface Auditable
+{
+ /**
+ * Add an AuditListener.
+ *
+ * @param the listener to add.
+ */
+ public void addAuditListener( AuditListener auditListener );
+
+ /**
+ * Remove an AuditListener.
+ *
+ * @param the listener to remove.
+ */
+ public void removeAuditListener( AuditListener auditListener );
+
+ /**
+ * Remove all registered {@link AuditListener} objects.
+ */
+ public void clearAuditListeners();
+}
</roleDefaults>
</configuration>
</plugin>
- <!--
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
</execution>
</executions>
</plugin>
- -->
</plugins>
</build>
<profiles>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration>
- <version>2</version>
- <managedRepositories>
- <managedRepository>
- <id>internal</id>
- <name>Archiva Managed Internal Repository</name>
- <location>${appserver.base}/data/repositories/internal</location>
- <layout>default</layout>
- <releases>true</releases>
- <snapshots>false</snapshots>
- <scanned>true</scanned>
- <refreshCronExpression>0 0 0 * * ?</refreshCronExpression>
- <daysOlder>30</daysOlder>
- </managedRepository>
- <managedRepository>
- <id>snapshots</id>
- <name>Archiva Managed Snapshot Repository</name>
- <location>${appserver.base}/data/repositories/snapshots</location>
- <layout>default</layout>
- <releases>false</releases>
- <snapshots>true</snapshots>
- <scanned>true</scanned>
- <refreshCronExpression>0 0\,30 0 * * ?</refreshCronExpression>
- <daysOlder>30</daysOlder>
- </managedRepository>
- </managedRepositories>
- <remoteRepositories>
- <remoteRepository>
- <id>central</id>
- <name>Central Repository</name>
- <url>http://repo1.maven.org/maven2</url>
- <layout>default</layout>
- </remoteRepository>
- <remoteRepository>
- <id>maven2-repository.dev.java.net</id>
- <name>Java.net Repository for Maven 2</name>
- <url>http://download.java.net/maven/2/</url>
- <layout>default</layout>
- </remoteRepository>
- </remoteRepositories>
-
- <proxyConnectors>
- <proxyConnector>
- <sourceRepoId>internal</sourceRepoId>
- <targetRepoId>central</targetRepoId>
- <proxyId/>
- <policies>
- <snapshots>disabled</snapshots>
- <releases>once</releases>
- <checksum>fix</checksum>
- <cache-failures>cached</cache-failures>
- </policies>
- <whiteListPatterns>
- <whiteListPattern>**/*</whiteListPattern>
- </whiteListPatterns>
- </proxyConnector>
- <proxyConnector>
- <sourceRepoId>internal</sourceRepoId>
- <targetRepoId>maven2-repository.dev.java.net</targetRepoId>
- <proxyId/>
- <policies>
- <snapshots>disabled</snapshots>
- <releases>once</releases>
- <checksum>fix</checksum>
- <cache-failures>cached</cache-failures>
- </policies>
- <whiteListPatterns>
- <whiteListPattern>javax/**</whiteListPattern>
- </whiteListPatterns>
- </proxyConnector>
- </proxyConnectors>
-
- <repositoryScanning>
- <fileTypes>
- <fileType>
- <id>artifacts</id>
- <patterns>
- <pattern>**/*.pom</pattern>
- <pattern>**/*.jar</pattern>
- <pattern>**/*.ear</pattern>
- <pattern>**/*.war</pattern>
- <pattern>**/*.car</pattern>
- <pattern>**/*.sar</pattern>
- <pattern>**/*.mar</pattern>
- <pattern>**/*.rar</pattern>
- <pattern>**/*.dtd</pattern>
- <pattern>**/*.tld</pattern>
- <pattern>**/*.tar.gz</pattern>
- <pattern>**/*.tar.bz2</pattern>
- <pattern>**/*.zip</pattern>
- </patterns>
- </fileType>
- <fileType>
- <id>indexable-content</id>
- <patterns>
- <pattern>**/*.txt</pattern>
- <pattern>**/*.TXT</pattern>
- <pattern>**/*.block</pattern>
- <pattern>**/*.config</pattern>
- <pattern>**/*.pom</pattern>
- <pattern>**/*.xml</pattern>
- <pattern>**/*.xsd</pattern>
- <pattern>**/*.dtd</pattern>
- <pattern>**/*.tld</pattern>
- </patterns>
- </fileType>
- <fileType>
- <id>auto-remove</id>
- <patterns>
- <pattern>**/*.bak</pattern>
- <pattern>**/*~</pattern>
- <pattern>**/*-</pattern>
- </patterns>
- </fileType>
- <fileType>
- <id>ignored</id>
- <patterns>
- <pattern>**/.htaccess</pattern>
- <pattern>**/KEYS</pattern>
- <pattern>**/*.rb</pattern>
- <pattern>**/*.sh</pattern>
- <pattern>**/.svn/**</pattern>
- <pattern>**/.DAV/**</pattern>
- </patterns>
- </fileType>
- </fileTypes>
- <knownContentConsumers>
- <knownContentConsumer>update-db-artifact</knownContentConsumer>
- <knownContentConsumer>create-missing-checksums</knownContentConsumer>
- <knownContentConsumer>update-db-repository-metadata</knownContentConsumer>
- <knownContentConsumer>validate-checksum</knownContentConsumer>
- <knownContentConsumer>validate-signature</knownContentConsumer>
- <knownContentConsumer>index-content</knownContentConsumer>
- <knownContentConsumer>auto-remove</knownContentConsumer>
- <knownContentConsumer>auto-rename</knownContentConsumer>
- <knownContentConsumer>metadata-updater</knownContentConsumer>
- <!--knownContentConsumer>repository-purge</knownContentConsumer-->
- </knownContentConsumers>
- <invalidContentConsumers>
- <invalidContentConsumer>update-db-bad-content</invalidContentConsumer>
- </invalidContentConsumers>
- </repositoryScanning>
-
- <databaseScanning>
- <cronExpression>0 0 0 * * ?</cronExpression>
- <unprocessedConsumers>
- <unprocessedConsumer>index-artifact</unprocessedConsumer>
- <unprocessedConsumer>update-db-project</unprocessedConsumer>
- <unprocessedConsumer>validate-repository-metadata</unprocessedConsumer>
- <unprocessedConsumer>index-archive-toc</unprocessedConsumer>
- <unprocessedConsumer>update-db-bytecode-stats</unprocessedConsumer>
- <unprocessedConsumer>index-public-methods</unprocessedConsumer>
- </unprocessedConsumers>
- <cleanupConsumers>
- <cleanupConsumer>not-present-remove-db-artifact</cleanupConsumer>
- <cleanupConsumer>not-present-remove-db-project</cleanupConsumer>
- <cleanupConsumer>not-present-remove-indexed</cleanupConsumer>
- </cleanupConsumers>
- </databaseScanning>
-
- <webapp>
- <ui>
- <showFindArtifacts>true</showFindArtifacts>
- <appletFindEnabled>true</appletFindEnabled>
- </ui>
- </webapp>
-
-</configuration>
+++ /dev/null
-package org.apache.maven.archiva.web.repository;
-
-/*
- * 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 org.apache.commons.lang.StringUtils;
-import org.codehaus.plexus.evaluator.EvaluatorException;
-import org.codehaus.plexus.evaluator.ExpressionEvaluator;
-import org.codehaus.plexus.evaluator.ExpressionSource;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
-import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
-import org.codehaus.plexus.webdav.DavServerComponent;
-import org.codehaus.plexus.webdav.DavServerListener;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-/**
- * AuditLog - Audit Log.
- *
- * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
- * @version $Id$
- *
- * @plexus.component role="org.apache.maven.archiva.web.repository.AuditLog"
- */
-public class AuditLog
- implements DavServerListener, Initializable
-{
- public static final String ROLE = AuditLog.class.getName();
-
- /**
- * @plexus.configuration default-value="${appserver.base}/logs/audit.log"
- */
- private String logFilename;
-
- /**
- * @plexus.configuration default-value="yyyy-MM-dd HH:mm:ss"
- */
- private String timestampFormat;
-
- /**
- * @plexus.requirement role-hint="default"
- */
- private ExpressionEvaluator expressionEvaluator;
-
- /**
- * @plexus.requirement role-hint="sysprops"
- */
- private ExpressionSource syspropExprSource;
-
- private File logFile;
-
- private PrintWriter writer;
-
- private SimpleDateFormat timestamp;
-
- private String getServerId( DavServerComponent server )
- {
- return "[" + server.getPrefix() + "]";
- }
-
- public void serverCollectionCreated( DavServerComponent server, String resource )
- {
- log( getServerId( server ) + " Created Directory \"" + resource + "\"" );
- }
-
- public void serverCollectionRemoved( DavServerComponent server, String resource )
- {
- log( getServerId( server ) + " Removed Directory \"" + resource + "\"" );
- }
-
- public void serverResourceCreated( DavServerComponent server, String resource )
- {
- log( getServerId( server ) + " Created File \"" + resource + "\"" );
- }
-
- public void serverResourceModified( DavServerComponent server, String resource )
- {
- log( getServerId( server ) + " Modified Existing File \"" + resource + "\"" );
- }
-
- public void serverResourceRemoved( DavServerComponent server, String resource )
- {
- log( getServerId( server ) + " Removed File \"" + resource + "\"" );
- }
-
- /**
- * Log the message to the file.
- *
- * @param msg the message.
- */
- public void log( String msg )
- {
- // Synchronize to prevent threading issues.
- synchronized ( writer )
- {
- writer.println( timestamp.format( new Date() ) + " - " + msg );
- // Manually flush buffer to ensure data is written to disk.
- writer.flush();
- }
- }
-
- public void initialize()
- throws InitializationException
- {
- String actualFilename;
- try
- {
- expressionEvaluator.addExpressionSource( syspropExprSource );
- actualFilename = expressionEvaluator.expand( this.logFilename );
- }
- catch ( EvaluatorException e1 )
- {
- actualFilename = this.logFilename;
- }
-
- this.logFile = new File( actualFilename );
-
- File parentDir = logFile.getParentFile();
- if ( parentDir != null )
- {
- if ( !parentDir.exists() )
- {
- parentDir.mkdirs();
- }
- }
-
- if ( StringUtils.isBlank( timestampFormat ) )
- {
- timestampFormat = "yyyy-MM-dd HH:mm:ss";
- }
-
- timestamp = new SimpleDateFormat( timestampFormat );
-
- try
- {
- writer = new PrintWriter( new FileWriter( logFile ) );
- log( "Logging Initialized." );
- }
- catch ( IOException e )
- {
- throw new InitializationException( "Unable to initialize log file writer: " + logFile.getAbsolutePath(), e );
- }
- }
-}
* under the License.
*/
+import org.apache.maven.archiva.common.utils.PathUtil;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.ProjectReference;
import org.apache.maven.archiva.model.VersionedReference;
import org.apache.maven.archiva.repository.RepositoryContentFactory;
import org.apache.maven.archiva.repository.RepositoryException;
import org.apache.maven.archiva.repository.RepositoryNotFoundException;
+import org.apache.maven.archiva.repository.audit.AuditEvent;
+import org.apache.maven.archiva.repository.audit.AuditListener;
+import org.apache.maven.archiva.repository.audit.Auditable;
import org.apache.maven.archiva.repository.content.RepositoryRequest;
import org.apache.maven.archiva.repository.layout.LayoutException;
import org.apache.maven.archiva.repository.metadata.MetadataTools;
import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
+import org.apache.maven.archiva.security.ArchivaUser;
import org.apache.maven.model.DistributionManagement;
import org.apache.maven.model.Model;
import org.apache.maven.model.Relocation;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
*/
public class ProxiedDavServer
extends AbstractDavServerComponent
+ implements Auditable
{
/**
* @plexus.requirement role-hint="simple"
*/
private DavServerComponent davServer;
-
+
+ /**
+ * @plexus.requirement role="org.apache.maven.archiva.repository.audit.AuditListener"
+ */
+ private List<AuditListener> auditListeners = new ArrayList<AuditListener>();
+
/**
* @plexus.requirement
*/
* @plexus.requirement
*/
private MetadataTools metadataTools;
+
+ /**
+ * @plexus.requirement role-hint="xwork"
+ */
+ private ArchivaUser archivaUser;
private ManagedRepositoryContent managedRepository;
{
boolean isGet = WebdavMethodUtil.isReadMethod( request.getRequest().getMethod() );
boolean isPut = WebdavMethodUtil.isWriteMethod( request.getRequest().getMethod() );
+ String resource = request.getLogicalResource();
if ( isGet )
{
// Default behaviour is to treat the resource natively.
- String resource = request.getLogicalResource();
File resourceFile = new File( managedRepository.getRepoRoot(), resource );
// If this a directory resource, then we are likely browsing.
// Adjust the pathInfo resource to be in the format that the dav server impl expects.
request.getRequest().setPathInfo( resource );
+ boolean previouslyExisted = resourceFile.exists();
+
// Attempt to fetch the resource from any defined proxy.
- fetchContentFromProxies( request, resource );
+ if( fetchContentFromProxies( request, resource ) )
+ {
+ processAuditEvents( request, resource, previouslyExisted, resourceFile, " (proxied)" );
+ }
}
catch ( LayoutException e )
{
File rootDirectory = getRootDirectory();
if ( rootDirectory != null )
{
- new File( rootDirectory, request.getLogicalResource() ).getParentFile().mkdirs();
+ File destDir = new File( rootDirectory, resource ).getParentFile();
+ if( !destDir.exists() )
+ {
+ destDir.mkdirs();
+ String relPath = PathUtil.getRelative( rootDirectory.getAbsolutePath(), destDir );
+ triggerAuditEvent( request, relPath, AuditEvent.CREATE_DIR );
+ }
}
+ File resourceFile = new File( managedRepository.getRepoRoot(), resource );
+
+ boolean previouslyExisted = resourceFile.exists();
+
// Allow the dav server to process the put request.
davServer.process( request, response );
+ processAuditEvents( request, resource, previouslyExisted, resourceFile, null );
+
// All done.
return;
}
}
}
- private void fetchContentFromProxies( DavServerRequest request, String resource )
+ private boolean fetchContentFromProxies( DavServerRequest request, String resource )
throws ServletException
{
if ( repositoryRequest.isSupportFile( resource ) )
// Checksums are fetched with artifact / metadata.
// Need to adjust the path for the checksum resource.
- return;
+ return false;
}
// Is it a Metadata resource?
if ( repositoryRequest.isDefault( resource ) && repositoryRequest.isMetadata( resource ) )
{
- if ( fetchMetadataFromProxies( request, resource ) )
- {
- return;
- }
+ return fetchMetadataFromProxies( request, resource );
}
// Not any of the above? Then it's gotta be an artifact reference.
{
applyServerSideRelocation( artifact );
- connectors.fetchFromProxies( managedRepository, artifact );
+ File proxiedFile = connectors.fetchFromProxies( managedRepository, artifact );
// Set the path to the resource using managed repository specific layout format.
request.getRequest().setPathInfo( managedRepository.toPath( artifact ) );
- return;
+ return ( proxiedFile != null );
}
}
catch ( LayoutException e )
{
throw new ServletException( "Unable to fetch artifact resource.", e );
}
+ return false;
}
private boolean fetchMetadataFromProxies( DavServerRequest request, String resource )
{
return managedRepository;
}
+
+ private void processAuditEvents( DavServerRequest request, String resource, boolean previouslyExisted,
+ File resourceFile, String suffix )
+ {
+ if( suffix == null )
+ {
+ suffix = "";
+ }
+
+ // Process Create Audit Events.
+ if ( !previouslyExisted && resourceFile.exists() )
+ {
+ if ( resourceFile.isFile() )
+ {
+ triggerAuditEvent( request, resource, AuditEvent.CREATE_FILE + suffix );
+ }
+ else if ( resourceFile.isDirectory() )
+ {
+ triggerAuditEvent( request, resource, AuditEvent.CREATE_DIR + suffix );
+ }
+ }
+ // Process Remove Audit Events.
+ else if ( previouslyExisted && !resourceFile.exists() )
+ {
+ if ( resourceFile.isFile() )
+ {
+ triggerAuditEvent( request, resource, AuditEvent.REMOVE_FILE + suffix );
+ }
+ else if ( resourceFile.isDirectory() )
+ {
+ triggerAuditEvent( request, resource, AuditEvent.REMOVE_DIR + suffix );
+ }
+ }
+ // Process modify events.
+ else
+ {
+ if ( resourceFile.isFile() )
+ {
+ triggerAuditEvent( request, resource, AuditEvent.MODIFY_FILE + suffix );
+ }
+ }
+ }
+
+ private void triggerAuditEvent( String user, String remoteIP, String resource, String action )
+ {
+ AuditEvent event = new AuditEvent( this.getPrefix(), user, resource, action );
+ event.setRemoteIP( remoteIP );
+
+ for ( AuditListener listener : auditListeners )
+ {
+ listener.auditEvent( event );
+ }
+ }
+
+ private void triggerAuditEvent( DavServerRequest request, String resource, String action )
+ {
+ triggerAuditEvent( archivaUser.getActivePrincipal(), getRemoteIP( request ), resource, action );
+ }
+
+ private String getRemoteIP( DavServerRequest request )
+ {
+ return request.getRequest().getRemoteAddr();
+ }
+
+ public void addAuditListener( AuditListener listener )
+ {
+ this.auditListeners.add( listener );
+ }
+
+ public void clearAuditListeners()
+ {
+ this.auditListeners.clear();
+ }
+
+ public void removeAuditListener( AuditListener listener )
+ {
+ this.auditListeners.remove( listener );
+ }
}
private HttpAuthenticator httpAuth;
- private AuditLog audit;
-
private ArchivaConfiguration configuration;
private Map<String, ManagedRepositoryConfiguration> repositoryMap;
securitySystem = (SecuritySystem) lookup( SecuritySystem.ROLE );
httpAuth = (HttpAuthenticator) lookup( HttpAuthenticator.ROLE, "basic" );
- audit = (AuditLog) lookup( AuditLog.ROLE );
configuration = (ArchivaConfiguration) lookup( ArchivaConfiguration.class.getName() );
configuration.addListener( this );
DavServerComponent server = createServer( repo.getId(), repoDir, servletConfig );
server.setUseIndexHtml( true );
- server.addListener( audit );
}
}
log( "Unable to release HttpAuth : " + e.getMessage(), e );
}
try
- {
- release( audit );
- }
- catch ( ServletException e )
- {
- log( "Unable to release AuditLog : " + e.getMessage(), e );
- }
- try
{
release( configuration );
}
<param name="ConversionPattern" value="%-4r [%t] %-5p %c %x - %m%n"/>
</layout>
</appender>
+
+ <appender name="auditlog" class="org.apache.log4j.DailyRollingFileAppender">
+ <param name="file" value="${appserver.base}/logs/audit.log" />
+ <param name="append" value="true" />
+ <param name="datePattern" value="'.'yyyy-MM-dd" />
+ <layout class="org.apache.log4j.PatternLayout">
+ <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %m%n"/>
+ </layout>
+ </appender>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<level value="debug" />
</logger>
+ <logger name="org.apache.archiva.AuditLog">
+ <level value="info" />
+ <appender-ref ref="auditlog" />
+ </logger>
+
<logger name="org.codehaus.plexus.security">
<level value="info"/>
</logger>