Increase code coverage 82/109182/4
authorBogumil Zebek <bogumil.zebek@nokia.com>
Tue, 16 Jun 2020 06:36:09 +0000 (08:36 +0200)
committerkrishna moorthy <krishna.moorthy6@wipro.com>
Mon, 6 Jul 2020 08:35:22 +0000 (08:35 +0000)
Issue-ID: OPTFRA-776
Signed-off-by: Zebek Bogumil <bogumil.zebek@nokia.com>
Change-Id: I80b775420a91cf6fcc06369043fc13b5081b23f7

cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java
cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java
cmso-service/src/test/java/org/onap/optf/cmso/aaf/AafClientCacheTest.java [new file with mode: 0644]
cmso-service/src/test/java/org/onap/optf/cmso/aaf/AafContainerFiltersTest.java [new file with mode: 0644]

index 847836b..3b55a84 100755 (executable)
@@ -90,7 +90,7 @@ public class AafClientCache {
         if (!env.getProperty(AafProperties.aafEnabled.toString(), Boolean.class, true)) {\r
             return AuthorizationResult.Authorized;\r
         }\r
-        Map<String, String> auth = getUserPasssword(requestContext);\r
+        Map<String, String> auth = getUserPassword(requestContext);\r
         String permissions = getPermissions(auth);\r
         if (permissions == null) {\r
             return AuthorizationResult.AuthenticationFailure;\r
@@ -209,7 +209,7 @@ public class AafClientCache {
         return AuthorizationResult.AuthenticationFailure;\r
     }\r
 \r
-    private Map<String, String> getUserPasssword(ContainerRequestContext requestContext) {\r
+    private Map<String, String> getUserPassword(ContainerRequestContext requestContext) {\r
 \r
         String header = requestContext.getHeaderString("Authorization");\r
         Map<String, String> userPassword = getUserPasswordFromAuthorizationHeader(header);\r
index a8d860d..f23dca0 100755 (executable)
@@ -1,6 +1,7 @@
 /*\r
  * Copyright (c) 2019 AT&T Intellectual Property.\r
  * Modifications Copyright © 2018 IBM.\r
+ * Modifications Copyright © 2020 Nokia.\r
  *\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
@@ -53,30 +54,43 @@ import org.springframework.stereotype.Component;
 @Profile(SpringProfiles.AAF_AUTHENTICATION)\r
 public class AafContainerFilters implements ContainerRequestFilter {\r
 \r
+    private static final String EMPTY_ENTITY_CONTENT = "";\r
+\r
     @Autowired\r
-    AafClientCache aafClientCache;\r
+    private AafClientCache aafClientCache;\r
 \r
     @Override\r
     public void filter(ContainerRequestContext requestContext) throws IOException {\r
-        ResponseBuilder builder = null;\r
-        AuthorizationResult status = null;\r
-        try {\r
-            status = aafClientCache.authorize(requestContext);\r
-        } catch (Exception e) {\r
-            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
-            status = AuthorizationResult.AuthenticationFailure;\r
-        }\r
-        switch (status) {\r
+        AuthorizationResult authorizationStatus = getAuthorizationResult(requestContext);\r
+        switch (authorizationStatus) {\r
             case AuthenticationFailure:\r
-                builder = Response.status(Response.Status.UNAUTHORIZED).entity("");\r
-                builder.header("WWW-Authenticate", "Basic realm=\"Realm\"");\r
-                throw new WebApplicationException(builder.build());\r
+                throw new WebApplicationException(createAuthenticationErrorResponse());\r
             case AuthorizationFailure:\r
-                builder = Response.status(Response.Status.FORBIDDEN).entity("");\r
-                throw new WebApplicationException(builder.build());\r
+                throw new WebApplicationException(createAuthorizationErrorResponse());\r
             case Authorized:\r
             case Authenticated:\r
             default:\r
         }\r
     }\r
+\r
+    private AuthorizationResult getAuthorizationResult(ContainerRequestContext requestContext) {\r
+        AuthorizationResult status;\r
+        try {\r
+            status = aafClientCache.authorize(requestContext);\r
+        } catch (Exception e) {\r
+            Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());\r
+            status = AuthorizationResult.AuthenticationFailure;\r
+        }\r
+        return status;\r
+    }\r
+\r
+    private Response createAuthenticationErrorResponse() {\r
+        ResponseBuilder builder = Response.status(Response.Status.UNAUTHORIZED).entity(EMPTY_ENTITY_CONTENT);\r
+        builder.header("WWW-Authenticate", "Basic realm=\"Realm\"");\r
+        return builder.build();\r
+    }\r
+\r
+    private Response createAuthorizationErrorResponse() {\r
+        return Response.status(Response.Status.FORBIDDEN).entity(EMPTY_ENTITY_CONTENT).build();\r
+    }\r
 }\r
diff --git a/cmso-service/src/test/java/org/onap/optf/cmso/aaf/AafClientCacheTest.java b/cmso-service/src/test/java/org/onap/optf/cmso/aaf/AafClientCacheTest.java
new file mode 100644 (file)
index 0000000..ef2e425
--- /dev/null
@@ -0,0 +1,169 @@
+package org.onap.optf.cmso.aaf;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.onap.optf.cmso.common.exceptions.CmsoException;
+import org.springframework.core.env.Environment;
+
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.UriInfo;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyMap;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AafClientCacheTest {
+
+    @Mock
+    Environment env;
+
+    @Mock
+    AafClient aafClient;
+
+    @Mock
+    AafUserRoleProperties aafUserRoleProperties;
+
+    @Mock
+    SecurityContext securityContext;
+
+    @Mock
+    ContainerRequestContext requestContext;
+
+    @Mock
+    UriInfo uriInfo;
+
+    @Mock
+    Response aafResponse;
+
+    @InjectMocks
+    AafClientCache aafClientCache;
+
+    @Test
+    public void shouldAuthorizeActorWhenAafIsDisabled() {
+        // given
+        when(env.getProperty(
+                eq(AafProperties.aafEnabled.toString()),
+                eq(Boolean.class),
+                eq(true))
+        ).thenReturn(false);
+
+        // when
+        final AafClientCache.AuthorizationResult result = aafClientCache.authorize(requestContext);
+
+        // then
+        assertThat(result).isEqualTo(AafClientCache.AuthorizationResult.Authorized);
+    }
+
+    @Test
+    public void shouldAuthorizeActorToResourceWhenActorHasProperPermissions() throws URISyntaxException, CmsoException, JsonProcessingException {
+        // given
+        when(env.getProperty(
+                eq(AafProperties.aafEnabled.toString()),
+                eq(Boolean.class),
+                eq(true))
+        ).thenReturn(true);
+
+        AafUserRole requiredRole = new AafUserRole("/context/someMethod","org\\.onap\\.osaaf\\.resources\\.access\\|rest\\|read");
+
+        // configure request context
+        setRequestContextWithAuthorizationHeader();
+
+        // configure aaf response
+        configureAafClientToReturnRequiredRole(requiredRole);
+
+        // define which role is required/expected for selected url and method
+        when(aafUserRoleProperties.getForUrlMethod(eq("/context"), eq("someMethod"))).thenReturn(List.of(requiredRole));
+
+        // when
+        final AafClientCache.AuthorizationResult result = aafClientCache.authorize(requestContext);
+
+        // then
+        assertThat(result).isEqualTo(AafClientCache.AuthorizationResult.Authorized);
+    }
+
+    @Test
+    public void shouldReportThatActorDoesNotHaveAccessToResourceWhenRolesDoNotMatch() throws URISyntaxException, CmsoException, JsonProcessingException {
+        // given
+        when(env.getProperty(
+                eq(AafProperties.aafEnabled.toString()),
+                eq(Boolean.class),
+                eq(true))
+        ).thenReturn(true);
+
+        AafUserRole requiredRole = new AafUserRole("/context/someMethod","org\\.onap\\.osaaf\\.resources\\.access\\|rest\\|read");
+        AafUserRole roleReturnedByAaf = new AafUserRole("/context/someMethod","org\\.onap\\.osaaf\\.resources\\.access\\|rest\\|write");
+
+        // configure request context
+        setRequestContextWithAuthorizationHeader();
+
+        // configure aaf response
+        configureAafClientToReturnRequiredRole(roleReturnedByAaf);
+
+        // define which role is required/expected for selected url and method
+        when(aafUserRoleProperties.getForUrlMethod(eq("/context"), eq("someMethod"))).thenReturn(List.of(requiredRole));
+
+        // when
+        final AafClientCache.AuthorizationResult result = aafClientCache.authorize(requestContext);
+
+        // then
+        assertThat(result).isEqualTo(AafClientCache.AuthorizationResult.AuthorizationFailure);
+    }
+
+    @Test
+    public void shouldReportThatActorDoesNotHaveAccessToResourceWhenUserAndPasswordWasNotSet() throws URISyntaxException {
+        // given
+        when(env.getProperty(
+                eq(AafProperties.aafEnabled.toString()),
+                eq(Boolean.class),
+                eq(true))
+        ).thenReturn(true);
+
+        setDefaultRequestContextConfiguration();
+
+        // when
+        final AafClientCache.AuthorizationResult result = aafClientCache.authorize(requestContext);
+
+        // then
+        assertThat(result).isEqualTo(AafClientCache.AuthorizationResult.AuthenticationFailure);
+    }
+
+    private void setRequestContextWithAuthorizationHeader() throws URISyntaxException {
+        when(requestContext.getHeaderString(eq("Authorization"))).thenReturn("Basic YWxhZGRpbjpvcGVuc2VzYW1l");
+        setDefaultRequestContextConfiguration();
+    }
+
+    private void setDefaultRequestContextConfiguration() throws URISyntaxException {
+        when(requestContext.getUriInfo()).thenReturn(uriInfo);
+        when(uriInfo.getAbsolutePath()).thenReturn(new URI("/context"));
+        when(requestContext.getMethod()).thenReturn("someMethod");
+        when(requestContext.getSecurityContext()).thenReturn(securityContext);
+    }
+
+    private void configureAafClientToReturnRequiredRole(AafUserRole requiredRole) throws JsonProcessingException, CmsoException {
+        when(aafResponse.getStatus()).thenReturn(Response.Status.OK.getStatusCode());
+        when(aafResponse.getStatusInfo()).thenReturn(Response.Status.OK);
+        when(aafResponse.readEntity(Mockito.eq(String.class))).thenReturn(givenAafResponse(requiredRole));
+
+        when(aafClient.getAuthz(anyMap())).thenReturn(aafResponse);
+    }
+
+    private String givenAafResponse(AafUserRole role) throws JsonProcessingException {
+        ObjectMapper om = new ObjectMapper();
+        final AafPermResponse aafPermResponse = new AafPermResponse();
+        aafPermResponse.setPerm(role.getAafPerms());
+        return om.writeValueAsString(aafPermResponse);
+    }
+}
diff --git a/cmso-service/src/test/java/org/onap/optf/cmso/aaf/AafContainerFiltersTest.java b/cmso-service/src/test/java/org/onap/optf/cmso/aaf/AafContainerFiltersTest.java
new file mode 100644 (file)
index 0000000..95ad4aa
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2020 Nokia.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ * Unless otherwise specified, all documentation contained herein is licensed
+ * under the Creative Commons License, Attribution 4.0 Intl. (the "License");
+ * you may not use this documentation except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         https://creativecommons.org/licenses/by/4.0/
+ *
+ * Unless required by applicable law or agreed to in writing, documentation
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onap.optf.cmso.aaf;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.container.ContainerRequestContext;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.assertj.core.api.Assertions.fail;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AafContainerFiltersTest {
+
+    @Mock
+    AafClientCache aafClientCache;
+
+    @Mock
+    ContainerRequestContext requestContext;
+
+    @InjectMocks
+    AafContainerFilters aafContainerFilters;
+
+    @Test
+    public void shouldReportUnauthorizedErrorWhenErrorOccursDuringFetchingDataFromAafCache() {
+
+        // given
+        Mockito.doThrow(new IllegalArgumentException("For JUnit only!"))
+                .when(aafClientCache)
+                .authorize(Mockito.any());
+
+        // when/then
+        assertThatThrownBy(() -> aafContainerFilters.filter(requestContext))
+                .isInstanceOf(WebApplicationException.class)
+                .hasMessage("HTTP 401 Unauthorized");
+    }
+
+
+    @Test
+    public void shouldReportAuthorizationErrorWhenAccessToResourceIsForbidden() {
+
+        // given
+        Mockito.when(aafClientCache.authorize(Mockito.any()))
+                .thenReturn(AafClientCache.AuthorizationResult.AuthorizationFailure);
+
+        // when/then
+        assertThatThrownBy(() -> aafContainerFilters.filter(requestContext))
+                .isInstanceOf(WebApplicationException.class)
+                .hasMessage("HTTP 403 Forbidden");
+    }
+
+    @Test
+    public void shouldAcceptRequestWhenActorWasAuthenticated() {
+
+        // given
+        Mockito.when(aafClientCache.authorize(Mockito.any()))
+                .thenReturn(AafClientCache.AuthorizationResult.Authenticated);
+
+        // when/then
+        try {
+            aafContainerFilters.filter(requestContext);
+        } catch (Exception e) {
+            fail("Operation should pass!");
+        }
+    }
+
+    @Test
+    public void shouldAcceptRequestWhenActorWasAuthorized() {
+
+        // given
+        Mockito.when(aafClientCache.authorize(Mockito.any()))
+                .thenReturn(AafClientCache.AuthorizationResult.Authorized);
+
+        // when/then
+        try {
+            aafContainerFilters.filter(requestContext);
+        } catch (Exception e) {
+            fail("Operation should pass!");
+        }
+    }
+}