View Javadoc

1   package com.atlassian.plugins.rest.common.security.jersey;
2   
3   import java.lang.annotation.Annotation;
4   import java.util.List;
5   
6   import javax.ws.rs.HttpMethod;
7   import javax.ws.rs.ext.Provider;
8   
9   import com.atlassian.plugin.PluginAccessor;
10  import com.atlassian.plugin.event.PluginEventManager;
11  import com.atlassian.plugin.tracker.DefaultPluginModuleTracker;
12  import com.atlassian.plugin.tracker.PluginModuleTracker;
13  import com.atlassian.plugins.rest.common.security.CorsAllowed;
14  import com.atlassian.plugins.rest.common.security.descriptor.CorsDefaults;
15  import com.atlassian.plugins.rest.common.security.descriptor.CorsDefaultsModuleDescriptor;
16  
17  import com.sun.jersey.api.model.AbstractMethod;
18  import com.sun.jersey.spi.container.ResourceFilter;
19  import com.sun.jersey.spi.container.ResourceFilterFactory;
20  
21  import org.springframework.beans.factory.DisposableBean;
22  
23  import static java.util.Collections.emptyList;
24  import static java.util.Collections.singletonList;
25  
26  /**
27   * Factory for the Cross-Origin Resource Sharing resource filter, triggering off {@link com.atlassian.plugins.rest.common.security.CorsAllowed}.
28   *
29   * @since 2.6
30   */
31  @Provider
32  public class CorsResourceFilterFactory implements ResourceFilterFactory, DisposableBean {
33      private final PluginModuleTracker<CorsDefaults, CorsDefaultsModuleDescriptor> tracker;
34  
35      public CorsResourceFilterFactory(PluginAccessor pluginAccessor, PluginEventManager pluginEventManager) {
36          tracker = new DefaultPluginModuleTracker<CorsDefaults, CorsDefaultsModuleDescriptor>(pluginAccessor, pluginEventManager, CorsDefaultsModuleDescriptor.class);
37      }
38  
39      public List<ResourceFilter> create(final AbstractMethod method) {
40          if (annotationIsPresent(method, CorsAllowed.class)) {
41              String targetMethod = HttpMethod.GET;
42              for (Annotation ann : method.getAnnotations()) {
43                  HttpMethod m = ann.annotationType().getAnnotation(HttpMethod.class);
44                  if (m != null) {
45                      targetMethod = m.value();
46                      break;
47                  }
48              }
49  
50              ResourceFilter resourceFilter = new CorsResourceFilter(tracker, targetMethod);
51              return singletonList(resourceFilter);
52  
53          } else {
54              return emptyList();
55          }
56      }
57  
58      private static boolean annotationIsPresent(AbstractMethod method, Class<? extends Annotation> annotationType) {
59          return method.isAnnotationPresent(annotationType)
60                  || method.getResource().isAnnotationPresent(annotationType)
61                  || packageHasAnnotation(annotationType, method.getResource().getResourceClass().getPackage());
62      }
63  
64      private static boolean packageHasAnnotation(Class<? extends Annotation> annotationClass, Package resourcePackage) {
65          return resourcePackage != null && resourcePackage.isAnnotationPresent(annotationClass);
66      }
67  
68      public void destroy() {
69          tracker.close();
70      }
71  }