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 (file.notExists())
  51             file.createFile();
  52 
  53         AclFileAttributeView view = file
  54             .getFileAttributeView(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 (file.getFileStore().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 = Attributes.getOwner(dir);
 119 
 120         // create file with initial ACL
 121         System.out.println("-- create file with initial ACL --");
 122         Path file = dir.resolve("gus");
 123         List<AclEntry> fileAcl = Arrays.asList(
 124             AclEntry.newBuilder()
 125                 .setType(AclEntryType.ALLOW)
 126                 .setPrincipal(user)
 127                 .setPermissions(SYNCHRONIZE, READ_DATA, WRITE_DATA,
 128                     READ_ATTRIBUTES, READ_ACL, WRITE_ATTRIBUTES, DELETE)
 129                 .build());
 130         file.createFile(asAclAttribute(fileAcl));
 131         assertEquals(Attributes.getAcl(file), fileAcl);
 132 
 133         // create directory with initial ACL
 134         System.out.println("-- create directory with initial ACL --");
 135         Path subdir = dir.resolve("stuff");
 136         List<AclEntry> dirAcl = Arrays.asList(
 137             AclEntry.newBuilder()
 138                 .setType(AclEntryType.ALLOW)
 139                 .setPrincipal(user)
 140                 .setPermissions(SYNCHRONIZE, ADD_FILE, DELETE)
 141                 .build(),
 142             AclEntry.newBuilder(fileAcl.get(0))
 143                 .setFlags(FILE_INHERIT)
 144                 .build());
 145         subdir.createDirectory(asAclAttribute(dirAcl));
 146         assertEquals(Attributes.getAcl(subdir), dirAcl);
 147     }
 148 
 149     public static void main(String[] args) throws IOException {
 150         // use work directory rather than system temporary directory to
 151         // improve chances that ACLs are supported
 152         Path dir = Paths.get("./work" + new Random().nextInt())
 153             .createDirectory();
 154         try {
 155             if (!dir.getFileStore().supportsFileAttributeView("acl")) {
 156                 System.out.println("ACLs not supported - test skipped!");
 157                 return;
 158             }
 159             testReadWrite(dir);
 160 
 161             // only currently feasible on Windows
 162             if (System.getProperty("os.name").startsWith("Windows"))
 163                 testCreateFile(dir);
 164 
 165         } finally {
 166             TestUtil.removeAll(dir);
 167         }
 168     }
 169 }