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) {
@@ -10,12 +10,20 @@ public final class AuditData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Long id; private final Long id;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String actionName;
@SuppressWarnings("unused")
private final String entityName;
@SuppressWarnings("unused")
private final String apiOperation; private final String apiOperation;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String resource; private final String resource;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final Long resourceId; private final Long resourceId;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String subResource;
@SuppressWarnings("unused")
private final Long subResourceId;
@SuppressWarnings("unused")
private final String maker; private final String maker;
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final DateTime madeOnDate; private final DateTime madeOnDate;
@@ -26,13 +34,22 @@ public final class AuditData {
@SuppressWarnings("unused") @SuppressWarnings("unused")
private final String commandAsJson; 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.actionName = actionName;
this.entityName = entityName;
this.apiOperation = apiOperation; this.apiOperation = apiOperation;
this.resource = resource; this.resource = resource;
this.resourceId = resourceId; this.resourceId = resourceId;
this.subResource = subResource;
this.subResourceId = subResourceId;
this.maker = maker; this.maker = maker;
this.madeOnDate = madeOnDate; this.madeOnDate = madeOnDate;
this.checker = checker; this.checker = checker;
@@ -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,13 +24,15 @@ 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
.getLogger(AuditReadPlatformServiceImpl.class);
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final AppUserReadPlatformService appUserReadPlatformService; private final AppUserReadPlatformService appUserReadPlatformService;
@Autowired @Autowired
public AuditReadPlatformServiceImpl(final PlatformSecurityContext context, final TenantAwareRoutingDataSource dataSource, public AuditReadPlatformServiceImpl(final PlatformSecurityContext context,
final TenantAwareRoutingDataSource dataSource,
final AppUserReadPlatformService appUserReadPlatformService) { final AppUserReadPlatformService appUserReadPlatformService) {
this.context = context; this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource); this.jdbcTemplate = new JdbcTemplate(dataSource);
@@ -43,25 +44,37 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
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, "
+ " aud.api_resource as resource, aud.resource_id as resourceId, aud.api_subresource as subResource, aud.subresource_id as subResourceId,"
+ " mk.username as maker, aud.made_on_date as madeOnDate, ck.username as checker, aud.checked_on_date as checkedOnDate" + " mk.username as maker, aud.made_on_date as madeOnDate, ck.username as checker, aud.checked_on_date as checkedOnDate"
+ commandAsJsonString + " from m_portfolio_command_source aud " + " left join m_appuser mk on mk.id = aud.maker_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"; + " 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 actionName = rs.getString("actionName");
final String entityName = rs.getString("entityName");
final String apiOperation = rs.getString("apiOperation"); final String apiOperation = rs.getString("apiOperation");
final String resource = rs.getString("resource"); final String resource = rs.getString("resource");
final Long resourceId = JdbcSupport.getLong(rs, "resourceId"); final Long resourceId = JdbcSupport.getLong(rs, "resourceId");
final String subResource = rs.getString("subResource");
final Long subResourceId = JdbcSupport.getLong(rs, "subResourceId");
final String maker = rs.getString("maker"); final String maker = rs.getString("maker");
final DateTime madeOnDate = JdbcSupport.getDateTime(rs, "madeOnDate"); final DateTime madeOnDate = JdbcSupport.getDateTime(rs,
"madeOnDate");
final String checker = rs.getString("checker"); final String checker = rs.getString("checker");
final DateTime checkedOnDate = JdbcSupport.getDateTime(rs, "checkedOnDate"); final DateTime checkedOnDate = JdbcSupport.getDateTime(rs,
"checkedOnDate");
String commandAsJson; String commandAsJson;
// commandAsJson might not be on the select list of columns // commandAsJson might not be on the select list of columns
try { try {
@@ -69,18 +82,22 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
} catch (SQLException e) { } catch (SQLException e) {
commandAsJson = null; commandAsJson = null;
} }
return new AuditData(id, apiOperation, resource, resourceId, maker, madeOnDate, checker, checkedOnDate, commandAsJson); 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,
boolean includeJson) {
context.authenticatedUser(); 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 += " where (" + extraCriteria + ")";
sql += " order by aud.id DESC"; sql += " order by aud.id DESC";
logger.info("sql: " + sql); logger.info("sql: " + sql);
return this.jdbcTemplate.query(sql, rm, new Object[] {}); return this.jdbcTemplate.query(sql, rm, new Object[] {});
@@ -100,43 +117,51 @@ public class AuditReadPlatformServiceImpl implements AuditReadPlatformService {
@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";
} }
} }
} }