001/* 002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * <a href="mailto:grenard@nuxeo.com">Guillaume Renard</a> 016 * 017 */ 018 019package org.nuxeo.ecm.platform.routing.core.audit.es; 020 021import java.util.ArrayList; 022import java.util.List; 023 024import org.json.JSONArray; 025import org.json.JSONException; 026import org.json.JSONObject; 027import org.nuxeo.ecm.core.api.CoreSession; 028import org.nuxeo.ecm.core.api.NuxeoPrincipal; 029import org.nuxeo.ecm.core.event.impl.DocumentEventContext; 030import org.nuxeo.ecm.platform.routing.api.DocumentRoute; 031import org.nuxeo.ecm.platform.routing.api.DocumentRoutingConstants; 032import org.nuxeo.ecm.platform.routing.api.DocumentRoutingService; 033import org.nuxeo.elasticsearch.audit.ESAuditBackend; 034import org.nuxeo.elasticsearch.http.readonly.filter.AuditRequestFilter; 035import org.nuxeo.runtime.api.Framework; 036 037/** 038 * Define a elasticsearch passthrough filter for audit_wf index view. Restrict to 'Routing' event category and, if the 039 * user is not an administrator, to the list of workflow model on which the user has the 'Data Visualization' 040 * permission. 041 * 042 * @since 7.4 043 */ 044public class RoutingAuditRequestFilter extends AuditRequestFilter { 045 046 private CoreSession session; 047 048 public void init(CoreSession session, String indices, String types, String rawQuery, String payload) { 049 this.session = session; 050 this.principal = (NuxeoPrincipal) session.getPrincipal(); 051 this.indices = ESAuditBackend.IDX_NAME; 052 this.types = ESAuditBackend.IDX_TYPE; 053 this.rawQuery = rawQuery; 054 this.payload = payload; 055 if (payload == null && !principal.isAdministrator()) { 056 // here we turn the UriSearch query_string into a body search 057 extractPayloadFromQuery(); 058 } 059 } 060 061 @Override 062 public String getPayload() throws JSONException { 063 if (filteredPayload == null) { 064 if (payload.contains("\\")) { 065 // JSONObject removes backslash so we need to hide them 066 payload = payload.replaceAll("\\\\", BACKSLASH_MARKER); 067 } 068 JSONObject payloadJson = new JSONObject(payload); 069 JSONObject query; 070 if (payloadJson.has("query")) { 071 query = payloadJson.getJSONObject("query"); 072 073 payloadJson.remove("query"); 074 } else { 075 query = new JSONObject("{\"match_all\":{}}"); 076 } 077 JSONObject categoryFilter = new JSONObject().put("term", new JSONObject().put( 078 DocumentEventContext.CATEGORY_PROPERTY_KEY, DocumentRoutingConstants.ROUTING_CATEGORY)); 079 080 JSONArray fs = new JSONArray().put(categoryFilter); 081 082 if (!principal.isAdministrator()) { 083 DocumentRoutingService documentRoutingService = Framework.getService(DocumentRoutingService.class); 084 List<DocumentRoute> wfModels = documentRoutingService.getAvailableDocumentRouteModel(session); 085 List<String> modelNames = new ArrayList<String>(); 086 for (DocumentRoute model : wfModels) { 087 if (session.hasPermission(model.getDocument().getRef(), DocumentRoutingConstants.CAN_DATA_VISU)) { 088 modelNames.add(model.getModelName()); 089 } 090 } 091 092 JSONObject wfModelFilter = new JSONObject().put("terms", 093 new JSONObject().put("extended.modelName", modelNames.toArray(new String[modelNames.size()]))); 094 095 fs.put(wfModelFilter); 096 } 097 098 JSONObject filter = new JSONObject().put("bool", new JSONObject().put("must", fs)); 099 100 JSONObject newQuery = new JSONObject().put("filtered", 101 new JSONObject().put("query", query).put("filter", filter)); 102 payloadJson.put("query", newQuery); 103 filteredPayload = payloadJson.toString(); 104 if (filteredPayload.contains(BACKSLASH_MARKER)) { 105 filteredPayload = filteredPayload.replaceAll(BACKSLASH_MARKER, "\\\\"); 106 } 107 108 } 109 return filteredPayload; 110 } 111 112}