Skip to content

Commit

Permalink
Issue #LR-676 feat: added organisationId validation to ownership tran…
Browse files Browse the repository at this point in the history
…s… (#1247)
  • Loading branch information
BharathwajShankar authored Apr 30, 2024
1 parent e981b02 commit 9b9ba14
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
package org.sunbird.actor.user;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.sunbird.actor.core.BaseActor;
import org.sunbird.exception.ProjectCommonException;
import org.sunbird.exception.ResponseCode;
import org.sunbird.kafka.InstructionEventGenerator;
import org.sunbird.keys.JsonKey;
import org.sunbird.model.user.User;
import org.sunbird.request.Request;
import org.sunbird.request.RequestContext;
import org.sunbird.response.Response;
import org.sunbird.response.ResponseParams;
import org.sunbird.service.organisation.OrgService;
import org.sunbird.service.organisation.impl.OrgServiceImpl;
import org.sunbird.service.user.UserRoleService;
import org.sunbird.service.user.UserService;
import org.sunbird.service.user.impl.UserRoleServiceImpl;
import org.sunbird.service.user.impl.UserServiceImpl;
import org.sunbird.util.ProjectUtil;
import org.sunbird.util.PropertiesCache;
import org.sunbird.util.user.UserUtil;

import java.text.MessageFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;

Expand All @@ -27,17 +31,16 @@ public class UserOwnershipTransferActor extends BaseActor {

private final UserRoleService userRoleService = UserRoleServiceImpl.getInstance();
private final UserService userService = UserServiceImpl.getInstance();
private final OrgService orgService = OrgServiceImpl.getInstance();

@Override
public void onReceive(Request request) throws Throwable {
handleOwnershipTransfer(request);
}

private void handleOwnershipTransfer(Request request) {
validateUserDetails(request.getRequest(), request.getRequestContext());
String userId = (String) ((Map<String, Object>) request.getRequest().get(JsonKey.ACTION_BY))
.get(JsonKey.USER_ID);
validateActionByUserRole(userId, request);
validateOrganizationId(request.getRequest(), request.getRequestContext());
validateUserDetails(request, request.getRequestContext());
List<Map<String, Object>> objects = getObjectsFromRequest(request);
if (!objects.isEmpty()) {
objects.forEach(object -> sendInstructionEvent(request, object));
Expand All @@ -48,36 +51,54 @@ private void handleOwnershipTransfer(Request request) {
sender().tell(response, self());
}

private void validateUserDetails(Map<String, Object> data, RequestContext requestContext) {
validateAndProceed(data, JsonKey.ACTION_BY, requestContext);
validateAndProceed(data, JsonKey.FROM_USER, requestContext);
validateAndProceed(data, JsonKey.TO_USER, requestContext);
private void validateOrganizationId(Map<String, Object> requestData, RequestContext requestContext) {
if (!requestData.containsKey(JsonKey.ORGANISATION_ID) ||
StringUtils.isBlank((String) requestData.get(JsonKey.ORGANISATION_ID))) {
throwInvalidRequestDataException("Organization ID is mandatory in the request.");
}
String orgId = (String) requestData.get(JsonKey.ORGANISATION_ID);
if (!organisationExists(orgId, requestContext)) {
throwInvalidRequestDataException("Organization with ID " + orgId + " does not exist.");
}
}

private boolean organisationExists(String orgId, RequestContext context) {
try {
Map<String, Object> organisation = orgService.getOrgById(orgId, context);
return MapUtils.isNotEmpty(organisation);
} catch (Exception ex) {
return false;
}
}

private void validateUserDetails(Request request, RequestContext requestContext) {
validateAndProceed(request, JsonKey.ACTION_BY, requestContext);
validateAndProceed(request, JsonKey.FROM_USER, requestContext);
validateAndProceed(request, JsonKey.TO_USER, requestContext);
}

private void validateAndProceed(Map<String, Object> data, String key, RequestContext requestContext) {
if (data.containsKey(key)) {
validateUser(data.get(key), key, requestContext, data);
private void validateAndProceed(Request request, String key, RequestContext requestContext) {
if (request.getRequest().containsKey(key)) {
validateUser(request.getRequest().get(key), key, requestContext, request);
} else {
throwInvalidRequestDataException(key + " key is not present in the data.");
}
}

private void validateUser(Object userNode, String userLabel, RequestContext requestContext,
Map<String, Object> data) {
Request request) {
if (userNode instanceof Map) {
Map<String, Object> user = (Map<String, Object>) userNode;
String userId = StringUtils.trimToNull(Objects.toString(user.get(JsonKey.USER_ID), ""));
String userName = StringUtils.trimToNull(Objects.toString(user.get(JsonKey.USERNAME), ""));

if (StringUtils.isBlank(StringUtils.trimToNull(userId)) ||
StringUtils.isBlank(StringUtils.trimToNull(userName))) {
throwInvalidRequestDataException("User id / user name key is not present in the " + userLabel);
}

if (validUser(userId, requestContext)) {
validateAndFilterRoles(user, userLabel, data);
if (StringUtils.isBlank(StringUtils.trimToNull(userId)) || !userExists(userId, requestContext)) {
throwInvalidRequestDataException("given user id under " + userLabel + " is not present or blank");
} else {
throwClientErrorException();
if (userLabel.equals(JsonKey.ACTION_BY)) {
validateActionByUserRole(userId, request);
} else {
validateAndFilterRoles(user, userLabel, request.getRequest());
}
addUserInfo(userId, user, userLabel, requestContext);
}
}
}
Expand Down Expand Up @@ -130,12 +151,6 @@ private void throwInvalidRequestDataException(String message) {
ResponseCode.CLIENT_ERROR.getResponseCode());
}

private void throwClientErrorException() {
ProjectCommonException.throwClientErrorException(
ResponseCode.invalidParameter,
MessageFormat.format(ResponseCode.invalidParameter.getErrorMessage(), JsonKey.USER_ID));
}

private void throwDataTypeErrorException() {
throw new ProjectCommonException(
ResponseCode.dataTypeError,
Expand All @@ -144,14 +159,18 @@ private void throwDataTypeErrorException() {
ERROR_CODE);
}

private boolean validUser(String userId, RequestContext context) {
return StringUtils.isNotBlank(userId) && userExists(userId, context);
private void addUserInfo(String userId, Map<String, Object> userRequestData, String userLabel, RequestContext context) {
User user = userService.getUserById(userId, context);
userRequestData.put(JsonKey.USERNAME, UserUtil.getDecryptedData(user.getUserName(), context));
if (userLabel.equals(JsonKey.TO_USER)) {
userRequestData.put(JsonKey.FIRST_NAME, user.getFirstName());
userRequestData.put(JsonKey.LAST_NAME, user.getLastName());
}
}

private boolean userExists(String userId, RequestContext context) {
try {
userService.getUserById(userId, context);
return true;
return userService.getUserById(userId, context) != null;
} catch (Exception ex) {
return false;
}
Expand Down Expand Up @@ -223,4 +242,4 @@ Response sendResponse(String statusMessage) {
response.putAll(result);
return response;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
import akka.dispatch.Futures;
import akka.testkit.TestActorRef;
import akka.testkit.javadsl.TestKit;
import org.junit.Before;
Expand All @@ -20,6 +19,7 @@
import org.sunbird.exception.ResponseCode;
import org.sunbird.helper.ServiceFactory;
import org.sunbird.keys.JsonKey;
import org.sunbird.model.user.User;
import org.sunbird.operations.ActorOperations;
import org.sunbird.request.Request;
import org.sunbird.request.RequestContext;
Expand All @@ -28,9 +28,7 @@
import org.sunbird.service.user.UserService;
import org.sunbird.service.user.impl.UserRoleServiceImpl;
import org.sunbird.service.user.impl.UserServiceImpl;
import scala.concurrent.Promise;

import java.text.MessageFormat;
import java.time.Duration;
import java.util.*;

Expand Down Expand Up @@ -109,7 +107,7 @@ public void testInvalidUser() {
subject.tell(request, probe.getRef());
ProjectCommonException errorResponse = probe.expectMsgClass(Duration.ofSeconds(120), ProjectCommonException.class);
assertEquals("UOS_UOWNTRANS0028", errorResponse.getErrorCode());
assertEquals("User id / user name key is not present in the fromUser", errorResponse.getMessage());
assertEquals("given user id under fromUser is not present or blank", errorResponse.getMessage());
assertEquals(400, errorResponse.getErrorResponseCode());
}

Expand Down Expand Up @@ -207,8 +205,8 @@ public void testOwnershipTransferWithInvalidUserId() {
subject.tell(request, probe.getRef());
ProjectCommonException errorResponse = probe.expectMsgClass(Duration.ofSeconds(120),
ProjectCommonException.class);
assertEquals("UOS_UOWNTRANS0019", errorResponse.getErrorCode());
assertEquals("Please provide valid userId.", errorResponse.getMessage());
assertEquals("UOS_UOWNTRANS0028", errorResponse.getErrorCode());
assertEquals("given user id under fromUser is not present or blank", errorResponse.getMessage());
assertEquals(ResponseCode.CLIENT_ERROR.getResponseCode(), errorResponse.getErrorResponseCode());
}

Expand All @@ -225,7 +223,7 @@ public void testInvalidActorDetails() {
ProjectCommonException errorResponse = probe.expectMsgClass(Duration.ofSeconds(120),
ProjectCommonException.class);
assertEquals("UOS_UOWNTRANS0028", errorResponse.getErrorCode());
assertEquals("User id / user name key is not present in the actionBy",
assertEquals("given user id under actionBy is not present or blank",
errorResponse.getMessage());
assertEquals(ResponseCode.CLIENT_ERROR.getResponseCode(), errorResponse.getErrorResponseCode());
}
Expand All @@ -239,18 +237,14 @@ private void mockStaticDependencies() {
when(UserServiceImpl.getInstance()).thenReturn(userServiceMock);
when(UserRoleServiceImpl.getInstance()).thenReturn(userRoleServiceMock);
when(ServiceFactory.getInstance()).thenReturn(cassandraOperation);
Promise<Boolean> booleanPromise = Futures.promise();
booleanPromise.success(true);
when(cassandraOperation.updateRecord(Mockito.anyString(), Mockito.anyString(), Mockito.anyMap(), Mockito.any()))
.thenReturn(getSuccessResponse());
when(cassandraOperation.insertRecord(Mockito.anyString(), Mockito.anyString(), Mockito.anyMap(), Mockito.any()))
.thenReturn(getSuccessResponse());
PowerMockito.when(userServiceMock.getUserById(
Mockito.argThat("123"::equals), Mockito.any(RequestContext.class)))
.thenThrow(new ProjectCommonException(
ResponseCode.resourceNotFound,
MessageFormat.format(ResponseCode.resourceNotFound.getErrorMessage(), JsonKey.USER),
ResponseCode.RESOURCE_NOT_FOUND.getResponseCode()));
when(userServiceMock.getUserById(eq("c9e6006e-5811-4337-aa7c-48d0f535e3b8"), Mockito.any(RequestContext.class)))
.thenReturn(getValidUserResponse()); // Return valid user response for valid user ID
when(userServiceMock.getUserById(eq("1234"), Mockito.any(RequestContext.class)))
.thenReturn(getValidUserResponse());
Response response2 = new Response();
Map<String, Object> user = new HashMap<>();
user.put(JsonKey.ID, "c9e6006e-5811-4337-aa7c-48d0f535e3b8");
Expand Down Expand Up @@ -285,6 +279,15 @@ private List<Map<String, Object>> getInvalidRoleResponse() {
return userRolesList;
}

private User getValidUserResponse() {
User user = new User();
user.setId("c9e6006e-5811-4337-aa7c-48d0f535e3b8");
user.setIsDeleted(false);
user.setFirstName("Testuser");
user.setStatus(1);
return user;
}


private Request createTestRequest() {
Request request = new Request();
Expand Down

0 comments on commit 9b9ba14

Please sign in to comment.