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  {
34      private final PluginModuleTracker<CorsDefaults, CorsDefaultsModuleDescriptor> tracker;
35  
36      public CorsResourceFilterFactory(PluginAccessor pluginAccessor, PluginEventManager pluginEventManager)
37      {
38          tracker = new DefaultPluginModuleTracker<CorsDefaults, CorsDefaultsModuleDescriptor>(pluginAccessor, pluginEventManager, CorsDefaultsModuleDescriptor.class);
39      }
40  
41      public List<ResourceFilter> create(final AbstractMethod method)
42      {
43          if (annotationIsPresent(method, CorsAllowed.class))
44          {
45              String targetMethod = HttpMethod.GET;
46              for (Annotation ann : method.getAnnotations())
47              {
48                  HttpMethod m = ann.annotationType().getAnnotation(HttpMethod.class);
49                  if (m != null)
50                  {
51                      targetMethod = m.value();
52                      break;
53                  }
54              }
55  
56              ResourceFilter resourceFilter = new CorsResourceFilter(tracker, targetMethod);
57              return singletonList(resourceFilter);
58  
59          } else
60          {
61              return emptyList();
62          }
63      }
64  
65      private static boolean annotationIsPresent(AbstractMethod method, Class<? extends Annotation> annotationType)
66      {
67          return method.isAnnotationPresent(annotationType)
68                  || method.getResource().isAnnotationPresent(annotationType)
69                  || packageHasAnnotation(annotationType, method.getResource().getResourceClass().getPackage());
70      }
71  
72      private static boolean packageHasAnnotation(Class<? extends Annotation> annotationClass, Package resourcePackage)
73      {
74          return resourcePackage != null && resourcePackage.isAnnotationPresent(annotationClass);
75      }
76  
77      public void destroy()
78      {
79          tracker.close();
80      }
81  }