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
31import java.nio.file.*;
32import java.nio.file.attribute.*;
33import java.io.IOException;
34import java.util.*;
35
36import static java.nio.file.attribute.AclEntryType.*;
37import static java.nio.file.attribute.AclEntryPermission.*;
38import static java.nio.file.attribute.AclEntryFlag.*;
39
40public 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}
174