wip audit services

This commit is contained in:
John Woodlock
2012-12-15 00:41:25 +00:00
parent b2639fea2c
commit 7b4f078cda
4 changed files with 175 additions and 133 deletions
@@ -65,8 +65,8 @@ public class AuditApiResource {
@Produces({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON })
public String retrieveAuditEntries( public String retrieveAuditEntries(
@Context final UriInfo uriInfo, @Context final UriInfo uriInfo,
@QueryParam("apiOperation") final String apiOperation, @QueryParam("actionName") final String actionName,
@QueryParam("resource") final String resource, @QueryParam("entityName") final String entityName,
@QueryParam("resourceId") final Long resourceId, @QueryParam("resourceId") final Long resourceId,
@QueryParam("makerId") final Long makerId, @QueryParam("makerId") final Long makerId,
@QueryParam("makerDateTimeFrom") final String makerDateTimeFrom, @QueryParam("makerDateTimeFrom") final String makerDateTimeFrom,
@@ -78,7 +78,7 @@ public class AuditApiResource {
context.authenticatedUser().validateHasReadPermission( context.authenticatedUser().validateHasReadPermission(
resourceNameForPermissions); resourceNameForPermissions);
final String extraCriteria = getExtraCriteria(apiOperation, resource, final String extraCriteria = getExtraCriteria(actionName, entityName,
resourceId, makerId, makerDateTimeFrom, makerDateTimeTo, resourceId, makerId, makerDateTimeFrom, makerDateTimeTo,
checkerId, checkerDateTimeFrom, checkerDateTimeTo); checkerId, checkerDateTimeFrom, checkerDateTimeTo);
@@ -133,21 +133,21 @@ public class AuditApiResource {
auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE); auditSearchData, RESPONSE_DATA_PARAMETERS_SEARCH_TEMPLATE);
} }
private String getExtraCriteria(final String apiOperation, private String getExtraCriteria(final String actionName,
final String resource, final Long resourceId, final Long makerId, final String entityName, final Long resourceId, final Long makerId,
final String makerDateTimeFrom, final String makerDateTimeTo, final String makerDateTimeFrom, final String makerDateTimeTo,
final Long checkerId, final String checkerDateTimeFrom, final Long checkerId, final String checkerDateTimeFrom,
final String checkerDateTimeTo) { final String checkerDateTimeTo) {
String extraCriteria = ""; String extraCriteria = "";
if (apiOperation != null) { if (actionName != null) {
extraCriteria += " and aud.api_operation = " extraCriteria += " and aud.action_name = "
+ ApiParameterHelper.sqlEncodeString(apiOperation); + ApiParameterHelper.sqlEncodeString(actionName);
} }
if (resource != null) { if (entityName != null) {
extraCriteria += " and aud.api_resource = " extraCriteria += " and aud.entity_name like "
+ ApiParameterHelper.sqlEncodeString(resource); + ApiParameterHelper.sqlEncodeString(entityName + "%");
} }
if (resourceId != null) { if (resourceId != null) {
@@ -7,36 +7,53 @@ import org.joda.time.DateTime;
*/ */
public final class AuditData { public final class AuditData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Long id; private final Long id;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String apiOperation; private final String actionName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String resource; private final String entityName;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Long resourceId; private final String apiOperation;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String maker; private final String resource;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final DateTime madeOnDate; private final Long resourceId;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String checker; private final String subResource;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final DateTime checkedOnDate; private final Long subResourceId;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String commandAsJson; private final String maker;
@SuppressWarnings("unused")
private final DateTime madeOnDate;
@SuppressWarnings("unused")
private final String checker;
@SuppressWarnings("unused")
private final DateTime checkedOnDate;
@SuppressWarnings("unused")
private final String commandAsJson;
public AuditData(final Long id, final String apiOperation, final String resource, final Long resourceId, final String maker, public AuditData(final Long id, final String actionName,
final DateTime madeOnDate, final String checker, final DateTime checkedOnDate, final String commandAsJson) { final String entityName, final String apiOperation,
final String resource, final Long resourceId,
final String subResource, final Long subResourceId,
final String maker, final DateTime madeOnDate,
final String checker, final DateTime checkedOnDate,
final String commandAsJson) {
this.id = id; this.id = id;
this.apiOperation = apiOperation; this.actionName = actionName;
this.resource = resource; this.entityName = entityName;
this.resourceId = resourceId; this.apiOperation = apiOperation;
this.maker = maker; this.resource = resource;
this.madeOnDate = madeOnDate; this.resourceId = resourceId;
this.checker = checker; this.subResource = subResource;
this.checkedOnDate = checkedOnDate; this.subResourceId = subResourceId;
this.commandAsJson = commandAsJson; this.maker = maker;
} this.madeOnDate = madeOnDate;
this.checker = checker;
this.checkedOnDate = checkedOnDate;
this.commandAsJson = commandAsJson;
}
} }
@@ -13,13 +13,13 @@ public final class AuditSearchData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Collection<AppUserLookup> appUsers; private final Collection<AppUserLookup> appUsers;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final List<String> apiOperations; private final List<String> actionNames;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final List<String> resources; private final List<String> entityNames;
public AuditSearchData(final Collection<AppUserLookup> appUsers, final List<String> apiOperations, final List<String> resources) { public AuditSearchData(final Collection<AppUserLookup> appUsers, final List<String> apiOperations, final List<String> resources) {
this.appUsers = appUsers; this.appUsers = appUsers;
this.apiOperations = apiOperations; this.actionNames = apiOperations;
this.resources = resources; this.entityNames = resources;
} }
} }
@@ -11,7 +11,6 @@ import org.mifosplatform.audit.data.AuditData;
import org.mifosplatform.audit.data.AuditSearchData; import org.mifosplatform.audit.data.AuditSearchData;
import org.mifosplatform.infrastructure.core.domain.JdbcSupport; import org.mifosplatform.infrastructure.core.domain.JdbcSupport;
import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource; import org.mifosplatform.infrastructure.core.service.TenantAwareRoutingDataSource;
import org.mifosplatform.infrastructure.dataqueries.service.ReadWriteNonCoreDataServiceImpl;
import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext; import org.mifosplatform.infrastructure.security.service.PlatformSecurityContext;
import org.mifosplatform.useradministration.data.AppUserLookup; import org.mifosplatform.useradministration.data.AppUserLookup;
import org.mifosplatform.useradministration.service.AppUserReadPlatformService; import org.mifosplatform.useradministration.service.AppUserReadPlatformService;
@@ -25,118 +24,144 @@ import org.springframework.stereotype.Service;
@Service @Service
public class AuditReadPlatformServiceImpl implements AuditReadPlatformService { public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
private final static Logger logger = LoggerFactory.getLogger(AuditReadPlatformServiceImpl.class); private final static Logger logger = LoggerFactory
private final JdbcTemplate jdbcTemplate; .getLogger(AuditReadPlatformServiceImpl.class);
private final PlatformSecurityContext context; private final JdbcTemplate jdbcTemplate;
private final AppUserReadPlatformService appUserReadPlatformService; private final PlatformSecurityContext context;
private final AppUserReadPlatformService appUserReadPlatformService;
@Autowired @Autowired
public AuditReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, public AuditReadPlatformServiceImpl(final PlatformSecurityContext context,
final AppUserReadPlatformService appUserReadPlatformService) { final TenantAwareRoutingDataSource dataSource,
this.context = context; final AppUserReadPlatformService appUserReadPlatformService) {
this.jdbcTemplate = new JdbcTemplate(dataSource); this.context = context;
this.appUserReadPlatformService = appUserReadPlatformService; this.jdbcTemplate = new JdbcTemplate(dataSource);
} this.appUserReadPlatformService = appUserReadPlatformService;
}
private static final class AuditMapper implements RowMapper<AuditData> { private static final class AuditMapper implements RowMapper<AuditData> {
public String schema(boolean includeJson) { public String schema(boolean includeJson) {
String commandAsJsonString = ""; String commandAsJsonString = "";
if (includeJson) commandAsJsonString = ", aud.command_as_json as commandAsJson "; if (includeJson)
commandAsJsonString = ", aud.command_as_json as commandAsJson ";
return " aud.id as id, aud.api_operation as apiOperation, aud.api_resource as resource, aud.resource_id as resourceId," return " aud.id as id, aud.action_name as actionName, aud.entity_name as entityName, aud.api_operation as apiOperation, "
+ " mk.username as maker, aud.made_on_date as madeOnDate, ck.username as checker, aud.checked_on_date as checkedOnDate" + " aud.api_resource as resource, aud.resource_id as resourceId, aud.api_subresource as subResource, aud.subresource_id as subResourceId,"
+ commandAsJsonString + " from m_portfolio_command_source aud " + " left join m_appuser mk on mk.id = aud.maker_id" + " mk.username as maker, aud.made_on_date as madeOnDate, ck.username as checker, aud.checked_on_date as checkedOnDate"
+ " left join m_appuser ck on ck.id = aud.checker_id"; + commandAsJsonString
} + " from m_portfolio_command_source aud "
+ " left join m_appuser mk on mk.id = aud.maker_id"
+ " left join m_appuser ck on ck.id = aud.checker_id";
}
@Override @Override
public AuditData mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { public AuditData mapRow(final ResultSet rs,
@SuppressWarnings("unused") final int rowNum)
throws SQLException {
final Long id = rs.getLong("id"); final Long id = rs.getLong("id");
final String apiOperation = rs.getString("apiOperation"); final String actionName = rs.getString("actionName");
final String resource = rs.getString("resource"); final String entityName = rs.getString("entityName");
final Long resourceId = JdbcSupport.getLong(rs, "resourceId"); final String apiOperation = rs.getString("apiOperation");
final String maker = rs.getString("maker"); final String resource = rs.getString("resource");
final DateTime madeOnDate = JdbcSupport.getDateTime(rs, "madeOnDate"); final Long resourceId = JdbcSupport.getLong(rs, "resourceId");
final String checker = rs.getString("checker"); final String subResource = rs.getString("subResource");
final DateTime checkedOnDate = JdbcSupport.getDateTime(rs, "checkedOnDate"); final Long subResourceId = JdbcSupport.getLong(rs, "subResourceId");
String commandAsJson; final String maker = rs.getString("maker");
// commandAsJson might not be on the select list of columns final DateTime madeOnDate = JdbcSupport.getDateTime(rs,
try { "madeOnDate");
commandAsJson = rs.getString("commandAsJson"); final String checker = rs.getString("checker");
} catch (SQLException e) { final DateTime checkedOnDate = JdbcSupport.getDateTime(rs,
commandAsJson = null; "checkedOnDate");
} String commandAsJson;
return new AuditData(id, apiOperation, resource, resourceId, maker, madeOnDate, checker, checkedOnDate, commandAsJson); // commandAsJson might not be on the select list of columns
} try {
} commandAsJson = rs.getString("commandAsJson");
} catch (SQLException e) {
commandAsJson = null;
}
return new AuditData(id, actionName, entityName, apiOperation,
resource, resourceId, subResource, subResourceId, maker,
madeOnDate, checker, checkedOnDate, commandAsJson);
}
}
@Override @Override
public Collection<AuditData> retrieveAuditEntries(String extraCriteria, boolean includeJson) { public Collection<AuditData> retrieveAuditEntries(String extraCriteria,
context.authenticatedUser(); boolean includeJson) {
context.authenticatedUser();
final AuditMapper rm = new AuditMapper(); final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(includeJson); String sql = "select " + rm.schema(includeJson);
if (StringUtils.isNotBlank(extraCriteria)) sql += " where (" + extraCriteria + ")"; if (StringUtils.isNotBlank(extraCriteria))
sql += " order by aud.id DESC"; sql += " where (" + extraCriteria + ")";
logger.info("sql: " + sql); sql += " order by aud.id DESC";
return this.jdbcTemplate.query(sql, rm, new Object[] {}); logger.info("sql: " + sql);
} return this.jdbcTemplate.query(sql, rm, new Object[] {});
}
@Override @Override
public AuditData retrieveAuditEntry(Long auditId) { public AuditData retrieveAuditEntry(Long auditId) {
context.authenticatedUser(); context.authenticatedUser();
final AuditMapper rm = new AuditMapper(); final AuditMapper rm = new AuditMapper();
String sql = "select " + rm.schema(true); String sql = "select " + rm.schema(true);
sql += " where aud.id = " + auditId; sql += " where aud.id = " + auditId;
return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {}); return this.jdbcTemplate.queryForObject(sql, rm, new Object[] {});
} }
@Override @Override
public AuditSearchData retrieveSearchTemplate() { public AuditSearchData retrieveSearchTemplate() {
Collection<AppUserLookup> appUsers = appUserReadPlatformService.retrieveSearchTemplate(); Collection<AppUserLookup> appUsers = appUserReadPlatformService
.retrieveSearchTemplate();
ApiOperationsMapper mapper = new ApiOperationsMapper(); ActionNamesMapper mapper = new ActionNamesMapper();
List<String> apiOperations = this.jdbcTemplate.query(mapper.schema(), mapper, new Object[] {}); List<String> actionNames = this.jdbcTemplate.query(mapper.schema(),
mapper, new Object[] {});
ApiResourcesMapper mapper2 = new ApiResourcesMapper(); EntityNamesMapper mapper2 = new EntityNamesMapper();
List<String> resources = this.jdbcTemplate.query(mapper2.schema(), mapper2, new Object[] {}); List<String> entityNames = this.jdbcTemplate.query(mapper2.schema(),
mapper2, new Object[] {});
return new AuditSearchData(appUsers, apiOperations, resources); return new AuditSearchData(appUsers, actionNames, entityNames);
} }
private static final class ApiOperationsMapper implements RowMapper<String> { private static final class ActionNamesMapper implements RowMapper<String> {
@Override @Override
public String mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { public String mapRow(final ResultSet rs,
@SuppressWarnings("unused") final int rowNum)
throws SQLException {
return rs.getString("apiOperation"); return rs.getString("actionName");
} }
public String schema() { public String schema() {
return " SELECT distinct(action_name) as apiOperation FROM m_permission " return " SELECT distinct(action_name) as actionName FROM m_permission "
+ " where action_name is not null and action_name <> 'READ' " + " where action_name is not null and action_name <> 'READ' "
+ " order by if(action_name in ('CREATE', 'DELETE', 'UPDATE'), action_name, 'ZZZ'), action_name"; + " order by if(action_name in ('CREATE', 'DELETE', 'UPDATE'), action_name, 'ZZZ'), action_name";
} }
} }
private static final class ApiResourcesMapper implements RowMapper<String> { private static final class EntityNamesMapper implements RowMapper<String> {
@Override @Override
public String mapRow(final ResultSet rs, @SuppressWarnings("unused") final int rowNum) throws SQLException { public String mapRow(final ResultSet rs,
return rs.getString("resource"); @SuppressWarnings("unused") final int rowNum)
} throws SQLException {
return rs.getString("entityName");
}
public String schema() { public String schema() {
return " select distinct(api_resource) as resource from m_portfolio_command_source order by api_resource"; return " select distinct(entity_name) as entityName from m_permission where action_name is not null and action_name <> 'READ' "
} + " order by if(grouping = 'datatable', 'ZZZ', entity_name), entity_name";
} }
}
} }