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

Adding delete user #524

Closed
wants to merge 5 commits into from
Closed
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
14 changes: 14 additions & 0 deletions src/controller/org.controller/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ class OrgControllerError extends idrErr.IDRError {
return err
}

userDoesNotExist (username) { // org
const err = {}
err.error = 'USER_DOES_NOT_EXIST'
err.message = `The user '${username}' does not exist.`
return err
}

uuidProvided () { // org
const err = {}
err.error = 'UUID_PROVIDED'
Expand All @@ -56,6 +63,13 @@ class OrgControllerError extends idrErr.IDRError {
err.message = `The organization cannot be renamed as '${shortname}' because this shortname is used by another organization.`
return err
}

userToBeRemovedSameAsRequester (username) { // org
const err = {}
err.error = 'USER_TO_BE_REMOVED_SAME_AS_REQUESTER'
err.message = `The user '${username}' cannot be removed as it is the same user as the requester.`
return err
}
}

module.exports = {
Expand Down
10 changes: 9 additions & 1 deletion src/controller/org.controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const router = express.Router()
const mw = require('../../middleware/middleware')
const controller = require('./org.controller')
const { body, param, query } = require('express-validator')
const { parseGetParams, parsePostParams, parseError, isOrgRole, isUserRole } = require('./org.middleware')
const { parseGetParams, parseDeleteParams, parsePostParams, parseError, isOrgRole, isUserRole } = require('./org.middleware')
const CONSTANTS = require('../../../src/constants')

router.get('/org',
Expand Down Expand Up @@ -90,6 +90,14 @@ router.put('/org/:shortname/user/:username',
parseError,
parsePostParams,
controller.USER_UPDATE_SINGLE)
router.delete('/org/:shortname/user/:username',
mw.onlySecretariatOrAdmin,
mw.validateUser,
param(['shortname']).isString().trim().escape().notEmpty(),
param(['username']).isString().trim().escape().notEmpty(),
parseError,
parseDeleteParams,
controller.USER_DELETE_SINGLE)
router.put('/org/:shortname/user/:username/reset_secret',
mw.validateUser,
param(['shortname']).isString().trim().escape().notEmpty(),
Expand Down
85 changes: 62 additions & 23 deletions src/controller/org.controller/org.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,67 @@ const uuid = require('uuid')
const errors = require('./error')
const error = new errors.OrgControllerError()

// Delete user from org
async function deleteUser (req, res, next) {
try {
const requesterShortName = req.ctx.org
const requesterUsername = req.ctx.user
const username = req.ctx.params.username
const shortName = req.ctx.params.shortname
const orgRepo = req.ctx.repositories.getOrgRepository()
const userRepo = req.ctx.repositories.getUserRepository()
const orgUUID = await orgRepo.getOrgUUID(shortName)
const isSecretariat = await orgRepo.isSecretariat(shortName)
const isAdmin = await userRepo.isAdmin(requesterUsername, shortName)
const changesRequirePrivilegedRole = true

if (!orgUUID) {
logger.info({ uuid: req.ctx.uuid, message: 'The user could not be deleted because ' + shortName + ' organization does not exist.' })
return res.status(404).json(error.orgDneParam(shortName))
}

const user = await userRepo.findOneByUserNameAndOrgUUID(username, orgUUID)
if (!user) {
logger.info({ uuid: req.ctx.uuid, message: 'The user could not be deleted because ' + username + ' does not exist for ' + shortName + ' organization.' })
return res.status(404).json(error.userDne(username))
}

// check if the user is not the requester or if the requester is not a secretariat
if ((shortName !== requesterShortName || username !== requesterUsername) && !isSecretariat) {
// check if the requester is not an admin; if admin, the requester must be from the same org as the user
if (!isAdmin || (isAdmin && shortName !== requesterShortName)) {
logger.info({ uuid: req.ctx.uuid, message: 'The user can only be deleted by the Secretariat, or an Org admin.' })
return res.status(403).json(error.notSameUserOrSecretariat())
}
}

if (username === requesterUsername) {
logger.info({ uuid: req.ctx.uuid, message: 'The' })
return res.status(403).json(error.userToBeRemovedSameAsRequester(username))
}

// deleting user's is only allowed for secretariats and org admins
if (changesRequirePrivilegedRole && !(isAdmin || isSecretariat)) {
logger.info({ uuid: req.ctx.uuid, message: 'The user could not be deleted because ' + requesterUsername + ' user is not Org Admin or Secretariat.' })
return res.status(403).json(error.notOrgAdminOrSecretariat())
}

const result = await userRepo.deleteByUserNameAndOrgUUID(username, orgUUID)
if (result.n === 0) {
logger.info({ uuid: req.ctx.uuid, message: 'The user could not be deleted because ' + username + 'does not exist for ' + shortName + 'organization.' })
return res.status(404).json(error.userDne(username))
}

const responseMessage = {
message: result.username + ' was successfully deleted.'
}

return res.status(204).json(responseMessage)
} catch (err) {
next(err)
}
}

// Get the details of all orgs
async function getOrgs (req, res, next) {
try {
Expand Down Expand Up @@ -424,15 +485,11 @@ async function createUser (req, res, next) {
return res.status(400).json(error.userExists(newUser.username))
}

// Parsing all user name fields
newUser.name = parseUserName(newUser)

await userRepo.updateByUserNameAndOrgUUID(newUser.username, newUser.org_UUID, newUser, { upsert: true }) // Create user in MongoDB if it doesn't exist
const agt = setAggregateUserObj({ username: newUser.username, org_UUID: newUser.org_UUID })
result = await userRepo.aggregate(agt)
result = result.length > 0 ? result[0] : null

result.secret = randomKey
const responseMessage = {
message: result.username + ' was successfully created.',
created: result
Expand Down Expand Up @@ -709,25 +766,6 @@ function setAggregateUserObj (query) {
]
}

function parseUserName (newUser) {
if (newUser.name) {
if (!newUser.name.first) {
newUser.name.first = ''
}
if (!newUser.name.last) {
newUser.name.last = ''
}
if (!newUser.name.middle) {
newUser.name.middle = ''
}
if (!newUser.name.suffix) {
newUser.name.suffix = ''
}
}

return newUser.name
}

module.exports = {
ORG_ALL: getOrgs,
ORG_SINGLE: getOrg,
Expand All @@ -737,6 +775,7 @@ module.exports = {
ORG_ID_QUOTA: getOrgIdQuota,
USER_SINGLE: getUser,
USER_CREATE_SINGLE: createUser,
USER_DELETE_SINGLE: deleteUser,
USER_UPDATE_SINGLE: updateUser,
USER_RESET_SECRET: resetSecret
}
6 changes: 6 additions & 0 deletions src/controller/org.controller/org.middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ function parseGetParams (req, res, next) {
next()
}

function parseDeleteParams (req, res, next) {
utils.reqCtxMapping(req, 'params', ['shortname', 'username'])
next()
}

function parseError (req, res, next) {
const err = validationResult(req).formatWith(({ location, msg, param, value, nestedErrors }) => {
return { msg: msg, param: param, location: location }
Expand All @@ -55,6 +60,7 @@ function parseError (req, res, next) {
module.exports = {
parsePostParams,
parseGetParams,
parseDeleteParams,
parseError,
isOrgRole,
isUserRole
Expand Down
4 changes: 4 additions & 0 deletions src/repositories/userRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ class UserRepository extends BaseRepository {
super(User)
}

async deleteByUserNameAndOrgUUID (username, orgUUID) {
return this.collection.findOneAndRemove().byUserNameAndOrgUUID(username, orgUUID)
}

async getUserUUID (userName, orgUUID) {
return utils.getUserUUID(userName, orgUUID)
}
Expand Down
Loading