// Copyright (C) 2014 The Android Open Source Project
//
// Licensed 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 com.googlesource.gerrit.plugins.gitblit.auth;

import static javax.servlet.http.HttpServletResponse.SC_UNAUTHORIZED;

import com.gitblit.manager.IGitblit;
import com.gitblit.models.UserModel;
import com.google.common.base.MoreObjects;
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.httpd.WebSession;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64;

@Singleton
public class GerritAuthFilter {
  private static final String LIT_BASIC = "Basic ";

  private final IGitblit gitBlit;

  @Inject
  public GerritAuthFilter(IGitblit gitBlit) {
    this.gitBlit = gitBlit;
  }

  /**
   * Returns the user making the request, if the user has authenticated.
   *
   * @param httpRequest
   * @return user
   */
  public UserModel getUser(HttpServletRequest httpRequest) {
    UserModel user = null;
    String username = (String) httpRequest.getAttribute("gerrit-username");
    String token = (String) httpRequest.getAttribute("gerrit-token");

    if (token == null || username == null) {
      return null;
    }

    user =
        gitBlit.authenticate(
            username, (GerritToGitBlitUserService.SESSIONAUTH + token).toCharArray(), null);
    if (user != null) {
      return user;
    }

    return null;
  }

  public boolean doFilter(
      final DynamicItem<WebSession> webSession, ServletRequest request, ServletResponse response)
      throws IOException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;

    String hdr = httpRequest.getHeader("Authorization");
    if (hdr != null) {
      return filterBasicAuth((HttpServletRequest) request, (HttpServletResponse) response, hdr);
    } else if (webSession.get().isSignedIn()) {
      return filterSessionAuth(webSession, (HttpServletRequest) request);
    } else {
      return true;
    }
  }

  public boolean filterSessionAuth(
      final DynamicItem<WebSession> webSession, HttpServletRequest request) {
    request.setAttribute("gerrit-username", webSession.get().getUser().getUserName());
    request.setAttribute("gerrit-token", webSession.get().getSessionId());
    return true;
  }

  public boolean filterBasicAuth(
      HttpServletRequest request, HttpServletResponse response, String hdr)
      throws IOException, UnsupportedEncodingException {
    if (!hdr.startsWith(LIT_BASIC)) {
      response.setHeader("WWW-Authenticate", "Basic realm=\"Gerrit Code Review\"");
      response.sendError(SC_UNAUTHORIZED);
      return false;
    }

    final byte[] decoded = new Base64().decode(hdr.substring(LIT_BASIC.length()).getBytes());
    String usernamePassword =
        new String(decoded, MoreObjects.firstNonNull(request.getCharacterEncoding(), "UTF-8"));
    int splitPos = usernamePassword.indexOf(':');
    if (splitPos < 1) {
      response.setHeader("WWW-Authenticate", "Basic realm=\"Gerrit Code Review\"");
      response.sendError(SC_UNAUTHORIZED);
      return false;
    }
    request.setAttribute("gerrit-username", usernamePassword.substring(0, splitPos));
    request.setAttribute("gerrit-password", usernamePassword.substring(splitPos + 1));

    return true;
  }
}
