/* * Copyright (c) 2018, SAP SE. All rights reserved. * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact SAP SE, Dietmar-Hopp-Allee 16, 69190 Walldorf, Germany * or visit www.sap.com if you need additional information or have any * questions. */ /** * @test * @modules jdk.zipfs * @run testng TestPosixPerms * @summary Test zip file operations handling posix permissions. */ import static java.nio.file.attribute.PosixFilePermission.*; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; import java.io.IOException; import java.nio.file.DirectoryStream; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFilePermission; import java.nio.file.attribute.PosixFilePermissions; import java.nio.file.spi.FileSystemProvider; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.testng.annotations.Test; public class TestPosixPerms { private static final int NUMBER_OF_ENTRIES_IN_POSIXTEST_ZIP = 10; private int entries; private static FileSystemProvider getZipFSProvider() { for (FileSystemProvider provider : FileSystemProvider.installedProviders()) { if ("jar".equals(provider.getScheme())) return provider; } return null; } private void checkPermissionsOfEntry(Path file, boolean directory, Set expected) { System.out.println("Checking " + file + "..."); assertEquals(Files.isDirectory(file), directory, "Unexpected directory attribute."); try { System.out.println(Files.readAttributes(file, PosixFileAttributes.class).toString()); } catch (IOException e) { fail("Failed to list file attributes (posix) for entry.", e); } try { Set permissions = Files.getPosixFilePermissions(file); assertNotEquals(permissions, null, "No posix permissions associated with entry."); assertNotEquals(expected, null, "Got a set of " + permissions.size() + " permissions but expected null/UnsupportedOperationException."); assertEquals(permissions.size(), expected.size(), "Unexpected number of permissions."); for (PosixFilePermission p : expected) { assertTrue(permissions.contains(p), "Posix permission " + p + " missing."); } } catch (UnsupportedOperationException e) { if (expected != null) { fail("Unexpected: No posix permissions associated with entry."); } } catch (IOException e) { fail("Caught unexpected exception obtaining posix file permissions.", e); } } private void putFile(FileSystem fs, String name, Set perms) throws IOException { if (perms == null) { Files.createFile(fs.getPath(name)); } else { Files.createFile(fs.getPath(name), PosixFilePermissions.asFileAttribute(perms)); } entries++; } private void putDirectory(FileSystem fs, String name, Set perms) throws IOException { if (perms == null) { Files.createDirectory(fs.getPath(name)); } else { Files.createDirectory(fs.getPath(name), PosixFilePermissions.asFileAttribute(perms)); } entries++; } @Test public void readCheckedInArchiveWithPosixPerms() throws Exception { FileSystemProvider provider = getZipFSProvider(); assertNotNull(provider, "ZIP filesystem provider is not installed"); try (FileSystem fs = provider.newFileSystem(Paths.get(System.getProperty("test.src", "."), "posixtest.zip"), Collections.emptyMap())) { System.out.println("Testing " + fs + "..."); entries = 0; try (DirectoryStream paths = Files.newDirectoryStream(fs.getPath("/"))) { paths.forEach((file)->{ entries++; String name = file.getFileName().toString(); if (name.startsWith("dir")) { checkPermissionsOfEntry(file, true, Set.of( OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, OTHERS_READ, OTHERS_WRITE, OTHERS_EXECUTE)); } else if (name.equals("uread")) { checkPermissionsOfEntry(file, false, Set.of(OWNER_READ)); } else if (name.equals("uwrite")) { checkPermissionsOfEntry(file, false, Set.of(OWNER_WRITE)); } else if (name.equals("uexec")) { checkPermissionsOfEntry(file, false, Set.of(OWNER_EXECUTE)); } else if (name.equals("gread")) { checkPermissionsOfEntry(file, false, Set.of(GROUP_READ)); } else if (name.equals("gwrite")) { checkPermissionsOfEntry(file, false, Set.of(GROUP_WRITE)); } else if (name.equals("gexec")) { checkPermissionsOfEntry(file, false, Set.of(GROUP_EXECUTE)); } else if (name.equals("oread")) { checkPermissionsOfEntry(file, false, Set.of(OTHERS_READ)); } else if (name.equals("owrite")) { checkPermissionsOfEntry(file, false, Set.of(OTHERS_WRITE)); } else if (name.equals("oexec")) { checkPermissionsOfEntry(file, false, Set.of(OTHERS_EXECUTE)); } else { fail("Found unknown entry " + name + "."); } }); } System.out.println("Number of entries: " + entries + "."); assertEquals(entries, NUMBER_OF_ENTRIES_IN_POSIXTEST_ZIP, "File contained wrong number of entries."); } } @Test public void testWriteAndReadArchiveWithPosixPerms() throws Exception { FileSystemProvider provider = getZipFSProvider(); assertNotNull(provider, "ZIP filesystem provider is not installed"); Path zpath = Paths.get(System.getProperty("test.dir", "."), "testPosixPerms.zip"); System.out.println("Create " + zpath + "..."); if (Files.exists(zpath)) { Files.delete(zpath); } Map env = new HashMap<>(); env.put("create", "true"); try (FileSystem fs = provider.newFileSystem(zpath, env)) { entries = 0; putDirectory(fs, "dir", Set.of( OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, OTHERS_READ, OTHERS_WRITE, OTHERS_EXECUTE)); putFile(fs, "uread", Set.of(OWNER_READ)); putFile(fs, "uwrite", Set.of(OWNER_WRITE)); putFile(fs, "uexec", Set.of(OWNER_EXECUTE)); putFile(fs, "gread", Set.of(GROUP_READ)); putFile(fs, "gwrite", Set.of(GROUP_WRITE)); putFile(fs, "gexec", Set.of(GROUP_EXECUTE)); putFile(fs, "oread", Set.of(OTHERS_READ)); putFile(fs, "owrite", Set.of(OTHERS_WRITE)); putFile(fs, "oexec", Set.of(OTHERS_EXECUTE)); putFile(fs, "emptyperms", Collections.emptySet()); putFile(fs, "noperms", null); putFile(fs, "permsaddedlater", null); Files.setPosixFilePermissions(fs.getPath("permsaddedlater"), Set.of(OWNER_READ)); } int entriesCreated = entries; System.out.println("Test reading " + zpath + "..."); env.clear(); try (FileSystem fs = provider.newFileSystem(zpath, env)) { entries = 0; try (DirectoryStream paths = Files.newDirectoryStream(fs.getPath("/"))) { paths.forEach((file)->{ entries++; String name = file.getFileName().toString(); if (name.startsWith("dir")) { checkPermissionsOfEntry(file, true, Set.of( OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, OTHERS_READ, OTHERS_WRITE, OTHERS_EXECUTE)); } else if (name.equals("uread")) { checkPermissionsOfEntry(file, false, Set.of(OWNER_READ)); } else if (name.equals("uwrite")) { checkPermissionsOfEntry(file, false, Set.of(OWNER_WRITE)); } else if (name.equals("uexec")) { checkPermissionsOfEntry(file, false, Set.of(OWNER_EXECUTE)); } else if (name.equals("gread")) { checkPermissionsOfEntry(file, false, Set.of(GROUP_READ)); } else if (name.equals("gwrite")) { checkPermissionsOfEntry(file, false, Set.of(GROUP_WRITE)); } else if (name.equals("gexec")) { checkPermissionsOfEntry(file, false, Set.of(GROUP_EXECUTE)); } else if (name.equals("oread")) { checkPermissionsOfEntry(file, false, Set.of(OTHERS_READ)); } else if (name.equals("owrite")) { checkPermissionsOfEntry(file, false, Set.of(OTHERS_WRITE)); } else if (name.equals("oexec")) { checkPermissionsOfEntry(file, false, Set.of(OTHERS_EXECUTE)); } else if (name.equals("emptyperms")) { checkPermissionsOfEntry(file, false, Collections.emptySet()); } else if (name.equals("noperms")) { checkPermissionsOfEntry(file, false, null); } else if (name.equals("permsaddedlater")) { checkPermissionsOfEntry(file, false, Set.of(OWNER_READ)); } else { fail("Found unknown entry " + name + "."); } }); } } System.out.println("Number of entries: " + entries + "."); assertEquals(entries, entriesCreated, "File contained wrong number of entries."); } }