/*
 * 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.hadoop.hdds.security.token;

import com.google.common.base.Strings;
import org.apache.hadoop.hdds.HddsUtils;
import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos;
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
import org.apache.hadoop.hdds.security.exception.SCMSecurityException;
import org.apache.hadoop.hdds.security.x509.SecurityConfig;
import org.apache.hadoop.hdds.security.x509.certificate.client.CertificateClient;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.util.Time;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.security.cert.X509Certificate;

import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Type.GetBlock;
import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Type.GetSmallFile;
import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Type.PutBlock;
import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Type.PutSmallFile;
import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Type.ReadChunk;
import static org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.Type.WriteChunk;


/**
 * Verify token and return a UGI with token if authenticated.
 */
public class BlockTokenVerifier implements TokenVerifier {

  private final CertificateClient caClient;
  private final SecurityConfig conf;
  private static boolean testStub = false;
  private final static Logger LOGGER =
      LoggerFactory.getLogger(BlockTokenVerifier.class);

  public BlockTokenVerifier(SecurityConfig conf, CertificateClient caClient) {
    this.conf = conf;
    this.caClient = caClient;
  }

  private boolean isExpired(long expiryDate) {
    return Time.now() > expiryDate;
  }

  @Override
  public void verify(String user, String tokenStr,
      ContainerProtos.Type cmd, String id) throws SCMSecurityException {
    if (!conf.isBlockTokenEnabled() || !HddsUtils.requireBlockToken(cmd)) {
      return;
    }

    // TODO: add audit logs.
    if (Strings.isNullOrEmpty(tokenStr)) {
      throw new BlockTokenException("Fail to find any token (empty or " +
          "null.)");
    }

    final Token<OzoneBlockTokenIdentifier> token = new Token();
    OzoneBlockTokenIdentifier tokenId = new OzoneBlockTokenIdentifier();
    try {
      token.decodeFromUrlString(tokenStr);
      ByteArrayInputStream buf = new ByteArrayInputStream(
          token.getIdentifier());
      DataInputStream in = new DataInputStream(buf);
      tokenId.readFields(in);
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Verifying token:{} for user:{} ", tokenId, user);
      }
    } catch (IOException ex) {
      throw new BlockTokenException("Failed to decode token : " + tokenStr);
    }

    if (caClient == null) {
      throw new SCMSecurityException("Certificate client not available " +
          "to validate token");
    }

    UserGroupInformation tokenUser = tokenId.getUser();
    X509Certificate signerCert;
    signerCert = caClient.getCertificate(tokenId.getOmCertSerialId());

    if (signerCert == null) {
      throw new BlockTokenException("Can't find signer certificate " +
          "(OmCertSerialId: " + tokenId.getOmCertSerialId() +
          ") of the block token for user: " + tokenUser);
    }
    boolean validToken = caClient.verifySignature(tokenId.getBytes(),
        token.getPassword(), signerCert);
    if (!validToken) {
      throw new BlockTokenException("Invalid block token for user: " +
          tokenId.getUser());
    }
    // check expiration
    if (isExpired(tokenId.getExpiryDate())) {
      throw new BlockTokenException("Expired block token for user: " +
          tokenUser);
    }

    // Token block id mismatch
    if (!tokenId.getBlockId().equals(id)) {
      throw new BlockTokenException("Block id mismatch. Token for block ID: " +
          tokenId.getBlockId() + " can't be used to access block: " + id +
          " by user: " + tokenUser);
    }

    if (cmd == ReadChunk || cmd == GetBlock || cmd == GetSmallFile) {
      if (!tokenId.getAccessModes().contains(
          HddsProtos.BlockTokenSecretProto.AccessModeProto.READ)) {
        throw new BlockTokenException("Block token with " + id
            + " doesn't have READ permission");
      }
    } else if (cmd == WriteChunk || cmd == PutBlock || cmd == PutSmallFile) {
      if (!tokenId.getAccessModes().contains(
          HddsProtos.BlockTokenSecretProto.AccessModeProto.WRITE)) {
        throw new BlockTokenException("Block token with " + id
            + " doesn't have WRITE permission");
      }
    } else {
      throw new BlockTokenException("Block token does not support " + cmd);
    }
  }

  public static boolean isTestStub() {
    return testStub;
  }

  // For testing purpose only.
  public static void setTestStub(boolean isTestStub) {
    BlockTokenVerifier.testStub = isTestStub;
  }
}
