/*
* This file is part of ReadonlyREST.
*
* ReadonlyREST 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.
*
* ReadonlyREST 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 ReadonlyREST. If not, see http://www.gnu.org/licenses/
*/
package org.elasticsearch.plugin.readonlyrest.es.requestcontext;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.IndicesRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.get.MultiGetRequest;
import org.elasticsearch.action.search.MultiSearchRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.plugin.readonlyrest.ESContext;
import org.elasticsearch.plugin.readonlyrest.acl.domain.LoggedUser;
import org.elasticsearch.plugin.readonlyrest.requestcontext.Delayed;
import org.elasticsearch.plugin.readonlyrest.requestcontext.IndicesRequestContext;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
* Created by sscarduzio on 13/04/2017.
*/
public class SubRequestContext extends Delayed implements IndicesRequestContext {
private final Logger logger;
private final RequestContextImpl originalRC;
private final Object originalSubRequest;
private final ESContext context;
private final SubRCTransactionalIndices indices;
public SubRequestContext(RequestContextImpl originalRequestContext, Object originalSubRequest, ESContext context) {
super("src", context);
this.logger = context.logger(getClass());
this.indices = new SubRCTransactionalIndices(this, context);
this.originalRC = originalRequestContext;
this.originalSubRequest = originalSubRequest;
this.context = context;
// Register transactional fields
indices.delegateTo(this);
}
static List<? extends IndicesRequest> extractNativeSubrequests(ActionRequest r) {
if (r instanceof MultiSearchRequest) {
return ((MultiSearchRequest) r).requests();
} else if (r instanceof MultiGetRequest) {
return ((MultiGetRequest) r).getItems();
} else if (r instanceof BulkRequest) {
return ((BulkRequest) r).requests();
} else return new ArrayList<>(0);
}
public Object getOriginalSubRequest() {
return originalSubRequest;
}
public Set<String> getIndices() {
return indices.getInitial();
}
public void setIndices(Set<String> newIndices) {
if (newIndices.size() == 0) {
throw context.rorException(
"Attempted to set empty indices list in a sub-request this would allow full access, therefore this is forbidden." +
" If this was intended, set '*' as indices.");
}
newIndices.remove("<no-index>");
newIndices.remove("");
Set<String> oldIndices = indices.get();
if (newIndices.equals(oldIndices)) {
logger.info("id: " + getId() + " - Not replacing in sub-request. Indices are the same. Old:" + oldIndices + " New:" + newIndices);
return;
}
logger.info("id: " + getId() + " - Replacing indices in sub-request. Old:" + oldIndices + " New:" + newIndices);
indices.mutate(newIndices);
}
@Override
public Optional<LoggedUser> getLoggedInUser() {
return originalRC.getLoggedInUser();
}
@Override
public void setLoggedInUser(LoggedUser user) {
originalRC.setLoggedInUser(user);
}
public boolean involvesIndices() {
return true;
}
public Set<String> getExpandedIndices() {
return originalRC.getExpandedIndices(indices.getInitial());
}
@Override
public String getId() {
return originalRC.getId() + "-sub-" + originalSubRequest.hashCode();
}
public Set<String> getAllIndicesAndAliases() {
return originalRC.getAllIndicesAndAliases();
}
public Boolean isReadRequest() {
if (originalSubRequest instanceof SearchRequest || originalSubRequest instanceof MultiGetRequest.Item) {
return true;
} else if (originalSubRequest instanceof DocWriteRequest<?>) {
return false;
} else {
throw context.rorException(
"Cannot detect if read or write request " + originalSubRequest.getClass().getSimpleName());
}
}
@Override
public Optional<String> resolveVariable(String original) {
return originalRC.resolveVariable(original);
}
public String toString() {
return "sub-request: { original:" + originalRC.getClass().getSimpleName() +
", sub:" + originalSubRequest.getClass().getSimpleName() + "}";
}
}