| /* $Id$ */ |
| /* Modified to MCFAuthorizerRestSearchAction.java 2015-04-28 Bart Superson */ |
| /** |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 org.apache.manifoldcf.elasticsearch; |
| |
| import org.elasticsearch.action.search.SearchRequest; |
| import org.elasticsearch.client.Client; |
| import org.elasticsearch.common.inject.Inject; |
| import org.elasticsearch.common.settings.Settings; |
| import org.elasticsearch.rest.*; |
| import org.elasticsearch.rest.action.search.RestSearchAction; |
| import org.elasticsearch.rest.action.RestStatusToXContentListener; |
| |
| import com.fasterxml.jackson.databind.JsonNode; |
| import com.fasterxml.jackson.databind.ObjectMapper; |
| import com.fasterxml.jackson.databind.node.ObjectNode; |
| import org.elasticsearch.action.support.IndicesOptions; |
| /**import org.elasticsearch.common.ParseFieldMatcher;*/ |
| import org.elasticsearch.common.bytes.BytesReference; |
| import org.elasticsearch.common.Strings; |
| import org.elasticsearch.index.query.*; |
| import org.elasticsearch.rest.RestRequest; |
| import org.elasticsearch.rest.action.RestActions; |
| import org.elasticsearch.search.Scroll; |
| import org.elasticsearch.search.builder.SearchSourceBuilder; |
| import org.elasticsearch.search.fetch.subphase.FetchSourceContext; |
| import org.elasticsearch.search.sort.SortOrder; |
| import org.elasticsearch.search.suggest.SuggestBuilders; |
| import org.elasticsearch.search.suggest.term.TermSuggestionBuilder; |
| import org.elasticsearch.common.unit.TimeValue; |
| import org.elasticsearch.common.xcontent.XContentParser; |
| |
| import java.io.*; |
| |
| public class MCFAuthorizerRestSearchAction extends RestSearchAction { |
| |
| protected final MCFAuthorizer authorizer; |
| |
| @Inject |
| public MCFAuthorizerRestSearchAction(Settings settings, final RestController restController) { |
| super(settings,restController); |
| final MCFConfigurationParameters conf = new MCFConfigurationParameters(settings); |
| authorizer = new MCFAuthorizer(conf); |
| } |
| |
| public void handleRequest(RestRequest request, RestChannel channel, Client client) { |
| SearchRequest searchRequest; |
| searchRequest = parseSearchRequestMCF(request); //, parseFieldMatcher); |
| client.search(searchRequest, new RestStatusToXContentListener(channel)); |
| } |
| |
| protected SearchRequest parseSearchRequestMCF( |
| final RestRequest request //, |
| // final ParseFieldMatcher parseFieldMatcher |
| ) throws MCFAuthorizerException { |
| final SearchRequest searchRequest; |
| if(request.param("u")!=null) { |
| searchRequest = new SearchRequest(); |
| String[] authenticatedUserNamesAndDomains = request.param("u").split(","); |
| String[] indices = Strings.splitStringByCommaToArray(request.param("index")); |
| searchRequest.indices(indices); |
| boolean isTemplateRequest = request.path().endsWith("/template"); |
| |
| if(request.hasContent() || request.hasParam("source")) { |
| QueryBuilder authorizationFilter = authorizer.buildAuthorizationFilter(authenticatedUserNamesAndDomains); |
| QueryBuilder filteredQueryBuilder; |
| |
| ObjectMapper objectMapper = new ObjectMapper(); |
| ObjectNode modifiedJSON, innerJSON; |
| JsonNode requestJSON; |
| |
| try { |
| requestJSON = objectMapper.readTree(RestActions.getQueryContent((XContentParser) request).toString()); |
| if (isTemplateRequest) { |
| modifiedJSON = (ObjectNode) requestJSON; |
| innerJSON = (ObjectNode)requestJSON.findValue("template"); |
| filteredQueryBuilder = QueryBuilders.boolQuery() |
| .must (QueryBuilders.wrapperQuery(innerJSON.findValue("query").toString())) |
| .must(authorizationFilter); |
| |
| modifiedJSON.replace("template",innerJSON.set("query", objectMapper.readTree(filteredQueryBuilder.toString()))); |
| searchRequest.templateSource(modifiedJSON.toString()); |
| searchRequest.set |
| } else { |
| filteredQueryBuilder = QueryBuilders.boolQuery() |
| .must(QueryBuilders.wrapperQuery(requestJSON.findValue("query").toString())) |
| .must(authorizationFilter); |
| |
| modifiedJSON = (ObjectNode) requestJSON; |
| modifiedJSON.set("query", objectMapper.readTree(filteredQueryBuilder.toString())); |
| searchRequest.source(modifiedJSON.toString()); |
| } |
| } catch (IOException e) { |
| throw new MCFAuthorizerException("JSON parser error: "+e.getMessage(), e); |
| } |
| } |
| |
| //parseSearchSource(searchRequest.source(), request); |
| searchRequest.source(parseSearchSourceMCF(request)); |
| searchRequest.searchType(request.param("search_type")); |
| |
| // Should this be done? |
| searchRequest.requestCache(request.paramAsBoolean("request_cache", null)); |
| |
| String scroll = request.param("scroll"); |
| if (scroll != null) { |
| searchRequest.scroll(new Scroll(TimeValue.parseTimeValue(scroll, null, "scroll"))); |
| } |
| |
| searchRequest.types(Strings.splitStringByCommaToArray(request.param("type"))); |
| searchRequest.routing(request.param("routing")); |
| searchRequest.preference(request.param("preference")); |
| searchRequest.indicesOptions(IndicesOptions.fromRequest(request, searchRequest.indicesOptions())); |
| } |
| else { |
| searchRequest = parseSearchRequest(request);//, parseFieldMatcher); |
| } |
| return searchRequest; |
| } |
| |
| protected SearchSourceBuilder parseSearchSourceMCF(final RestRequest request) throws MCFAuthorizerException { |
| SearchSourceBuilder searchSourceBuilder = null; |
| String queryString = request.param("q"); |
| if(queryString != null) { |
| String[] authenticatedUserNamesAndDomains = request.param("u").split(","); |
| QueryBuilder authorizationFilter = authorizer.buildAuthorizationFilter(authenticatedUserNamesAndDomains); |
| QueryStringQueryBuilder from = QueryBuilders.queryStringQuery(queryString); |
| from.defaultField(request.param("df")); |
| from.analyzer(request.param("analyzer")); |
| from.analyzeWildcard(request.paramAsBoolean("analyze_wildcard", false)); |
| // from.lowercaseExpandedTerms(request.paramAsBoolean("lowercase_expanded_terms", true)); |
| from.lenient(request.paramAsBoolean("lenient", (Boolean)null)); |
| String size = request.param("default_operator"); |
| if(size != null) { |
| if("OR".equals(size)) { |
| from.defaultOperator(Operator.OR); |
| } else { |
| if(!"AND".equals(size)) { |
| throw new IllegalArgumentException("Unsupported defaultOperator [" + size + "], can either be [OR] or [AND]"); |
| } |
| |
| from.defaultOperator(Operator.AND); |
| } |
| } |
| |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| searchSourceBuilder.query(QueryBuilders.boolQuery() |
| .must(from) |
| .must(authorizationFilter)); |
| } |
| else { |
| if(!(request.hasContent() || request.hasParam("source"))){ |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| QueryBuilder authorizationFilter = authorizer.buildAuthorizationFilter(request.param("u")); |
| searchSourceBuilder.query(QueryBuilders.boolQuery() |
| .must(authorizationFilter)); |
| } |
| } |
| |
| int var19 = request.paramAsInt("from", -1); |
| if(var19 != -1) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| searchSourceBuilder.from(var19); |
| } |
| |
| int var20 = request.paramAsInt("size", -1); |
| if(var20 != -1) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| searchSourceBuilder.size(var20); |
| } |
| |
| if(request.hasParam("explain")) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| searchSourceBuilder.explain(request.paramAsBoolean("explain", (Boolean)null)); |
| } |
| |
| if(request.hasParam("version")) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| searchSourceBuilder.version(request.paramAsBoolean("version", (Boolean)null)); |
| } |
| |
| if(request.hasParam("timeout")) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| searchSourceBuilder.timeout(request.paramAsTime("timeout", (TimeValue)null)); |
| } |
| |
| if(request.hasParam("terminate_after")) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| int sField = request.paramAsInt("terminate_after", 0); |
| if(sField < 0) { |
| throw new IllegalArgumentException("terminateAfter must be > 0"); |
| } |
| |
| if(sField > 0) { |
| searchSourceBuilder.terminateAfter(sField); |
| } |
| } |
| |
| String var21 = request.param("fields"); |
| String suggestField; |
| if(var21 != null) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| if(!Strings.hasText(var21)) { |
| searchSourceBuilder.noFields(); |
| } else { |
| String[] fetchSourceContext = Strings.splitStringByCommaToArray(var21); |
| if(fetchSourceContext != null) { |
| String[] sSorts = fetchSourceContext; |
| int sIndicesBoost = fetchSourceContext.length; |
| |
| for(int sStats = 0; sStats < sIndicesBoost; ++sStats) { |
| suggestField = sSorts[sStats]; |
| searchSourceBuilder.field(suggestField); |
| } |
| } |
| } |
| } |
| |
| FetchSourceContext var22 = FetchSourceContext.parseFromRestRequest(request); |
| if(var22 != null) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| searchSourceBuilder.fetchSource(var22); |
| } |
| |
| if(request.hasParam("track_scores")) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| searchSourceBuilder.trackScores(request.paramAsBoolean("track_scores", false)); |
| } |
| |
| String var23 = request.param("sort"); |
| int suggestText; |
| String indexName; |
| String[] var26; |
| if(var23 != null) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| String[] var24 = Strings.splitStringByCommaToArray(var23); |
| var26 = var24; |
| int var27 = var24.length; |
| |
| for(suggestText = 0; suggestText < var27; ++suggestText) { |
| String suggestSize = var26[suggestText]; |
| int suggestMode = suggestSize.lastIndexOf(":"); |
| if(suggestMode != -1) { |
| String divisor = suggestSize.substring(0, suggestMode); |
| indexName = suggestSize.substring(suggestMode + 1); |
| if("asc".equals(indexName)) { |
| searchSourceBuilder.sort(divisor, SortOrder.ASC); |
| } else if("desc".equals(indexName)) { |
| searchSourceBuilder.sort(divisor, SortOrder.DESC); |
| } |
| } else { |
| searchSourceBuilder.sort(suggestSize); |
| } |
| } |
| } |
| |
| String var25 = request.param("indices_boost"); |
| int var31; |
| String var32; |
| if(var25 != null) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| var26 = Strings.splitStringByCommaToArray(var25); |
| String[] var29 = var26; |
| suggestText = var26.length; |
| |
| for(var31 = 0; var31 < suggestText; ++var31) { |
| var32 = var29[var31]; |
| int var33 = var32.indexOf(44); |
| if(var33 == -1) { |
| throw new IllegalArgumentException("Illegal index boost [" + var32 + "], no \',\'"); |
| } |
| |
| indexName = var32.substring(0, var33); |
| String sBoost = var32.substring(var33 + 1); |
| |
| try { |
| searchSourceBuilder.indexBoost(indexName, Float.parseFloat(sBoost)); |
| } catch (NumberFormatException var18) { |
| throw new IllegalArgumentException("Illegal index boost [" + var32 + "], boost not a float number"); |
| } |
| } |
| } |
| |
| String var28 = request.param("stats"); |
| if(var28 != null) { |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| searchSourceBuilder.stats(Strings.splitStringByCommaToArray(var28)); |
| } |
| |
| suggestField = request.param("suggest_field"); |
| if(suggestField != null) { |
| String var30 = request.param("suggest_text", queryString); |
| var31 = request.paramAsInt("suggest_size", 5); |
| if(searchSourceBuilder == null) { |
| searchSourceBuilder = new SearchSourceBuilder(); |
| } |
| |
| var32 = request.param("suggest_mode"); |
| searchSourceBuilder.suggest().addSuggestion(((TermSuggestionBuilder)((TermSuggestionBuilder)((TermSuggestionBuilder)SuggestBuilders.termSuggestion(suggestField).field(suggestField)).text(var30)).size(var31)).suggestMode(var32)); |
| } |
| |
| return searchSourceBuilder; |
| } |
| |
| } |