Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions acs-integration-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<parent>
<groupId>com.ge.predix</groupId>
<artifactId>acs</artifactId>
<version>4.8.3-SNAPSHOT</version>
<version>5.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

Expand Down Expand Up @@ -162,7 +162,7 @@
<dependency>
<groupId>com.ge.predix</groupId>
<artifactId>acs-service</artifactId>
<version>4.8.3-SNAPSHOT</version>
<version>5.0.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>io.netty</groupId>
Expand Down
2 changes: 1 addition & 1 deletion commons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<parent>
<groupId>com.ge.predix</groupId>
<artifactId>acs</artifactId>
<version>4.8.3-SNAPSHOT</version>
<version>5.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<parent>
<groupId>com.ge.predix</groupId>
<artifactId>acs</artifactId>
<version>4.8.3-SNAPSHOT</version>
<version>5.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<!-- Project information necessary to deploy to Maven Central (see: http://central.sonatype.org/pages/requirements.html) -->
<groupId>com.ge.predix</groupId>
<artifactId>acs</artifactId>
<version>4.8.3-SNAPSHOT</version>
<version>5.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Predix Access Control Services Parent</name>
<description>Service to enforce authentication and/or authorization of certain resources</description>
Expand Down
2 changes: 1 addition & 1 deletion service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<parent>
<groupId>com.ge.predix</groupId>
<artifactId>acs</artifactId>
<version>4.8.3-SNAPSHOT</version>
<version>5.0.0-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<artifactId>acs-service</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package com.ge.predix.acs.security;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
Expand All @@ -13,13 +16,17 @@

import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import com.google.common.net.HttpHeaders;

public abstract class AbstractHttpMethodsFilter extends OncePerRequestFilter {

private final Map<String, Set<HttpMethod>> uriPatternsAndAllowedHttpMethods;
private static final Set<MimeType> ACCEPTABLE_MIME_TYPES =
new HashSet<>(Arrays.asList(MimeTypeUtils.ALL, MimeTypeUtils.APPLICATION_JSON, MimeTypeUtils.TEXT_PLAIN));

public AbstractHttpMethodsFilter(final Map<String, Set<HttpMethod>> uriPatternsAndAllowedHttpMethods) {
this.uriPatternsAndAllowedHttpMethods = Collections.unmodifiableMap(uriPatternsAndAllowedHttpMethods);
Expand All @@ -31,16 +38,24 @@ private static void addCommonResponseHeaders(final HttpServletResponse response)
}
}

private static void sendMethodNotAllowedError(final HttpServletResponse response) throws IOException {
addCommonResponseHeaders(response);
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase());
}

private static void sendNotAcceptableError(final HttpServletResponse response) throws IOException {
addCommonResponseHeaders(response);
response.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE, HttpStatus.NOT_ACCEPTABLE.getReasonPhrase());
}

@Override
protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
final FilterChain filterChain) throws ServletException, IOException {

String requestMethod = request.getMethod();

if (HttpMethod.TRACE.matches(requestMethod)) {
addCommonResponseHeaders(response);
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED,
HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase());
sendMethodNotAllowedError(response);
return;
}

Expand All @@ -52,20 +67,31 @@ protected void doFilterInternal(final HttpServletRequest request, final HttpServ
.entrySet()) {
if (Pattern.compile(uriPatternsAndAllowedHttpMethodsEntry.getKey()).matcher(requestUri).matches()) {
if (!uriPatternsAndAllowedHttpMethodsEntry.getValue().contains(HttpMethod.resolve(requestMethod))) {
addCommonResponseHeaders(response);
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED,
HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase());
sendMethodNotAllowedError(response);
return;
}

String acceptHeaderValue = request.getHeader(HttpHeaders.ACCEPT);
Pattern validAcceptHeaderRegex = Pattern.compile("\\A(\\*/\\*)|(application/json)|(text/plain)\\Z");

if (acceptHeaderValue != null && !validAcceptHeaderRegex.matcher(acceptHeaderValue).matches()) {
addCommonResponseHeaders(response);
response.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE,
HttpStatus.NOT_ACCEPTABLE.getReasonPhrase());
return;
if (acceptHeaderValue != null) {
try {
List<MimeType> parsedMimeTypes = MimeTypeUtils.parseMimeTypes(acceptHeaderValue);
boolean foundAcceptableMimeType = false;
for (MimeType parsedMimeType : parsedMimeTypes) {
// When checking for acceptable MIME types, strip out the character set
if (ACCEPTABLE_MIME_TYPES.contains(
new MimeType(parsedMimeType.getType(), parsedMimeType.getSubtype()))) {
foundAcceptableMimeType = true;
break;
}
}
if (!foundAcceptableMimeType) {
sendNotAcceptableError(response);
return;
}
} catch (Exception e) {
sendNotAcceptableError(response);
return;
}
}

break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import java.net.URI;
import java.util.Collections;

import org.eclipse.jetty.http.MimeTypes;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
Expand Down Expand Up @@ -54,17 +56,28 @@ public void setup() {
MockMvcBuilders.standaloneSetup(this.dummyController).addFilters(new DummyHttpMethodsFilter()).build();
}

@Test
public void testWithNoAcceptHeaderInRequest() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.GET, URI.create(V1_DUMMY)))
.andExpect(MockMvcResultMatchers.status().isOk());
}

@Test(dataProvider = "mediaTypesAndExpectedStatuses")
public void testUnacceptableMediaTypes(final String mediaType, final ResultMatcher resultMatcher) throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.GET, URI.create(V1_DUMMY)).accept(mediaType))
.andExpect(resultMatcher);
this.mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.GET, URI.create(V1_DUMMY))
.header(HttpHeaders.ACCEPT, mediaType)).andExpect(resultMatcher);
}

@DataProvider
public Object[][] mediaTypesAndExpectedStatuses() {
return new Object[][] { new Object[] { MediaType.ALL_VALUE, MockMvcResultMatchers.status().isOk() },
{ MediaType.APPLICATION_JSON_VALUE, MockMvcResultMatchers.status().isOk() },
{ MimeTypes.Type.APPLICATION_JSON_UTF_8.toString(), MockMvcResultMatchers.status().isOk() },
{ MediaType.APPLICATION_JSON_VALUE + ", application/*+json", MockMvcResultMatchers.status().isOk() },
{ MediaType.TEXT_PLAIN_VALUE, MockMvcResultMatchers.status().isOk() },
{ MimeTypes.Type.TEXT_PLAIN_UTF_8.toString(), MockMvcResultMatchers.status().isOk() },
{ "text/*+plain, " + MediaType.TEXT_PLAIN_VALUE, MockMvcResultMatchers.status().isOk() },
{ "fake/type, " + MediaType.TEXT_PLAIN_VALUE, MockMvcResultMatchers.status().isOk() },
{ "fake/type", MockMvcResultMatchers.status().isNotAcceptable() } };
}
}