/plugin/src/main/java/com/atlassian/plugin/remotable/plugin/permission/DefaultPermissionModuleDescriptor.java

https://bitbucket.org/rodogu/remotable-plugins · Java · 242 lines · 210 code · 30 blank · 2 comment · 5 complexity · c410ead73e723741f2e6b73859712e08 MD5 · raw file

  1. package com.atlassian.plugin.remotable.plugin.permission;
  2. import com.atlassian.fugue.Option;
  3. import com.atlassian.plugin.Plugin;
  4. import com.atlassian.plugin.PluginParseException;
  5. import com.atlassian.plugin.descriptors.AbstractModuleDescriptor;
  6. import com.atlassian.plugin.module.ModuleFactory;
  7. import com.atlassian.plugin.remotable.api.InstallationMode;
  8. import com.atlassian.plugin.remotable.spi.PermissionDeniedException;
  9. import com.atlassian.plugin.remotable.spi.Permissions;
  10. import com.atlassian.plugin.remotable.spi.permission.DefaultPermission;
  11. import com.atlassian.plugin.remotable.spi.permission.Permission;
  12. import com.atlassian.plugin.remotable.spi.permission.PermissionInfo;
  13. import com.atlassian.plugin.remotable.spi.permission.PermissionModuleDescriptor;
  14. import com.atlassian.plugin.remotable.spi.permission.scope.ApiResourceInfo;
  15. import com.atlassian.plugin.remotable.spi.permission.scope.ApiScope;
  16. import com.google.common.base.Function;
  17. import com.google.common.base.Predicate;
  18. import com.google.common.base.Supplier;
  19. import com.google.common.base.Suppliers;
  20. import org.dom4j.Element;
  21. import org.slf4j.Logger;
  22. import org.slf4j.LoggerFactory;
  23. import javax.servlet.http.HttpServletRequest;
  24. import javax.validation.constraints.NotNull;
  25. import java.util.List;
  26. import java.util.Set;
  27. import static com.atlassian.plugin.remotable.spi.permission.AbstractPermission.DEFAULT_INSTALLATION_MODES;
  28. import static com.google.common.base.Preconditions.checkNotNull;
  29. import static com.google.common.collect.ImmutableSet.copyOf;
  30. import static com.google.common.collect.Iterables.filter;
  31. import static com.google.common.collect.Iterables.transform;
  32. public final class DefaultPermissionModuleDescriptor extends AbstractModuleDescriptor<Permission> implements PermissionModuleDescriptor
  33. {
  34. private final Logger logger = LoggerFactory.getLogger(this.getClass());
  35. private Supplier<? extends Permission> permissionSupplier;
  36. public DefaultPermissionModuleDescriptor(ModuleFactory moduleFactory)
  37. {
  38. super(moduleFactory);
  39. }
  40. @Override
  41. public void init(@NotNull final Plugin plugin, @NotNull Element element) throws PluginParseException
  42. {
  43. checkHasDefinePluginPermissionPermission(plugin);
  44. super.init(plugin, element);
  45. final Set<InstallationMode> installationModes = getInstallationModes(element);
  46. final PermissionInfo permissionInfo = getPermissionInfo();
  47. permissionSupplier = Suppliers.memoize(new Supplier<Permission>()
  48. {
  49. @Override
  50. public Permission get()
  51. {
  52. final Permission permission;
  53. if (moduleClassName == null)
  54. {
  55. permission = new DefaultPermission(getKey(), installationModes.isEmpty() ? DEFAULT_INSTALLATION_MODES : installationModes, permissionInfo);
  56. }
  57. else
  58. {
  59. final Permission permissionFromModuleClassName = getPermissionFromModuleClassName();
  60. if (permissionFromModuleClassName instanceof ApiScope)
  61. {
  62. permission = new ForwardingApiScope((ApiScope) permissionFromModuleClassName, permissionInfo);
  63. }
  64. else
  65. {
  66. permission = new ForwardingPermission<Permission>(permissionFromModuleClassName, permissionInfo);
  67. }
  68. }
  69. return permission;
  70. }
  71. });
  72. }
  73. private Permission getPermissionFromModuleClassName()
  74. {
  75. return moduleFactory.createModule(moduleClassName, DefaultPermissionModuleDescriptor.this);
  76. }
  77. private void checkHasDefinePluginPermissionPermission(Plugin plugin)
  78. {
  79. boolean hasAllPermissions;
  80. try
  81. {
  82. hasAllPermissions = plugin.hasAllPermissions();
  83. }
  84. catch (NoSuchMethodError error)
  85. {
  86. // we're on Atlassian Plugins v2, where permissions are not supported, so plugins have all permissions
  87. logger.debug("We're using Atlassian Plugins 2, plugins have all permissions, will allow {}", Permissions.DEFINE_PLUGIN_PERMISSION, error);
  88. hasAllPermissions = true;
  89. }
  90. if (hasAllPermissions)
  91. {
  92. return;
  93. }
  94. if (!plugin.getActivePermissions().contains(Permissions.DEFINE_PLUGIN_PERMISSION))
  95. {
  96. throw new PermissionDeniedException(
  97. plugin.getKey(),
  98. String.format("Could not define permission, as plugin doesn't have the required '%s' permission", Permissions.DEFINE_PLUGIN_PERMISSION));
  99. }
  100. }
  101. // todo: support i18n
  102. private PermissionInfo getPermissionInfo()
  103. {
  104. return new DefaultPermissionInfo(getName(), getDescription());
  105. }
  106. private Set<InstallationMode> getInstallationModes(Element element)
  107. {
  108. final List<Element> elements = (List<Element>) element.elements("installation-mode");
  109. return copyOf(transform(filter(transform(elements,
  110. new Function<Element, Option<InstallationMode>>()
  111. {
  112. @Override
  113. public Option<InstallationMode> apply(Element e)
  114. {
  115. return InstallationMode.of(e.getText());
  116. }
  117. }),
  118. new Predicate<Option<InstallationMode>>()
  119. {
  120. @Override
  121. public boolean apply(Option<InstallationMode> mode)
  122. {
  123. return mode.isDefined();
  124. }
  125. }),
  126. new Function<Option<InstallationMode>, InstallationMode>()
  127. {
  128. @Override
  129. public InstallationMode apply(Option<InstallationMode> option)
  130. {
  131. return option.get();
  132. }
  133. }));
  134. }
  135. @Override
  136. public Permission getModule()
  137. {
  138. return permissionSupplier.get();
  139. }
  140. private static final class DefaultPermissionInfo implements PermissionInfo
  141. {
  142. private final String name;
  143. private final String description;
  144. private DefaultPermissionInfo(String name, String description)
  145. {
  146. this.name = name;
  147. this.description = description;
  148. }
  149. @Override
  150. public String getName()
  151. {
  152. return name;
  153. }
  154. @Override
  155. public String getDescription()
  156. {
  157. return description;
  158. }
  159. }
  160. private static class ForwardingPermission<P extends Permission> implements Permission
  161. {
  162. protected final P delegate;
  163. private final PermissionInfo permissionInfo;
  164. private ForwardingPermission(P delegate, PermissionInfo permissionInfo)
  165. {
  166. this.delegate = checkNotNull(delegate);
  167. this.permissionInfo = checkNotNull(permissionInfo);
  168. }
  169. @Override
  170. public String getKey()
  171. {
  172. return delegate.getKey();
  173. }
  174. @Override
  175. public PermissionInfo getPermissionInfo()
  176. {
  177. return permissionInfo;
  178. }
  179. @Override
  180. public Set<InstallationMode> getInstallationModes()
  181. {
  182. return delegate.getInstallationModes();
  183. }
  184. @Override
  185. public String getName()
  186. {
  187. return permissionInfo.getName();
  188. }
  189. @Override
  190. public String getDescription()
  191. {
  192. return permissionInfo.getDescription();
  193. }
  194. }
  195. private static final class ForwardingApiScope extends ForwardingPermission<ApiScope> implements ApiScope
  196. {
  197. private ForwardingApiScope(ApiScope delegate, PermissionInfo permissionInfo)
  198. {
  199. super(delegate, permissionInfo);
  200. }
  201. @Override
  202. public boolean allow(HttpServletRequest request, String user)
  203. {
  204. return delegate.allow(request, user);
  205. }
  206. @Override
  207. public Iterable<ApiResourceInfo> getApiResourceInfos()
  208. {
  209. return delegate.getApiResourceInfos();
  210. }
  211. }
  212. }