1 /* 2 * Copyright (c) 2018, SAP SE. All rights reserved. 3 * 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact SAP SE, Dietmar-Hopp-Allee 16, 69190 Walldorf, Germany 23 * or visit www.sap.com if you need additional information or have any 24 * questions. 25 */ 26 27 /** 28 * @test 29 * @modules jdk.zipfs 30 * @run testng TestPosixPerms 31 * @summary Test zip file operations handling posix permissions. 32 */ 33 34 import static java.nio.file.attribute.PosixFilePermission.*; 35 import static org.testng.Assert.assertEquals; 36 import static org.testng.Assert.assertNotEquals; 37 import static org.testng.Assert.assertNotNull; 38 import static org.testng.Assert.assertTrue; 39 import static org.testng.Assert.fail; 40 41 import java.io.IOException; 42 import java.nio.file.DirectoryStream; 43 import java.nio.file.FileSystem; 44 import java.nio.file.Files; 45 import java.nio.file.Path; 46 import java.nio.file.Paths; 47 import java.nio.file.attribute.PosixFileAttributes; 48 import java.nio.file.attribute.PosixFilePermission; 49 import java.nio.file.attribute.PosixFilePermissions; 50 import java.nio.file.spi.FileSystemProvider; 51 import java.util.Collections; 52 import java.util.HashMap; 53 import java.util.Map; 54 import java.util.Set; 55 56 import org.testng.annotations.Test; 57 58 public class TestPosixPerms { 59 60 private static final int NUMBER_OF_ENTRIES_IN_POSIXTEST_ZIP = 10; 61 62 private int entries; 63 64 private static FileSystemProvider getZipFSProvider() { 65 for (FileSystemProvider provider : FileSystemProvider.installedProviders()) { 66 if ("jar".equals(provider.getScheme())) 67 return provider; 68 } 69 return null; 70 } 71 72 private void checkPermissionsOfEntry(Path file, boolean directory, Set<PosixFilePermission> expected) { 73 System.out.println("Checking " + file + "..."); 74 assertEquals(Files.isDirectory(file), directory, "Unexpected directory attribute."); 75 try { 76 System.out.println(Files.readAttributes(file, PosixFileAttributes.class).toString()); 77 } catch (IOException e) { 78 fail("Failed to list file attributes (posix) for entry.", e); 79 } 80 try { 81 Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(file); 82 assertNotEquals(permissions, null, "No posix permissions associated with entry."); 83 assertNotEquals(expected, null, "Got a set of " + permissions.size() + 84 " permissions but expected null/UnsupportedOperationException."); 85 assertEquals(permissions.size(), expected.size(), "Unexpected number of permissions."); 86 for (PosixFilePermission p : expected) { 87 assertTrue(permissions.contains(p), "Posix permission " + p + " missing."); 88 } 89 } catch (UnsupportedOperationException e) { 90 if (expected != null) { 91 fail("Unexpected: No posix permissions associated with entry."); 92 } 93 } catch (IOException e) { 94 fail("Caught unexpected exception obtaining posix file permissions.", e); 95 } 96 } 97 98 private void putFile(FileSystem fs, String name, Set<PosixFilePermission> perms) throws IOException { 99 if (perms == null) { 100 Files.createFile(fs.getPath(name)); 101 } else { 102 Files.createFile(fs.getPath(name), PosixFilePermissions.asFileAttribute(perms)); 103 } 104 entries++; 105 } 106 107 private void putDirectory(FileSystem fs, String name, Set<PosixFilePermission> perms) throws IOException { 108 if (perms == null) { 109 Files.createDirectory(fs.getPath(name)); 110 } else { 111 Files.createDirectory(fs.getPath(name), PosixFilePermissions.asFileAttribute(perms)); 112 } 113 entries++; 114 } 115 116 @Test 117 public void readCheckedInArchiveWithPosixPerms() throws Exception { 118 FileSystemProvider provider = getZipFSProvider(); 119 assertNotNull(provider, "ZIP filesystem provider is not installed"); 120 try (FileSystem fs = provider.newFileSystem(Paths.get(System.getProperty("test.src", "."), "posixtest.zip"), 121 Collections.<String, Object>emptyMap())) { 122 System.out.println("Testing " + fs + "..."); 123 entries = 0; 124 try (DirectoryStream<Path> paths = Files.newDirectoryStream(fs.getPath("/"))) { 125 paths.forEach((file)->{ 126 entries++; 127 String name = file.getFileName().toString(); 128 if (name.startsWith("dir")) { 129 checkPermissionsOfEntry(file, true, Set.of( 130 OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, 131 GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, 132 OTHERS_READ, OTHERS_WRITE, OTHERS_EXECUTE)); 133 } else if (name.equals("uread")) { 134 checkPermissionsOfEntry(file, false, Set.of(OWNER_READ)); 135 } else if (name.equals("uwrite")) { 136 checkPermissionsOfEntry(file, false, Set.of(OWNER_WRITE)); 137 } else if (name.equals("uexec")) { 138 checkPermissionsOfEntry(file, false, Set.of(OWNER_EXECUTE)); 139 } else if (name.equals("gread")) { 140 checkPermissionsOfEntry(file, false, Set.of(GROUP_READ)); 141 } else if (name.equals("gwrite")) { 142 checkPermissionsOfEntry(file, false, Set.of(GROUP_WRITE)); 143 } else if (name.equals("gexec")) { 144 checkPermissionsOfEntry(file, false, Set.of(GROUP_EXECUTE)); 145 } else if (name.equals("oread")) { 146 checkPermissionsOfEntry(file, false, Set.of(OTHERS_READ)); 147 } else if (name.equals("owrite")) { 148 checkPermissionsOfEntry(file, false, Set.of(OTHERS_WRITE)); 149 } else if (name.equals("oexec")) { 150 checkPermissionsOfEntry(file, false, Set.of(OTHERS_EXECUTE)); 151 } else { 152 fail("Found unknown entry " + name + "."); 153 } 154 }); 155 } 156 System.out.println("Number of entries: " + entries + "."); 157 assertEquals(entries, NUMBER_OF_ENTRIES_IN_POSIXTEST_ZIP, "File contained wrong number of entries."); 158 } 159 } 160 161 @Test 162 public void testWriteAndReadArchiveWithPosixPerms() throws Exception { 163 FileSystemProvider provider = getZipFSProvider(); 164 assertNotNull(provider, "ZIP filesystem provider is not installed"); 165 Path zpath = Paths.get(System.getProperty("test.dir", "."), "testPosixPerms.zip"); 166 System.out.println("Create " + zpath + "..."); 167 if (Files.exists(zpath)) { 168 Files.delete(zpath); 169 } 170 Map<String, Object> env = new HashMap<>(); 171 env.put("create", "true"); 172 try (FileSystem fs = provider.newFileSystem(zpath, env)) { 173 entries = 0; 174 putDirectory(fs, "dir", Set.of( 175 OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, 176 GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, 177 OTHERS_READ, OTHERS_WRITE, OTHERS_EXECUTE)); 178 putFile(fs, "uread", Set.of(OWNER_READ)); 179 putFile(fs, "uwrite", Set.of(OWNER_WRITE)); 180 putFile(fs, "uexec", Set.of(OWNER_EXECUTE)); 181 putFile(fs, "gread", Set.of(GROUP_READ)); 182 putFile(fs, "gwrite", Set.of(GROUP_WRITE)); 183 putFile(fs, "gexec", Set.of(GROUP_EXECUTE)); 184 putFile(fs, "oread", Set.of(OTHERS_READ)); 185 putFile(fs, "owrite", Set.of(OTHERS_WRITE)); 186 putFile(fs, "oexec", Set.of(OTHERS_EXECUTE)); 187 putFile(fs, "emptyperms", Collections.<PosixFilePermission>emptySet()); 188 putFile(fs, "noperms", null); 189 putFile(fs, "permsaddedlater", null); 190 Files.setPosixFilePermissions(fs.getPath("permsaddedlater"), Set.of(OWNER_READ)); 191 } 192 int entriesCreated = entries; 193 194 System.out.println("Test reading " + zpath + "..."); 195 env.clear(); 196 try (FileSystem fs = provider.newFileSystem(zpath, env)) { 197 entries = 0; 198 try (DirectoryStream<Path> paths = Files.newDirectoryStream(fs.getPath("/"))) { 199 paths.forEach((file)->{ 200 entries++; 201 String name = file.getFileName().toString(); 202 if (name.startsWith("dir")) { 203 checkPermissionsOfEntry(file, true, Set.of( 204 OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, 205 GROUP_READ, GROUP_WRITE, GROUP_EXECUTE, 206 OTHERS_READ, OTHERS_WRITE, OTHERS_EXECUTE)); 207 } else if (name.equals("uread")) { 208 checkPermissionsOfEntry(file, false, Set.of(OWNER_READ)); 209 } else if (name.equals("uwrite")) { 210 checkPermissionsOfEntry(file, false, Set.of(OWNER_WRITE)); 211 } else if (name.equals("uexec")) { 212 checkPermissionsOfEntry(file, false, Set.of(OWNER_EXECUTE)); 213 } else if (name.equals("gread")) { 214 checkPermissionsOfEntry(file, false, Set.of(GROUP_READ)); 215 } else if (name.equals("gwrite")) { 216 checkPermissionsOfEntry(file, false, Set.of(GROUP_WRITE)); 217 } else if (name.equals("gexec")) { 218 checkPermissionsOfEntry(file, false, Set.of(GROUP_EXECUTE)); 219 } else if (name.equals("oread")) { 220 checkPermissionsOfEntry(file, false, Set.of(OTHERS_READ)); 221 } else if (name.equals("owrite")) { 222 checkPermissionsOfEntry(file, false, Set.of(OTHERS_WRITE)); 223 } else if (name.equals("oexec")) { 224 checkPermissionsOfEntry(file, false, Set.of(OTHERS_EXECUTE)); 225 } else if (name.equals("emptyperms")) { 226 checkPermissionsOfEntry(file, false, Collections.<PosixFilePermission>emptySet()); 227 } else if (name.equals("noperms")) { 228 checkPermissionsOfEntry(file, false, null); 229 } else if (name.equals("permsaddedlater")) { 230 checkPermissionsOfEntry(file, false, Set.of(OWNER_READ)); 231 } else { 232 fail("Found unknown entry " + name + "."); 233 } 234 }); 235 } 236 } 237 System.out.println("Number of entries: " + entries + "."); 238 assertEquals(entries, entriesCreated, "File contained wrong number of entries."); 239 } 240 }