diff options
author | Bogumil Zebek <bogumil.zebek@nokia.com> | 2020-06-16 08:36:09 +0200 |
---|---|---|
committer | krishna moorthy <krishna.moorthy6@wipro.com> | 2020-07-06 08:35:22 +0000 |
commit | 9a99a9484f673655d55c35c15ef0ee596299a117 (patch) | |
tree | 3ec71fc24ad09d959e218ea8d5907c774bcc4d32 | |
parent | b25b9d3b5e7d139b60776f1c7e9797023202033f (diff) |
Increase code coverage
Issue-ID: OPTFRA-776
Signed-off-by: Zebek Bogumil <bogumil.zebek@nokia.com>
Change-Id: I80b775420a91cf6fcc06369043fc13b5081b23f7
4 files changed, 315 insertions, 17 deletions
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java index 847836b..3b55a84 100755 --- a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java +++ b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafClientCache.java @@ -90,7 +90,7 @@ public class AafClientCache { if (!env.getProperty(AafProperties.aafEnabled.toString(), Boolean.class, true)) {
return AuthorizationResult.Authorized;
}
- Map<String, String> auth = getUserPasssword(requestContext);
+ Map<String, String> auth = getUserPassword(requestContext);
String permissions = getPermissions(auth);
if (permissions == null) {
return AuthorizationResult.AuthenticationFailure;
@@ -209,7 +209,7 @@ public class AafClientCache { return AuthorizationResult.AuthenticationFailure;
}
- private Map<String, String> getUserPasssword(ContainerRequestContext requestContext) {
+ private Map<String, String> getUserPassword(ContainerRequestContext requestContext) {
String header = requestContext.getHeaderString("Authorization");
Map<String, String> userPassword = getUserPasswordFromAuthorizationHeader(header);
diff --git a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java index a8d860d..f23dca0 100755 --- a/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java +++ b/cmso-service/src/main/java/org/onap/optf/cmso/aaf/AafContainerFilters.java @@ -1,6 +1,7 @@ /*
* Copyright (c) 2019 AT&T Intellectual Property.
* Modifications Copyright © 2018 IBM.
+ * Modifications Copyright © 2020 Nokia.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -53,30 +54,43 @@ import org.springframework.stereotype.Component; @Profile(SpringProfiles.AAF_AUTHENTICATION)
public class AafContainerFilters implements ContainerRequestFilter {
+ private static final String EMPTY_ENTITY_CONTENT = "";
+
@Autowired
- AafClientCache aafClientCache;
+ private AafClientCache aafClientCache;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
- ResponseBuilder builder = null;
- AuthorizationResult status = null;
- try {
- status = aafClientCache.authorize(requestContext);
- } catch (Exception e) {
- Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
- status = AuthorizationResult.AuthenticationFailure;
- }
- switch (status) {
+ AuthorizationResult authorizationStatus = getAuthorizationResult(requestContext);
+ switch (authorizationStatus) {
case AuthenticationFailure:
- builder = Response.status(Response.Status.UNAUTHORIZED).entity("");
- builder.header("WWW-Authenticate", "Basic realm=\"Realm\"");
- throw new WebApplicationException(builder.build());
+ throw new WebApplicationException(createAuthenticationErrorResponse());
case AuthorizationFailure:
- builder = Response.status(Response.Status.FORBIDDEN).entity("");
- throw new WebApplicationException(builder.build());
+ throw new WebApplicationException(createAuthorizationErrorResponse());
case Authorized:
case Authenticated:
default:
}
}
+
+ private AuthorizationResult getAuthorizationResult(ContainerRequestContext requestContext) {
+ AuthorizationResult status;
+ try {
+ status = aafClientCache.authorize(requestContext);
+ } catch (Exception e) {
+ Observation.report(LogMessages.UNEXPECTED_EXCEPTION, e, e.getMessage());
+ status = AuthorizationResult.AuthenticationFailure;
+ }
+ return status;
+ }
+
+ private Response createAuthenticationErrorResponse() {
+ ResponseBuilder builder = Response.status(Response.Status.UNAUTHORIZED).entity(EMPTY_ENTITY_CONTENT);
+ builder.header("WWW-Authenticate", "Basic realm=\"Realm\"");
+ return builder.build();
+ }
+
+ private Response createAuthorizationErrorResponse() {
+ return Response.status(Response.Status.FORBIDDEN).entity(EMPTY_ENTITY_CONTENT).build();
+ }
}
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 index 0000000..ef2e425 --- /dev/null +++ b/cmso-service/src/test/java/org/onap/optf/cmso/aaf/AafClientCacheTest.java @@ -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 index 0000000..95ad4aa --- /dev/null +++ b/cmso-service/src/test/java/org/onap/optf/cmso/aaf/AafContainerFiltersTest.java @@ -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!"); + } + } +} |