diff --git a/provider/entitlements-v2-azure/src/main/java/org/opengroup/osdu/entitlements/v2/azure/filters/AppIdFilter.java b/provider/entitlements-v2-azure/src/main/java/org/opengroup/osdu/entitlements/v2/azure/filters/AppIdFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..ff0472e09b60b7435f24c07bc6ad47851eb08cc4 --- /dev/null +++ b/provider/entitlements-v2-azure/src/main/java/org/opengroup/osdu/entitlements/v2/azure/filters/AppIdFilter.java @@ -0,0 +1,31 @@ +package org.opengroup.osdu.entitlements.v2.azure.filters; + +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.stereotype.Component; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.io.IOException; + +/** + * This filter was created as an extension of + * {@link org.opengroup.osdu.azure.filters.Slf4jMDCFilter} + */ +@Component +@ConditionalOnProperty(value = "logging.mdccontext.enabled", havingValue = "true", matchIfMissing = true) +public class AppIdFilter implements Filter { + @Autowired + private DpsHeaders dpsHeaders; + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { + MDC.put(DpsHeaders.APP_ID, dpsHeaders.getAppId()); + filterChain.doFilter(servletRequest, servletResponse); + } +} diff --git a/provider/entitlements-v2-azure/src/test/java/org/opengroup/osdu/entitlements/v2/azure/filters/AppIdCustomDimentionTest.java b/provider/entitlements-v2-azure/src/test/java/org/opengroup/osdu/entitlements/v2/azure/filters/AppIdCustomDimentionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..13e5d05d8e1b2561bb8ac18daa1bc4ceffc9fdb6 --- /dev/null +++ b/provider/entitlements-v2-azure/src/test/java/org/opengroup/osdu/entitlements/v2/azure/filters/AppIdCustomDimentionTest.java @@ -0,0 +1,83 @@ +package org.opengroup.osdu.entitlements.v2.azure.filters; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentMatchers; +import org.mockito.Mockito; +import org.opengroup.osdu.core.common.logging.JaxRsDpsLog; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.opengroup.osdu.core.common.model.tenant.TenantInfo; +import org.opengroup.osdu.core.common.provider.interfaces.ITenantFactory; +import org.opengroup.osdu.entitlements.v2.api.AddMemberApi; +import org.opengroup.osdu.entitlements.v2.auth.AuthorizationService; +import org.opengroup.osdu.entitlements.v2.azure.AzureAppProperties; +import org.opengroup.osdu.entitlements.v2.azure.config.CacheConfig; +import org.opengroup.osdu.entitlements.v2.model.Role; +import org.opengroup.osdu.entitlements.v2.model.addmember.AddMemberDto; +import org.opengroup.osdu.entitlements.v2.service.AddMemberService; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import java.nio.charset.StandardCharsets; +import java.util.Collections; + +@RunWith(SpringRunner.class) +@WebMvcTest(controllers = AddMemberApi.class) +@ComponentScan({"org.opengroup.osdu.entitlements.v2"}) +public class AppIdCustomDimentionTest { + @Autowired + private MockMvc mockMvc; + @Autowired + private ObjectMapper objectMapper; + @MockBean + private AddMemberService service; + @MockBean + private JaxRsDpsLog logger; + @MockBean + private ITenantFactory tenantFactory; + @MockBean + private AuthorizationService authService; + @MockBean + private CacheConfig cacheConfig; + @MockBean + private AzureAppProperties azureAppProperties; + + @Test + public void shouldMatchExpectedHttpRequest() throws Exception { + final TenantInfo tenantInfo = new TenantInfo(); + tenantInfo.setDataPartitionId("common"); + tenantInfo.setServiceAccount("internal-service-account"); + Mockito.when(tenantFactory.listTenantInfo()).thenReturn(Collections.singletonList(tenantInfo)); + Mockito.when(tenantFactory.getTenantInfo("common")).thenReturn(tenantInfo); + Mockito.when(authService.isAuthorized(ArgumentMatchers.any(), ArgumentMatchers.any())).thenReturn(true); + Mockito.when(azureAppProperties.getDomain()).thenReturn("contoso.com"); + String appIdValue = "app-id-value"; + performRequest(appIdValue); + Assert.assertTrue(MDC.getCopyOfContextMap().entrySet().stream() + .anyMatch(entry -> DpsHeaders.APP_ID.equals(entry.getKey()) && appIdValue.equals(entry.getValue()))); + } + + private void performRequest(String appId) throws Exception { + AddMemberDto dto = new AddMemberDto("a@common.com", Role.OWNER); + String group = "service.viewers.users@common.contoso.com"; + mockMvc.perform(MockMvcRequestBuilders.post("/groups/{group_email}/members", group) + .contentType(MediaType.APPLICATION_JSON) + .characterEncoding(StandardCharsets.UTF_8.toString()) + .header(DpsHeaders.AUTHORIZATION, "Bearer token") + .header(DpsHeaders.DATA_PARTITION_ID, "common") + .header(DpsHeaders.USER_ID, "a@b.com") + .header(DpsHeaders.APP_ID, appId) + .content(objectMapper.writeValueAsString(dto))) + .andExpect(MockMvcResultMatchers.status().isOk()); + } +} diff --git a/provider/entitlements-v2-azure/src/test/java/org/opengroup/osdu/entitlements/v2/azure/filters/AppIdFilterTest.java b/provider/entitlements-v2-azure/src/test/java/org/opengroup/osdu/entitlements/v2/azure/filters/AppIdFilterTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5ac2756b769f3f48207dd9886a3b4ad3ea414842 --- /dev/null +++ b/provider/entitlements-v2-azure/src/test/java/org/opengroup/osdu/entitlements/v2/azure/filters/AppIdFilterTest.java @@ -0,0 +1,43 @@ +package org.opengroup.osdu.entitlements.v2.azure.filters; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.opengroup.osdu.core.common.model.http.DpsHeaders; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.slf4j.MDC; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import java.io.IOException; + +@RunWith(PowerMockRunner.class) +@PrepareForTest(MDC.class) +public class AppIdFilterTest { + + @InjectMocks + private AppIdFilter appIdFilter; + + @Mock + private DpsHeaders dpsHeaders; + + @Test + public void shouldPopulateAppIdSuccessfully() throws IOException, ServletException { + PowerMockito.mockStatic(MDC.class); + HttpServletRequest httpServletRequest = Mockito.mock(HttpServletRequest.class); + HttpServletResponse httpServletResponse = Mockito.mock(HttpServletResponse.class); + FilterChain filterChain = Mockito.mock(FilterChain.class); + Mockito.when(dpsHeaders.getAppId()).thenReturn("x-app-id-value"); + appIdFilter.doFilter(httpServletRequest, httpServletResponse, filterChain); + + PowerMockito.verifyStatic(MDC.class); + MDC.put("x-app-id", "x-app-id-value"); + } +}