/**
 * 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.tez.common.security;

import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.classification.InterfaceAudience.Private;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.yarn.api.records.ApplicationAccessType;
import org.apache.tez.dag.api.TezConfiguration;

import com.google.common.annotations.VisibleForTesting;

/**
 * Class to manage ACLs for the Tez AM and DAGs and provides functionality to check whether
 * a user is authorized to take certain actions.
 */
@Private
public class ACLManager {

  private static final Log LOG = LogFactory.getLog(ACLManager.class);
  static final String WILDCARD_ACL_VALUE = "*";

  private final String dagUser;
  private final String amUser;
  private final Map<ACLType, Set<String>> users;
  private final Map<ACLType, Set<String>> groups;
  private final boolean aclsEnabled;

  public ACLManager(String amUser) {
    this(amUser, new Configuration(false));
  }

  public ACLManager(String amUser, Configuration conf) {
    this.amUser = amUser;
    this.dagUser = null;
    this.users = new HashMap<ACLType, Set<String>>();
    this.groups = new HashMap<ACLType, Set<String>>();
    aclsEnabled = conf.getBoolean(TezConfiguration.TEZ_AM_ACLS_ENABLED,
        TezConfiguration.TEZ_AM_ACLS_ENABLED_DEFAULT);
    if (!aclsEnabled) {
      return;
    }
    ACLConfigurationParser parser = new ACLConfigurationParser(conf);
    if (parser.getAllowedUsers() != null) {
      this.users.putAll(parser.getAllowedUsers());
    }
    if (parser.getAllowedGroups() != null) {
      this.groups.putAll(parser.getAllowedGroups());
    }
  }

  public ACLManager(ACLManager amACLManager, String dagUser, Configuration dagConf) {
    this.amUser = amACLManager.amUser;
    this.dagUser = dagUser;
    this.users = amACLManager.users;
    this.groups = amACLManager.groups;
    this.aclsEnabled = amACLManager.aclsEnabled;
    if (!aclsEnabled) {
      return;
    }
    ACLConfigurationParser parser = new ACLConfigurationParser(dagConf, true);
    if (parser.getAllowedUsers() != null) {
      this.users.putAll(parser.getAllowedUsers());
    }
    if (parser.getAllowedGroups() != null) {
      this.groups.putAll(parser.getAllowedGroups());
    }
  }

  @VisibleForTesting
  boolean checkAccess(UserGroupInformation ugi, ACLType aclType) {

    if (!aclsEnabled) {
      return true;
    }

    String user = ugi.getShortUserName();
    Collection<String> userGroups = Arrays.asList(ugi.getGroupNames());

    if (amUser.equals(user)) {
      return true;
    }

    if (EnumSet.of(ACLType.DAG_MODIFY_ACL, ACLType.DAG_VIEW_ACL).contains(aclType)) {
      if (dagUser != null && dagUser.equals(user)) {
        return true;
      }
    }
    if (users != null && !users.isEmpty()) {
      Set<String> set = users.get(aclType);
      if (set != null) {
        if (set.contains(WILDCARD_ACL_VALUE)) {
          return true;
        }
        if (set.contains(user)) {
          return true;
        }
      }
    }
    if (userGroups != null && !userGroups.isEmpty()
        && groups != null && !groups.isEmpty()) {
      Set<String> set = groups.get(aclType);
      if (set != null) {
        for (String userGrp : userGroups) {
          if (set.contains(userGrp)) {
            return true;
          }
        }
      }
    }
    return false;
  }

  public boolean checkAMViewAccess(UserGroupInformation ugi) {
    return checkAccess(ugi, ACLType.AM_VIEW_ACL);
  }

  public boolean checkAMModifyAccess(UserGroupInformation ugi) {
    return checkAccess(ugi, ACLType.AM_MODIFY_ACL);
  }

  public boolean checkDAGViewAccess(UserGroupInformation ugi) {
    return checkAccess(ugi, ACLType.AM_VIEW_ACL)
        || checkAccess(ugi, ACLType.DAG_VIEW_ACL);
  }

  public boolean checkDAGModifyAccess(UserGroupInformation ugi) {
    return checkAccess(ugi, ACLType.AM_MODIFY_ACL)
        || checkAccess(ugi, ACLType.DAG_MODIFY_ACL);
  }

  public Map<ApplicationAccessType, String> toYARNACls() {
    Map<ApplicationAccessType, String> acls = new HashMap<ApplicationAccessType, String>(2);
    if (!this.aclsEnabled) {
      acls.put(ApplicationAccessType.VIEW_APP, "*");
      acls.put(ApplicationAccessType.MODIFY_APP, "*");
      return acls;
    }
    acls.put(ApplicationAccessType.VIEW_APP, amUser);
    acls.put(ApplicationAccessType.MODIFY_APP, amUser);
    boolean viewAclsWildCard = false;
    boolean modifyAclsWildCard = false;
    if (users != null && !users.isEmpty()) {
      for (Entry<ACLType, Set<String>> entry : users.entrySet()) {
        if (entry.getKey().equals(ACLType.AM_VIEW_ACL)) {
          if (entry.getValue().contains(WILDCARD_ACL_VALUE)) {
            acls.put(ApplicationAccessType.VIEW_APP, "*");
            viewAclsWildCard = true;
            continue;
          } else if (!entry.getValue().isEmpty()) {
            String aclsStr = acls.get(ApplicationAccessType.VIEW_APP);
            String commaSepList = toCommaSeparatedString(entry.getValue());
            if (!commaSepList.isEmpty()) {
              aclsStr += "," + commaSepList;
            }
            acls.put(ApplicationAccessType.VIEW_APP, aclsStr);
          }
        } else if (entry.getKey().equals(ACLType.AM_MODIFY_ACL)) {
          if (entry.getValue().contains(WILDCARD_ACL_VALUE)) {
            acls.put(ApplicationAccessType.MODIFY_APP, "*");
            modifyAclsWildCard = true;
            continue;
          } else if (!entry.getValue().isEmpty()) {
            String aclsStr = acls.get(ApplicationAccessType.MODIFY_APP);
            String commaSepList = toCommaSeparatedString(entry.getValue());
            if (!commaSepList.isEmpty()) {
              aclsStr += "," + commaSepList;
            }
            acls.put(ApplicationAccessType.MODIFY_APP, aclsStr);
          }
        }
      }
    }
    if (groups != null && !groups.isEmpty()) {
      for (Entry<ACLType, Set<String>> entry : groups.entrySet()) {
        if (entry.getKey().equals(ACLType.AM_VIEW_ACL)
          && !viewAclsWildCard && !entry.getValue().isEmpty()) {
          // Append groups only if wild card not set
          String aclsStr = acls.containsKey(ApplicationAccessType.VIEW_APP) ?
              acls.get(ApplicationAccessType.VIEW_APP) : "";
          aclsStr += " " + toCommaSeparatedString(entry.getValue());
          acls.put(ApplicationAccessType.VIEW_APP, aclsStr);
        } else if (entry.getKey().equals(ACLType.AM_MODIFY_ACL)
            && !modifyAclsWildCard && !entry.getValue().isEmpty()) {
          // Append groups only if wild card not set
          String aclsStr = acls.containsKey(ApplicationAccessType.MODIFY_APP) ?
              acls.get(ApplicationAccessType.MODIFY_APP) : "";
          aclsStr += " " + toCommaSeparatedString(entry.getValue());
          acls.put(ApplicationAccessType.MODIFY_APP, aclsStr);
        }
      }
    }
    return acls;
  }

  static String toCommaSeparatedString(Collection<String> collection) {
    StringBuilder sb = new StringBuilder();
    boolean first = true;
    for (String s : collection) {
      if (!first) {
        sb.append(",");
      } else {
        first = false;
      }
      sb.append(s);
    }
    return sb.toString();
  }
}


