Enhance RProxy authorization to use request method

Authorization filter now takes into account the
request method. The desired method can now be
added to the authorization file defaulting to
GET if not supplied. The request URI & method
can now be checked against the authorization
configuration along with the needed permissions.

Issue-ID: AAF-786

Change-Id: I25f6f2180ac9d94a30ca5ba1aa349fb424c18d81
Signed-off-by: IanB <IanB@amdocs.com>
diff --git a/sidecar/rproxy/config/auth/uri-authorization.json b/sidecar/rproxy/config/auth/uri-authorization.json
index 61ea9e6..208db1a 100644
--- a/sidecar/rproxy/config/auth/uri-authorization.json
+++ b/sidecar/rproxy/config/auth/uri-authorization.json
@@ -7,6 +7,14 @@
     },
     {
       "uri": "\/single\/permission\/required$",
+      "method": "GET",
+      "permissions": [
+        "test.single.access\\|single\\|permission"
+       ]
+    },    
+    {
+      "uri": "\/single\/permission\/required$",
+      "method": "PUT|POST",
       "permissions": [
         "test.single.access\\|single\\|permission"
        ]
@@ -92,6 +100,7 @@
     },
     {
       "uri": "\/aai\/v13\/cloud-infrastructure\/cloud-regions\/cloud-region\/[^\/]+[\/][^\/]+$*",
+      "method": "GET",
       "permissions": [
         "test.auth.access\\|clouds\\|read",
         "test.auth.access\\|tenants\\|read"
diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyAuthorizationFilter.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyAuthorizationFilter.java
index 2ef4cc0..5a09f6e 100644
--- a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyAuthorizationFilter.java
+++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/ReverseProxyAuthorizationFilter.java
@@ -98,13 +98,15 @@
         }
 
         String requestPath;
+        String requestMethod;
         try {
             requestPath = new URI(((HttpServletRequest) servletRequest).getRequestURI()).getPath();
+            requestMethod = ((HttpServletRequest)servletRequest).getMethod();
         } catch (URISyntaxException e) {
             throw new ServletException("Request URI not valid", e);
         }
 
-        if (authorizeRequest(grantedPermissions, requestPath)) {
+        if (authorizeRequest(grantedPermissions, requestPath, requestMethod)) {
             LOGGER.info("Authorized");
             filterChain.doFilter(servletRequest, servletResponse);
         } else {
@@ -121,12 +123,14 @@
      * 
      * @param grantedPermissions The granted permissions for the request path
      * @param requestPath The request path
+     * @param requestMethod The request method i.e. HTTP verb e.g. GET, PUT, POST etc
      * @return true if permissions match
      */
-    private boolean authorizeRequest(List<Permission> grantedPermissions, String requestPath) {
+    private boolean authorizeRequest(List<Permission> grantedPermissions, String requestPath, String requestMethod) {
         boolean authorized = false;
         for (ReverseProxyAuthorization reverseProxyAuthorization : reverseProxyAuthorizations) {
-            if (requestPath.matches(reverseProxyAuthorization.getUri())) {
+            if (requestPath.matches(reverseProxyAuthorization.getUri()) &&
+            	requestMethod.matches(reverseProxyAuthorization.getMethod())) {
                 LOGGER.debug("The URI:{}  matches:{}", requestPath, reverseProxyAuthorization.getUri());
                 if (checkPermissionsMatch(grantedPermissions, reverseProxyAuthorization)) {
                     authorized = true;
diff --git a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyAuthorization.java b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyAuthorization.java
index fd9db8e..994121c 100644
--- a/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyAuthorization.java
+++ b/sidecar/rproxy/src/main/java/org/onap/aaf/cadi/sidecar/rproxy/utils/ReverseProxyAuthorization.java
@@ -22,6 +22,7 @@
 public class ReverseProxyAuthorization {
 
     private String uri;
+    private String method;
     private String[] permissions;
 
     public String getUri() {
@@ -31,4 +32,8 @@
     public String[] getPermissions() {
         return permissions;
     }
+
+	public String getMethod() {
+		return method == null ? "GET" : method;
+	}
 }
diff --git a/sidecar/rproxy/src/test/java/org/onap/aaf/cadi/sidecar/rproxy/test/PermissionMatchingTest.java b/sidecar/rproxy/src/test/java/org/onap/aaf/cadi/sidecar/rproxy/test/PermissionMatchingTest.java
index e9dd95b..51f4ffc 100644
--- a/sidecar/rproxy/src/test/java/org/onap/aaf/cadi/sidecar/rproxy/test/PermissionMatchingTest.java
+++ b/sidecar/rproxy/src/test/java/org/onap/aaf/cadi/sidecar/rproxy/test/PermissionMatchingTest.java
@@ -29,6 +29,7 @@
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 
 import javax.annotation.Resource;
+
 import org.eclipse.jetty.util.security.Password;
 import org.junit.Before;
 import org.junit.Test;
@@ -141,6 +142,47 @@
 	}
 	
 	@Test
+	public void testURIPUTMatchSinglePermissionMatch() throws Exception {
+		
+        String transactionId = "63f88b50-6345-4a61-bc59-3a48cabb60a4";
+        String testUrl = "/single/permission/required";
+        String testResponse = "Response from MockRestService";
+
+        mockServer
+        	.expect(requestTo(primaryServiceBaseUrl + testUrl))
+        	.andExpect(method(HttpMethod.PUT))
+        	.andExpect(header(transactionIdHeaderName, transactionId))
+        	.andRespond(withSuccess(testResponse, MediaType.APPLICATION_JSON));
+        
+        // Send request to mock server with transaction Id
+        mockMvc
+        	.perform(MockMvcRequestBuilders.put(testUrl).accept(MediaType.APPLICATION_JSON).header(transactionIdHeaderName, transactionId))
+        	.andExpect(status().isOk())
+            .andExpect(content().string(equalTo(testResponse)));
+
+        mockServer.verify();        
+        
+	}
+	
+	
+	@Test
+	public void testURIPATCHMatchSinglePermissionMatch() throws Exception {
+		
+        String transactionId = "63f88b50-6345-4a61-bc59-3a48cabb60a4";
+        String testUrl = "/single/permission/required";
+        String testResponse = "Sorry, the request is not allowed";
+        
+        // Send request to mock server with transaction Id
+        mockMvc
+        	.perform(MockMvcRequestBuilders.patch(testUrl).accept(MediaType.APPLICATION_JSON).header(transactionIdHeaderName, transactionId))
+        	.andExpect(status().isForbidden())
+        	.andExpect(status().reason(testResponse));        
+
+        mockServer.verify();        
+        
+	}	
+	
+	@Test
 	public void testURIMatchMultiplePermissionMatch() throws Exception {
 		
         String transactionId = "63f88b50-6345-4a61-bc59-3a48cabb60a4";