mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
SAIL-240 (SAIL-294) AuditDAO: AuditService enhancements
- Added isAuditEnabled and enableAudit for global case (system-wide) - Some neatening up of Audit SQL (common WHERE and ORDER BY clauses) - AuditService enforces 'admin' role for all methods git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@21471 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -145,6 +145,45 @@
|
|||||||
</isNotNull>
|
</isNotNull>
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
|
<sql id="select_AuditEntriesWhereSnippet">
|
||||||
|
<dynamic prepend="where">
|
||||||
|
<isNotNull prepend="and" property="auditAppNameId">
|
||||||
|
app.app_name_id = #auditAppNameId#
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull prepend="and" property="auditUserId">
|
||||||
|
entry.audit_user_id = #auditUserId#
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull prepend="and" property="auditFromId">
|
||||||
|
<![CDATA[entry.id >= #auditFromId#]]>
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull prepend="and" property="auditToId">
|
||||||
|
<![CDATA[entry.id < #auditToId#]]>
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull prepend="and" property="auditFromTime">
|
||||||
|
<![CDATA[entry.audit_time >= #auditFromTime#]]>
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull prepend="and" property="auditToTime">
|
||||||
|
<![CDATA[entry.audit_time < #auditToTime#]]>
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull prepend="and" property="searchKeyId">
|
||||||
|
sp_kpl.key_prop_id = #searchKeyId#
|
||||||
|
</isNotNull>
|
||||||
|
<isNotNull prepend="and" property="searchValueId">
|
||||||
|
sp_mpl.value_prop_id = #searchValueId#
|
||||||
|
</isNotNull>
|
||||||
|
</dynamic>
|
||||||
|
</sql>
|
||||||
|
<sql id="select_AuditEntriesOrderBySnippet">
|
||||||
|
<isEqual property="forward" compareProperty="forwardTrue">
|
||||||
|
order by
|
||||||
|
entry.id asc
|
||||||
|
</isEqual>
|
||||||
|
<isNotEqual property="forward" compareProperty="forwardTrue">
|
||||||
|
order by
|
||||||
|
entry.id desc
|
||||||
|
</isNotEqual>
|
||||||
|
</sql>
|
||||||
|
|
||||||
<!-- Get audit entries -->
|
<!-- Get audit entries -->
|
||||||
<select id="select_AuditEntriesWithValues" parameterClass="AuditQueryParameters" resultMap="result_AuditQueryAllValues">
|
<select id="select_AuditEntriesWithValues" parameterClass="AuditQueryParameters" resultMap="result_AuditQueryAllValues">
|
||||||
select
|
select
|
||||||
@@ -181,40 +220,8 @@
|
|||||||
left join alf_prop_double_value dv on (dv.id = pv.long_value and pv.persisted_type = 2)
|
left join alf_prop_double_value dv on (dv.id = pv.long_value and pv.persisted_type = 2)
|
||||||
left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 OR pv.persisted_type = 5))
|
left join alf_prop_string_value sv on (sv.id = pv.long_value and (pv.persisted_type = 3 OR pv.persisted_type = 5))
|
||||||
left join alf_prop_serializable_value serv on (serv.id = pv.long_value and pv.persisted_type = 4)
|
left join alf_prop_serializable_value serv on (serv.id = pv.long_value and pv.persisted_type = 4)
|
||||||
<dynamic prepend="where">
|
<include refid="select_AuditEntriesWhereSnippet"/>
|
||||||
<isNotNull prepend="and" property="auditAppNameId">
|
<include refid="select_AuditEntriesOrderBySnippet"/>
|
||||||
app.app_name_id = #auditAppNameId#
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="auditUserId">
|
|
||||||
entry.audit_user_id = #auditUserId#
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="auditFromId">
|
|
||||||
<![CDATA[entry.id >= #auditFromId#]]>
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="auditToId">
|
|
||||||
<![CDATA[entry.id < #auditToId#]]>
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="auditFromTime">
|
|
||||||
<![CDATA[entry.audit_time >= #auditFromTime#]]>
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="auditToTime">
|
|
||||||
<![CDATA[entry.audit_time < #auditToTime#]]>
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="searchKeyId">
|
|
||||||
sp_kpl.key_prop_id = #searchKeyId#
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="searchValueId">
|
|
||||||
sp_mpl.value_prop_id = #searchValueId#
|
|
||||||
</isNotNull>
|
|
||||||
</dynamic>
|
|
||||||
<isEqual property="forward" compareProperty="forwardTrue">
|
|
||||||
order by
|
|
||||||
entry.id asc
|
|
||||||
</isEqual>
|
|
||||||
<isNotEqual property="forward" compareProperty="forwardTrue">
|
|
||||||
order by
|
|
||||||
entry.id desc
|
|
||||||
</isNotEqual>
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- Get audit entries -->
|
<!-- Get audit entries -->
|
||||||
@@ -236,40 +243,8 @@
|
|||||||
join alf_prop_link sp_mpl on (sp_mpl.root_prop_id = entry.audit_values_id)
|
join alf_prop_link sp_mpl on (sp_mpl.root_prop_id = entry.audit_values_id)
|
||||||
</isNotNull>
|
</isNotNull>
|
||||||
|
|
||||||
<dynamic prepend="where">
|
<include refid="select_AuditEntriesWhereSnippet"/>
|
||||||
<isNotNull prepend="and" property="auditAppNameId">
|
<include refid="select_AuditEntriesOrderBySnippet"/>
|
||||||
app.app_name_id = #auditAppNameId#
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="auditUserId">
|
|
||||||
entry.audit_user_id = #auditUserId#
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="auditFromId">
|
|
||||||
<![CDATA[entry.id >= #auditFromId#]]>
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="auditToId">
|
|
||||||
<![CDATA[entry.id < #auditToId#]]>
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="auditFromTime">
|
|
||||||
<![CDATA[entry.audit_time >= #auditFromTime#]]>
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="auditToTime">
|
|
||||||
<![CDATA[entry.audit_time < #auditToTime#]]>
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="searchKeyId">
|
|
||||||
sp_kpl.key_prop_id = #searchKeyId#
|
|
||||||
</isNotNull>
|
|
||||||
<isNotNull prepend="and" property="searchValueId">
|
|
||||||
sp_mpl.value_prop_id = #searchValueId#
|
|
||||||
</isNotNull>
|
|
||||||
</dynamic>
|
|
||||||
<isEqual property="forward" compareProperty="forwardTrue">
|
|
||||||
order by
|
|
||||||
entry.id asc
|
|
||||||
</isEqual>
|
|
||||||
<isNotEqual property="forward" compareProperty="forwardTrue">
|
|
||||||
order by
|
|
||||||
entry.id desc
|
|
||||||
</isNotEqual>
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</sqlMap>
|
</sqlMap>
|
@@ -857,7 +857,16 @@
|
|||||||
|
|
||||||
<!-- TODO: Add audit security -->
|
<!-- TODO: Add audit security -->
|
||||||
|
|
||||||
<bean id="AuditService_security" class="org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor" />
|
<bean id="AuditService_security" class="org.alfresco.repo.security.permissions.impl.acegi.MethodSecurityInterceptor">
|
||||||
|
<property name="authenticationManager"><ref bean="authenticationManager"/></property>
|
||||||
|
<property name="accessDecisionManager"><ref local="accessDecisionManager"/></property>
|
||||||
|
<property name="afterInvocationManager"><ref local="afterInvocationManager"/></property>
|
||||||
|
<property name="objectDefinitionSource">
|
||||||
|
<value>
|
||||||
|
org.alfresco.service.cmr.audit.AuditService.*=ACL_METHOD.ROLE_ADMINISTRATOR
|
||||||
|
</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!-- ======================== -->
|
<!-- ======================== -->
|
||||||
<!-- Repository Admin Service -->
|
<!-- Repository Admin Service -->
|
||||||
|
@@ -512,10 +512,10 @@ public class AuditComponentTest extends TestCase
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auditService.clearAudit(APPLICATION_API_TEST);
|
clearAuditLog(APPLICATION_API_TEST);
|
||||||
results.clear();
|
results.clear();
|
||||||
sb.delete(0, sb.length());
|
sb.delete(0, sb.length());
|
||||||
auditService.auditQuery(auditQueryCallback, params, -1);
|
queryAuditLog(auditQueryCallback, params, -1);
|
||||||
logger.debug(sb.toString());
|
logger.debug(sb.toString());
|
||||||
assertTrue("There should be no audit entries for the API test after a clear", results.isEmpty());
|
assertTrue("There should be no audit entries for the API test after a clear", results.isEmpty());
|
||||||
|
|
||||||
@@ -535,7 +535,7 @@ public class AuditComponentTest extends TestCase
|
|||||||
AuthenticationUtil.runAs(createAuthenticationWork, AuthenticationUtil.getSystemUserName());
|
AuthenticationUtil.runAs(createAuthenticationWork, AuthenticationUtil.getSystemUserName());
|
||||||
|
|
||||||
// Clear everything out and do a successful authentication
|
// Clear everything out and do a successful authentication
|
||||||
auditService.clearAudit(APPLICATION_API_TEST);
|
clearAuditLog(APPLICATION_API_TEST);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AuthenticationUtil.pushAuthentication();
|
AuthenticationUtil.pushAuthentication();
|
||||||
@@ -549,12 +549,12 @@ public class AuditComponentTest extends TestCase
|
|||||||
// Check that the call was audited
|
// Check that the call was audited
|
||||||
results.clear();
|
results.clear();
|
||||||
sb.delete(0, sb.length());
|
sb.delete(0, sb.length());
|
||||||
auditService.auditQuery(auditQueryCallback, params, -1);
|
queryAuditLog(auditQueryCallback, params, -1);
|
||||||
logger.debug(sb.toString());
|
logger.debug(sb.toString());
|
||||||
assertFalse("Did not get any audit results after successful login", results.isEmpty());
|
assertFalse("Did not get any audit results after successful login", results.isEmpty());
|
||||||
|
|
||||||
// Clear everything and check that unsuccessful authentication was audited
|
// Clear everything and check that unsuccessful authentication was audited
|
||||||
auditService.clearAudit(APPLICATION_API_TEST);
|
clearAuditLog(APPLICATION_API_TEST);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
authenticationService.authenticate("banana", "****".toCharArray());
|
authenticationService.authenticate("banana", "****".toCharArray());
|
||||||
@@ -566,7 +566,7 @@ public class AuditComponentTest extends TestCase
|
|||||||
}
|
}
|
||||||
results.clear();
|
results.clear();
|
||||||
sb.delete(0, sb.length());
|
sb.delete(0, sb.length());
|
||||||
auditService.auditQuery(auditQueryCallback, params, -1);
|
queryAuditLog(auditQueryCallback, params, -1);
|
||||||
logger.debug(sb.toString());
|
logger.debug(sb.toString());
|
||||||
assertFalse("Did not get any audit results after failed login", results.isEmpty());
|
assertFalse("Did not get any audit results after failed login", results.isEmpty());
|
||||||
}
|
}
|
||||||
@@ -606,7 +606,40 @@ public class AuditComponentTest extends TestCase
|
|||||||
params.setApplicationName(APPLICATION_API_TEST);
|
params.setApplicationName(APPLICATION_API_TEST);
|
||||||
params.setForward(false);
|
params.setForward(false);
|
||||||
params.setToId(Long.MAX_VALUE);
|
params.setToId(Long.MAX_VALUE);
|
||||||
auditService.auditQuery(auditQueryCallback, params, 1);
|
queryAuditLog(auditQueryCallback, params, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clearn the audit log as 'admin'
|
||||||
|
*/
|
||||||
|
private void clearAuditLog(final String applicationName)
|
||||||
|
{
|
||||||
|
RunAsWork<Void> work = new RunAsWork<Void>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Void doWork() throws Exception
|
||||||
|
{
|
||||||
|
auditService.clearAudit(applicationName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
AuthenticationUtil.runAs(work, AuthenticationUtil.getAdminRoleName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clearn the audit log as 'admin'
|
||||||
|
*/
|
||||||
|
private void queryAuditLog(final AuditQueryCallback callback, final AuditQueryParameters parameters, final int maxResults)
|
||||||
|
{
|
||||||
|
RunAsWork<Void> work = new RunAsWork<Void>()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public Void doWork() throws Exception
|
||||||
|
{
|
||||||
|
auditService.auditQuery(callback, parameters, maxResults);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
AuthenticationUtil.runAs(work, AuthenticationUtil.getAdminRoleName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,16 +18,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.audit;
|
package org.alfresco.repo.audit;
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
import org.alfresco.service.cmr.audit.AuditQueryParameters;
|
import org.alfresco.service.cmr.audit.AuditQueryParameters;
|
||||||
import org.alfresco.service.cmr.audit.AuditService;
|
import org.alfresco.service.cmr.audit.AuditService;
|
||||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The implementation of the AuditService for application auditing.
|
* The implementation of the AuditService for application auditing.
|
||||||
*
|
*
|
||||||
* @author Andy Hind
|
* @author Derek Hulley
|
||||||
|
* @since 3.2
|
||||||
*/
|
*/
|
||||||
public class AuditServiceImpl implements AuditService
|
public class AuditServiceImpl implements AuditService
|
||||||
{
|
{
|
||||||
@@ -43,6 +41,15 @@ public class AuditServiceImpl implements AuditService
|
|||||||
this.auditComponent = auditComponent;
|
this.auditComponent = auditComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
public boolean isAuditEnabled()
|
||||||
|
{
|
||||||
|
return auditComponent.isAuditEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* @since 3.2
|
* @since 3.2
|
||||||
@@ -89,55 +96,4 @@ public class AuditServiceImpl implements AuditService
|
|||||||
{
|
{
|
||||||
auditComponent.auditQuery(callback, parameters, maxResults);
|
auditComponent.auditQuery(callback, parameters, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
public void auditQuery(
|
|
||||||
AuditQueryCallback callback,
|
|
||||||
boolean forward,
|
|
||||||
String applicationName, String user, Long from, Long to,
|
|
||||||
int maxResults)
|
|
||||||
|
|
||||||
{
|
|
||||||
ParameterCheck.mandatory("callback", callback);
|
|
||||||
|
|
||||||
AuditQueryParameters params = new AuditQueryParameters();
|
|
||||||
params.setForward(true);
|
|
||||||
params.setApplicationName(applicationName);
|
|
||||||
params.setUser(user);
|
|
||||||
params.setFromTime(from);
|
|
||||||
params.setToTime(to);
|
|
||||||
|
|
||||||
auditComponent.auditQuery(callback, params, maxResults);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
* @since 3.2
|
|
||||||
*/
|
|
||||||
public void auditQuery(
|
|
||||||
AuditQueryCallback callback,
|
|
||||||
boolean forward,
|
|
||||||
String applicationName, String user, Long from, Long to,
|
|
||||||
String searchKey, Serializable searchValue,
|
|
||||||
int maxResults)
|
|
||||||
|
|
||||||
{
|
|
||||||
ParameterCheck.mandatory("callback", callback);
|
|
||||||
|
|
||||||
AuditQueryParameters params = new AuditQueryParameters();
|
|
||||||
params.setForward(true);
|
|
||||||
params.setApplicationName(applicationName);
|
|
||||||
params.setUser(user);
|
|
||||||
params.setFromTime(from);
|
|
||||||
params.setToTime(to);
|
|
||||||
if (searchKey != null || searchValue != null)
|
|
||||||
{
|
|
||||||
params.addSearchKey(searchKey, searchValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
auditComponent.auditQuery(callback, params, maxResults);
|
|
||||||
}
|
|
||||||
}
|
}
|
@@ -31,6 +31,13 @@ import org.alfresco.service.PublicService;
|
|||||||
@PublicService
|
@PublicService
|
||||||
public interface AuditService
|
public interface AuditService
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @return Returns <tt>true</tt> if auditing is globally enabled
|
||||||
|
*
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
boolean isAuditEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param applicationName the name of the application to check
|
* @param applicationName the name of the application to check
|
||||||
* @param path the path to check
|
* @param path the path to check
|
||||||
@@ -122,49 +129,4 @@ public interface AuditService
|
|||||||
* @since 3.3
|
* @since 3.3
|
||||||
*/
|
*/
|
||||||
void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults);
|
void auditQuery(AuditQueryCallback callback, AuditQueryParameters parameters, int maxResults);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the audit entries that match the given criteria.
|
|
||||||
*
|
|
||||||
* @param callback the callback that will handle results
|
|
||||||
* @param forward <tt>true</tt> for results to ordered from first to last,
|
|
||||||
* or <tt>false</tt> to order from last to first
|
|
||||||
* @param applicationName if not <tt>null</tt>, find entries logged against this application
|
|
||||||
* @param user if not <tt>null</tt>, find entries logged against this user
|
|
||||||
* @param from the start search time (<tt>null</tt> to start at the beginning)
|
|
||||||
* @param to the end search time (<tt>null</tt> for no limit)
|
|
||||||
* @param maxResults the maximum number of results to retrieve (zero or negative to ignore)
|
|
||||||
*
|
|
||||||
* @since 3.2
|
|
||||||
* @deprecated Use {@link #auditQuery(AuditQueryCallback, AuditQueryParameters)}
|
|
||||||
*/
|
|
||||||
void auditQuery(
|
|
||||||
AuditQueryCallback callback,
|
|
||||||
boolean forward,
|
|
||||||
String applicationName, String user, Long from, Long to,
|
|
||||||
int maxResults);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the audit entries that match the given criteria.
|
|
||||||
*
|
|
||||||
* @param callback the callback that will handle results
|
|
||||||
* @param forward <tt>true</tt> for results to ordered from first to last,
|
|
||||||
* or <tt>false</tt> to order from last to first
|
|
||||||
* @param applicationName if not <tt>null</tt>, find entries logged against this application
|
|
||||||
* @param user if not <tt>null</tt>, find entries logged against this user
|
|
||||||
* @param from the start search time (<tt>null</tt> to start at the beginning)
|
|
||||||
* @param to the end search time (<tt>null</tt> for no limit)
|
|
||||||
* @param searchKey the audit key path that must exist (<tt>null</tt> to ignore)
|
|
||||||
* @param searchValue an audit value that must exist (<tt>null</tt> to ignore)
|
|
||||||
* @param maxResults the maximum number of results to retrieve (zero or negative to ignore)
|
|
||||||
*
|
|
||||||
* @since 3.2
|
|
||||||
* @deprecated Use {@link #auditQuery(AuditQueryCallback, AuditQueryParameters)}
|
|
||||||
*/
|
|
||||||
void auditQuery(
|
|
||||||
AuditQueryCallback callback,
|
|
||||||
boolean forward,
|
|
||||||
String applicationName, String user, Long from, Long to,
|
|
||||||
String searchKey, Serializable searchValue,
|
|
||||||
int maxResults);
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user