/**
 * 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.metron.rest.config;

import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import com.nimbusds.jwt.SignedJWT;
import org.apache.metron.rest.security.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.support.LdapNameBuilder;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.cert.CertificateException;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static org.apache.metron.rest.MetronRestConstants.SECURITY_ROLE_PREFIX;
import static org.springframework.ldap.query.LdapQueryBuilder.query;

/**
 * This class is a Servlet Filter that authenticates a Knox SSO token.  The token is stored in a cookie and is
 * verified against a public Knox key.  The token expiration and begin time are also validated.  Upon successful validation,
 * a Spring Authentication object is built from the user name and user groups queried from LDAP.  Currently, user groups are
 * mapped directly to Spring roles and prepended with "ROLE_".
 */
public class KnoxSSOAuthenticationFilter implements Filter {
  private static final Logger LOG = LoggerFactory.getLogger(KnoxSSOAuthenticationFilter.class);

  private String userSearchBase;
  private Path knoxKeyFile;
  private String knoxKeyString;
  private String knoxCookie;
  private LdapTemplate ldapTemplate;

  public KnoxSSOAuthenticationFilter(String userSearchBase,
                                     Path knoxKeyFile,
                                     String knoxKeyString,
                                     String knoxCookie,
                                     LdapTemplate ldapTemplate) {
    this.userSearchBase = userSearchBase;
    this.knoxKeyFile = knoxKeyFile;
    this.knoxKeyString = knoxKeyString;
    this.knoxCookie = knoxCookie;
    if (ldapTemplate == null) {
      throw new IllegalStateException("KnoxSSO requires LDAP. You must add 'ldap' to the active profiles.");
    }
    this.ldapTemplate = ldapTemplate;
  }

  @Override
  public void init(FilterConfig filterConfig) {
  }

  @Override
  public void destroy() {
  }

  /**
   * Extracts the Knox token from the configured cookie.  If basic authentication headers are present, SSO authentication
   * is skipped.
   * @param request ServletRequest
   * @param response ServletResponse
   * @param chain FilterChain
   * @throws IOException
   * @throws ServletException
   */
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
          throws IOException, ServletException {
    HttpServletRequest httpRequest = (HttpServletRequest) request;

    // If a basic authentication header is present, use that to authenticate and skip SSO
    String authHeader = httpRequest.getHeader("Authorization");
    if (authHeader == null || !authHeader.startsWith("Basic")) {
      String serializedJWT = getJWTFromCookie(httpRequest);
      if (serializedJWT != null) {
        SignedJWT jwtToken;
        try {
          jwtToken = parseJWT(serializedJWT);
          String userName = jwtToken.getJWTClaimsSet().getSubject();
          LOG.info("SSO login user : {} ", userName);
          if (isValid(jwtToken, userName)) {
            Authentication authentication = getAuthentication(userName, httpRequest);
            getSecurityContext().setAuthentication(authentication);
          }
        } catch (ParseException e) {
          LOG.warn("Unable to parse the JWT token", e);
        }
      }
    }
    chain.doFilter(request, response);
  }

  // exposed for testing
  protected SecurityContext getSecurityContext() {
    return SecurityContextHolder.getContext();
  }

  // exposed for testing
  protected SignedJWT parseJWT(String serializedJWT) throws ParseException {
    return SignedJWT.parse(serializedJWT);
  }

  /**
   * Validates a Knox token with expiration and begin times and verifies the token with a public Knox key.
   * @param jwtToken Knox token
   * @param userName User name associated with the token
   * @return Whether a token is valid or not
   * @throws ParseException JWT Token could not be parsed.
   */
  protected boolean isValid(SignedJWT jwtToken, String userName) throws ParseException {
    // Verify the user name is present
    if (userName == null || userName.isEmpty()) {
      LOG.info("Could not find user name in SSO token");
      return false;
    }

    Date now = new Date();

    // Verify the token has not expired
    Date expirationTime = jwtToken.getJWTClaimsSet().getExpirationTime();
    if (expirationTime != null && now.after(expirationTime)) {
      LOG.info("SSO token expired: {} ", userName);
      return false;
    }

    // Verify the token is not before time
    Date notBeforeTime = jwtToken.getJWTClaimsSet().getNotBeforeTime();
    if (notBeforeTime != null && now.before(notBeforeTime)) {
      LOG.info("SSO token not yet valid: {} ", userName);
      return false;
    }

    return validateSignature(jwtToken);
  }

  /**
   * Verify the signature of the JWT token in this method. This method depends on
   * the public key that was established during init based upon the provisioned
   * public key. Override this method in subclasses in order to customize the
   * signature verification behavior.
   *
   * @param jwtToken The token that contains the signature to be validated.
   * @return valid true if signature verifies successfully; false otherwise
   */
  protected boolean validateSignature(SignedJWT jwtToken) {
    // Verify the token signature algorithm was as expected
    String receivedSigAlg = jwtToken.getHeader().getAlgorithm().getName();

    if (!receivedSigAlg.equals(JWSAlgorithm.RS256.getName())) {
      return false;
    }

    // Verify the token has been properly signed
    if (JWSObject.State.SIGNED == jwtToken.getState()) {
      LOG.debug("SSO token is in a SIGNED state");
      if (jwtToken.getSignature() != null) {
        LOG.debug("SSO token signature is not null");
        try {
          JWSVerifier verifier = getRSASSAVerifier();
          if (jwtToken.verify(verifier)) {
            LOG.debug("SSO token has been successfully verified");
            return true;
          } else {
            LOG.warn("SSO signature verification failed. Please check the public key.");
          }
        } catch (Exception e) {
          LOG.warn("Error while validating signature", e);
        }
      }
    }
    return false;
  }

  // exposed for testing
  protected RSASSAVerifier getRSASSAVerifier() throws CertificateException, IOException {
    return new RSASSAVerifier(SecurityUtils.parseRSAPublicKey(getKnoxKey()));
  }

  /**
   * Encapsulate the acquisition of the JWT token from HTTP cookies within the
   * request.
   *
   * @param req ServletRequest to get the JWT token from
   * @return serialized JWT token
   */
  protected String getJWTFromCookie(HttpServletRequest req) {
    String serializedJWT = null;
    Cookie[] cookies = req.getCookies();
    if (cookies != null) {
      for (Cookie cookie : cookies) {
        LOG.debug(String.format("Found cookie: %s [%s]", cookie.getName(), cookie.getValue()));
        if (knoxCookie.equals(cookie.getName())) {
          if (LOG.isDebugEnabled()) {
            LOG.debug(knoxCookie + " cookie has been found and is being processed");
          }
          serializedJWT = cookie.getValue();
          break;
        }
      }
    } else {
      if (LOG.isDebugEnabled()) {
        LOG.debug(knoxCookie + " not found");
      }
    }
    return serializedJWT;
  }

  /**
   * A public Knox key can either be passed in directly or read from a file.
   * @return Public Knox key
   * @throws IOException There was a problem reading the Knox key file.
   */
  protected String getKnoxKey() throws IOException {
    String knoxKey;
    if ((this.knoxKeyString == null || this.knoxKeyString.isEmpty()) && this.knoxKeyFile != null) {
      List<String> keyLines = Files.readAllLines(knoxKeyFile, StandardCharsets.UTF_8);
      knoxKey = String.join("", keyLines);
    } else {
      knoxKey = this.knoxKeyString;
    }
    return knoxKey;
  }

  /**
   * Builds the Spring Authentication object using the supplied user name and groups looked up from LDAP.  Groups are currently
   * mapped directly to Spring roles by converting to upper case and prepending the name with "ROLE_".
   * @param userName The username to build the Authentication object with.
   * @param httpRequest HttpServletRequest
   * @return Authentication object for the given user.
   */
  protected Authentication getAuthentication(String userName, HttpServletRequest httpRequest) {
    String ldapName = LdapNameBuilder.newInstance().add(userSearchBase).add("uid", userName).build().toString();

    // Search ldap for a user's groups and convert to a Spring role
    List<GrantedAuthority> grantedAuths = ldapTemplate.search(query()
            .where("objectclass")
            .is("groupOfNames")
            .and("member")
            .is(ldapName), (AttributesMapper<String>) attrs -> (String) attrs.get("cn").get())
            .stream()
            .map(group -> String.format("%s%s", SECURITY_ROLE_PREFIX, group.toUpperCase()))
            .map(SimpleGrantedAuthority::new).collect(Collectors.toList());

    final UserDetails principal = new User(userName, "", grantedAuths);
    final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
            principal, "", grantedAuths);
    WebAuthenticationDetails webDetails = new WebAuthenticationDetails(httpRequest);
    authentication.setDetails(webDetails);
    return authentication;
  }

}
