1 package com.atlassian.plugins.rest.common.feature.jersey;
2
3 import com.atlassian.plugins.rest.common.feature.RequiresDarkFeature;
4 import com.atlassian.sal.api.features.DarkFeatureManager;
5 import com.sun.jersey.api.NotFoundException;
6 import com.sun.jersey.api.model.AbstractMethod;
7 import com.sun.jersey.spi.container.ContainerRequest;
8 import com.sun.jersey.spi.container.ContainerRequestFilter;
9 import com.sun.jersey.spi.container.ContainerResponseFilter;
10 import com.sun.jersey.spi.container.ResourceFilter;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13
14 import java.lang.reflect.AnnotatedElement;
15 import javax.annotation.Nonnull;
16
17 import static com.atlassian.plugins.rest.common.util.ReflectionUtils.getAnnotation;
18 import static com.google.common.base.Preconditions.checkNotNull;
19
20
21
22
23
24
25
26
27
28 public class DarkFeatureResourceFilter implements ResourceFilter, ContainerRequestFilter {
29 private static final Logger log = LoggerFactory.getLogger(DarkFeatureResourceFilter.class);
30
31 private final DarkFeatureManager darkFeatureManager;
32 private final AbstractMethod abstractMethod;
33
34 public DarkFeatureResourceFilter(@Nonnull final AbstractMethod method, @Nonnull final DarkFeatureManager darkFeatureManager) {
35 this.darkFeatureManager = checkNotNull(darkFeatureManager);
36 this.abstractMethod = checkNotNull(method);
37 }
38
39 @Override
40 public ContainerRequestFilter getRequestFilter() {
41 return this;
42 }
43
44 @Override
45 public ContainerResponseFilter getResponseFilter() {
46 return null;
47 }
48
49 @Override
50 public ContainerRequest filter(final ContainerRequest request) {
51 log.debug("Applying dark feature filter to request {} {}", request.getMethod(), request.getRequestUri());
52 if (accessIsAllowed(abstractMethod) && accessIsAllowed(abstractMethod.getResource())) {
53 log.debug("Dark feature check OK");
54 return request;
55 }
56 log.debug("Dark feature check failed. Refusing access to the resource.");
57
58 throw new NotFoundException(request.getRequestUri());
59 }
60
61 private boolean accessIsAllowed(AnnotatedElement e) {
62 if (e == null) {
63 return true;
64 }
65
66 final RequiresDarkFeature annotation = getAnnotation(RequiresDarkFeature.class, e);
67 return annotation == null || allFeaturesAreEnabled(annotation.value());
68 }
69
70 private boolean allFeaturesAreEnabled(String[] featureKeys) {
71 for (String featureKey : featureKeys) {
72 if (!darkFeatureManager.isFeatureEnabledForCurrentUser(featureKey)) {
73 return false;
74 }
75 }
76 return true;
77 }
78 }