1   package com.atlassian.plugins.rest.common.security.jersey;
2   
3   import com.atlassian.plugins.rest.common.security.AnonymousAllowed;
4   import com.atlassian.plugins.rest.common.security.AuthenticationContext;
5   import com.atlassian.plugins.rest.common.security.AuthenticationRequiredException;
6   import com.google.common.base.Preconditions;
7   import com.sun.jersey.api.model.AbstractMethod;
8   import com.sun.jersey.spi.container.ContainerRequest;
9   import com.sun.jersey.spi.container.ContainerRequestFilter;
10  import com.sun.jersey.spi.container.ContainerResponseFilter;
11  import com.sun.jersey.spi.container.ResourceFilter;
12  
13  /**
14   * <p>This is a Jersey resource filter that checks wether the current client is authenticated or not.
15   * If the client is not authenticated then an {@link AuthenticationRequiredException} is thrown.</p>
16   * <p>Resources can be marked as not needing authentication by using the {@link AnonymousAllowed} annotation.</p>
17   */
18  class AuthenticatedResourceFilter implements ResourceFilter, ContainerRequestFilter
19  {
20      private final AbstractMethod abstractMethod;
21      private final AuthenticationContext authenticationContext;
22  
23      public AuthenticatedResourceFilter(AbstractMethod abstractMethod, AuthenticationContext authenticationContext)
24      {
25          this.abstractMethod = Preconditions.checkNotNull(abstractMethod);
26          this.authenticationContext = Preconditions.checkNotNull(authenticationContext);
27      }
28  
29      public ContainerRequestFilter getRequestFilter()
30      {
31          return this;
32      }
33  
34      public ContainerResponseFilter getResponseFilter()
35      {
36          return null;
37      }
38  
39      public ContainerRequest filter(ContainerRequest request)
40      {
41          if (!isAnonymousAllowed() && !isClientAuthenticated())
42          {
43              throw new AuthenticationRequiredException();
44          }
45          return request;
46      }
47  
48      private boolean isAnonymousAllowed()
49      {
50          return (abstractMethod.getMethod() != null && abstractMethod.getMethod().getAnnotation(AnonymousAllowed.class) != null)
51                  || abstractMethod.getResource().getAnnotation(AnonymousAllowed.class) != null;
52      }
53  
54      private boolean isClientAuthenticated()
55      {
56          return authenticationContext.isAuthenticated();
57      }
58  }