1
0
mirror of https://github.com/sismics/docs.git synced 2025-12-13 09:46:17 +00:00

#20: Audit log displayed on main screen

This commit is contained in:
jendib
2015-05-17 22:20:34 +02:00
parent b2a38cea62
commit ea4e3fd8f2
28 changed files with 890 additions and 39 deletions

View File

@@ -20,17 +20,13 @@ import org.apache.log4j.Logger;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import com.sismics.docs.core.dao.jpa.DocumentDao;
import com.sismics.docs.core.dao.jpa.FileDao;
import com.sismics.docs.core.dao.jpa.criteria.DocumentCriteria;
import com.sismics.docs.core.dao.jpa.dto.DocumentDto;
import com.sismics.docs.core.model.context.AppContext;
import com.sismics.docs.core.model.jpa.File;
import com.sismics.docs.core.util.ConfigUtil;
import com.sismics.docs.core.util.DirectoryUtil;
import com.sismics.docs.core.util.jpa.PaginatedList;
import com.sismics.docs.core.util.jpa.PaginatedLists;
import com.sismics.docs.core.util.jpa.SortCriteria;
import com.sismics.docs.rest.constant.BaseFunction;
import com.sismics.rest.exception.ForbiddenClientException;
import com.sismics.rest.exception.ServerException;
@@ -64,20 +60,6 @@ public class AppResource extends BaseResource {
JSONObject response = new JSONObject();
// Specific data
DocumentDao documentDao = new DocumentDao();
PaginatedList<DocumentDto> paginatedList = PaginatedLists.create(1, 0);
SortCriteria sortCriteria = new SortCriteria(0, true);
DocumentCriteria documentCriteria = new DocumentCriteria();
documentCriteria.setUserId(principal.getId());
try {
documentDao.findByCriteria(paginatedList, documentCriteria, sortCriteria);
} catch (Exception e) {
throw new ServerException("SearchError", "Error searching in documents", e);
}
response.put("document_count", paginatedList.getResultCount());
// General data
response.put("current_version", currentVersion.replace("-SNAPSHOT", ""));
response.put("min_version", minVersion);
response.put("total_memory", Runtime.getRuntime().totalMemory());

View File

@@ -0,0 +1,90 @@
package com.sismics.docs.rest.resource;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import com.sismics.docs.core.constant.PermType;
import com.sismics.docs.core.dao.jpa.AclDao;
import com.sismics.docs.core.dao.jpa.AuditLogDao;
import com.sismics.docs.core.dao.jpa.criteria.AuditLogCriteria;
import com.sismics.docs.core.dao.jpa.dto.AuditLogDto;
import com.sismics.docs.core.util.jpa.PaginatedList;
import com.sismics.docs.core.util.jpa.PaginatedLists;
import com.sismics.docs.core.util.jpa.SortCriteria;
import com.sismics.rest.exception.ForbiddenClientException;
import com.sismics.rest.exception.ServerException;
/**
* Audit log REST resources.
*
* @author bgamard
*/
@Path("/auditlog")
public class AuditLogResource extends BaseResource {
/**
* Returns the list of all logs for a document or user.
*
* @return Response
* @throws JSONException
*/
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response list(@QueryParam("document") String documentId) throws JSONException {
if (!authenticate()) {
throw new ForbiddenClientException();
}
// On a document or a user?
PaginatedList<AuditLogDto> paginatedList = PaginatedLists.create(100, 0);
SortCriteria sortCriteria = new SortCriteria(1, true);
AuditLogCriteria criteria = new AuditLogCriteria();
if (documentId == null) {
// Search logs for a user
criteria.setUserId(principal.getId());
} else {
// Check ACL on the document
AclDao aclDao = new AclDao();
if (!aclDao.checkPermission(documentId, PermType.READ, principal.getId())) {
throw new ForbiddenClientException();
}
criteria.setDocumentId(documentId);
}
// Search the logs
try {
AuditLogDao auditLogDao = new AuditLogDao();
auditLogDao.findByCriteria(paginatedList, criteria, sortCriteria);
} catch (Exception e) {
throw new ServerException("SearchError", "Error searching in logs", e);
}
// Assemble the results
List<JSONObject> logs = new ArrayList<>();
JSONObject response = new JSONObject();
for (AuditLogDto auditLogDto : paginatedList.getResultList()) {
JSONObject log = new JSONObject();
log.put("id", auditLogDto.getId());
log.put("target", auditLogDto.getEntityId());
log.put("class", auditLogDto.getEntityClass());
log.put("type", auditLogDto.getType().name());
log.put("message", auditLogDto.getMessage());
log.put("create_date", auditLogDto.getCreateTimestamp());
logs.add(log);
}
// Send the response
response.put("logs", logs);
response.put("total", paginatedList.getResultCount());
return Response.ok().entity(response).build();
}
}

View File

@@ -447,6 +447,8 @@ public class DocumentResource extends BaseResource {
document.setLanguage(language);
}
document = documentDao.update(document);
// Update tags
updateTagList(id, tagList);

View File

@@ -175,6 +175,8 @@ public class TagResource extends BaseResource {
tag.setColor(color);
}
tagDao.update(tag);
JSONObject response = new JSONObject();
response.put("id", id);
return Response.ok().entity(response).build();

View File

@@ -9,6 +9,11 @@ angular.module('docs').controller('DocumentDefault', function($scope, $state, Re
$scope.app = data;
});
// Load user audit log
Restangular.one('auditlog').get().then(function(data) {
$scope.logs = data.logs;
});
/**
* Load unlinked files.
*/

View File

@@ -1,10 +1,6 @@
<img src="img/loader.gif" ng-show="!app" />
<div ng-show="app">
<h1>
{{ app.document_count }} <small>document{{ app.document_count > 1 ? 's' : '' }} in the database</small>
</h1>
<div class="row upload-zone" ng-model="dropFiles" ng-file-drop drag-over-class="bg-success"
ng-multiple="true" allow-dir="false" accept="image/*,application/pdf,application/zip" ng-file-change="fileDropped($files, $event, $rejectedFiles)">
<div class="col-xs-6 col-sm-4 col-md-3 col-lg-2 text-center" ng-repeat="file in files">
@@ -45,6 +41,17 @@
<div ui-view="file"></div>
<table class="table">
<tr>
<th>Date</th>
<th>Message</th>
</tr>
<tr ng-repeat="log in logs">
<td>{{ log.create_date | date: 'yyyy-MM-dd HH:mm' }}</td>
<td>{{ log.class }} {{ log.type }} {{ log.message }}</td>
</tr>
</table>
<div class="text-muted text-right">
<ul class="list-inline">
<li><strong>Version:</strong> {{ app.current_version }}</li>

View File

@@ -41,7 +41,6 @@ public class TestAppResource extends BaseJerseyTest {
Assert.assertTrue(freeMemory > 0);
Long totalMemory = json.getLong("total_memory");
Assert.assertTrue(totalMemory > 0 && totalMemory > freeMemory);
Assert.assertEquals(0, json.getInt("document_count"));
// Rebuild Lucene index
appResource = resource().path("/app/batch/reindex");

View File

@@ -0,0 +1,98 @@
package com.sismics.docs.rest;
import java.util.Date;
import com.sismics.docs.rest.filter.CookieAuthenticationFilter;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.ClientResponse.Status;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import junit.framework.Assert;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.junit.Test;
/**
* Test the audit log resource.
*
* @author bgamard
*/
public class TestAuditLogResource extends BaseJerseyTest {
/**
* Test the audit log resource.
*
* @throws JSONException
*/
@Test
public void testAuditLogResource() throws JSONException {
// Login auditlog1
clientUtil.createUser("auditlog1");
String auditlog1Token = clientUtil.login("auditlog1");
// Create a tag
WebResource tagResource = resource().path("/tag");
tagResource.addFilter(new CookieAuthenticationFilter(auditlog1Token));
MultivaluedMapImpl postParams = new MultivaluedMapImpl();
postParams.add("name", "SuperTag");
postParams.add("color", "#ffff00");
ClientResponse response = tagResource.put(ClientResponse.class, postParams);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
JSONObject json = response.getEntity(JSONObject.class);
String tag1Id = json.optString("id");
Assert.assertNotNull(tag1Id);
// Create a document
WebResource documentResource = resource().path("/document");
documentResource.addFilter(new CookieAuthenticationFilter(auditlog1Token));
postParams = new MultivaluedMapImpl();
postParams.add("title", "My super title document 1");
postParams.add("description", "My super description for document 1");
postParams.add("tags", tag1Id);
postParams.add("language", "eng");
long create1Date = new Date().getTime();
postParams.add("create_date", create1Date);
response = documentResource.put(ClientResponse.class, postParams);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
json = response.getEntity(JSONObject.class);
String document1Id = json.optString("id");
Assert.assertNotNull(document1Id);
// Get all logs for the document
WebResource auditLogResource = resource().path("/auditlog");
auditLogResource.addFilter(new CookieAuthenticationFilter(auditlog1Token));
response = auditLogResource.queryParam("document", document1Id).get(ClientResponse.class);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
json = response.getEntity(JSONObject.class);
JSONArray logs = json.getJSONArray("logs");
Assert.assertTrue(logs.length() == 3);
// Get all logs for the current user
auditLogResource = resource().path("/auditlog");
auditLogResource.addFilter(new CookieAuthenticationFilter(auditlog1Token));
response = auditLogResource.get(ClientResponse.class);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
json = response.getEntity(JSONObject.class);
logs = json.getJSONArray("logs");
Assert.assertTrue(logs.length() == 3);
// Deletes a tag
tagResource = resource().path("/tag/" + tag1Id);
tagResource.addFilter(new CookieAuthenticationFilter(auditlog1Token));
response = tagResource.delete(ClientResponse.class);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
json = response.getEntity(JSONObject.class);
Assert.assertEquals("ok", json.getString("status"));
// Get all logs for the current user
auditLogResource = resource().path("/auditlog");
auditLogResource.addFilter(new CookieAuthenticationFilter(auditlog1Token));
response = auditLogResource.get(ClientResponse.class);
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
json = response.getEntity(JSONObject.class);
logs = json.getJSONArray("logs");
Assert.assertTrue(logs.length() == 4);
}
}