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 
printAcl(List<AclEntry> acl)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
testReadWrite(Path dir)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 
asAclAttribute(final List<AclEntry> acl)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 }
174