Skip to content

Instantly share code, notes, and snippets.

@sethrylan
Last active January 3, 2016 21:09
Show Gist options
  • Select an option

  • Save sethrylan/8519413 to your computer and use it in GitHub Desktop.

Select an option

Save sethrylan/8519413 to your computer and use it in GitHub Desktop.

Revisions

  1. sethrylan revised this gist Aug 7, 2014. 2 changed files with 0 additions and 2 deletions.
    1 change: 0 additions & 1 deletion Audited.java
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@
    package us.vistacore.leipr;

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    1 change: 0 additions & 1 deletion AuditedResourceMethodDispatchAdapter.java
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,3 @@
    package us.vistacore.leipr;

    import com.google.common.collect.ImmutableSet;
    import com.google.common.net.HttpHeaders;
  2. sethrylan created this gist Jan 20, 2014.
    14 changes: 14 additions & 0 deletions Audited.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,14 @@
    package us.vistacore.leipr;

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Audited {

    boolean requireRemoteIp() default true;

    }
    89 changes: 89 additions & 0 deletions AuditedResourceMethodDispatchAdapter.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,89 @@
    package us.vistacore.leipr;

    import com.google.common.collect.ImmutableSet;
    import com.google.common.net.HttpHeaders;
    import com.sun.jersey.api.core.HttpContext;
    import com.sun.jersey.api.core.HttpRequestContext;
    import com.sun.jersey.api.model.AbstractResourceMethod;
    import com.sun.jersey.spi.container.ResourceMethodDispatchAdapter;
    import com.sun.jersey.spi.container.ResourceMethodDispatchProvider;
    import com.sun.jersey.spi.dispatch.RequestDispatcher;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;

    import javax.ws.rs.ext.Provider;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;

    @Provider
    public class AuditedResourceMethodDispatchAdapter implements ResourceMethodDispatchAdapter {

    private final static Set<String> REDACTED_HEADERS = ImmutableSet.of(HttpHeaders.AUTHORIZATION);

    private static class AuditResourceMethodDispatchProvider implements ResourceMethodDispatchProvider {

    private final ResourceMethodDispatchProvider provider;

    private AuditResourceMethodDispatchProvider(ResourceMethodDispatchProvider provider) {
    this.provider = provider;
    }

    @Override
    public RequestDispatcher create(AbstractResourceMethod abstractResourceMethod) {
    final RequestDispatcher dispatcher = provider.create(abstractResourceMethod);
    final Audited audited = abstractResourceMethod.getAnnotation(Audited.class);

    if (audited != null) {
    return new AuditedRequestDispatcher(dispatcher, audited.requireRemoteIp());
    }
    return dispatcher;
    }
    }

    @Override
    public ResourceMethodDispatchProvider adapt(ResourceMethodDispatchProvider provider) {
    return new AuditResourceMethodDispatchProvider(provider);
    }

    private static class AuditedRequestDispatcher implements RequestDispatcher {

    private static Logger logger = LoggerFactory.getLogger(AuditedResourceMethodDispatchAdapter.class);

    private final RequestDispatcher dispatcher;
    private final boolean requireRemoteIPAddressInformation;

    private AuditedRequestDispatcher(RequestDispatcher dispatcher, boolean requireRemoteIPAddressInformation) {
    this.dispatcher = dispatcher;
    this.requireRemoteIPAddressInformation = requireRemoteIPAddressInformation;
    }

    @Override
    public void dispatch(Object resource, HttpContext context) {
    dispatcher.dispatch(resource, context);

    final HttpRequestContext request = context.getRequest();
    final StringBuilder builder = new StringBuilder();
    builder.append("\nPROTECTED RESOURCE ACCESS\n");
    builder.append(" Resource : " + resource.getClass() + "\n");

    if (requireRemoteIPAddressInformation && !request.getRequestHeaders().keySet().contains(HttpHeaders.X_FORWARDED_FOR)) {
    throw new RuntimeException("Header " + HttpHeaders.X_FORWARDED_FOR + " is required but was not found in the request");
    }

    for (Map.Entry<String, List<String>> entry : request.getRequestHeaders().entrySet()) {
    if (!REDACTED_HEADERS.contains(entry.getKey())) {
    builder.append(" Header : " + entry.getKey() + " = " + entry.getValue() + "\n");
    }
    }
    builder.append(" Method : " + request.getMethod() + "\n");
    builder.append(" URI : " + request.getRequestUri() + "\n");
    for (Map.Entry<String, List<String>> entry : request.getQueryParameters(true).entrySet()) {
    final String name = entry.getKey();
    final List<String> value = entry.getValue();
    builder.append(" Param : " + name + " = " + value + " \n");
    }
    logger.info(builder.toString());
    }
    }
    }
    1 change: 1 addition & 0 deletions in LeiprApplication.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    environment.jersey().register(new AuditedResourceMethodDispatchAdapter());
    11 changes: 11 additions & 0 deletions in VprResource.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    /**
    * Returns a list of site codes for available VistA sites.
    * @return JSON list of site codes strings
    */
    @GET
    @Audited
    @Path("sites")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSites() {
    return (new Gson()).toJson(this.rpcService.getSiteCodeList());
    }