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.ElasticSearchConstants; 034import org.nuxeo.elasticsearch.api.ElasticSearchAdmin; 035import org.nuxeo.elasticsearch.http.readonly.filter.AuditRequestFilter; 036import org.nuxeo.runtime.api.Framework; 037 038/** 039 * Define a elasticsearch passthrough filter for audit_wf index view. Restrict to 'Routing' event category and, if the 040 * user is not an administrator, to the list of workflow model on which the user has the 'Data Visualization' 041 * permission. 042 * 043 * @since 7.4 044 */ 045public class RoutingAuditRequestFilter extends AuditRequestFilter { 046 047 private CoreSession session; 048 049 @Override 050 public void init(CoreSession session, String indices, String types, String rawQuery, String payload) { 051 this.session = session; 052 principal = (NuxeoPrincipal) session.getPrincipal(); 053 ElasticSearchAdmin esa = Framework.getService(ElasticSearchAdmin.class); 054 this.indices = esa.getIndexNameForType(ElasticSearchConstants.ENTRY_TYPE); 055 this.types = ElasticSearchConstants.ENTRY_TYPE; 056 this.rawQuery = rawQuery; 057 this.payload = payload; 058 if (payload == null && !principal.isAdministrator()) { 059 // here we turn the UriSearch query_string into a body search 060 extractPayloadFromQuery(); 061 } 062 } 063 064 @Override 065 public String getPayload() throws JSONException { 066 if (filteredPayload == null) { 067 if (payload.contains("\\")) { 068 // JSONObject removes backslash so we need to hide them 069 payload = payload.replaceAll("\\\\", BACKSLASH_MARKER); 070 } 071 JSONObject payloadJson = new JSONObject(payload); 072 JSONObject query; 073 if (payloadJson.has("query")) { 074 query = payloadJson.getJSONObject("query"); 075 076 payloadJson.remove("query"); 077 } else { 078 query = new JSONObject("{\"match_all\":{}}"); 079 } 080 JSONObject categoryFilter = new JSONObject().put("term", new JSONObject().put( 081 DocumentEventContext.CATEGORY_PROPERTY_KEY, DocumentRoutingConstants.ROUTING_CATEGORY)); 082 083 JSONArray fs = new JSONArray().put(categoryFilter); 084 085 if (!principal.isAdministrator()) { 086 DocumentRoutingService documentRoutingService = Framework.getService(DocumentRoutingService.class); 087 List<DocumentRoute> wfModels = documentRoutingService.getAvailableDocumentRouteModel(session); 088 List<String> modelNames = new ArrayList<String>(); 089 for (DocumentRoute model : wfModels) { 090 if (session.hasPermission(model.getDocument().getRef(), DocumentRoutingConstants.CAN_DATA_VISU)) { 091 modelNames.add(model.getModelName()); 092 } 093 } 094 095 JSONObject wfModelFilter = new JSONObject().put("terms", 096 new JSONObject().put("extended.modelName", modelNames.toArray(new String[modelNames.size()]))); 097 098 fs.put(wfModelFilter); 099 } 100 101 JSONObject filter = new JSONObject().put("bool", new JSONObject().put("must", fs)); 102 103 JSONObject newQuery = new JSONObject().put("filtered", 104 new JSONObject().put("query", query).put("filter", filter)); 105 payloadJson.put("query", newQuery); 106 filteredPayload = payloadJson.toString(); 107 if (filteredPayload.contains(BACKSLASH_MARKER)) { 108 filteredPayload = filteredPayload.replaceAll(BACKSLASH_MARKER, "\\\\"); 109 } 110 111 } 112 return filteredPayload; 113 } 114 115}