From 0c41b32e5c891f829aa6636bcf375c3e424e4c77 Mon Sep 17 00:00:00 2001
From: Nicolas Capponi <nicolas.capponi@forgerock.com>
Date: Wed, 12 Oct 2016 12:35:41 +0000
Subject: [PATCH] OPENDJ-3365 Ensure all scripts are set as executable when extracting OpenDJ archive in EmbeddedDirectoryServer

---
 opendj-server-legacy/src/main/java/org/forgerock/opendj/server/embedded/EmbeddedDirectoryServer.java  |   11 +++++
 opendj-server-legacy/src/test/java/org/forgerock/server/embedded/EmbeddedDirectoryServerTestCase.java |   11 ++++-
 opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java                            |   43 +++++++++++++++++++--
 3 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/opendj-server-legacy/src/main/java/org/forgerock/opendj/server/embedded/EmbeddedDirectoryServer.java b/opendj-server-legacy/src/main/java/org/forgerock/opendj/server/embedded/EmbeddedDirectoryServer.java
index 37ae50f..791236d 100644
--- a/opendj-server-legacy/src/main/java/org/forgerock/opendj/server/embedded/EmbeddedDirectoryServer.java
+++ b/opendj-server-legacy/src/main/java/org/forgerock/opendj/server/embedded/EmbeddedDirectoryServer.java
@@ -25,6 +25,8 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
 
 import org.forgerock.i18n.LocalizableMessage;
 import org.forgerock.opendj.adapter.server3x.Adapters;
@@ -61,6 +63,13 @@
   private static final String QUICKSETUP_ROOT_PROPERTY = "org.opends.quicksetup.Root";
   private static final String QUICKSETUP_INSTANCE_PROPERTY = "org.opends.quicksetup.instance";
 
+  /** List of directories resulting from the OpenDJ archive where all files should be set as executable. */
+  private static final List<String> EXECUTABLE_DJ_DIRECTORIES = Arrays.asList("opendj/bin");
+  /** List of individual files resulting from the OpenDJ archive which should be set as executable. */
+  private static final List<String> EXECUTABLE_DJ_FILES =
+      Arrays.asList("opendj/setup", "opendj/upgrade", "opendj/uninstall", "opendj/setup.bat", "opendj/upgrade.bat",
+          "opendj/uninstall.bat");
+
   /** The parameters for install and instance directories, and configuration file of the server. */
   private final ConfigParameters configParams;
 
@@ -443,7 +452,7 @@
       }
       // the directory where the zip file is extracted should be one level up from the server root.
       File deployDirectory = serverRoot.getParentFile();
-      StaticUtils.extractZipArchive(openDJZipFile, deployDirectory);
+      StaticUtils.extractZipArchive(openDJZipFile, deployDirectory, EXECUTABLE_DJ_DIRECTORIES, EXECUTABLE_DJ_FILES);
     }
     catch (IOException e)
     {
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java b/opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java
index 19549f7..5e1cc16 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/util/StaticUtils.java
@@ -95,6 +95,8 @@
   /** Size of buffer used to copy/move/extract files. */
   public static final int BUFFER_SIZE = 8192;
 
+  private static final String[] EXECUTABLE_FILES_SUFFIXES = { ".sh", ".bat", ".exe" };
+
   /**
    * Number of bytes in a Kibibyte.
    * <p>
@@ -2487,16 +2489,28 @@
   /**
    * Extracts the provided zip archive to the provided target directory.
    * <p>
-   * Archive files ending by "sh" or beginning by "bin" are set as executable files.
+   * A file is set to executable if one or more of the following three conditions apply:
+   * <ul>
+   *   <li>It ends with a suffix identified as executable file suffix (.sh, .bat, .exe)</li>
+   *   <li>It is listed in the provided executableFiles</li>
+   *   <li>It is included in a directory that is listed in the provided executableDirectories</li>
+   * </ul>
    *
    * @param zipFile
    *            The zip file to extract.
    * @param targetDirectory
    *            The target directory for the content of the archive.
+   * @param executableDirectories
+   *            List of extracted directories which should have all their files set as executable.
+   *            Each directory must be provided as a path relative to the target directory (e.g. "opendj/bin")
+   * @param executableFiles
+   *            List of individual files which should be set as executable.
+   *            Each file must be provided as a path relative to the target directory (e.g. "opendj/setup")
    * @throws IOException
    *            If zip archive can't be read or target files can be written.
    */
-  public static void extractZipArchive(File zipFile, File targetDirectory) throws IOException
+  public static void extractZipArchive(File zipFile, File targetDirectory, List<String> executableDirectories,
+      List<String> executableFiles) throws IOException
   {
     try (ZipInputStream zipStream = new ZipInputStream(new FileInputStream(zipFile)))
     {
@@ -2512,12 +2526,33 @@
         }
         extractFileFromZip(zipStream, targetFile);
 
-        if (fileEntry.getName().endsWith("sh") || fileEntry.getName().startsWith("bin"))
+        for (String suffix : EXECUTABLE_FILES_SUFFIXES)
         {
-          targetFile.setExecutable(true);
+          if (fileEntry.getName().toLowerCase().endsWith(suffix))
+          {
+            targetFile.setExecutable(true);
+          }
         }
       }
     }
+    for (String dir: executableDirectories)
+    {
+      File directory = new File(targetDirectory.getPath(), dir);
+      for (File file: directory.listFiles())
+      {
+        if (file.isFile()) {
+          file.setExecutable(true);
+        }
+      }
+    }
+    for (String name : executableFiles)
+    {
+      File file = new File(targetDirectory.getPath(), name);
+      if (file.exists())
+      {
+        file.setExecutable(true);
+      }
+    }
   }
 
   /**
diff --git a/opendj-server-legacy/src/test/java/org/forgerock/server/embedded/EmbeddedDirectoryServerTestCase.java b/opendj-server-legacy/src/test/java/org/forgerock/server/embedded/EmbeddedDirectoryServerTestCase.java
index 106ea65..3bb1809 100644
--- a/opendj-server-legacy/src/test/java/org/forgerock/server/embedded/EmbeddedDirectoryServerTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/forgerock/server/embedded/EmbeddedDirectoryServerTestCase.java
@@ -102,6 +102,7 @@
     assertTrue(server.isRunning());
   }
 
+  @Test
   public void testReadConfigurationOffline() throws Exception
   {
     EmbeddedDirectoryServer server = getServer();
@@ -125,11 +126,13 @@
     }
   }
 
+  @Test
   public void testReadConfigurationOnline() throws Exception
   {
     readConfiguration(getServer());
   }
 
+  @Test
   public void testUpdateConfiguration() throws Exception
   {
     EmbeddedDirectoryServer server = getServer();
@@ -157,6 +160,7 @@
    * This test only ensures that the rebuild index process is correctly launched and does not fail.
    * There is no assertions.
    */
+  @Test
   public void testRebuildIndexOffline() throws Exception
   {
     EmbeddedDirectoryServer server = getServer();
@@ -182,6 +186,7 @@
    * This test only ensures that the upgrade index is correctly launched and does not fail.
    * There is no assertions.
    */
+  @Test
   public void testUpgradeOffline() throws Exception
   {
     EmbeddedDirectoryServer server = getServer();
@@ -200,11 +205,13 @@
    * This test only ensures that the upgrade index is correctly launched and does not fail.
    * There is no assertions.
    */
+  @Test
   public void testUpgradeOnline() throws Exception
   {
     getServer().upgrade(upgradeParams().isIgnoreErrors(false));
   }
 
+  @Test
   public void testImportDataOnline() throws Exception
   {
     EmbeddedDirectoryServer server = getServer();
@@ -231,6 +238,7 @@
     }
   }
 
+  @Test
   public void testSetupFromArchive() throws Exception
   {
     EmbeddedDirectoryServer server = getServer();
@@ -269,5 +277,4 @@
       server.start();
     }
   }
-
-}
+}
\ No newline at end of file

--
Gitblit v1.10.0