1/*
2 * Copyright (c) 2017, 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
24package p;
25
26import java.security.AccessControlContext;
27import java.security.AccessControlException;
28import java.security.AccessController;
29import java.security.AllPermission;
30import java.security.CodeSource;
31import java.security.Permission;
32import java.security.PermissionCollection;
33import java.security.Permissions;
34import java.security.PrivilegedAction;
35import java.security.ProtectionDomain;
36import java.util.ServiceConfigurationError;
37import java.util.ServiceLoader;
38import java.util.ServiceLoader.Provider;
39import static java.security.AccessController.doPrivileged;
40
41import org.testng.annotations.Test;
42import org.testng.annotations.BeforeTest;
43import static org.testng.Assert.*;
44
45/**
46 * Basic tests with a security manager to ensure that the provider code
47 * is run with permissions restricted by whatever created the ServiceLoader
48 * object.
49 */
50
51public class Tests {
52
53    static final Permission PERM = new RuntimePermission("eatMuffin");
54
55    static <T> PrivilegedAction<ServiceLoader<T>> loadAction(Class<T> service) {
56        return () -> ServiceLoader.load(service);
57    }
58
59    static AccessControlContext withPermissions(Permission... perms) {
60        Permissions p = new Permissions();
61        for (Permission perm : perms) {
62            p.add(perm);
63        }
64        ProtectionDomain pd = new ProtectionDomain(null, p);
65        return new AccessControlContext(new ProtectionDomain[]{ pd });
66    }
67
68    static AccessControlContext noPermissions() {
69        return withPermissions(/*empty*/);
70    }
71
72    @BeforeTest
73    public void setSecurityManager() {
74        class Policy extends java.security.Policy {
75            private final Permissions perms;
76            public Policy(Permission... permissions) {
77                perms = new Permissions();
78                for (Permission permission : permissions) {
79                    perms.add(permission);
80                }
81            }
82            public PermissionCollection getPermissions(CodeSource cs) {
83                return perms;
84            }
85            public PermissionCollection getPermissions(ProtectionDomain pd) {
86                return perms;
87            }
88            public boolean implies(ProtectionDomain pd, Permission p) {
89                return perms.implies(p);
90            }
91            public void refresh() { }
92        }
93        Policy policy = new Policy(new AllPermission());
94        Policy.setPolicy(policy);
95        System.setSecurityManager(new SecurityManager());
96    }
97
98    @Test
99    public void testConstructorUsingIteratorWithPermission() {
100        ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), withPermissions(PERM));
101        S1 obj = sl.iterator().next();
102    }
103
104    @Test
105    public void testConstructorUsingStreamWithPermission() {
106        ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), withPermissions(PERM));
107        assertTrue(sl.stream().map(Provider::get).count() == 1);
108    }
109
110    @Test
111    public void testConstructorUsingIteratorNoPermission() {
112        ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), noPermissions());
113        try {
114            sl.iterator().next();
115            assertTrue(false);
116        } catch (ServiceConfigurationError e) {
117            assertTrue(e.getCause() instanceof AccessControlException);
118        }
119    }
120
121    @Test
122    public void testConstructorUsingStreamNoPermission() {
123        ServiceLoader<S1> sl = doPrivileged(loadAction(S1.class), noPermissions());
124        try {
125            sl.stream().map(Provider::get).count();
126            assertTrue(false);
127        } catch (ServiceConfigurationError e) {
128            assertTrue(e.getCause() instanceof AccessControlException);
129        }
130    }
131
132    @Test
133    public void testFactoryMethodUsingIteratorWithPermission() {
134        ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), withPermissions(PERM));
135        S2 obj = sl.iterator().next();
136    }
137
138    @Test
139    public void testFactoryMethodUsingStreamWithPermission() {
140        ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), withPermissions(PERM));
141        assertTrue(sl.stream().map(Provider::get).count() == 1);
142    }
143
144    @Test
145    public void testFactoryMethodUsingIteratorNoPermission() {
146        ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), noPermissions());
147        try {
148            sl.iterator().next();
149            assertTrue(false);
150        } catch (ServiceConfigurationError e) {
151            assertTrue(e.getCause() instanceof AccessControlException);
152        }
153    }
154
155    @Test
156    public void testFactoryMethodUsingStreamNoPermission() {
157        ServiceLoader<S2> sl = doPrivileged(loadAction(S2.class), noPermissions());
158        try {
159            sl.stream().map(Provider::get).count();
160            assertTrue(false);
161        } catch (ServiceConfigurationError e) {
162            assertTrue(e.getCause() instanceof AccessControlException);
163        }
164    }
165
166
167    // service types and implementations
168
169    public static interface S1 { }
170    public static interface S2 { }
171
172    public static class P1 implements S1 {
173        public P1() {
174            AccessController.getContext().checkPermission(PERM);
175        }
176    }
177    public static class P2 implements S2 {
178        private P2() {
179            AccessController.getContext().checkPermission(PERM);
180        }
181        public static S2 provider() {
182            return new P2();
183        }
184    }
185}
186