jdk/test/java/nio/file/Files/CheckPermissions.java
changeset 8158 77d9c0f1c19f
parent 7668 d4a77089c587
child 9035 1255eb81cc2f
child 9025 a72fc1fc4b71
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Files/CheckPermissions.java	Fri Jan 28 09:28:43 2011 +0000
@@ -0,0 +1,723 @@
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. 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.
+ *
+ * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 6866804 7006126
+ * @summary Unit test for java.nio.file.Files
+ * @library ..
+ * @build CheckPermissions
+ * @run main/othervm CheckPermissions
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import static java.nio.file.Files.*;
+import static java.nio.file.StandardOpenOption.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.security.Permission;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Checks each method that accesses the file system does the right permission
+ * check when there is a security manager set.
+ */
+
+public class CheckPermissions {
+
+    static class Checks {
+        private List<Permission> permissionsChecked = new ArrayList<>();
+        private Set<String>  propertiesChecked = new HashSet<>();
+        private List<String> readsChecked   = new ArrayList<>();
+        private List<String> writesChecked  = new ArrayList<>();
+        private List<String> deletesChecked = new ArrayList<>();
+        private List<String> execsChecked   = new ArrayList<>();
+
+        List<Permission> permissionsChecked()  { return permissionsChecked; }
+        Set<String> propertiesChecked()        { return propertiesChecked; }
+        List<String> readsChecked()            { return readsChecked; }
+        List<String> writesChecked()           { return writesChecked; }
+        List<String> deletesChecked()          { return deletesChecked; }
+        List<String> execsChecked()            { return execsChecked; }
+    }
+
+    static ThreadLocal<Checks> myChecks =
+        new ThreadLocal<Checks>() {
+            @Override protected Checks initialValue() {
+                return null;
+            }
+        };
+
+    static void prepare() {
+        myChecks.set(new Checks());
+    }
+
+    static void assertCheckPermission(Class<? extends Permission> type,
+                                      String name)
+    {
+        for (Permission perm: myChecks.get().permissionsChecked()) {
+            if (type.isInstance(perm) && perm.getName().equals(name))
+                return;
+        }
+        throw new RuntimeException(type.getName() + "(\"" + name + "\") not checked");
+    }
+
+    static void assertCheckPropertyAccess(String key) {
+        if (!myChecks.get().propertiesChecked().contains(key))
+            throw new RuntimeException("Property " + key + " not checked");
+    }
+
+    static void assertChecked(Path file, List<String> list) {
+        String s = file.toString();
+        for (String f: list) {
+            if (f.endsWith(s))
+                return;
+        }
+        throw new RuntimeException("Access not checked");
+    }
+
+    static void assertCheckRead(Path file) {
+        assertChecked(file, myChecks.get().readsChecked());
+    }
+
+    static void assertCheckWrite(Path file) {
+        assertChecked(file, myChecks.get().writesChecked());
+    }
+
+    static void assertCheckWriteToDirectory(Path dir) {
+        String s = dir.toString();
+        List<String> list = myChecks.get().writesChecked();
+        for (String f: list) {
+            if (f.startsWith(s)) {
+                return;
+            }
+        }
+        throw new RuntimeException("Access not checked");
+    }
+
+    static void assertCheckDelete(Path file) {
+        assertChecked(file, myChecks.get().deletesChecked());
+    }
+
+    static void assertCheckExec(Path file) {
+        assertChecked(file, myChecks.get().execsChecked());
+    }
+
+    static class LoggingSecurityManager extends SecurityManager {
+        static void install() {
+            System.setSecurityManager(new LoggingSecurityManager());
+        }
+
+        @Override
+        public void checkPermission(Permission perm) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.permissionsChecked().add(perm);
+        }
+
+        @Override
+        public void checkPropertyAccess(String key) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.propertiesChecked().add(key);
+        }
+
+        @Override
+        public void checkRead(String file) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.readsChecked().add(file);
+        }
+
+        @Override
+        public void checkWrite(String file) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.writesChecked().add(file);
+        }
+
+        @Override
+        public void checkDelete(String file) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.deletesChecked().add(file);
+        }
+
+        @Override
+        public void checkExec(String file) {
+            Checks checks = myChecks.get();
+            if (checks != null)
+                checks.execsChecked().add(file);
+        }
+    }
+
+    static void testBasicFileAttributeView(BasicFileAttributeView view, Path file)
+        throws IOException
+    {
+        prepare();
+        view.readAttributes();
+        assertCheckRead(file);
+
+        prepare();
+        FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+        view.setTimes(null, now, now);
+        assertCheckWrite(file);
+    }
+
+    static void testPosixFileAttributeView(PosixFileAttributeView view, Path file)
+        throws IOException
+    {
+        prepare();
+        PosixFileAttributes attrs = view.readAttributes();
+        assertCheckRead(file);
+        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+        prepare();
+        view.setPermissions(attrs.permissions());
+        assertCheckWrite(file);
+        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+        prepare();
+        view.setOwner(attrs.owner());
+        assertCheckWrite(file);
+        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+        prepare();
+        view.setOwner(attrs.owner());
+        assertCheckWrite(file);
+        assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+    }
+
+    public static void main(String[] args) throws IOException {
+        final Path testdir = Paths.get(System.getProperty("test.dir", ".")).toAbsolutePath();
+        final Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir"));
+
+        Path file = createFile(testdir.resolve("file1234"));
+        try {
+            LoggingSecurityManager.install();
+
+            // -- check access --
+
+            prepare();
+            exists(file);
+            assertCheckRead(file);
+
+            prepare();
+            isReadable(file);
+            assertCheckRead(file);
+
+            prepare();
+            isWritable(file);
+            assertCheckWrite(file);
+
+            prepare();
+            isExecutable(file);
+            assertCheckExec(file);
+
+            // -- copy --
+
+            Path target = testdir.resolve("target1234");
+            prepare();
+            copy(file, target);
+            try {
+                assertCheckRead(file);
+                assertCheckWrite(target);
+            } finally {
+                delete(target);
+            }
+
+            if (TestUtil.supportsLinks(testdir)) {
+                Path link = testdir.resolve("link1234");
+                createSymbolicLink(link, file);
+                try {
+                    prepare();
+                    copy(link, target, LinkOption.NOFOLLOW_LINKS);
+                    try {
+                        assertCheckRead(link);
+                        assertCheckWrite(target);
+                        assertCheckPermission(LinkPermission.class, "symbolic");
+                    } finally {
+                        delete(target);
+                    }
+                } finally {
+                    delete(link);
+                }
+            }
+
+            // -- createDirectory --
+
+            Path subdir = testdir.resolve("subdir1234");
+            prepare();
+            createDirectory(subdir);
+            try {
+                assertCheckWrite(subdir);
+            } finally {
+                delete(subdir);
+            }
+
+            // -- createFile --
+
+            Path fileToCreate = testdir.resolve("file7890");
+            prepare();
+            createFile(fileToCreate);
+            try {
+                assertCheckWrite(fileToCreate);
+            } finally {
+                delete(fileToCreate);
+            }
+
+            // -- createSymbolicLink --
+
+            if (TestUtil.supportsLinks(testdir)) {
+                prepare();
+                Path link = testdir.resolve("link1234");
+                createSymbolicLink(link, file);
+                try {
+                    assertCheckWrite(link);
+                    assertCheckPermission(LinkPermission.class, "symbolic");
+                } finally {
+                    delete(link);
+                }
+            }
+
+            // -- createLink --
+
+            if (TestUtil.supportsLinks(testdir)) {
+                prepare();
+                Path link = testdir.resolve("entry234");
+                createLink(link, file);
+                try {
+                    assertCheckWrite(link);
+                    assertCheckPermission(LinkPermission.class, "hard");
+                } finally {
+                    delete(link);
+                }
+            }
+
+            // -- createTempFile --
+
+            prepare();
+            Path tmpfile1 = createTempFile("foo", null);
+            try {
+                assertCheckWriteToDirectory(tmpdir);
+            } finally {
+                delete(tmpfile1);
+            }
+            prepare();
+            Path tmpfile2 = createTempFile(testdir, "foo", ".tmp");
+            try {
+                assertCheckWriteToDirectory(testdir);
+            } finally {
+                delete(tmpfile2);
+            }
+
+            // -- createTempDirectory --
+
+            prepare();
+            Path tmpdir1 = createTempDirectory("foo");
+            try {
+                assertCheckWriteToDirectory(tmpdir);
+            } finally {
+                delete(tmpdir1);
+            }
+            prepare();
+            Path tmpdir2 = createTempDirectory(testdir, "foo");
+            try {
+                assertCheckWriteToDirectory(testdir);
+            } finally {
+                delete(tmpdir2);
+            }
+
+            // -- delete/deleteIfExists --
+
+            Path fileToDelete = testdir.resolve("file7890");
+
+            createFile(fileToDelete);
+            prepare();
+            delete(fileToDelete);
+            assertCheckDelete(fileToDelete);
+
+            createFile(fileToDelete);
+            prepare();
+            deleteIfExists(fileToDelete);   // file exists
+            assertCheckDelete(fileToDelete);
+
+            prepare();
+            deleteIfExists(fileToDelete);   // file does not exist
+            assertCheckDelete(fileToDelete);
+
+            // -- exists/notExists --
+
+            prepare();
+            exists(file);
+            assertCheckRead(file);
+
+            prepare();
+            notExists(file);
+            assertCheckRead(file);
+
+            // -- getFileStore --
+
+            prepare();
+            getFileStore(file);
+            assertCheckRead(file);
+            assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes");
+
+            // -- isSameFile --
+
+            prepare();
+            isSameFile(file, testdir);
+            assertCheckRead(file);
+            assertCheckRead(testdir);
+
+            // -- move --
+
+            Path target2 = testdir.resolve("target1234");
+            prepare();
+            move(file, target2);
+            try {
+                assertCheckWrite(file);
+                assertCheckWrite(target2);
+            } finally {
+                // restore file
+                move(target2, file);
+            }
+
+            // -- newByteChannel --
+
+            prepare();
+            try (SeekableByteChannel sbc = newByteChannel(file)) {
+                assertCheckRead(file);
+            }
+            prepare();
+            try (SeekableByteChannel sbc = newByteChannel(file, WRITE)) {
+                assertCheckWrite(file);
+            }
+            prepare();
+            try (SeekableByteChannel sbc = newByteChannel(file, READ, WRITE)) {
+                assertCheckRead(file);
+                assertCheckWrite(file);
+            }
+
+            prepare();
+            try (SeekableByteChannel sbc = newByteChannel(file, DELETE_ON_CLOSE)) {
+                assertCheckRead(file);
+                assertCheckDelete(file);
+            }
+            createFile(file); // restore file
+
+
+            // -- newInputStream/newOutptuStream --
+
+            prepare();
+            try (InputStream in = newInputStream(file)) {
+                assertCheckRead(file);
+            }
+            prepare();
+            try (OutputStream out = newOutputStream(file)) {
+                assertCheckWrite(file);
+            }
+
+            // -- newDirectoryStream --
+
+            prepare();
+            try (DirectoryStream<Path> stream = newDirectoryStream(testdir)) {
+                assertCheckRead(testdir);
+
+                if (stream instanceof SecureDirectoryStream<?>) {
+                    Path entry;
+                    SecureDirectoryStream<Path> sds =
+                        (SecureDirectoryStream<Path>)stream;
+
+                    // newByteChannel
+                    entry = file.getFileName();
+                    prepare();
+                    try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(READ))) {
+                        assertCheckRead(file);
+                    }
+                    prepare();
+                    try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(WRITE))) {
+                        assertCheckWrite(file);
+                    }
+
+                    // deleteFile
+                    entry = file.getFileName();
+                    prepare();
+                    sds.deleteFile(entry);
+                    assertCheckDelete(file);
+                    createFile(testdir.resolve(entry));  // restore file
+
+                    // deleteDirectory
+                    entry = Paths.get("subdir1234");
+                    createDirectory(testdir.resolve(entry));
+                    prepare();
+                    sds.deleteDirectory(entry);
+                    assertCheckDelete(testdir.resolve(entry));
+
+                    // move
+                    entry = Paths.get("tempname1234");
+                    prepare();
+                    sds.move(file.getFileName(), sds, entry);
+                    assertCheckWrite(file);
+                    assertCheckWrite(testdir.resolve(entry));
+                    sds.move(entry, sds, file.getFileName());  // restore file
+
+                    // newDirectoryStream
+                    entry = Paths.get("subdir1234");
+                    createDirectory(testdir.resolve(entry));
+                    try {
+                        prepare();
+                        sds.newDirectoryStream(entry).close();
+                        assertCheckRead(testdir.resolve(entry));
+                    } finally {
+                        delete(testdir.resolve(entry));
+                    }
+
+                    // getFileAttributeView to access attributes of directory
+                    testBasicFileAttributeView(sds
+                        .getFileAttributeView(BasicFileAttributeView.class), testdir);
+                    testPosixFileAttributeView(sds
+                        .getFileAttributeView(PosixFileAttributeView.class), testdir);
+
+                    // getFileAttributeView to access attributes of entry
+                    entry = file.getFileName();
+                    testBasicFileAttributeView(sds
+                        .getFileAttributeView(entry, BasicFileAttributeView.class), file);
+                    testPosixFileAttributeView(sds
+                        .getFileAttributeView(entry, PosixFileAttributeView.class), file);
+
+                } else {
+                    System.out.println("SecureDirectoryStream not tested");
+                }
+            }
+
+            // -- toAbsolutePath --
+
+            prepare();
+            file.getFileName().toAbsolutePath();
+            assertCheckPropertyAccess("user.dir");
+
+            // -- toRealPath --
+
+            prepare();
+            file.toRealPath(true);
+            assertCheckRead(file);
+
+            prepare();
+            file.toRealPath(false);
+            assertCheckRead(file);
+
+            prepare();
+            Paths.get(".").toRealPath(true);
+            assertCheckPropertyAccess("user.dir");
+
+            prepare();
+            Paths.get(".").toRealPath(false);
+            assertCheckPropertyAccess("user.dir");
+
+            // -- register --
+
+            try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
+                prepare();
+                testdir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
+                assertCheckRead(testdir);
+            }
+
+            // -- getAttribute/setAttribute/readAttributes --
+
+            prepare();
+            getAttribute(file, "size");
+            assertCheckRead(file);
+
+            prepare();
+            setAttribute(file, "lastModifiedTime",
+                FileTime.fromMillis(System.currentTimeMillis()));
+            assertCheckWrite(file);
+
+            prepare();
+            readAttributes(file, "*");
+            assertCheckRead(file);
+
+            // -- BasicFileAttributeView --
+            testBasicFileAttributeView(
+                getFileAttributeView(file, BasicFileAttributeView.class), file);
+
+            // -- PosixFileAttributeView --
+
+            {
+                PosixFileAttributeView view =
+                    getFileAttributeView(file, PosixFileAttributeView.class);
+                if (view != null &&
+                    getFileStore(file).supportsFileAttributeView(PosixFileAttributeView.class))
+                {
+                    testPosixFileAttributeView(view, file);
+                } else {
+                    System.out.println("PosixFileAttributeView not tested");
+                }
+            }
+
+            // -- DosFileAttributeView --
+
+            {
+                DosFileAttributeView view =
+                    getFileAttributeView(file, DosFileAttributeView.class);
+                if (view != null &&
+                    getFileStore(file).supportsFileAttributeView(DosFileAttributeView.class))
+                {
+                    prepare();
+                    view.readAttributes();
+                    assertCheckRead(file);
+
+                    prepare();
+                    view.setArchive(false);
+                    assertCheckWrite(file);
+
+                    prepare();
+                    view.setHidden(false);
+                    assertCheckWrite(file);
+
+                    prepare();
+                    view.setReadOnly(false);
+                    assertCheckWrite(file);
+
+                    prepare();
+                    view.setSystem(false);
+                    assertCheckWrite(file);
+                } else {
+                    System.out.println("DosFileAttributeView not tested");
+                }
+            }
+
+            // -- FileOwnerAttributeView --
+
+            {
+                FileOwnerAttributeView view =
+                    getFileAttributeView(file, FileOwnerAttributeView.class);
+                if (view != null &&
+                    getFileStore(file).supportsFileAttributeView(FileOwnerAttributeView.class))
+                {
+                    prepare();
+                    UserPrincipal owner = view.getOwner();
+                    assertCheckRead(file);
+                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+                    prepare();
+                    view.setOwner(owner);
+                    assertCheckWrite(file);
+                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+                } else {
+                    System.out.println("FileOwnerAttributeView not tested");
+                }
+            }
+
+            // -- UserDefinedFileAttributeView --
+
+            {
+                UserDefinedFileAttributeView view =
+                    getFileAttributeView(file, UserDefinedFileAttributeView.class);
+                if (view != null &&
+                    getFileStore(file).supportsFileAttributeView(UserDefinedFileAttributeView.class))
+                {
+                    prepare();
+                    view.write("test", ByteBuffer.wrap(new byte[100]));
+                    assertCheckWrite(file);
+                    assertCheckPermission(RuntimePermission.class,
+                                               "accessUserDefinedAttributes");
+
+                    prepare();
+                    view.read("test", ByteBuffer.allocate(100));
+                    assertCheckRead(file);
+                    assertCheckPermission(RuntimePermission.class,
+                                               "accessUserDefinedAttributes");
+
+                    prepare();
+                    view.size("test");
+                    assertCheckRead(file);
+                    assertCheckPermission(RuntimePermission.class,
+                                               "accessUserDefinedAttributes");
+
+                    prepare();
+                    view.list();
+                    assertCheckRead(file);
+                    assertCheckPermission(RuntimePermission.class,
+                                               "accessUserDefinedAttributes");
+
+                    prepare();
+                    view.delete("test");
+                    assertCheckWrite(file);
+                    assertCheckPermission(RuntimePermission.class,
+                                               "accessUserDefinedAttributes");
+                } else {
+                    System.out.println("UserDefinedFileAttributeView not tested");
+                }
+            }
+
+            // -- AclFileAttributeView --
+            {
+                AclFileAttributeView view =
+                    getFileAttributeView(file, AclFileAttributeView.class);
+                if (view != null &&
+                    getFileStore(file).supportsFileAttributeView(AclFileAttributeView.class))
+                {
+                    prepare();
+                    List<AclEntry> acl = view.getAcl();
+                    assertCheckRead(file);
+                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+                    prepare();
+                    view.setAcl(acl);
+                    assertCheckWrite(file);
+                    assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+                } else {
+                    System.out.println("AclFileAttributeView not tested");
+                }
+            }
+
+            // -- UserPrincipalLookupService
+
+            UserPrincipalLookupService lookupService =
+                FileSystems.getDefault().getUserPrincipalLookupService();
+            UserPrincipal owner = getOwner(file);
+
+            prepare();
+            lookupService.lookupPrincipalByName(owner.getName());
+            assertCheckPermission(RuntimePermission.class,
+                                       "lookupUserInformation");
+
+            try {
+                UserPrincipal group = readAttributes(file, PosixFileAttributes.class).group();
+                prepare();
+                lookupService.lookupPrincipalByGroupName(group.getName());
+                assertCheckPermission(RuntimePermission.class,
+                                           "lookupUserInformation");
+            } catch (UnsupportedOperationException ignore) {
+                System.out.println("lookupPrincipalByGroupName not tested");
+            }
+
+
+        } finally {
+            deleteIfExists(file);
+        }
+    }
+}