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

CO-668 implemmenting delete user/:userId endpoint #318

Merged
merged 11 commits into from
Nov 17, 2023
6 changes: 6 additions & 0 deletions src/routes/programRoutes.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const programService = require('../service/programService');
const userProgramPreference = require('../service/userProgramPreference');
const formConfig = require('../service/formConfig');
const userService = require('../service/userService');

const requestMiddleware = require('../middlewares/request.middleware')

const BASE_URL = '/program/v1'
Expand Down Expand Up @@ -133,4 +135,8 @@ module.exports = function (app) {
app.route(BASE_URL + '/form/read')
.post(requestMiddleware.gzipCompression(), requestMiddleware.createAndValidateRequestBody,
formConfig.getForm)

app.route(BASE_URL + '/user/:userId')
.delete(requestMiddleware.createAndValidateRequestBody,
userService.deleteUser)
}
12 changes: 12 additions & 0 deletions src/service/messageUtil.js
Original file line number Diff line number Diff line change
Expand Up @@ -1011,3 +1011,15 @@ exports.PROGRAM_FEED = {
INFO: 'Search For Program Feed Updates'
}
}

exports.USER = {
DELETE: {
FAILED_CODE: "ERR_DELETING_USER_FAILED",
MISSING_CODE: 'ERR_DELETING_USER_MISSING',
MISSING_MESSAGE: "User id is not passed in the request",
FAILED_MESSAGE: 'Unable to delete given user',
EXCEPTION_CODE: 'USER_DEL',
INFO: 'Delete User'
}
}

3 changes: 1 addition & 2 deletions src/service/programService.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ const cacheManager = new SbCacheManager({ttl: envVariables.CACHE_TTL});
const cacheManager_programReport = new SbCacheManager({ttl: 86400});
const registryService = new RegistryService()
const hierarchyService = new HierarchyService()
const UserService = require('./userService');
const userService = new UserService();
const userService = require('./userService');

function getProgram(req, response) {
const logObject = {
Expand Down
281 changes: 278 additions & 3 deletions src/service/userService.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
const envVariables = require('../envVariables')
const uuid = require("uuid/v1")

const learnerService = envVariables['LEARNER_SERVICE_URL']
const axios = require('axios');
const _ = require("lodash");
const { successResponse, errorResponse, loggerError } = require('../helpers/responseUtil');
const KafkaService = require('../helpers/kafkaUtil')
const { of } = require("rxjs");
const RegistryService = require('./registryService')
const registryService = new RegistryService()
const loggerService = require('./loggerService');
const messageUtils = require('./messageUtil');
const responseCode = messageUtils.RESPONSE_CODE;
const userMessages = messageUtils.USER;
var async = require('async');
const { response } = require('express');
let mappedOrgs = [];
let logObject = {};

class UserService {
async getDikshaUserProfiles(req, identifier) {
async function getDikshaUserProfiles(req, identifier) {
const option = {
url: learnerService + '/user/v3/search',
method: 'post',
Expand All @@ -19,7 +34,267 @@ class UserService {
}
};
return axios(option);
}

function getOsRequestBody(action, osRequest) {
return regReq = {
body: {
id: "open-saber.registry." + action,
request: osRequest
}
}
}

function searchRegistry(entity, filter, callback) {
let request = {
entityType: entity,
filters: {
filter
}
}
let regReq = getOsRequestBody('search', request)

return registryService.searchRecord(regReq, callback);
}

function searchOsUserWithUserId(userId, callback) {
let filter= {
userId: {
eq: userId
}
}
return searchRegistry(["User"], filter, callback);
}

function deleteOsUser (userOsId, callback) {
let request = {
User: {
osid: userOsId,
firstName: "Deleted User",
lastName: (userDetails.lastName) ? "Deleted USer": '',
isDeleted: true
}
}
let regReq = getOsRequestBody('update', request)

return registryService.updateRecord(regReq, callback);
}

function getuserOrgList(userId) {
let filter = {
userId: {
eq: userId
}
}
return searchRegistry(["User_Org"], filter, callback);
}

function searchAdminOfOrg (orgOsId, callback) {
let filter = {
orgId: {
eq: orgOsId
},
roles: {'contains': 'admin'}
}
return searchRegistry(["User_Org"], filter, callback);
}

module.exports = UserService;
function searchOSUserWithOsId (userOsId, callback) {
let filter = {
osid: {
eq: userOsId
}
}
return searchRegistry(["User"], filter, callback);
}

function getUserRole(req, response, userDetails) {
if (userDetails.roles.includes('individual')) {
return 'individual';
} else {
getuserOrgList(userDetails.osid, (userOrgError, userOrgRes) => {
if (userOrgRes && userOrgRes.status == 200 && userOrgRes.data.result.User_Org.length > 0) {
mappedOrgs = userOrgRes.data.result.User_Org;
let userRoles = _.map(userOrgRes.data.result.User_Org, 'role');
const osroles = ['user', 'admin', 'sourcing_admin', 'sourcing_reviewer']

_.forEach(osroles, (roleName) => {
if (userRoles.includes(roleName)) {
return roleName;
}
})
// if contributing org user
/*if (userRoles.includes('user')) {
return 'user';
} else if (userRoles.includes('admin')) {
return 'admin';
}
else if (userRoles.includes('sourcing_admin')) {
return 'sourcing_admin';
}
else if (userRoles.includes('sourcing_reviewer')) {
return 'sourcing_reviewer';
}*/
} else {
handleUserDeleteError(req, response, userOrgError);
}
});
}
}

function onIndividualUserDeletion (req, response, userDetails) {
const eventData = generateDeleteUserEvent (req, response, userDetails, {});
KafkaService.sendRecord(eventData, function (err, res) {
if (err) {
handleUserDeleteError(req, response, error);
} else {
handleUserDeleteSuccess(req, response, 'User deleted Successfully ${req.params.userId}');
}
});
}
function onOrgUserDeletion(req, response, userDetails) {
const orgId = _.get(_.find(mappedOrgs, { role: 'user', userId: userDetails.osid }), 'orgId');

// find admin of the org to transfer ownership of contents
searchAdminOfOrg(orgId, (error, res) => {
if (res && res.status == 200) {
if (res.data.result.User_Org.length > 0) {
var adminUserOrgDetails = res.data.result.User_Org[0];
if (adminUserOrgDetails.userId) {
searchOSUserWithOsId(adminUserOrgDetails.userId, (adminErr, adminRes) => {
if (adminRes && adminRes.status == 200 && adminRes.data.result.User.length > 0) {
var adminDetails = adminRes.data.result.User[0];
const eventData = generateDeleteUserEvent (req, response, userDetails, {role: 'admin', users: [adminDetails.userId]});
KafkaService.sendRecord(eventData, function (err, res) {
if (err) {
handleUserDeleteError(req, response, error);
} else {
handleUserDeleteSuccess(req, response, 'User deleted Successfully ${req.params.userId}');
}
});
} else {
handleUserDeleteError(req, response, adminErr)
}
});
}
} else {
handleUserDeleteError(req, response, "Admin for the org not found");
}
} else {
handleUserDeleteError(req, response, error);
}
});
}
function handleUserDeleteSuccess(req, response, result){
var rspObj = req.rspObj
rspObj.responseCode = 'OK'
rspObj.result = result
loggerService.exitLog({responseCode: rspObj.responseCode}, logObject);
return response.status(200).send(successResponse(rspObj));
}

function handleUserDeleteError (req, response, error) {
var rspObj = req.rspObj
console.log('User deletion failed', JSON.stringify(error))
if(error.response && error.response.data) {
console.log(`User delete error ==> ${req.params.userId} ==>`, JSON.stringify(error.response.data));
}
const errCode = userMessages.DELETE.EXCEPTION_CODE;
rspObj.errCode = userMessages.DELETE.FAILED_CODE;
rspObj.errMsg = userMessages.DELETE.FAILED_MESSAGE
rspObj.responseCode = responseCode.SERVER_ERROR
rspObj.result = error;
loggerError(rspObj, errCode);
loggerService.exitLog({responseCode: rspObj.responseCode}, logObject);
return response.status(500).send(errorResponse(rspObj, errCode));
}

function generateDeleteUserEvent(req, response, userDetails, replacementUsers) {
var ets = Date.now();
var dataObj = {
'eid': 'BE_JOB_REQUEST',
'ets': ets,
'mid': `LP.${ets}.${uuid()}`,
'actor': {
'id': 'delete-user',
'type': 'System'
},
'context': {
'pdata': {
'ver': '1.0',
'id': 'org.sunbird.platform'
},
'channel': userDetails.channel,
'env': envVariables.PUBLISH_ENV
},
'object': {
'type': 'User',
'id': userDetails.userId
},
'edata': {
'action': 'delete-user',
'iteration': 1,
'organisationId': '',
'userId': userDetails.userId,
'suggested_users' : replacementUsers
}
}

return dataObj;
}

function deleteUser(req, response) {
logObject['message'] = userMessages.DELETE.INFO
logObject['traceId'] = req.headers['x-request-id'] || '',
loggerService.entryLog(req.body, logObject);
var rspObj = req.rspObj
if (req.params.userId) {
console.log(req.params.userId);
searchOsUserWithUserId(req.params.userId, (err, res) => {
if (res && res.status == 200) {
if (res.data.result.User.length > 0) {
var userDetails = res.data.result.User[0];
if (userDetails.osid) {
deleteOsUser(userDetails.osid, (mapErr, mapRes) => {
if (mapRes && mapRes.status == 200 && _.get(mapRes.data, 'params.status' == "SUCCESSFULL")) {
const userRole = getUserRole(req, response, userDetails);
switch(userRole) {
case 'individual' :
onIndividualUserDeletion (req, response, userDetails)
break;
case 'user':
onOrgUserDeletion(req, response, userDetails)
break;
case 'admin':
break;
case 'sourcing_admin':
break;
case 'sourcing_reviewer':
break;
default:
break;
}
} else {
handleUserDeleteError(req, response, mapErr)
}
});
} else {
handleUserDeleteError(req, response, 'OpenSaber entry for given user is not found');
}
} else {
handleUserDeleteError(req, response, 'OpenSaber entry for given user is not found');
}
} else {
handleUserDeleteError(req, response, err)
}
});
} else {
rspObj.errCode = userMessages.DELETE.MISSING_CODE
rspObj.errMsg = userMessages.DELETE.MISSING_MESSAGE
rspObj.responseCode = responseCode.CLIENT_ERROR
loggerError(rspObj,errCode);
loggerService.exitLog({responseCode: rspObj.responseCode}, logObject);
return response.status(400).send(errorResponse(rspObj,errCode))
}
}
module.exports = { getSunbirdUserProfiles, deleteUser };