/**
 * 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.crypto.key;

import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.List;
import java.util.UUID;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.crypto.key.KeyProvider.KeyVersion;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.security.Credentials;
import org.apache.hadoop.security.ProviderUtils;
import org.apache.hadoop.security.UserGroupInformation;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

public class TestKeyProviderFactory {

  private static File tmpDir;

  @Before
  public void setup() {
    tmpDir = new File(System.getProperty("test.build.data", "target"),
        UUID.randomUUID().toString());
    tmpDir.mkdirs();
  }

  @Test
  public void testFactory() throws Exception {
    Configuration conf = new Configuration();
    conf.set(KeyProviderFactory.KEY_PROVIDER_PATH,
        UserProvider.SCHEME_NAME + ":///," +
            JavaKeyStoreProvider.SCHEME_NAME + "://file" + tmpDir + "/test.jks");
    List<KeyProvider> providers = KeyProviderFactory.getProviders(conf);
    assertEquals(2, providers.size());
    assertEquals(UserProvider.class, providers.get(0).getClass());
    assertEquals(JavaKeyStoreProvider.class, providers.get(1).getClass());
    assertEquals(UserProvider.SCHEME_NAME +
        ":///", providers.get(0).toString());
    assertEquals(JavaKeyStoreProvider.SCHEME_NAME +
        "://file" + tmpDir + "/test.jks",
        providers.get(1).toString());
  }

  @Test
  public void testFactoryErrors() throws Exception {
    Configuration conf = new Configuration();
    conf.set(KeyProviderFactory.KEY_PROVIDER_PATH, "unknown:///");
    try {
      List<KeyProvider> providers = KeyProviderFactory.getProviders(conf);
      assertTrue("should throw!", false);
    } catch (IOException e) {
      assertEquals("No KeyProviderFactory for unknown:/// in " +
          KeyProviderFactory.KEY_PROVIDER_PATH,
          e.getMessage());
    }
  }

  @Test
  public void testUriErrors() throws Exception {
    Configuration conf = new Configuration();
    conf.set(KeyProviderFactory.KEY_PROVIDER_PATH, "unkn@own:/x/y");
    try {
      List<KeyProvider> providers = KeyProviderFactory.getProviders(conf);
      assertTrue("should throw!", false);
    } catch (IOException e) {
      assertEquals("Bad configuration of " +
          KeyProviderFactory.KEY_PROVIDER_PATH +
          " at unkn@own:/x/y", e.getMessage());
    }
  }

  static void checkSpecificProvider(Configuration conf,
                                   String ourUrl) throws Exception {
    KeyProvider provider = KeyProviderFactory.getProviders(conf).get(0);
    byte[] key1 = new byte[32];
    byte[] key2 = new byte[32];
    byte[] key3 = new byte[32];
    for(int i =0; i < key1.length; ++i) {
      key1[i] = (byte) i;
      key2[i] = (byte) (i * 2);
      key3[i] = (byte) (i * 3);
    }
    // ensure that we get nulls when the key isn't there
    assertEquals(null, provider.getKeyVersion("no-such-key"));
    assertEquals(null, provider.getMetadata("key"));
    // create a new key
    try {
      provider.createKey("key3", key3, KeyProvider.options(conf));
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
    // check the metadata for key3
    KeyProvider.Metadata meta = provider.getMetadata("key3");
    assertEquals(KeyProvider.DEFAULT_CIPHER, meta.getCipher());
    assertEquals(KeyProvider.DEFAULT_BITLENGTH, meta.getBitLength());
    assertEquals(1, meta.getVersions());
    // make sure we get back the right key
    assertArrayEquals(key3, provider.getCurrentKey("key3").getMaterial());
    assertEquals("key3@0", provider.getCurrentKey("key3").getVersionName());
    // try recreating key3
    try {
      provider.createKey("key3", key3, KeyProvider.options(conf));
      assertTrue("should throw", false);
    } catch (IOException e) {
      assertEquals("Key key3 already exists in " + ourUrl, e.getMessage());
    }
    provider.deleteKey("key3");
    try {
      provider.deleteKey("key3");
      assertTrue("should throw", false);
    } catch (IOException e) {
      assertEquals("Key key3 does not exist in " + ourUrl, e.getMessage());
    }
    provider.createKey("key3", key3, KeyProvider.options(conf));
    try {
      provider.createKey("key4", key3,
          KeyProvider.options(conf).setBitLength(8));
      assertTrue("should throw", false);
    } catch (IOException e) {
      assertEquals("Wrong key length. Required 8, but got 256", e.getMessage());
    }
    provider.createKey("key4", new byte[]{1},
        KeyProvider.options(conf).setBitLength(8));
    provider.rollNewVersion("key4", new byte[]{2});
    meta = provider.getMetadata("key4");
    assertEquals(2, meta.getVersions());
    assertArrayEquals(new byte[]{2},
        provider.getCurrentKey("key4").getMaterial());
    assertArrayEquals(new byte[]{1},
        provider.getKeyVersion("key4@0").getMaterial());
    assertEquals("key4@1", provider.getCurrentKey("key4").getVersionName());
    try {
      provider.rollNewVersion("key4", key1);
      assertTrue("should throw", false);
    } catch (IOException e) {
      assertEquals("Wrong key length. Required 8, but got 256", e.getMessage());
    }
    try {
      provider.rollNewVersion("no-such-key", key1);
      assertTrue("should throw", false);
    } catch (IOException e) {
      assertEquals("Key no-such-key not found", e.getMessage());
    }
    provider.flush();
    // get a new instance of the provider to ensure it was saved correctly
    provider = KeyProviderFactory.getProviders(conf).get(0);
    assertArrayEquals(new byte[]{2},
        provider.getCurrentKey("key4").getMaterial());
    assertArrayEquals(key3, provider.getCurrentKey("key3").getMaterial());
    assertEquals("key3@0", provider.getCurrentKey("key3").getVersionName());

    List<String> keys = provider.getKeys();
    assertTrue("Keys should have been returned.", keys.size() == 2);
    assertTrue("Returned Keys should have included key3.", keys.contains("key3"));
    assertTrue("Returned Keys should have included key4.", keys.contains("key4"));

    List<KeyVersion> kvl = provider.getKeyVersions("key3");
    assertTrue("KeyVersions should have been returned for key3.", kvl.size() == 1);
    assertTrue("KeyVersions should have included key3@0.", kvl.get(0).getVersionName().equals("key3@0"));
    assertArrayEquals(key3, kvl.get(0).getMaterial());
  }

  @Test
  public void testUserProvider() throws Exception {
    Configuration conf = new Configuration();
    final String ourUrl = UserProvider.SCHEME_NAME + ":///";
    conf.set(KeyProviderFactory.KEY_PROVIDER_PATH, ourUrl);
    checkSpecificProvider(conf, ourUrl);
    // see if the credentials are actually in the UGI
    Credentials credentials =
        UserGroupInformation.getCurrentUser().getCredentials();
    assertArrayEquals(new byte[]{1},
        credentials.getSecretKey(new Text("key4@0")));
    assertArrayEquals(new byte[]{2},
        credentials.getSecretKey(new Text("key4@1")));
  }

  @Test
  public void testJksProvider() throws Exception {
    Configuration conf = new Configuration();
    final String ourUrl =
        JavaKeyStoreProvider.SCHEME_NAME + "://file" + tmpDir + "/test.jks";

    File file = new File(tmpDir, "test.jks");
    file.delete();
    conf.set(KeyProviderFactory.KEY_PROVIDER_PATH, ourUrl);
    checkSpecificProvider(conf, ourUrl);
    Path path = ProviderUtils.unnestUri(new URI(ourUrl));
    FileSystem fs = path.getFileSystem(conf);
    FileStatus s = fs.getFileStatus(path);
    assertTrue(s.getPermission().toString().equals("rwx------"));
    assertTrue(file + " should exist", file.isFile());

    // check permission retention after explicit change
    fs.setPermission(path, new FsPermission("777"));
    checkPermissionRetention(conf, ourUrl, path);
  }

  public void checkPermissionRetention(Configuration conf, String ourUrl, Path path) throws Exception {
    KeyProvider provider = KeyProviderFactory.getProviders(conf).get(0);
    // let's add a new key and flush and check that permissions are still set to 777
    byte[] key = new byte[32];
    for(int i =0; i < key.length; ++i) {
      key[i] = (byte) i;
    }
    // create a new key
    try {
      provider.createKey("key5", key, KeyProvider.options(conf));
    } catch (Exception e) {
      e.printStackTrace();
      throw e;
    }
    provider.flush();
    // get a new instance of the provider to ensure it was saved correctly
    provider = KeyProviderFactory.getProviders(conf).get(0);
    assertArrayEquals(key, provider.getCurrentKey("key5").getMaterial());

    FileSystem fs = path.getFileSystem(conf);
    FileStatus s = fs.getFileStatus(path);
    assertTrue("Permissions should have been retained from the preexisting keystore.", s.getPermission().toString().equals("rwxrwxrwx"));
  }

  @Test
  public void testJksProviderPasswordViaConfig() throws Exception {
    Configuration conf = new Configuration();
    final String ourUrl =
        JavaKeyStoreProvider.SCHEME_NAME + "://file" + tmpDir + "/test.jks";
    File file = new File(tmpDir, "test.jks");
    file.delete();
    try {
      conf.set(KeyProviderFactory.KEY_PROVIDER_PATH, ourUrl);
      conf.set(JavaKeyStoreProvider.KEYSTORE_PASSWORD_FILE_KEY,
          "javakeystoreprovider.password");
      KeyProvider provider = KeyProviderFactory.getProviders(conf).get(0);
      provider.createKey("key3", new byte[32], KeyProvider.options(conf));
      provider.flush();
    } catch (Exception ex) {
      Assert.fail("could not create keystore with password file");
    }
    KeyProvider provider = KeyProviderFactory.getProviders(conf).get(0);
    Assert.assertNotNull(provider.getCurrentKey("key3"));

    try {
      conf.set(JavaKeyStoreProvider.KEYSTORE_PASSWORD_FILE_KEY, "bar");
      KeyProviderFactory.getProviders(conf).get(0);
      Assert.fail("using non existing password file, it should fail");
    } catch (IOException ex) {
      //NOP
    }
    try {
      conf.set(JavaKeyStoreProvider.KEYSTORE_PASSWORD_FILE_KEY, "core-site.xml");
      KeyProviderFactory.getProviders(conf).get(0);
      Assert.fail("using different password file, it should fail");
    } catch (IOException ex) {
      //NOP
    }
    try {
      conf.unset(JavaKeyStoreProvider.KEYSTORE_PASSWORD_FILE_KEY);
      KeyProviderFactory.getProviders(conf).get(0);
      Assert.fail("No password file property, env not set, it should fail");
    } catch (IOException ex) {
      //NOP
    }
  }

}
