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