1 package com.atlassian.plugin.loaders;
2
3 import com.atlassian.plugin.ModuleDescriptorFactory;
4 import com.atlassian.plugin.Permissions;
5 import com.atlassian.plugin.Plugin;
6 import com.atlassian.plugin.PluginArtifact;
7 import com.atlassian.plugin.PluginArtifactBackedPlugin;
8 import com.atlassian.plugin.PluginParseException;
9 import com.atlassian.plugin.impl.UnloadablePlugin;
10 import com.google.common.base.Function;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13
14 import static com.google.common.collect.ImmutableList.copyOf;
15 import static com.google.common.collect.Iterables.transform;
16
17 public final class PermissionCheckingPluginLoader extends ForwardingPluginLoader
18 {
19 private static final Logger logger = LoggerFactory.getLogger(PermissionCheckingPluginLoader.class);
20
21 public PermissionCheckingPluginLoader(PluginLoader delegate)
22 {
23 super(delegate);
24 }
25
26 @Override
27 public Iterable<Plugin> loadAllPlugins(ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException
28 {
29 return copyOf(transform(delegate().loadAllPlugins(moduleDescriptorFactory), new CheckPluginPermissionFunction()));
30 }
31
32 @Override
33 public Iterable<Plugin> loadFoundPlugins(ModuleDescriptorFactory moduleDescriptorFactory) throws PluginParseException
34 {
35 return copyOf(transform(delegate().loadFoundPlugins(moduleDescriptorFactory), new CheckPluginPermissionFunction()));
36 }
37
38 private static final class CheckPluginPermissionFunction implements Function<Plugin, Plugin>
39 {
40 @Override
41 public Plugin apply(Plugin p)
42 {
43
44 if (p.hasAllPermissions() || p.getActivePermissions().contains(Permissions.EXECUTE_JAVA))
45 {
46 return p;
47 }
48
49 if (p instanceof PluginArtifactBackedPlugin)
50 {
51 return checkPlugin((PluginArtifactBackedPlugin) p);
52 }
53 return p;
54 }
55
56 private Plugin checkPlugin(PluginArtifactBackedPlugin p)
57 {
58 final PluginArtifact pluginArtifact = p.getPluginArtifact();
59
60 if (pluginArtifact.containsJavaExecutableCode())
61 {
62 UnloadablePlugin unloadablePlugin = new UnloadablePlugin(
63 "Plugin doesn't require '" + Permissions.EXECUTE_JAVA + "' permission yet references some java executable code. " +
64 "This could be either embedded java classes, embedded java libraries, spring context files or bundle activator.");
65 unloadablePlugin.setKey(p.getKey());
66 unloadablePlugin.setName(p.getName());
67
68 logger.warn("Plugin '{}' only requires permission {} which doesn't include '{}', yet has some java code " +
69 "(classes, libs, spring context, etc), making un-loadable.",
70 new Object[]{p.getKey(), p.getActivePermissions(), Permissions.EXECUTE_JAVA});
71
72 return unloadablePlugin;
73 }
74 else
75 {
76 return p;
77 }
78 }
79 }
80 }