Implement a more capable servlet auditing interface.

In order to facilitate action-specific auditing, the RestResource,
RestView, and HttpServletRequest are incorporated into a new extended
audit event class, supplementing all existing fields (some redundant)
in HttpAuditEvent. Although the request is already available from the
Guice injector, adding this high-value information as a field
facilitates convenient access.

Change-Id: I3ebd629c90921237bbcfbb00d9ea990740099104
This commit is contained in:
David Pletcher
2015-04-30 15:59:41 -07:00
parent 79d17aa007
commit 86535611f3
2 changed files with 64 additions and 7 deletions

View File

@@ -46,7 +46,7 @@ import com.google.common.io.BaseEncoding;
import com.google.common.math.IntMath; import com.google.common.math.IntMath;
import com.google.common.net.HttpHeaders; import com.google.common.net.HttpHeaders;
import com.google.gerrit.audit.AuditService; import com.google.gerrit.audit.AuditService;
import com.google.gerrit.audit.HttpAuditEvent; import com.google.gerrit.audit.ExtendedHttpAuditEvent;
import com.google.gerrit.common.Nullable; import com.google.gerrit.common.Nullable;
import com.google.gerrit.common.TimeUtil; import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.registration.DynamicItem; import com.google.gerrit.extensions.registration.DynamicItem;
@@ -204,6 +204,8 @@ public class RestApiServlet extends HttpServlet {
Object result = null; Object result = null;
Multimap<String, String> params = LinkedHashMultimap.create(); Multimap<String, String> params = LinkedHashMultimap.create();
Object inputRequestBody = null; Object inputRequestBody = null;
RestResource rsrc = TopLevelResource.INSTANCE;
ViewData viewData = null;
try { try {
checkUserSession(req); checkUserSession(req);
@@ -213,8 +215,8 @@ public class RestApiServlet extends HttpServlet {
CapabilityUtils.checkRequiresCapability(globals.currentUser, CapabilityUtils.checkRequiresCapability(globals.currentUser,
null, rc.getClass()); null, rc.getClass());
RestResource rsrc = TopLevelResource.INSTANCE; viewData = new ViewData(null, null);
ViewData viewData = new ViewData(null, null);
if (path.isEmpty()) { if (path.isEmpty()) {
if (isGetOrHead(req)) { if (isGetOrHead(req)) {
viewData = new ViewData(null, rc.list()); viewData = new ViewData(null, rc.list());
@@ -386,10 +388,10 @@ public class RestApiServlet extends HttpServlet {
status = SC_INTERNAL_SERVER_ERROR; status = SC_INTERNAL_SERVER_ERROR;
handleException(e, req, res); handleException(e, req, res);
} finally { } finally {
globals.auditService.dispatch(new HttpAuditEvent(globals.webSession.get() globals.auditService.dispatch(new ExtendedHttpAuditEvent(globals.webSession.get()
.getSessionId(), globals.currentUser.get(), req.getRequestURI(), .getSessionId(), globals.currentUser.get(), req,
auditStartTs, params, req.getMethod(), inputRequestBody, status, auditStartTs, params, inputRequestBody, status,
result)); result, rsrc, viewData.view));
} }
} }

View File

@@ -0,0 +1,55 @@
// Copyright (C) 2015 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.audit;
import com.google.common.base.Preconditions;
import com.google.common.collect.Multimap;
import com.google.gerrit.extensions.restapi.RestResource;
import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.server.CurrentUser;
import javax.servlet.http.HttpServletRequest;
/**
* Extended audit event. Adds request, resource and view data to HttpAuditEvent.
*/
public class ExtendedHttpAuditEvent extends HttpAuditEvent {
public final HttpServletRequest httpRequest;
public final RestResource resource;
public final RestView<? extends RestResource> view;
/**
* Creates a new audit event with results
*
* @param sessionId session id the event belongs to
* @param who principal that has generated the event
* @param httpRequest the HttpServletRequest
* @param when time-stamp of when the event started
* @param params parameters of the event
* @param result result of the event
* @param resource REST resource data
* @param view view rendering object
*/
public ExtendedHttpAuditEvent(String sessionId, CurrentUser who,
HttpServletRequest httpRequest, long when, Multimap<String, ?> params,
Object input, int status, Object result, RestResource resource,
RestView<RestResource> view) {
super(sessionId, who, httpRequest.getRequestURI(), when, params, httpRequest.getMethod(),
input, status, result);
this.httpRequest = Preconditions.checkNotNull(httpRequest);
this.resource = resource;
this.view = view;
}
}