diff options
6 files changed, 224 insertions, 67 deletions
diff --git a/utils/src/main/java/org/onap/policy/common/utils/resources/DirectoryUtils.java b/utils/src/main/java/org/onap/policy/common/utils/resources/DirectoryUtils.java new file mode 100644 index 00000000..35a13138 --- /dev/null +++ b/utils/src/main/java/org/onap/policy/common/utils/resources/DirectoryUtils.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.resources; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utilities for manipulating directories. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class DirectoryUtils { + private static final Logger logger = LoggerFactory.getLogger(DirectoryUtils.class); + + /** + * Creates a directory file, only accessible by the owner. + * + * @param prefix file name prefix + * @return a new, temporary directory + * @throws IOException if an error occurs + */ + public static Path createTempDirectory(String prefix) throws IOException { + /* + * Disabling sonar, as the code below sets the permissions, just as sonar + * suggests it be fixed. + */ + var path = Files.createTempDirectory(prefix); // NOSONAR + logger.info("created temporary directory, {}", path); + + var file = path.toFile(); + + TextFileUtils.setDefaultPermissions(file); + + // ensure nothing has been written to it yet + FileUtils.cleanDirectory(file); + + return path; + } +} diff --git a/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java b/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java index 83d41fb3..001c9f06 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java +++ b/utils/src/main/java/org/onap/policy/common/utils/resources/ResourceUtils.java @@ -23,11 +23,11 @@ package org.onap.policy.common.utils.resources; import com.google.re2j.Pattern; -import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.Enumeration; import java.util.Set; @@ -36,6 +36,7 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,9 +51,6 @@ public final class ResourceUtils { private static final Pattern SLASH_PAT = Pattern.compile("/"); - // The length of byte buffers used to read resources into strings - private static final int BYTE_BUFFER_LENGH = 1024; - // Resource types private static final String FILE_PROTOCOL = "file"; private static final String JAR_PROTOCOL = "jar"; @@ -90,20 +88,13 @@ public final class ResourceUtils { return null; } - // Read the stream contents in to an output stream - final var resourceOutputStreamBuffer = new ByteArrayOutputStream(); - final var resourceBuffer = new byte[BYTE_BUFFER_LENGH]; - int length; - try { - while ((length = resourceStream.read(resourceBuffer)) != -1) { - resourceOutputStreamBuffer.write(resourceBuffer, 0, length); - } + // Read the stream contents, closing when done + try (var streamCloser = resourceStream) { + return IOUtils.toString(resourceStream, StandardCharsets.UTF_8); } catch (final IOException e) { LOGGER.debug("error reading resource stream {}", resourceName, e); return null; } - - return resourceOutputStreamBuffer.toString(); } /** diff --git a/utils/src/main/java/org/onap/policy/common/utils/resources/TextFileUtils.java b/utils/src/main/java/org/onap/policy/common/utils/resources/TextFileUtils.java index 9df98801..7701eae9 100644 --- a/utils/src/main/java/org/onap/policy/common/utils/resources/TextFileUtils.java +++ b/utils/src/main/java/org/onap/policy/common/utils/resources/TextFileUtils.java @@ -31,6 +31,8 @@ import java.nio.file.Files; import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.apache.commons.io.IOUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The Class TextFileUtils is class that provides useful functions for handling text files. Functions to read and write @@ -40,6 +42,7 @@ import org.apache.commons.io.IOUtils; */ @NoArgsConstructor(access = AccessLevel.PRIVATE) public final class TextFileUtils { + private static final Logger logger = LoggerFactory.getLogger(TextFileUtils.class); /** * Method to return the contents of a text file as a string. @@ -101,4 +104,35 @@ public final class TextFileUtils { public static String getReaderAsString(final Reader textReader) throws IOException { return IOUtils.toString(textReader); } + + /** + * Creates a temporary file, only accessible by the owner. + * + * @param prefix file name prefix + * @param suffix file name suffix + * @return a new, temporary file + * @throws IOException if an error occurs + */ + public static File createTempFile(String prefix, String suffix) throws IOException { + /* + * Disabling sonar, because setDefaultPermissions() will set the permissions of + * the file. + */ + var file = File.createTempFile(prefix, suffix); // NOSONAR + + setDefaultPermissions(file); + + return file; + } + + /** + * Sets permissions on a file or directory so that only the owner can access it. + * + * @param file file or directory on which permissions are to be set + */ + public static void setDefaultPermissions(File file) { + if (!file.setReadable(true, true) || !file.setWritable(true, true) || !file.setExecutable(true, true)) { + logger.warn("cannot set permissions for {}", file); + } + } } diff --git a/utils/src/test/java/org/onap/policy/common/utils/resources/DirectoryUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/resources/DirectoryUtilsTest.java new file mode 100644 index 00000000..c12ef9f8 --- /dev/null +++ b/utils/src/test/java/org/onap/policy/common/utils/resources/DirectoryUtilsTest.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2021 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.common.utils.resources; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.nio.file.Path; +import org.apache.commons.io.FileUtils; +import org.junit.Test; + +public class DirectoryUtilsTest { + + @Test + public void testCreateTempDirectory() throws IOException { + Path path = DirectoryUtils.createTempDirectory("directoryUtilsTest"); + + var file = path.toFile(); + FileUtils.forceDeleteOnExit(file); + + assertThat(file).canRead().canWrite().isDirectory(); + assertThat(file.canExecute()).isTrue(); + } +} diff --git a/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java index 6a2fe1ad..d78d909e 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/resources/ResourceUtilsTest.java @@ -1,7 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2018 Ericsson. All rights reserved. - * Modifications Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved. * Modifications Copyright (C) 2020-2021 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,7 +30,6 @@ import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Set; @@ -183,45 +182,26 @@ public class ResourceUtilsTest { * Test get resource as stream. */ @Test - public void testGetResourceAsStream() { - InputStream theStream = ResourceUtils.getResourceAsStream(tmpDir.getAbsolutePath()); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(tmpEmptyFile.getAbsolutePath()); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(tmpUsedFile.getAbsolutePath()); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(jarDirResource); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(jarFileResource); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(PATH_DIR_RESOURCE); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(PATH_FILE_RESOURCE); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(RESOURCES_PATH + PATH_DIR_RESOURCE); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(RESOURCES_PATH + PATH_FILE_RESOURCE); - assertNotNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(NON_EXISTENT_RESOURCE); - assertNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(INVALID_RESOURCE); - assertNull(theStream); - - theStream = ResourceUtils.getResourceAsStream(null); - assertNull(theStream); + public void testGetResourceAsStream() throws IOException { + verifyStream(tmpDir.getAbsolutePath()); + verifyStream(tmpEmptyFile.getAbsolutePath()); + verifyStream(tmpUsedFile.getAbsolutePath()); + verifyStream(jarDirResource); + verifyStream(jarFileResource); + verifyStream(PATH_DIR_RESOURCE); + verifyStream(PATH_FILE_RESOURCE); + verifyStream(RESOURCES_PATH + PATH_DIR_RESOURCE); + verifyStream(RESOURCES_PATH + PATH_FILE_RESOURCE); + assertNull(ResourceUtils.getResourceAsStream(NON_EXISTENT_RESOURCE)); + assertNull(ResourceUtils.getResourceAsStream(INVALID_RESOURCE)); + assertNull(ResourceUtils.getResourceAsStream(null)); + verifyStream(""); + } - theStream = ResourceUtils.getResourceAsStream(""); - assertNotNull(theStream); + private void verifyStream(String path) throws IOException { + try (var theStream = ResourceUtils.getResourceAsStream(path)) { + assertNotNull(theStream); + } } /** diff --git a/utils/src/test/java/org/onap/policy/common/utils/resources/TextFileUtilsTest.java b/utils/src/test/java/org/onap/policy/common/utils/resources/TextFileUtilsTest.java index 67cdab52..91268979 100644 --- a/utils/src/test/java/org/onap/policy/common/utils/resources/TextFileUtilsTest.java +++ b/utils/src/test/java/org/onap/policy/common/utils/resources/TextFileUtilsTest.java @@ -1,7 +1,7 @@ /*- * ============LICENSE_START======================================================= * Copyright (C) 2019 Nordix Foundation. - * Modifications Copyright (C) 2020 AT&T Intellectual Property. All rights reserved. + * Modifications Copyright (C) 2020-2021 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,11 +21,13 @@ package org.onap.policy.common.utils.resources; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import org.apache.commons.io.FileUtils; import org.junit.Test; /** @@ -39,35 +41,80 @@ public class TextFileUtilsTest { @Test public void testPutToFile() throws IOException { - final File tempTextFile = File.createTempFile("Test", "txt"); + final File tempTextFile = File.createTempFile("Test", ".txt"); + tempTextFile.deleteOnExit(); TextFileUtils.putStringAsTextFile(FILE_CONTENT, tempTextFile.getAbsolutePath()); final String textFileString0 = TextFileUtils.getTextFileAsString(tempTextFile.getAbsolutePath()); assertEquals(FILE_CONTENT, textFileString0); - final FileInputStream fis = new FileInputStream(tempTextFile); - final String textFileString1 = TextFileUtils.getStreamAsString(fis); - assertEquals(textFileString0, textFileString1); + try (final FileInputStream fis = new FileInputStream(tempTextFile)) { + final String textFileString1 = TextFileUtils.getStreamAsString(fis); + assertEquals(textFileString0, textFileString1); + } } @Test public void testPutToFileWithNewPath() throws IOException { String tempDirAndFileName = System.getProperty("java.io.tmpdir") + "/non/existant/path/Test.txt"; + FileUtils.forceDeleteOnExit(new File(tempDirAndFileName)); TextFileUtils.putStringAsTextFile(FILE_CONTENT, tempDirAndFileName); final String textFileString0 = TextFileUtils.getTextFileAsString(tempDirAndFileName); assertEquals(FILE_CONTENT, textFileString0); - final FileInputStream fis = new FileInputStream(tempDirAndFileName); - final String textFileString1 = TextFileUtils.getStreamAsString(fis); - assertEquals(textFileString0, textFileString1); + try (final FileInputStream fis = new FileInputStream(tempDirAndFileName)) { + final String textFileString1 = TextFileUtils.getStreamAsString(fis); + assertEquals(textFileString0, textFileString1); + } + } + + @Test + public void testCreateTempFile() throws IOException { + var file = TextFileUtils.createTempFile("textFileUtilsTest", ".txt"); + file.deleteOnExit(); + + verifyDefaultPermissions(file); + } + + @Test + public void testSetDefaultPermissions() throws IOException { + var file = new File("target/tempfile.txt"); + file.deleteOnExit(); + + // ensure it doesn't exist before we create it + file.delete(); + assertThat(file.createNewFile()).isTrue(); + + // check using whatever permissions it comes with + + TextFileUtils.setDefaultPermissions(file); + + verifyDefaultPermissions(file); + + // prevent read-write-execute by anyone + file.setReadable(false); + file.setWritable(false); + file.setExecutable(false); + + TextFileUtils.setDefaultPermissions(file); + + verifyDefaultPermissions(file); + + // make it read-write-execute by everyone + file.setReadable(true); + file.setWritable(true); + file.setExecutable(true); + + TextFileUtils.setDefaultPermissions(file); + + verifyDefaultPermissions(file); + } - File tempDirAndFile = new File(tempDirAndFileName); - tempDirAndFile.delete(); - tempDirAndFile.getParentFile().delete(); - tempDirAndFile.getParentFile().getParentFile().delete(); - tempDirAndFile.getParentFile().getParentFile().getParentFile().delete(); + private void verifyDefaultPermissions(File file) { + assertThat(file).canRead().canWrite(); + assertThat(file.canExecute()).isTrue(); } } |