1 package com.atlassian.plugin.loaders;
2
3 import com.atlassian.plugin.ModuleDescriptor;
4 import com.atlassian.plugin.ModuleDescriptorFactory;
5 import com.atlassian.plugin.Permissions;
6 import com.atlassian.plugin.Plugin;
7 import com.atlassian.plugin.PluginArtifact;
8 import com.atlassian.plugin.PluginException;
9 import com.atlassian.plugin.PluginInformation;
10 import com.atlassian.plugin.PluginInternal;
11 import com.atlassian.plugin.impl.UnloadablePlugin;
12 import com.google.common.collect.ImmutableList;
13 import com.google.common.collect.ImmutableSet;
14 import com.google.common.collect.Iterables;
15 import org.junit.Before;
16 import org.junit.Test;
17 import org.junit.runner.RunWith;
18 import org.mockito.Mock;
19 import org.mockito.junit.MockitoJUnitRunner;
20
21 import java.util.Set;
22
23 import static org.hamcrest.Matchers.instanceOf;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertSame;
26 import static org.junit.Assert.assertThat;
27 import static org.junit.Assert.assertTrue;
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.Mockito.doThrow;
30 import static org.mockito.Mockito.mock;
31 import static org.mockito.Mockito.times;
32 import static org.mockito.Mockito.verify;
33 import static org.mockito.Mockito.when;
34
35 @RunWith(MockitoJUnitRunner.Silent.class)
36 public final class PermissionCheckingPluginLoaderTest {
37
38 private PermissionCheckingPluginLoader permissionCheckingPluginLoader;
39 @Mock
40 private PluginLoader pluginLoader;
41 @Mock
42 private ModuleDescriptorFactory moduleDescriptorFactory;
43
44 @Before
45 public void setUp() {
46 permissionCheckingPluginLoader = new PermissionCheckingPluginLoader(pluginLoader);
47 }
48
49 @Test
50 public void loadAllPluginsWithEmptyCollectionOfPlugins() {
51 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of());
52 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
53 assertTrue(Iterables.isEmpty(plugins));
54 }
55
56 @Test
57 public void loadFoundPluginsWithEmptyCollectionOfPlugins() {
58 when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of());
59 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
60 assertTrue(Iterables.isEmpty(plugins));
61 }
62
63 @Test
64 public void loadFoundPluginsWithPluginWithoutExecuteJavaPermissionAndNoJava() {
65 final Plugin plugin = newPlugin(ImmutableSet.of(), false, false);
66
67 when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
68 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
69
70 assertEquals(1, Iterables.size(plugins));
71 assertSame(plugin, Iterables.get(plugins, 0));
72 }
73
74 @Test
75 public void loadAllPluginsWithPluginWithoutExecuteJavaPermissionAndNoJava() {
76 final Plugin plugin = newPlugin(ImmutableSet.of(), false, false);
77
78 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
79 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
80
81 assertEquals(1, Iterables.size(plugins));
82 assertSame(plugin, Iterables.get(plugins, 0));
83 }
84
85 @Test
86 public void loadFoundPluginsWithPluginWithoutExecuteJavaPermissionAndSomeJava() {
87 final Plugin plugin = newPlugin(ImmutableSet.of(), true, false);
88
89 when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
90 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
91
92 assertEquals(1, Iterables.size(plugins));
93 assertTrue(Iterables.get(plugins, 0) instanceof UnloadablePlugin);
94 }
95
96 @Test
97 public void loadAllPluginsWithPluginWithoutExecuteJavaPermissionAndSomeJava() {
98 final Plugin plugin = newPlugin(ImmutableSet.of(), true, false);
99
100 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
101 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
102
103 assertEquals(1, Iterables.size(plugins));
104 assertTrue(Iterables.get(plugins, 0) instanceof UnloadablePlugin);
105 }
106
107 @Test
108 public void loadAllPluginsWithUnloadablePluginThenRemoved() {
109 final Plugin plugin = newPlugin(ImmutableSet.of(), true, false);
110
111 doThrow(new PluginException("cannot find plugin")).when(pluginLoader).removePlugin(any(Plugin.class));
112 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
113 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
114
115 assertEquals(1, Iterables.size(plugins));
116 Plugin loadedPlugin = Iterables.get(plugins, 0);
117 assertTrue(loadedPlugin instanceof UnloadablePlugin);
118 permissionCheckingPluginLoader.removePlugin(loadedPlugin);
119 }
120
121 @Test
122 public void loadAllPluginsWithGoodPluginThenDiscarded() throws Exception {
123
124 final DiscardablePluginLoader discardablePluginLoader = mock(DiscardablePluginLoader.class);
125 permissionCheckingPluginLoader = new PermissionCheckingPluginLoader(discardablePluginLoader);
126
127 final Plugin plugin = newPlugin(ImmutableSet.of(), true, true);
128
129 when(discardablePluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
130 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
131 permissionCheckingPluginLoader.discardPlugin(plugin);
132 verify(discardablePluginLoader).discardPlugin(plugin);
133 }
134
135 @Test
136 public void loadAllPluginsWithUnloadablePluginThenDiscarded() {
137
138 final DiscardablePluginLoader discardablePluginLoader = mock(DiscardablePluginLoader.class);
139 permissionCheckingPluginLoader = new PermissionCheckingPluginLoader(discardablePluginLoader);
140
141 final Plugin containsJavaButNoPermission = newPlugin(ImmutableSet.of(), true, false);
142 final Plugin hasSystemButNoPermission = newPlugin(ImmutableSet.of(), false, false);
143 addModuleDescriptor(hasSystemButNoPermission, true);
144
145
146 final Iterable<Plugin> pluginsToLoad = ImmutableList.of(containsJavaButNoPermission, hasSystemButNoPermission);
147 when(discardablePluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(pluginsToLoad);
148
149 final Iterable<Plugin> loadedPlugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
150
151 for (final Plugin plugin : pluginsToLoad) {
152 verify(discardablePluginLoader).discardPlugin(plugin);
153 }
154
155 assertEquals(Iterables.size(loadedPlugins), Iterables.size(pluginsToLoad));
156 for (final Plugin plugin : loadedPlugins) {
157 assertThat(plugin, instanceOf(UnloadablePlugin.class));
158 permissionCheckingPluginLoader.discardPlugin(plugin);
159 }
160
161
162 verify(discardablePluginLoader, times(Iterables.size(pluginsToLoad))).discardPlugin(any(Plugin.class));
163 }
164
165 @Test
166 public void loadFoundPluginsWithGoodPluginThenDiscarded() throws Exception {
167
168 final DiscardablePluginLoader discardablePluginLoader = mock(DiscardablePluginLoader.class);
169 permissionCheckingPluginLoader = new PermissionCheckingPluginLoader(discardablePluginLoader);
170
171 final Plugin plugin = newPlugin(ImmutableSet.of(), true, true);
172
173 when(discardablePluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
174 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
175 permissionCheckingPluginLoader.discardPlugin(plugin);
176 verify(discardablePluginLoader).discardPlugin(plugin);
177 }
178
179 @Test
180 public void loadFoundPluginsWithUnloadablePluginThenDiscarded() {
181
182 final DiscardablePluginLoader discardablePluginLoader = mock(DiscardablePluginLoader.class);
183 permissionCheckingPluginLoader = new PermissionCheckingPluginLoader(discardablePluginLoader);
184
185 final Plugin containsJavaButNoPermission = newPlugin(ImmutableSet.of(), true, false);
186 final Plugin hasSystemButNoPermission = newPlugin(ImmutableSet.of(), false, false);
187 addModuleDescriptor(hasSystemButNoPermission, true);
188
189
190 final Iterable<Plugin> pluginsToLoad = ImmutableList.of(containsJavaButNoPermission, hasSystemButNoPermission);
191 when(discardablePluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(pluginsToLoad);
192
193 final Iterable<Plugin> loadedPlugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
194
195 for (final Plugin plugin : pluginsToLoad) {
196 verify(discardablePluginLoader).discardPlugin(plugin);
197 }
198
199 assertEquals(Iterables.size(loadedPlugins), Iterables.size(pluginsToLoad));
200 for (final Plugin plugin : loadedPlugins) {
201 assertThat(plugin, instanceOf(UnloadablePlugin.class));
202 permissionCheckingPluginLoader.discardPlugin(plugin);
203 }
204
205
206 verify(discardablePluginLoader, times(Iterables.size(pluginsToLoad))).discardPlugin(any(Plugin.class));
207 }
208
209 @Test
210 public void loadAllPluginsWithPluginWithNoPermissionsAndSystemModules() throws Exception {
211 final Plugin plugin = newPlugin(ImmutableSet.of(), false, false);
212
213 addModuleDescriptor(plugin, true);
214
215 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
216 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
217
218 assertEquals(1, Iterables.size(plugins));
219 assertTrue(Iterables.get(plugins, 0) instanceof UnloadablePlugin);
220 }
221
222 @Test
223 public void loadAllPluginsWithPluginWithNoPermissionsAndNoSystemModules() throws Exception {
224 final Plugin plugin = newPlugin(ImmutableSet.of(), false, false);
225
226 addModuleDescriptor(plugin, false);
227
228 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
229 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
230
231 assertEquals(1, Iterables.size(plugins));
232 assertSame(plugin, Iterables.get(plugins, 0));
233 }
234
235 @Test
236 public void loadFoundPluginsWithPluginWithJavaPermissionAndSomeJava() throws Exception {
237 final Plugin plugin = newPlugin(ImmutableSet.of(Permissions.EXECUTE_JAVA), true, false);
238
239 when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
240 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
241
242 assertEquals(1, Iterables.size(plugins));
243 assertSame(plugin, Iterables.get(plugins, 0));
244 }
245
246 @Test
247 public void loadAllPluginsWithPluginWithCreateSystemModulePermissionsAndSystemModules() throws Exception {
248 final Plugin plugin = newPlugin(ImmutableSet.of(Permissions.CREATE_SYSTEM_MODULES), false, false);
249
250 addModuleDescriptor(plugin, true);
251
252 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
253 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
254
255 assertEquals(1, Iterables.size(plugins));
256 assertSame(plugin, Iterables.get(plugins, 0));
257 }
258
259 @Test
260 public void loadAllPluginsWithPluginWithCreateSystemModulePermissionsAndNoSystemModules() throws Exception {
261 final Plugin plugin = newPlugin(ImmutableSet.of(Permissions.CREATE_SYSTEM_MODULES), false, false);
262
263 addModuleDescriptor(plugin, false);
264
265 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
266 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
267
268 assertEquals(1, Iterables.size(plugins));
269 assertSame(plugin, Iterables.get(plugins, 0));
270 }
271
272 @Test
273 public void loadFoundPluginsWithPluginWithJavaPermissionAndNoJava() throws Exception {
274 final Plugin plugin = newPlugin(ImmutableSet.of(Permissions.EXECUTE_JAVA), false, false);
275
276 when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
277 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
278
279 assertEquals(1, Iterables.size(plugins));
280 assertSame(plugin, Iterables.get(plugins, 0));
281 }
282
283 @Test
284 public void loadAllPluginsWithPluginWithJavaPermissionAndNoJava() throws Exception {
285 final Plugin plugin = newPlugin(ImmutableSet.of(Permissions.EXECUTE_JAVA), false, false);
286
287 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
288 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
289
290 assertEquals(1, Iterables.size(plugins));
291 assertSame(plugin, Iterables.get(plugins, 0));
292 }
293
294 @Test
295 public void loadFoundPluginsWithPluginWithAllPermissionsAndSomeJava() throws Exception {
296 final Plugin plugin = newPlugin(ImmutableSet.of(), true, true);
297
298 when(pluginLoader.loadFoundPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
299 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadFoundPlugins(moduleDescriptorFactory);
300
301 assertEquals(1, Iterables.size(plugins));
302 assertSame(plugin, Iterables.get(plugins, 0));
303 }
304
305 @Test
306 public void loadAllPluginsWithPluginWithAllPermissionsAndSomeJava() throws Exception {
307 final Plugin plugin = newPlugin(ImmutableSet.of(), true, true);
308
309 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
310 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
311
312 assertEquals(1, Iterables.size(plugins));
313 assertSame(plugin, Iterables.get(plugins, 0));
314 }
315
316 @Test
317 public void loadAllPluginsWithPluginWithAllPermissionsAndSystemModules() throws Exception {
318 final Plugin plugin = newPlugin(ImmutableSet.of(), false, true);
319 addModuleDescriptor(plugin, true);
320
321 when(pluginLoader.loadAllPlugins(moduleDescriptorFactory)).thenReturn(ImmutableList.of(plugin));
322 final Iterable<Plugin> plugins = permissionCheckingPluginLoader.loadAllPlugins(moduleDescriptorFactory);
323
324 assertEquals(1, Iterables.size(plugins));
325 assertSame(plugin, Iterables.get(plugins, 0));
326 }
327
328 private void addModuleDescriptor(Plugin plugin, boolean system) {
329 ModuleDescriptor descriptor = mock(ModuleDescriptor.class);
330 when(descriptor.getKey()).thenReturn("foo");
331 when(descriptor.isSystemModule()).thenReturn(system);
332 when(plugin.getModuleDescriptors()).thenReturn(ImmutableList.of(descriptor));
333 }
334
335 private Plugin newPlugin(Set<String> permissions, boolean hasJava, boolean hasAllPermissions) {
336 final PluginInternal plugin = mockPlugin(PluginInternal.class);
337 final PluginArtifact pluginArtifact = mock(PluginArtifact.class);
338 when(plugin.hasAllPermissions()).thenReturn(hasAllPermissions);
339 when(plugin.getActivePermissions()).thenReturn(permissions);
340 when(plugin.getPluginArtifact()).thenReturn(pluginArtifact);
341 when(pluginArtifact.containsJavaExecutableCode()).thenReturn(hasJava);
342 return plugin;
343 }
344
345 private <P extends Plugin> P mockPlugin(Class<P> type) {
346 P mock = mock(type);
347 when(mock.getKey()).thenReturn("test-plugin-key");
348 when(mock.getName()).thenReturn("Test Plugin");
349 PluginInformation pluginInformation = mock(PluginInformation.class);
350 when(mock.getPluginInformation()).thenReturn(pluginInformation);
351 return mock;
352 }
353 }