1 /*
   2  * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /* @test
  25  * @bug 4313887 6838333 6891404
  26  * @summary Unit test for java.nio.file.attribute.AclFileAttribueView
  27  * @library ../..
  28  * @key randomness
  29  */
  30 
  31 import java.nio.file.*;
  32 import java.nio.file.attribute.*;
  33 import java.io.IOException;
  34 import java.util.*;
  35 
  36 import static java.nio.file.attribute.AclEntryType.*;
  37 import static java.nio.file.attribute.AclEntryPermission.*;
  38 import static java.nio.file.attribute.AclEntryFlag.*;
  39 
  40 public class Basic {
  41 
  42     static void printAcl(List<AclEntry> acl) {
  43         for (AclEntry entry: acl) {
  44             System.out.format("  %s%n", entry);
  45         }
  46     }
  47 
  48     // sanity check read and writing ACL
  49     static void testReadWrite(Path dir) throws IOException {
  50         Path file = dir.resolve("foo");
  51         if (Files.notExists(file))
  52             Files.createFile(file);
  53 
  54         AclFileAttributeView view =
  55             Files.getFileAttributeView(file, AclFileAttributeView.class);
  56 
  57         // print existing ACL
  58         List<AclEntry> acl = view.getAcl();
  59         System.out.println(" -- current ACL --");
  60         printAcl(acl);
  61 
  62         // insert entry to grant owner read access
  63         UserPrincipal owner = view.getOwner();
  64         AclEntry entry = AclEntry.newBuilder()
  65             .setType(ALLOW)
  66             .setPrincipal(owner)
  67             .setPermissions(READ_DATA, READ_ATTRIBUTES)
  68             .build();
  69         System.out.println(" -- insert (entry 0) --");
  70         System.out.format("  %s%n", entry);
  71         acl.add(0, entry);
  72         view.setAcl(acl);
  73 
  74         // re-ACL and check entry
  75         List<AclEntry> newacl = view.getAcl();
  76         System.out.println(" -- current ACL --");
  77         printAcl(acl);
  78         if (!newacl.get(0).equals(entry)) {
  79             throw new RuntimeException("Entry 0 is not expected");
  80         }
  81 
  82         // if PosixFileAttributeView then repeat test with OWNER@
  83         if (Files.getFileStore(file).supportsFileAttributeView("posix")) {
  84             owner = file.getFileSystem().getUserPrincipalLookupService()
  85                 .lookupPrincipalByName("OWNER@");
  86             entry = AclEntry.newBuilder(entry).setPrincipal(owner).build();
  87 
  88             System.out.println(" -- replace (entry 0) --");
  89             System.out.format("  %s%n", entry);
  90 
  91             acl.set(0, entry);
  92             view.setAcl(acl);
  93             newacl = view.getAcl();
  94             System.out.println(" -- current ACL --");
  95             printAcl(acl);
  96             if (!newacl.get(0).equals(entry)) {
  97                 throw new RuntimeException("Entry 0 is not expected");
  98             }
  99         }
 100     }
 101 
 102     static FileAttribute<List<AclEntry>> asAclAttribute(final List<AclEntry> acl) {
 103         return new FileAttribute<List<AclEntry>>() {
 104             public String name() { return "acl:acl"; }
 105             public List<AclEntry> value() { return acl; }
 106         };
 107     }
 108 
 109     static void assertEquals(List<AclEntry> actual, List<AclEntry> expected) {
 110         if (!actual.equals(expected)) {
 111             System.err.format("Actual: %s\n", actual);
 112             System.err.format("Expected: %s\n", expected);
 113             throw new RuntimeException("ACL not expected");
 114         }
 115     }
 116 
 117     // sanity check create a file or directory with initial ACL
 118     static void testCreateFile(Path dir) throws IOException {
 119         UserPrincipal user = Files.getOwner(dir);
 120         AclFileAttributeView view;
 121 
 122         // create file with initial ACL
 123         System.out.println("-- create file with initial ACL --");
 124         Path file = dir.resolve("gus");
 125         List<AclEntry> fileAcl = Arrays.asList(
 126             AclEntry.newBuilder()
 127                 .setType(AclEntryType.ALLOW)
 128                 .setPrincipal(user)
 129                 .setPermissions(SYNCHRONIZE, READ_DATA, WRITE_DATA,
 130                     READ_ATTRIBUTES, READ_ACL, WRITE_ATTRIBUTES, DELETE)
 131                 .build());
 132         Files.createFile(file, asAclAttribute(fileAcl));
 133         view = Files.getFileAttributeView(file, AclFileAttributeView.class);
 134         assertEquals(view.getAcl(), fileAcl);
 135 
 136         // create directory with initial ACL
 137         System.out.println("-- create directory with initial ACL --");
 138         Path subdir = dir.resolve("stuff");
 139         List<AclEntry> dirAcl = Arrays.asList(
 140             AclEntry.newBuilder()
 141                 .setType(AclEntryType.ALLOW)
 142                 .setPrincipal(user)
 143                 .setPermissions(SYNCHRONIZE, ADD_FILE, DELETE)
 144                 .build(),
 145             AclEntry.newBuilder(fileAcl.get(0))
 146                 .setFlags(FILE_INHERIT)
 147                 .build());
 148         Files.createDirectory(subdir, asAclAttribute(dirAcl));
 149         view = Files.getFileAttributeView(subdir, AclFileAttributeView.class);
 150         assertEquals(view.getAcl(), dirAcl);
 151     }
 152 
 153     public static void main(String[] args) throws IOException {
 154         // use work directory rather than system temporary directory to
 155         // improve chances that ACLs are supported
 156         Path dir = Paths.get("./work" + new Random().nextInt());
 157         Files.createDirectory(dir);
 158         try {
 159             if (!Files.getFileStore(dir).supportsFileAttributeView("acl")) {
 160                 System.out.println("ACLs not supported - test skipped!");
 161                 return;
 162             }
 163             testReadWrite(dir);
 164 
 165             // only currently feasible on Windows
 166             if (System.getProperty("os.name").startsWith("Windows"))
 167                 testCreateFile(dir);
 168 
 169         } finally {
 170             TestUtil.removeAll(dir);
 171         }
 172     }
 173 }