mirror of
https://github.com/dalbodeule/snap-admin.git
synced 2025-06-08 21:38:21 +00:00
Search by username in audit logs (#34)
This commit is contained in:
parent
bdbdd6e8a2
commit
7625462eae
@ -33,7 +33,6 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import tech.ailef.snapadmin.external.SnapAdmin;
|
||||
import tech.ailef.snapadmin.external.SnapAdminProperties;
|
||||
import tech.ailef.snapadmin.external.exceptions.SnapAdminException;
|
||||
import tech.ailef.snapadmin.external.exceptions.SnapAdminForbiddenException;
|
||||
import tech.ailef.snapadmin.external.exceptions.SnapAdminNotFoundException;
|
||||
import tech.ailef.snapadmin.internal.UserConfiguration;
|
||||
|
||||
|
@ -30,6 +30,11 @@ import tech.ailef.snapadmin.external.dbmapping.fields.DbFieldType;
|
||||
import tech.ailef.snapadmin.external.exceptions.SnapAdminException;
|
||||
import tech.ailef.snapadmin.external.exceptions.UnsupportedFieldTypeException;
|
||||
|
||||
/*
|
||||
* A class that holds output fields from a user-provided SQL query
|
||||
* run in the SQL console. If possible, this field is mapped to a proper
|
||||
* {@link Dbfield} object, otherwise it is left as a raw object.
|
||||
*/
|
||||
public class DbQueryOutputField {
|
||||
private String name;
|
||||
|
||||
|
@ -23,6 +23,10 @@ package tech.ailef.snapadmin.external.dbmapping.query;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A wrapper for results returned by user-provided SQL queries run via
|
||||
* the SQL console.
|
||||
*/
|
||||
public class DbQueryResult {
|
||||
private List<DbQueryResultRow> rows;
|
||||
|
||||
|
@ -26,6 +26,10 @@ import java.util.Map;
|
||||
|
||||
import tech.ailef.snapadmin.external.exceptions.SnapAdminException;
|
||||
|
||||
/**
|
||||
* A single row of results coming from a user-provided SQL query
|
||||
* run via the SQL console.
|
||||
*/
|
||||
public class DbQueryResultRow {
|
||||
private Map<DbQueryOutputField, Object> values;
|
||||
|
||||
|
@ -65,6 +65,11 @@ public class LogsSearchRequest implements FilterRequest {
|
||||
*/
|
||||
private String sortOrder;
|
||||
|
||||
/**
|
||||
* The requested username filter
|
||||
*/
|
||||
private String username;
|
||||
|
||||
/**
|
||||
* Returns the table specified in this search request. If the value is blank or 'Any',
|
||||
* the method returns null in order ignore the field in subsequent queries.
|
||||
@ -170,6 +175,14 @@ public class LogsSearchRequest implements FilterRequest {
|
||||
+ page + ", pageSize=" + pageSize + ", sortKey=" + sortKey + ", sortOrder=" + sortOrder + "]";
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Spring PageRequest object from the parameters in this request
|
||||
* @return a Spring PageRequest object
|
||||
|
@ -26,6 +26,10 @@ import java.util.Map;
|
||||
import jakarta.validation.ConstraintViolation;
|
||||
import jakarta.validation.ConstraintViolationException;
|
||||
|
||||
/**
|
||||
* Holds information about JPA validation errors occurring during
|
||||
* creation or editing of items.
|
||||
*/
|
||||
public class ValidationErrorsContainer {
|
||||
private Map<String, List<ConstraintViolation<?>>> errors = new HashMap<>();
|
||||
|
||||
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* SnapAdmin - An automatically generated CRUD admin UI for Spring Boot apps
|
||||
|
||||
* Copyright (C) 2023 Ailef (http://ailef.tech)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
package tech.ailef.snapadmin.external.exceptions;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
public class SnapAdminForbiddenException extends ResponseStatusException {
|
||||
private static final long serialVersionUID = 4090093290330473479L;
|
||||
|
||||
public SnapAdminForbiddenException(String message) {
|
||||
super(HttpStatus.NOT_FOUND, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return getReason();
|
||||
}
|
||||
|
||||
}
|
@ -27,6 +27,6 @@ import tech.ailef.snapadmin.internal.model.UserAction;
|
||||
public interface CustomActionRepository {
|
||||
public List<UserAction> findActions(LogsSearchRequest r);
|
||||
|
||||
public long countActions(String table, String actionType, String itemId);
|
||||
public long countActions(LogsSearchRequest request);
|
||||
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ public class CustomActionRepositoryImpl implements CustomActionRepository {
|
||||
public List<UserAction> findActions(LogsSearchRequest request) {
|
||||
String table = request.getTable();
|
||||
String actionType = request.getActionType();
|
||||
String username = request.getUsername();
|
||||
String itemId = request.getItemId();
|
||||
PageRequest page = request.toPageRequest();
|
||||
|
||||
@ -68,6 +69,8 @@ public class CustomActionRepositoryImpl implements CustomActionRepository {
|
||||
predicates.add(cb.equal(userAction.get("actionType"), actionType));
|
||||
if (itemId != null)
|
||||
predicates.add(cb.equal(userAction.get("primaryKey"), itemId));
|
||||
if (username != null)
|
||||
predicates.add(cb.equal(userAction.get("username"), username));
|
||||
|
||||
if (!predicates.isEmpty()) {
|
||||
query.select(userAction)
|
||||
@ -95,12 +98,17 @@ public class CustomActionRepositoryImpl implements CustomActionRepository {
|
||||
* @return the number of user actions matching the filtering parameters
|
||||
*/
|
||||
@Override
|
||||
public long countActions(String table, String actionType, String itemId) {
|
||||
public long countActions(LogsSearchRequest request) {
|
||||
|
||||
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
||||
CriteriaQuery<Long> query = cb.createQuery(Long.class);
|
||||
Root<UserAction> userAction = query.from(UserAction.class);
|
||||
|
||||
String table = request.getTable();
|
||||
String actionType = request.getActionType();
|
||||
String itemId = request.getItemId();
|
||||
String username = request.getUsername();
|
||||
|
||||
List<Predicate> predicates = new ArrayList<>();
|
||||
if (table != null)
|
||||
predicates.add(cb.equal(userAction.get("onTable"), table));
|
||||
@ -108,6 +116,8 @@ public class CustomActionRepositoryImpl implements CustomActionRepository {
|
||||
predicates.add(cb.equal(userAction.get("actionType"), actionType));
|
||||
if (itemId != null)
|
||||
predicates.add(cb.equal(userAction.get("primaryKey"), itemId));
|
||||
if (username != null)
|
||||
predicates.add(cb.equal(userAction.get("username"), username));
|
||||
|
||||
if (!predicates.isEmpty()) {
|
||||
query.select(cb.count(userAction))
|
||||
|
@ -60,12 +60,9 @@ public class UserActionService {
|
||||
* @return a page of results matching the input request
|
||||
*/
|
||||
public PaginatedResult<UserAction> findActions(LogsSearchRequest request) {
|
||||
String table = request.getTable();
|
||||
String actionType = request.getActionType();
|
||||
String itemId = request.getItemId();
|
||||
PageRequest page = request.toPageRequest();
|
||||
|
||||
long count = customRepo.countActions(table, actionType, itemId);
|
||||
long count = customRepo.countActions(request);
|
||||
List<UserAction> actions = customRepo.findActions(request);
|
||||
int maxPage = (int)(Math.ceil ((double)count / page.getPageSize()));
|
||||
|
||||
|
@ -44,6 +44,9 @@
|
||||
<span class="input-group-text ms-3">Item ID</span>
|
||||
<input type="text" class="form-control" name="itemId"
|
||||
th:value="${searchRequest.getItemId()}">
|
||||
<span class="input-group-text ms-3">User</span>
|
||||
<input type="text" class="form-control" name="username"
|
||||
th:value="${searchRequest.getUsername()}">
|
||||
<button class="ui-btn btn btn-primary ms-3">Filter</button>
|
||||
</div>
|
||||
</form>
|
||||
|
Loading…
x
Reference in New Issue
Block a user