Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #LR-676:feat added organisationId validation to ownership trans… #1247

Merged
merged 4 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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