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
28
29
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 }