1 /*
   2  * Copyright (c) 2008, 2009, 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  */
  29 
  30 import java.nio.file.*;
  31 import java.nio.file.attribute.*;
  32 import java.io.IOException;
  33 import java.util.*;
  34 
  35 import static java.nio.file.attribute.AclEntryType.*;
  36 import static java.nio.file.attribute.AclEntryPermission.*;
  37 import static java.nio.file.attribute.AclEntryFlag.*;
  38 
  39 public class Basic {
  40 
  41     static void printAcl(List<AclEntry> acl) {
  42         for (AclEntry entry: acl) {
  43             System.out.format("  %s%n", entry);
  44         }
  45     }
  46 
  47     // sanity check read and writing ACL
  48     static void testReadWrite(Path dir) throws IOException {
  49         Path file = dir.resolve("foo");
  50         if (Files.notExists(file))
  51             Files.createFile(file);
  52 
  53         AclFileAttributeView view =
  54             Files.getFileAttributeView(file, AclFileAttributeView.class);
  55 
  56         // print existing ACL
  57         List<AclEntry> acl = view.getAcl();
  58         System.out.println(" -- current ACL --");
  59         printAcl(acl);
  60 
  61         // insert entry to grant owner read access
  62         UserPrincipal owner = view.getOwner();
  63         AclEntry entry = AclEntry.newBuilder()
  64             .setType(ALLOW)
  65             .setPrincipal(owner)
  66             .setPermissions(READ_DATA, READ_ATTRIBUTES)
  67             .build();
  68         System.out.println(" -- insert (entry 0) --");
  69         System.out.format("  %s%n", entry);
  70         acl.add(0, entry);
  71         view.setAcl(acl);
  72 
  73         // re-ACL and check entry
  74         List<AclEntry> newacl = view.getAcl();
  75         System.out.println(" -- current ACL --");
  76         printAcl(acl);
  77         if (!newacl.get(0).equals(entry)) {
  78             throw new RuntimeException("Entry 0 is not expected");
  79         }
  80 
  81         // if PosixFileAttributeView then repeat test with OWNER@
  82         if (Files.getFileStore(file).supportsFileAttributeView("posix")) {
  83             owner = file.getFileSystem().getUserPrincipalLookupService()
  84                 .lookupPrincipalByName("OWNER@");
  85             entry = AclEntry.newBuilder(entry).setPrincipal(owner).build();
  86 
  87             System.out.println(" -- replace (entry 0) --");
  88             System.out.format("  %s%n", entry);
  89 
  90             acl.set(0, entry);
  91             view.setAcl(acl);
  92             newacl = view.getAcl();
  93             System.out.println(" -- current ACL --");
  94             printAcl(acl);
  95             if (!newacl.get(0).equals(entry)) {
  96                 throw new RuntimeException("Entry 0 is not expected");
  97             }
  98         }
  99     }
 100 
 101     static FileAttribute<List<AclEntry>> asAclAttribute(final List<AclEntry> acl) {
 102         return new FileAttribute<List<AclEntry>>() {
 103             public String name() { return "acl:acl"; }
 104             public List<AclEntry> value() { return acl; }
 105         };
 106     }
 107 
 108     static void assertEquals(List<AclEntry> actual, List<AclEntry> expected) {
 109         if (!actual.equals(expected)) {
 110             System.err.format("Actual: %s\n", actual);
 111             System.err.format("Expected: %s\n", expected);
 112             throw new RuntimeException("ACL not expected");
 113         }
 114     }
 115 
 116     // sanity check create a file or directory with initial ACL
 117     static void testCreateFile(Path dir) throws IOException {
 118         UserPrincipal user = Files.getOwner(dir);
 119         AclFileAttributeView view;
 120 
 121         // create file with initial ACL
 122         System.out.println("-- create file with initial ACL --");
 123         Path file = dir.resolve("gus");
 124         List<AclEntry> fileAcl = Arrays.asList(
 125             AclEntry.newBuilder()
 126                 .setType(AclEntryType.ALLOW)
 127                 .setPrincipal(user)
 128                 .setPermissions(SYNCHRONIZE, READ_DATA, WRITE_DATA,
 129                     READ_ATTRIBUTES, READ_ACL, WRITE_ATTRIBUTES, DELETE)
 130                 .build());
 131         Files.createFile(file, asAclAttribute(fileAcl));
 132         view = Files.getFileAttributeView(file, AclFileAttributeView.class);
 133         assertEquals(view.getAcl(), fileAcl);
 134 
 135         // create directory with initial ACL
 136         System.out.println("-- create directory with initial ACL --");
 137         Path subdir = dir.resolve("stuff");
 138         List<AclEntry> dirAcl = Arrays.asList(
 139             AclEntry.newBuilder()
 140                 .setType(AclEntryType.ALLOW)
 141                 .setPrincipal(user)
 142                 .setPermissions(SYNCHRONIZE, ADD_FILE, DELETE)
 143                 .build(),
 144             AclEntry.newBuilder(fileAcl.get(0))
 145                 .setFlags(FILE_INHERIT)
 146                 .build());
 147         Files.createDirectory(subdir, asAclAttribute(dirAcl));
 148         view = Files.getFileAttributeView(subdir, AclFileAttributeView.class);
 149         assertEquals(view.getAcl(), dirAcl);
 150     }
 151 
 152     public static void main(String[] args) throws IOException {
 153         // use work directory rather than system temporary directory to
 154         // improve chances that ACLs are supported
 155         Path dir = Paths.get("./work" + new Random().nextInt());
 156         Files.createDirectory(dir);
 157         try {
 158             if (!Files.getFileStore(dir).supportsFileAttributeView("acl")) {
 159                 System.out.println("ACLs not supported - test skipped!");
 160                 return;
 161             }
 162             testReadWrite(dir);
 163 
 164             // only currently feasible on Windows
 165             if (System.getProperty("os.name").startsWith("Windows"))
 166                 testCreateFile(dir);
 167 
 168         } finally {
 169             TestUtil.removeAll(dir);
 170         }
 171     }
 172 }