Skip to content
Snippets Groups Projects
Commit 29e1d6f8 authored by Alok Joshi's avatar Alok Joshi
Browse files

add caching for Entitlements

parent 8357eea8
No related branches found
No related tags found
2 merge requests!211Updated topics.json - Replace common with osdu as common data partition is not a concept in OSDU.,!159Add cache for Entitlements getGroups() call
Pipeline #90711 failed
package org.opengroup.osdu.register.di;
import org.opengroup.osdu.core.common.cache.VmCache;
import org.opengroup.osdu.core.common.model.entitlements.AuthorizationResponse;
import org.opengroup.osdu.register.utils.MathUtil;
import org.springframework.stereotype.Component;
@Component
public class GroupVmCache extends VmCache<String, AuthorizationResponse> {
public GroupVmCache() {
super(MathUtil.generateRandomNumberBetweenBounds(30, 60), 1000);
}
}
......@@ -21,6 +21,8 @@ import org.opengroup.osdu.core.common.model.entitlements.AuthorizationResponse;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.provider.interfaces.IAuthorizationService;
import org.opengroup.osdu.core.common.util.Crc32c;
import org.opengroup.osdu.register.di.GroupVmCache;
import org.opengroup.osdu.register.utils.ServiceRequestInfo;
import org.opengroup.osdu.register.utils.ServiceRole;
import org.springframework.beans.factory.annotation.Autowired;
......@@ -42,6 +44,8 @@ public class AuthorizationFilter {
private HttpServletRequest request;
@Autowired
private ServiceRequestInfo requestInfo;
@Autowired
private GroupVmCache groupVmCache;
public boolean hasAnyPermission(String... requiredRoles) {
String path = request.getServletPath();
......@@ -77,7 +81,25 @@ public class AuthorizationFilter {
}
}
/*
Check cache first, fall back to authorization service call otherwise
*/
private AuthorizationResponse checkApiAccess(String[] requiredRoles, DpsHeaders dpsHeaders) {
return authorizationService.authorizeAny(dpsHeaders, requiredRoles);
String cacheKey = getGroupCacheKey(dpsHeaders);
AuthorizationResponse authorizationResponse = groupVmCache.get(cacheKey);
if(authorizationResponse != null && authorizationResponse.getGroups() != null)
return authorizationResponse;
else {
authorizationResponse = authorizationService.authorizeAny(dpsHeaders, requiredRoles);
groupVmCache.put(cacheKey, authorizationResponse);
return authorizationResponse;
}
}
private String getGroupCacheKey(DpsHeaders dpsHeaders) {
String key = String.format("register-entitlement-groups:%s:%s", dpsHeaders.getPartitionIdWithFallbackToAccountId(),
dpsHeaders.getAuthorization());
return Crc32c.hashToBase64EncodedString(key);
}
}
package org.opengroup.osdu.register.utils;
import java.util.Random;
public class MathUtil {
/*
Returns a random number between lower(inclusive) and upper(exclusive)
*/
public static int generateRandomNumberBetweenBounds(int lower, int upper) {
Random random = new Random();
return random.nextInt(upper - lower) + lower;
}
}
......@@ -22,15 +22,21 @@ import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.opengroup.osdu.core.common.model.entitlements.AuthorizationResponse;
import org.opengroup.osdu.core.common.model.entitlements.GroupInfo;
import org.opengroup.osdu.core.common.model.entitlements.Groups;
import org.opengroup.osdu.core.common.model.http.AppException;
import org.opengroup.osdu.core.common.model.http.DpsHeaders;
import org.opengroup.osdu.core.common.provider.interfaces.IAuthorizationService;
import org.opengroup.osdu.register.di.GroupVmCache;
import org.opengroup.osdu.register.utils.ServiceRequestInfo;
import org.opengroup.osdu.register.utils.ServiceRole;
import org.powermock.modules.junit4.PowerMockRunner;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
......@@ -53,6 +59,8 @@ public class AuthorizationFilterTest {
private IAuthorizationService authorizationService;
@Mock
private ServiceRequestInfo requestInfo;
@Mock
private GroupVmCache groupVmCache;
@InjectMocks
private AuthorizationFilter sut;
......@@ -61,10 +69,12 @@ public class AuthorizationFilterTest {
when(headers.getAuthorization()).thenReturn("Bearer 123456");
}
private final String USER_EMAIL = "test@slb.com";
@Test
public void should_authenticateRequest_when_resourceIsRolesAllowedAnnotated() {
final String USER_EMAIL = "test@slb.com";
AuthorizationResponse authorizationResponse = AuthorizationResponse.builder().user(USER_EMAIL).build();
when(this.groupVmCache.get("+CjZlg==")).thenReturn(null);
when(this.authorizationService.authorizeAny(any(), eq(ROLE1), eq(ROLE2))).thenReturn(authorizationResponse);
assertTrue(this.sut.hasAnyPermission(ROLE1, ROLE2));
......@@ -74,7 +84,6 @@ public class AuthorizationFilterTest {
@Test(expected = AppException.class)
public void should_throwAppError_when_noAuthzProvided() {
when(headers.getAuthorization()).thenReturn("");
final String USER_EMAIL = "test@slb.com";
this.sut.hasAnyPermission(ROLE1, ROLE2);
assertEquals(USER_EMAIL, this.headers.getUserEmail());
......@@ -95,4 +104,22 @@ public class AuthorizationFilterTest {
when(this.requestInfo.isCronRequest()).thenReturn(false);
this.sut.hasAnyPermission(ROLE3);
}
@Test
public void should_authenticateRequest_when_groupsAreAvailableInCache() {
Groups groups = new Groups();
List<GroupInfo> groupInfos = new ArrayList<>();
GroupInfo groupInfo = new GroupInfo();
groupInfo.setEmail("groupInfoEmail");
groupInfo.setDescription("description");
groupInfo.setName("role1");
groupInfos.add(groupInfo);
groups.setGroups(groupInfos);
groups.setDesId("desid");
groups.setMemberEmail("memberEmail");
AuthorizationResponse authorizationResponse = AuthorizationResponse.builder().groups(groups).user(USER_EMAIL).build();
when(this.groupVmCache.get("+CjZlg==")).thenReturn(authorizationResponse);
assertTrue(this.sut.hasAnyPermission(ROLE1, ROLE2));
verify(headers).put(DpsHeaders.USER_EMAIL, USER_EMAIL);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment