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

import java.util.Iterator;
import java.util.Set;
import java.util.List;

import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.apache.hadoop.classification.InterfaceAudience;
import org.apache.hadoop.classification.InterfaceStability;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
import org.apache.hadoop.util.NativeCodeLoader;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.Groups;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.authorize.AccessControlList;

@InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
@InterfaceStability.Evolving
public class TestAccessControlList {

  private static final Log LOG =
    LogFactory.getLog(TestAccessControlList.class);

  /**
   * Test the netgroups (groups in ACL rules that start with @)
   *
   * This is a  manual test because it requires:
   *   - host setup
   *   - native code compiled
   *   - specify the group mapping class
   *
   * Host setup:
   *
   * /etc/nsswitch.conf should have a line like this:
   * netgroup: files
   *
   * /etc/netgroup should be (the whole file):
   * lasVegas (,elvis,)
   * memphis (,elvis,) (,jerryLeeLewis,)
   *
   * To run this test:
   *
   * export JAVA_HOME='path/to/java'
   * ant \
   *   -Dtestcase=TestAccessControlList \
   *   -Dtest.output=yes \
   *   -DTestAccessControlListGroupMapping=$className \
   *   compile-native test
   *
   * where $className is one of the classes that provide group
   * mapping services, i.e. classes that implement
   * GroupMappingServiceProvider interface, at this time:
   *   - org.apache.hadoop.security.JniBasedUnixGroupsNetgroupMapping
   *   - org.apache.hadoop.security.ShellBasedUnixGroupsNetgroupMapping
   *
   */
  @Test
  public void testNetgroups() throws Exception {

    if(!NativeCodeLoader.isNativeCodeLoaded()) {
      LOG.info("Not testing netgroups, " +
        "this test only runs when native code is compiled");
      return;
    }

    String groupMappingClassName =
      System.getProperty("TestAccessControlListGroupMapping");

    if(groupMappingClassName == null) {
      LOG.info("Not testing netgroups, no group mapping class specified, " +
        "use -DTestAccessControlListGroupMapping=$className to specify " +
        "group mapping class (must implement GroupMappingServiceProvider " +
        "interface and support netgroups)");
      return;
    }

    LOG.info("Testing netgroups using: " + groupMappingClassName);

    Configuration conf = new Configuration();
    conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_GROUP_MAPPING,
      groupMappingClassName);

    Groups groups = Groups.getUserToGroupsMappingService(conf);

    AccessControlList acl;

    // create these ACLs to populate groups cache
    acl = new AccessControlList("ja my"); // plain
    acl = new AccessControlList("sinatra ratpack,@lasVegas"); // netgroup
    acl = new AccessControlList(" somegroup,@someNetgroup"); // no user

    // this ACL will be used for testing ACLs
    acl = new AccessControlList("carlPerkins ratpack,@lasVegas");
    acl.addGroup("@memphis");

    // validate the netgroups before and after rehresh to make
    // sure refresh works correctly
    validateNetgroups(groups, acl);
    groups.refresh();
    validateNetgroups(groups, acl);

  }

  /**
   * Validate the netgroups, both group membership and ACL
   * functionality
   *
   * Note: assumes a specific acl setup done by testNetgroups
   *
   * @param groups group to user mapping service
   * @param acl ACL set up in a specific way, see testNetgroups
   */
  private void validateNetgroups(Groups groups,
    AccessControlList acl) throws Exception {

    // check that the netgroups are working
    List<String> elvisGroups = groups.getGroups("elvis");
    assertTrue(elvisGroups.contains("@lasVegas"));
    assertTrue(elvisGroups.contains("@memphis"));
    List<String> jerryLeeLewisGroups = groups.getGroups("jerryLeeLewis");
    assertTrue(jerryLeeLewisGroups.contains("@memphis"));

    // allowed becuase his netgroup is in ACL
    UserGroupInformation elvis = 
      UserGroupInformation.createRemoteUser("elvis");
    assertUserAllowed(elvis, acl);

    // allowed because he's in ACL
    UserGroupInformation carlPerkins = 
      UserGroupInformation.createRemoteUser("carlPerkins");
    assertUserAllowed(carlPerkins, acl);

    // not allowed because he's not in ACL and has no netgroups
    UserGroupInformation littleRichard = 
      UserGroupInformation.createRemoteUser("littleRichard");
    assertUserNotAllowed(littleRichard, acl);
  }

  @Test
  public void testWildCardAccessControlList() throws Exception {
    AccessControlList acl;
    
    acl = new AccessControlList("*");
    assertTrue(acl.isAllAllowed());
    
    acl = new AccessControlList("  * ");
    assertTrue(acl.isAllAllowed());
    
    acl = new AccessControlList(" *");
    assertTrue(acl.isAllAllowed());
    
    acl = new AccessControlList("*  ");
    assertTrue(acl.isAllAllowed());
  }

  // Check if AccessControlList.toString() works as expected.
  // Also validate if getAclString() for various cases.
  @Test
  public void testAclString() {
    AccessControlList acl;

    acl = new AccessControlList("*");
    assertTrue(acl.toString().equals("All users are allowed"));
    validateGetAclString(acl);

    acl = new AccessControlList(" ");
    assertTrue(acl.toString().equals("No users are allowed"));

    acl = new AccessControlList("user1,user2");
    assertTrue(acl.toString().equals("Users [user1, user2] are allowed"));
    validateGetAclString(acl);

    acl = new AccessControlList("user1,user2 ");// with space
    assertTrue(acl.toString().equals("Users [user1, user2] are allowed"));
    validateGetAclString(acl);

    acl = new AccessControlList(" group1,group2");
    assertTrue(acl.toString().equals(
        "Members of the groups [group1, group2] are allowed"));
    validateGetAclString(acl);

    acl = new AccessControlList("user1,user2 group1,group2");
    assertTrue(acl.toString().equals(
        "Users [user1, user2] and " +
        "members of the groups [group1, group2] are allowed"));
    validateGetAclString(acl);
  }

  // Validates if getAclString() is working as expected. i.e. if we can build
  // a new ACL instance from the value returned by getAclString().
  private void validateGetAclString(AccessControlList acl) {
    assertTrue(acl.toString().equals(
        new AccessControlList(acl.getAclString()).toString()));
  }

  @Test
  public void testAccessControlList() throws Exception {
    AccessControlList acl;
    Set<String> users;
    Set<String> groups;
    
    acl = new AccessControlList("drwho tardis");
    users = acl.getUsers();
    assertEquals(users.size(), 1);
    assertEquals(users.iterator().next(), "drwho");
    groups = acl.getGroups();
    assertEquals(groups.size(), 1);
    assertEquals(groups.iterator().next(), "tardis");
    
    acl = new AccessControlList("drwho");
    users = acl.getUsers();
    assertEquals(users.size(), 1);
    assertEquals(users.iterator().next(), "drwho");
    groups = acl.getGroups();
    assertEquals(groups.size(), 0);
    
    acl = new AccessControlList("drwho ");
    users = acl.getUsers();
    assertEquals(users.size(), 1);
    assertEquals(users.iterator().next(), "drwho");
    groups = acl.getGroups();
    assertEquals(groups.size(), 0);
    
    acl = new AccessControlList(" tardis");
    users = acl.getUsers();
    assertEquals(users.size(), 0);
    groups = acl.getGroups();
    assertEquals(groups.size(), 1);
    assertEquals(groups.iterator().next(), "tardis");

    Iterator<String> iter;    
    acl = new AccessControlList("drwho,joe tardis, users");
    users = acl.getUsers();
    assertEquals(users.size(), 2);
    iter = users.iterator();
    assertEquals(iter.next(), "drwho");
    assertEquals(iter.next(), "joe");
    groups = acl.getGroups();
    assertEquals(groups.size(), 2);
    iter = groups.iterator();
    assertEquals(iter.next(), "tardis");
    assertEquals(iter.next(), "users");
  }

  /**
   * Test addUser/Group and removeUser/Group api.
   */
  @Test
  public void testAddRemoveAPI() {
    AccessControlList acl;
    Set<String> users;
    Set<String> groups;
    acl = new AccessControlList(" ");
    assertEquals(0, acl.getUsers().size());
    assertEquals(0, acl.getGroups().size());
    assertEquals(" ", acl.getAclString());
    
    acl.addUser("drwho");
    users = acl.getUsers();
    assertEquals(users.size(), 1);
    assertEquals(users.iterator().next(), "drwho");
    assertEquals("drwho ", acl.getAclString());
    
    acl.addGroup("tardis");
    groups = acl.getGroups();
    assertEquals(groups.size(), 1);
    assertEquals(groups.iterator().next(), "tardis");
    assertEquals("drwho tardis", acl.getAclString());
    
    acl.addUser("joe");
    acl.addGroup("users");
    users = acl.getUsers();
    assertEquals(users.size(), 2);
    Iterator<String> iter = users.iterator();
    assertEquals(iter.next(), "drwho");
    assertEquals(iter.next(), "joe");
    groups = acl.getGroups();
    assertEquals(groups.size(), 2);
    iter = groups.iterator();
    assertEquals(iter.next(), "tardis");
    assertEquals(iter.next(), "users");
    assertEquals("drwho,joe tardis,users", acl.getAclString());

    acl.removeUser("joe");
    acl.removeGroup("users");
    users = acl.getUsers();
    assertEquals(users.size(), 1);
    assertFalse(users.contains("joe"));
    groups = acl.getGroups();
    assertEquals(groups.size(), 1);
    assertFalse(groups.contains("users"));
    assertEquals("drwho tardis", acl.getAclString());
    
    acl.removeGroup("tardis");
    groups = acl.getGroups();
    assertEquals(0, groups.size());
    assertFalse(groups.contains("tardis"));
    assertEquals("drwho ", acl.getAclString());
    
    acl.removeUser("drwho");
    assertEquals(0, users.size());
    assertFalse(users.contains("drwho"));
    assertEquals(0, acl.getGroups().size());
    assertEquals(0, acl.getUsers().size());
    assertEquals(" ", acl.getAclString());
  }
  
  /**
   * Tests adding/removing wild card as the user/group.
   */
  @Test
  public void testAddRemoveWildCard() {
    AccessControlList acl = new AccessControlList("drwho tardis");
    
    Throwable th = null;
    try {
      acl.addUser(" * ");
    } catch (Throwable t) {
      th = t;
    }
    assertNotNull(th);
    assertTrue(th instanceof IllegalArgumentException);
    
    th = null;
    try {
      acl.addGroup(" * ");
    } catch (Throwable t) {
      th = t;
    }
    assertNotNull(th);
    assertTrue(th instanceof IllegalArgumentException);
    th = null;
    try {
    acl.removeUser(" * ");
    } catch (Throwable t) {
      th = t;
    }
    assertNotNull(th);
    assertTrue(th instanceof IllegalArgumentException);
    th = null;
    try {
    acl.removeGroup(" * ");
    } catch (Throwable t) {
      th = t;
    }
    assertNotNull(th);
    assertTrue(th instanceof IllegalArgumentException);
  }
  
  /**
   * Tests adding user/group to an wild card acl.
   */
  @Test
  public void testAddRemoveToWildCardACL() {
    AccessControlList acl = new AccessControlList(" * ");
    assertTrue(acl.isAllAllowed());

    UserGroupInformation drwho =
      UserGroupInformation.createUserForTesting("drwho@APACHE.ORG",
          new String[] { "aliens" });
    UserGroupInformation drwho2 =
      UserGroupInformation.createUserForTesting("drwho2@APACHE.ORG",
          new String[] { "tardis" });

    acl.addUser("drwho");
    assertTrue(acl.isAllAllowed());
    assertFalse(acl.getAclString().contains("drwho"));
    acl.addGroup("tardis");
    assertTrue(acl.isAllAllowed());
    assertFalse(acl.getAclString().contains("tardis"));
   
    acl.removeUser("drwho");
    assertTrue(acl.isAllAllowed());
    assertUserAllowed(drwho, acl);
    acl.removeGroup("tardis");
    assertTrue(acl.isAllAllowed());
    assertUserAllowed(drwho2, acl);
  }

  /**
   * Verify the method isUserAllowed()
   */
  @Test
  public void testIsUserAllowed() {
    AccessControlList acl;

    UserGroupInformation drwho =
        UserGroupInformation.createUserForTesting("drwho@APACHE.ORG",
            new String[] { "aliens", "humanoids", "timelord" });
    UserGroupInformation susan =
        UserGroupInformation.createUserForTesting("susan@APACHE.ORG",
            new String[] { "aliens", "humanoids", "timelord" });
    UserGroupInformation barbara =
        UserGroupInformation.createUserForTesting("barbara@APACHE.ORG",
            new String[] { "humans", "teachers" });
    UserGroupInformation ian =
        UserGroupInformation.createUserForTesting("ian@APACHE.ORG",
            new String[] { "humans", "teachers" });

    acl = new AccessControlList("drwho humanoids");
    assertUserAllowed(drwho, acl);
    assertUserAllowed(susan, acl);
    assertUserNotAllowed(barbara, acl);
    assertUserNotAllowed(ian, acl);

    acl = new AccessControlList("drwho");
    assertUserAllowed(drwho, acl);
    assertUserNotAllowed(susan, acl);
    assertUserNotAllowed(barbara, acl);
    assertUserNotAllowed(ian, acl);

    acl = new AccessControlList("drwho ");
    assertUserAllowed(drwho, acl);
    assertUserNotAllowed(susan, acl);
    assertUserNotAllowed(barbara, acl);
    assertUserNotAllowed(ian, acl);

    acl = new AccessControlList(" humanoids");
    assertUserAllowed(drwho, acl);
    assertUserAllowed(susan, acl);
    assertUserNotAllowed(barbara, acl);
    assertUserNotAllowed(ian, acl);

    acl = new AccessControlList("drwho,ian aliens,teachers");
    assertUserAllowed(drwho, acl);
    assertUserAllowed(susan, acl);
    assertUserAllowed(barbara, acl);
    assertUserAllowed(ian, acl);
  }

  private void assertUserAllowed(UserGroupInformation ugi,
      AccessControlList acl) {
    assertTrue("User " + ugi + " is not granted the access-control!!",
        acl.isUserAllowed(ugi));
  }

  private void assertUserNotAllowed(UserGroupInformation ugi,
      AccessControlList acl) {
    assertFalse("User " + ugi
        + " is incorrectly granted the access-control!!",
        acl.isUserAllowed(ugi));
  }
}
