mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged HEAD-BUG-FIX (4.3/Cloud) to HEAD (4.3/Cloud)
67735: Merged V4.2-BUG-FIX (4.2.3) to HEAD-BUG-FIX (4.3/Cloud) 65767: Merged DEV to V4.2-BUG-FIX 65559 : MNT-10807 : Auditing does not take into account audit.filter.alfresco-access.transaction.user Added UserAuditFilter class, inject an instance into AuditComponentImpl. Added unit test. 65671 : MNT-10807 : Auditing does not take into account audit.filter.alfresco-access.transaction.user Fixed some code problem. Reverted test from AuditComponentTest and created new UserAuditFilterTest. 65754 : MNT-10807 : Auditing does not take into account audit.filter.alfresco-access.transaction.user Included 'UserAuditFilterTest' test in a test suite. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@68374 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
<property name="auditDAO" ref="auditDAO"/>
|
||||
<property name="auditModelRegistry" ref="Audit"/>
|
||||
<property name="propertyValueDAO" ref="propertyValueDAO"/>
|
||||
<property name="userAuditFilter" ref="userAuditFilter"/>
|
||||
<property name="auditFilter">
|
||||
<bean class="org.alfresco.repo.audit.PropertyAuditFilter">
|
||||
<property name="properties" ref="global-properties" />
|
||||
@@ -37,6 +38,14 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- User Audit Filter -->
|
||||
|
||||
<bean id="userAuditFilter" class="org.alfresco.repo.audit.UserAuditFilter">
|
||||
<property name="userFilterPattern">
|
||||
<value>${audit.filter.alfresco-access.transaction.user}</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Access Auditor -->
|
||||
|
||||
<bean id="accessAuditor" class="org.alfresco.repo.audit.access.AccessAuditor">
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2010 Alfresco Software Limited.
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
@@ -53,6 +53,13 @@ public interface AuditComponent
|
||||
*/
|
||||
public void setAuditEnabled(boolean enable);
|
||||
|
||||
/**
|
||||
* @param userAuditFilter
|
||||
*
|
||||
* @since 4.2
|
||||
*/
|
||||
public void setUserAuditFilter(UserAuditFilter userAuditFilter);
|
||||
|
||||
/**
|
||||
* Get all registered audit applications, whether active or not.
|
||||
*
|
||||
|
@@ -75,6 +75,7 @@ public class AuditComponentImpl implements AuditComponent
|
||||
private AuditDAO auditDAO;
|
||||
private TransactionService transactionService;
|
||||
private AuditFilter auditFilter;
|
||||
private UserAuditFilter userAuditFilter;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
@@ -126,6 +127,11 @@ public class AuditComponentImpl implements AuditComponent
|
||||
this.auditFilter = auditFilter;
|
||||
}
|
||||
|
||||
public void setUserAuditFilter(UserAuditFilter userAuditFilter)
|
||||
{
|
||||
this.userAuditFilter = userAuditFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @since 3.2
|
||||
@@ -499,7 +505,8 @@ public class AuditComponentImpl implements AuditComponent
|
||||
ParameterCheck.mandatory("rootPath", rootPath);
|
||||
AuditApplication.checkPathFormat(rootPath);
|
||||
|
||||
if (values == null || values.isEmpty() || !areAuditValuesRequired() || !auditFilter.accept(rootPath, values))
|
||||
String username = AuthenticationUtil.getFullyAuthenticatedUser();
|
||||
if (values == null || values.isEmpty() || !areAuditValuesRequired() || !userAuditFilter.acceptUser(username) || !auditFilter.accept(rootPath, values))
|
||||
{
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
109
source/java/org/alfresco/repo/audit/UserAuditFilter.java
Normal file
109
source/java/org/alfresco/repo/audit/UserAuditFilter.java
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.audit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
public class UserAuditFilter implements InitializingBean
|
||||
{
|
||||
private static final char NOT = '~';
|
||||
private static final String REG_EXP_SEPARATOR = ";";
|
||||
private static final char ESCAPE = '\\';
|
||||
private static final String ESCAPED_NOT = ""+ESCAPE+NOT;
|
||||
|
||||
private String userFilterPattern;
|
||||
private List<Pair<Boolean, Pattern>> listOfPairValue = new ArrayList<Pair<Boolean, Pattern>>();
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public UserAuditFilter()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Set user audit pattern. For example "audit.filter.alfresco-access.transaction.user=~user1;user2;.*"
|
||||
*
|
||||
* @param userFilterPattern 'userFilterPattern' is String type. The value of 'userFilterPattern' couldn't empty
|
||||
* or have 0 length value. An expression that starts with a '~' indicates that any
|
||||
* matching value should be rejected. Each regular expression in the list is separated
|
||||
* by a semicolon (';').
|
||||
*/
|
||||
public void setUserFilterPattern(String userFilterPattern)
|
||||
{
|
||||
this.userFilterPattern = userFilterPattern;
|
||||
}
|
||||
|
||||
public void afterPropertiesSet()
|
||||
{
|
||||
parseProperties();
|
||||
}
|
||||
|
||||
private void parseProperties()
|
||||
{
|
||||
String userPropertyValue = userFilterPattern;
|
||||
if (!PropertyCheck.isValidPropertyString(userPropertyValue))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String[] arrValues = userPropertyValue.split(REG_EXP_SEPARATOR);
|
||||
for (String prop : arrValues)
|
||||
{
|
||||
boolean includeExp = prop.charAt(0) != NOT;
|
||||
|
||||
if (!includeExp || prop.startsWith(ESCAPED_NOT))
|
||||
{
|
||||
prop = prop.substring(1);
|
||||
}
|
||||
try
|
||||
{
|
||||
listOfPairValue.add(new Pair<Boolean, Pattern>(includeExp, Pattern.compile(prop)));
|
||||
}
|
||||
catch (PatternSyntaxException ex)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("The 'audit.filter.alfresco-access.transaction.user' property parse exception; see property 'audit.filter.alfresco-access.transaction.user'.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean acceptUser(String value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
value = "null";
|
||||
}
|
||||
for (Pair<Boolean, Pattern> val : listOfPairValue)
|
||||
{
|
||||
if (val.getSecond().matcher(value).matches())
|
||||
{
|
||||
return val.getFirst();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -932,8 +932,6 @@ public class AuditComponentTest extends TestCase
|
||||
AuthenticationUtil.runAs(testRunAs, "SomeOtherUser");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Clearn the audit log as 'admin'
|
||||
*/
|
||||
|
@@ -40,6 +40,7 @@ public class AuditTestSuite extends TestSuite
|
||||
suite.addTestSuite(AuditableAspectTest.class);
|
||||
suite.addTestSuite(AuditBootstrapTest.class);
|
||||
suite.addTestSuite(AuditComponentTest.class);
|
||||
suite.addTestSuite(UserAuditFilterTest.class);
|
||||
|
||||
suite.addTest(new JUnit4TestAdapter(PropertyAuditFilterTest.class));
|
||||
suite.addTest(new JUnit4TestAdapter(AccessAuditorTest.class));
|
||||
|
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2014 Alfresco Software Limited.
|
||||
*
|
||||
* This file is part of Alfresco
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.alfresco.repo.audit;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.audit.model.AuditModelRegistryImpl;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
|
||||
import org.alfresco.repo.transaction.RetryingTransactionHelper.RetryingTransactionCallback;
|
||||
import org.alfresco.service.ServiceRegistry;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
|
||||
/**
|
||||
* Tests user filter.
|
||||
*
|
||||
* @see UserAuditFilter
|
||||
*
|
||||
* @author Vasily Olhin
|
||||
* @since 4.2
|
||||
*/
|
||||
public class UserAuditFilterTest extends TestCase
|
||||
{
|
||||
private static ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
|
||||
|
||||
private AuditModelRegistryImpl auditModelRegistry;
|
||||
private AuditComponent auditComponent;
|
||||
private ServiceRegistry serviceRegistry;
|
||||
private TransactionService transactionService;
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception
|
||||
{
|
||||
auditModelRegistry = (AuditModelRegistryImpl) ctx.getBean("auditModel.modelRegistry");
|
||||
auditComponent = (AuditComponent) ctx.getBean("auditComponent");
|
||||
serviceRegistry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
|
||||
transactionService = serviceRegistry.getTransactionService();
|
||||
|
||||
// Register the test model
|
||||
URL testModelUrl = ResourceUtils.getURL("classpath:alfresco/testaudit/alfresco-audit-test.xml");
|
||||
auditModelRegistry.registerModel(testModelUrl);
|
||||
auditModelRegistry.loadAuditModels();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception
|
||||
{
|
||||
AuthenticationUtil.clearCurrentSecurityContext();
|
||||
// Throw away the reconfigured registry state
|
||||
auditModelRegistry.destroy();
|
||||
}
|
||||
|
||||
public void testUserFilter()
|
||||
{
|
||||
Map<Boolean, String> userArr = new HashMap<Boolean, String>();
|
||||
userArr.put(false, "user1");
|
||||
userArr.put(true, "user2");
|
||||
userArr.put(true, "bob");
|
||||
UserAuditFilter userAuditFilter = new UserAuditFilter();
|
||||
userAuditFilter.setUserFilterPattern("~user1;user2;.*");
|
||||
userAuditFilter.afterPropertiesSet();
|
||||
auditComponent.setUserAuditFilter(userAuditFilter);
|
||||
|
||||
final RetryingTransactionCallback<Map<String, Serializable>> testCallback = new RetryingTransactionCallback<Map<String, Serializable>>()
|
||||
{
|
||||
public Map<String, Serializable> execute() throws Throwable
|
||||
{
|
||||
Map<String, Serializable> values = new HashMap<String, Serializable>(13);
|
||||
values.put("/3.1/4.1", new Long(41));
|
||||
values.put("/3.1/4.2", "42");
|
||||
values.put("/3.1/4.3", new Date());
|
||||
values.put("/3.1/4.4", "");
|
||||
values.put("/3.1/4.5", null);
|
||||
|
||||
return auditComponent.recordAuditValues("/test/one.one/two.one", values);
|
||||
}
|
||||
};
|
||||
RunAsWork<Map<String, Serializable>> testRunAs = new RunAsWork<Map<String, Serializable>>()
|
||||
{
|
||||
public Map<String, Serializable> doWork() throws Exception
|
||||
{
|
||||
return transactionService.getRetryingTransactionHelper().doInTransaction(testCallback);
|
||||
}
|
||||
};
|
||||
// record audit values using different users
|
||||
Map<String, Serializable> result;
|
||||
Set<Map.Entry<Boolean, String>> userSet = userArr.entrySet();
|
||||
for(Map.Entry<Boolean, String> entry : userSet)
|
||||
{
|
||||
result = AuthenticationUtil.runAs(testRunAs, entry.getValue());
|
||||
assertEquals((boolean) entry.getKey(), !result.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
public void testUserFilterParseRedirectProperty()
|
||||
{
|
||||
UserAuditFilter userAuditFilter = new UserAuditFilter();
|
||||
userAuditFilter.setUserFilterPattern("~user1;${audit.test.user};.*");
|
||||
try
|
||||
{
|
||||
userAuditFilter.afterPropertiesSet();
|
||||
fail("UserAuditFilter shouldn't parse property with redirect '$'");
|
||||
}
|
||||
catch (AlfrescoRuntimeException ex)
|
||||
{
|
||||
// Expected
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user