/*
 * 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.drill.exec.rpc.user;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.drill.common.util.JacksonUtils;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Sets;
import org.apache.drill.common.exceptions.DrillRuntimeException;
import org.apache.drill.common.exceptions.UserException;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.proto.UserBitShared.UserCredentials;
import org.apache.drill.exec.server.options.OptionMetaData;
import org.apache.drill.exec.server.options.OptionValue;
import org.apache.drill.exec.server.options.OptionSet;
import org.apache.drill.exec.server.options.TypeValidators.StringValidator;
import org.apache.drill.exec.util.ImpersonationUtil;
import org.apache.hadoop.security.UserGroupInformation;

import java.io.IOException;
import java.util.List;
import java.util.Set;

/**
 * Helper class to manage inbound impersonation.
 * <p/>
 * Impersonation policies format:
 * [
 *   {
 *    proxy_principals : { users : ["..."], groups : ["..."] },
 *    target_principals : { users : ["..."], groups : ["..."] }
 *   },
 *   {
 *    proxy_principals : { users : ["..."], groups : ["..."] },
 *    target_principals : { users : ["..."], groups : ["..."] }
 *   },
 *   ...
 * ]
 */
public class InboundImpersonationManager {
  private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(InboundImpersonationManager.class);

  private static final String STAR = "*";
  private static final ObjectMapper impersonationPolicyMapper = JacksonUtils.createObjectMapper();

  private List<ImpersonationPolicy> impersonationPolicies;
  private String policiesString; // used to test if policies changed

  static {
    impersonationPolicyMapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
    impersonationPolicyMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
  }

  private static class ImpersonationPolicy {
    public UserGroupDefinition proxy_principals = new UserGroupDefinition();
    public UserGroupDefinition target_principals = new UserGroupDefinition();
  }

  private static class UserGroupDefinition {
    public Set<String> users = Sets.newHashSet();
    public Set<String> groups = Sets.newHashSet();
  }

  private static List<ImpersonationPolicy> deserializeImpersonationPolicies(final String impersonationPolicies)
      throws IOException {
    return impersonationPolicyMapper.readValue(impersonationPolicies,
        new TypeReference<List<ImpersonationPolicy>>() {});
  }

  /**
   * Validator for impersonation policies.
   */
  public static class InboundImpersonationPolicyValidator extends StringValidator {

    public InboundImpersonationPolicyValidator(String name) {
      super(name, null);
    }

    @Override
    public void validate(final OptionValue v, final OptionMetaData metaData, final OptionSet manager) {
      super.validate(v, metaData, manager);

      final List<ImpersonationPolicy> policies;
      try {
        policies = deserializeImpersonationPolicies(v.string_val);
      } catch (final IOException e) {
        throw UserException.validationError()
            .message("Invalid impersonation policies.\nDetails: %s", e.getMessage())
            .build(logger);
      }

      for (final ImpersonationPolicy policy : policies) {
        if (policy.proxy_principals.users.contains(STAR) ||
            policy.proxy_principals.groups.contains(STAR)) {
          throw UserException.validationError()
              .message("Proxy principals cannot have a wildcard entry.")
              .build(logger);
        }
      }
    }
  }

  /**
   * Checks if the proxy user is authorized to impersonate the target user based on the policies.
   *
   * @param proxyName  proxy user name
   * @param targetName target user name
   * @param policies   impersonation policies
   * @return true iff proxy user is authorized to impersonate the target user
   */
  private static boolean hasImpersonationPrivileges(final String proxyName, final String targetName,
                                                    final List<ImpersonationPolicy> policies) {
    final UserGroupInformation proxyUgi = ImpersonationUtil.createProxyUgi(proxyName);
    final Set<String> proxyGroups = Sets.newHashSet(proxyUgi.getGroupNames());
    final UserGroupInformation targetUgi = ImpersonationUtil.createProxyUgi(targetName);
    final Set<String> targetGroups = Sets.newHashSet(targetUgi.getGroupNames());
    for (final ImpersonationPolicy definition : policies) {
      // check if proxy user qualifies within this policy
      if (definition.proxy_principals.users.contains(proxyName) ||
          !Sets.intersection(definition.proxy_principals.groups, proxyGroups).isEmpty()) {
        // check if target qualifies within this policy
        if (definition.target_principals.users.contains(targetName) ||
            definition.target_principals.users.contains(STAR) ||
            !Sets.intersection(definition.target_principals.groups, targetGroups).isEmpty() ||
            definition.target_principals.groups.contains(STAR)) {
          return true;
        }
      }
    }
    return false;
  }

  @VisibleForTesting
  public static boolean hasImpersonationPrivileges(final String proxyName, final String targetName,
                                                   final String policiesString) throws IOException {
    return hasImpersonationPrivileges(proxyName, targetName,
        deserializeImpersonationPolicies(policiesString));
  }

  /**
   * Check if the current session user, as a proxy user, is authorized to impersonate the given target user
   * based on the system's impersonation policies.
   *
   * @param targetName target user name
   * @param session    user session
   */
  public void replaceUserOnSession(final String targetName, final UserSession session) {
    final String policiesString = session.getOptions().getOption(ExecConstants.IMPERSONATION_POLICY_VALIDATOR);
    if (!policiesString.equals(this.policiesString)) {
      try {
        impersonationPolicies = deserializeImpersonationPolicies(policiesString);
        this.policiesString = policiesString;
      } catch (final IOException e) {
        // This never happens. Impersonation policies must have been validated.
        logger.warn("Impersonation policies must have been validated.");
        throw new DrillRuntimeException("Failure while checking for impersonation policies.", e);
      }
    }

    final String proxyName = session.getCredentials().getUserName();
    if (!hasImpersonationPrivileges(proxyName, targetName, impersonationPolicies)) {
      throw UserException.permissionError()
          .message("Proxy user '%s' is not authorized to impersonate target user '%s'.", proxyName, targetName)
          .build(logger);
    }

    // replace session's user credentials
    final UserCredentials newCredentials = UserCredentials.newBuilder()
        .setUserName(targetName)
        .build();
    session.replaceUserCredentials(this, newCredentials);
  }
}
