View Javadoc

1   package com.atlassian.plugins.rest.common.sal.websudo;
2   
3   import static com.google.common.base.Preconditions.checkNotNull;
4   
5   import com.atlassian.sal.api.websudo.WebSudoNotRequired;
6   import com.atlassian.sal.api.websudo.WebSudoRequired;
7   import com.sun.jersey.api.model.AbstractMethod;
8   import com.sun.jersey.api.model.AbstractResource;
9   import com.sun.jersey.spi.container.ContainerRequest;
10  import com.sun.jersey.spi.container.ContainerRequestFilter;
11  import com.sun.jersey.spi.container.ContainerResponseFilter;
12  import com.sun.jersey.spi.container.ResourceFilter;
13  
14  import java.lang.reflect.Method;
15  
16  /**
17   * This is a Jersey resource filter that checks whether the resource requires or opts out of WebSudo protection.
18   * The check is based on annotations ({@link com.atlassian.sal.api.websudo.WebSudoRequired} and
19   * {@link com.atlassian.sal.api.websudo.WebSudoNotRequired}) that can be applied on the method, class and package level.
20   * <p/>
21   * Annotations on more specific elements override annotations applied to more general elements (in ascending order from specific to general):
22   * <ul>
23   * <li>Method level</li>
24   * <li>Class level</li>
25   * <li>Package level</li>
26   * </li>
27   */
28  final class WebSudoResourceFilter implements ResourceFilter, ContainerRequestFilter {
29      private final AbstractMethod abstractMethod;
30      private final WebSudoResourceContext webSudoResourceContext;
31  
32      public WebSudoResourceFilter(final AbstractMethod abstractMethod, final WebSudoResourceContext webSudoResourceContext) {
33          this.abstractMethod = checkNotNull(abstractMethod);
34          this.webSudoResourceContext = checkNotNull(webSudoResourceContext);
35      }
36  
37      public ContainerRequestFilter getRequestFilter() {
38          return this;
39      }
40  
41      public ContainerResponseFilter getResponseFilter() {
42          return null;
43      }
44  
45      public ContainerRequest filter(final ContainerRequest request) {
46          if (requiresWebSudo() && webSudoResourceContext.shouldEnforceWebSudoProtection()) {
47              throw new WebSudoRequiredException("This resource requires WebSudo.");
48          }
49          return request;
50      }
51  
52      private boolean requiresWebSudo() {
53          final Method m = abstractMethod.getMethod();
54          if (null != m && m.getAnnotation(WebSudoRequired.class) != null) {
55              return true;
56          }
57          if (null != m && m.getAnnotation(WebSudoNotRequired.class) != null) {
58              return false;
59          }
60  
61          final AbstractResource resource = abstractMethod.getResource();
62          if (resource.isAnnotationPresent(WebSudoRequired.class)) {
63              return true;
64          }
65          if (resource.isAnnotationPresent(WebSudoNotRequired.class)) {
66              return false;
67          }
68  
69          final Package p = abstractMethod.getResource().getResourceClass().getPackage();
70          if (p.getAnnotation(WebSudoRequired.class) != null) {
71              return true;
72          }
73          if (p.getAnnotation(WebSudoNotRequired.class) != null) {
74              return false;
75          }
76          return false;
77      }
78  }