package jp.hashiwa.elasticsearch.authplugin;

import org.apache.logging.log4j.Logger;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.rest.*;

public class AuthRestHandler implements RestHandler {
  private final Logger logger = Loggers.getLogger(AuthRestHandler.class);
  private final RestHandler originalHandler;
  private final RestResponse unauthorizedResponse = new RestResponse() {
    @Override
    public String contentType() {
      return "application/json";
    }

    @Override
    public BytesReference content() {
      return new BytesArray("{\"error\": \"Unauthorized.\"}");
    }

    @Override
    public RestStatus status() {
      return RestStatus.UNAUTHORIZED;
    }
  };

  AuthRestHandler(RestHandler restHandler) {
    this.originalHandler = restHandler;
  }

  @Override
  public void handleRequest(RestRequest restRequest, RestChannel restChannel, NodeClient nodeClient) throws Exception {
    this.logger.debug(restRequest.path());
    this.logger.debug(restRequest.rawPath());
    if (isOk(restRequest)) {
      this.originalHandler.handleRequest(restRequest, restChannel, nodeClient);
    } else {
      restChannel.sendResponse(unauthorizedResponse);
    }
  }

  private boolean isOk(RestRequest restRequest) {
    for (java.util.Map.Entry<String, String> entry: restRequest.headers()) {
      String key = entry.getKey();
      String value = entry.getValue();
      if (key.equals("user") && value.equals("admin")) {
        return true;
      }
    }
    return false;

    // ES 5.4
    // return restRequest.getHeaders().get("user").equals("admin");
  }
}

@@ -315,16 +315,101 @@
 est.*;%0A%0A
+import java.util.*;%0Aimport java.util.regex.Pattern;%0Aimport java.util.stream.Stream;%0A%0A
 public c
@@ -951,16 +951,499 @@
   %7D%0A  %7D;
+%0A  private final Map%3CRestRequest.Method, Stream%3CPattern%3E%3E authPatterns = new HashMap%3CRestRequest.Method, Stream%3CPattern%3E%3E() %7B%0A    %7B%0A      this.put(RestRequest.Method.POST, Stream.of(%0A              Pattern.compile(%22%5E/testindex(/.*)?$%22)%0A      ));%0A      this.put(RestRequest.Method.PUT, Stream.of(%0A              Pattern.compile(%22%5E/testindex(/.*)?$%22)%0A      ));%0A      // all methods%0A      this.put(null, Stream.of(%0A              Pattern.compile(%22%5E/adminindex(/.*)?$%22)%0A      ));%0A    %7D%0A  %7D;
 %0A%0A  Auth
@@ -1956,39 +1956,605 @@
 ean 
-isOk(RestRequest restRequest) %7B
+needAuth(RestRequest.Method method, String path) %7B%0A    if (authPatterns.containsKey(method)) %7B%0A      Stream%3CPattern%3E patterns = authPatterns.get(method);%0A      boolean match = patterns.anyMatch(%0A              p -%3E p.matcher(path).matches()%0A      );%0A      return match;%0A    %7D%0A    return false;%0A  %7D%0A%0A  private boolean isOk(RestRequest restRequest) %7B%0A    RestRequest.Method method = restRequest.method();%0A    String path = restRequest.path(); // use rawpath() ?%0A    boolean needAuth = needAuth(method, path)%0A                    %7C%7C needAuth(null, path);%0A    if (! needAuth) %7B%0A      return true;%0A    %7D%0A
 %0A   

add method/path check