Skip to content

Commit

Permalink
Merge branch 'dev' into dependabot/npm_and_yarn/mongoose-5.13.20
Browse files Browse the repository at this point in the history
  • Loading branch information
jdaigneau5 authored Jul 25, 2023
2 parents 49a0f51 + 7948977 commit 15825e8
Show file tree
Hide file tree
Showing 4 changed files with 205 additions and 6 deletions.
6 changes: 3 additions & 3 deletions src/controller/org.controller/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ router.post('/org/:shortname/user',
*/
mw.validateUser,
mw.onlySecretariatOrAdmin,
mw.onlyOrgWithRole,
mw.onlyOrgWithPartnerRole,
param(['shortname']).isString().trim().escape().notEmpty().isLength({ min: CONSTANTS.MIN_SHORTNAME_LENGTH, max: CONSTANTS.MAX_SHORTNAME_LENGTH }),
body(['username']).isString().trim().escape().notEmpty().custom(isValidUsername),
body(['org_uuid']).optional().isString().trim().escape(),
Expand Down Expand Up @@ -712,7 +712,7 @@ router.put('/org/:shortname/user/:username',
}
*/
mw.validateUser,
mw.onlyOrgWithRole,
mw.onlyOrgWithPartnerRole,
query().custom((query) => {
return mw.validateQueryParameterNames(query, ['active', 'new_username', 'org_short_name', 'name.first', 'name.last', 'name.middle',
'name.suffix', 'active_roles.add', 'active_roles.remove'])
Expand Down Expand Up @@ -806,7 +806,7 @@ router.put('/org/:shortname/user/:username/reset_secret',
}
*/
mw.validateUser,
mw.onlyOrgWithRole,
mw.onlyOrgWithPartnerRole,
param(['shortname']).isString().trim().escape().notEmpty().isLength({ min: CONSTANTS.MIN_SHORTNAME_LENGTH, max: CONSTANTS.MAX_SHORTNAME_LENGTH }),
param(['username']).isString().trim().escape().notEmpty().custom(isValidUsername),
parseError,
Expand Down
7 changes: 7 additions & 0 deletions src/middleware/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ class MiddlewareError extends idrErr.IDRError {
return err
}

orgHasNoPartnerRole (shortname) { // mw
const err = {}
err.error = 'ORG_HAS_NO_PARTNER_ROLE'
err.message = `The '${shortname}' organization designated by the shortname parameter does not have any partner roles.`
return err
}

orgDoesNotOwnId (org, id) {
const err = {
error: 'ORG_DOES_NOT_OWN_ID',
Expand Down
9 changes: 6 additions & 3 deletions src/middleware/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ async function onlyAdps (req, res, next) {
}
}
// Checks that an org has a role or any sort
async function onlyOrgWithRole (req, res, next) {
async function onlyOrgWithPartnerRole (req, res, next) {
const shortName = req.ctx.org
const orgRepo = req.ctx.repositories.getOrgRepository()

Expand All @@ -264,12 +264,15 @@ async function onlyOrgWithRole (req, res, next) {
if (org === null) {
logger.info({ uuid: req.ctx.uuid, message: shortName + ' does NOT exist ' })
return res.status(404).json(error.orgDoesNotExist(shortName))
} else if (org.authority.active_roles.length === 1 && org.authority.active_roles[0] === 'BULK_DOWNLOAD') {
logger.info({ uuid: req.ctx.uuid, message: org.short_name + 'only has BULK_DOWNLOAD role ' })
return res.status(403).json(error.orgHasNoPartnerRole(shortName))
} else if (org.authority.active_roles.length > 0) {
logger.info({ uuid: req.ctx.uuid, message: org.short_name + ' has a role ' })
next()
} else {
logger.info({ uuid: req.ctx.uuid, message: org.short_name + ' does NOT have a role ' })
return res.status(403).json(error.orgHasNoRole(shortName))
return res.status(403).json(error.orgHasNoPartnerRole(shortName))
}
} catch (err) {
next(err)
Expand Down Expand Up @@ -445,7 +448,7 @@ module.exports = {
onlySecretariatOrAdmin,
onlyCnas,
onlyAdps,
onlyOrgWithRole,
onlyOrgWithPartnerRole,
validateQueryParameterNames,
cnaMustOwnID,
createCtxAndReqUUID,
Expand Down
189 changes: 189 additions & 0 deletions test/unit-tests/middleware/onlyOrgWithPartnerRoleTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/* eslint-disable no-unused-expressions */

const chai = require('chai')
const sinon = require('sinon')
const { faker } = require('@faker-js/faker')
const expect = chai.expect

const OrgRepository = require('../../../src/repositories/orgRepository.js')
const { onlyOrgWithPartnerRole } = require('../../../src/middleware/middleware.js')
const errors = require('../../../src/middleware/error.js')
const error = new errors.MiddlewareError()

const stubAdpOrg = {
short_name: 'adpOrg',
name: 'test_adp',
UUID: faker.datatype.uuid(),
authority: {
active_roles: [
'ADP'
]
}
}

const stubCnaOrg = {
short_name: 'cnaOrg',
name: 'test_cna',
UUID: faker.datatype.uuid(),
authority: {
active_roles: [
'CNA'
]
}
}

const stubBulkDownloadOrg = {
short_name: 'bdOrg',
name: 'test_bd',
UUID: faker.datatype.uuid(),
authority: {
active_roles: [
'BULK_DOWNLOAD'
]
}
}

const stubOrgNoRole = {
short_name: 'NoRole',
name: 'test_org',
UUID: faker.datatype.uuid(),
authority: {
active_roles: []
}
}

const stubSecretariat = {
short_name: 'secOrg',
name: 'test_sec',
UUID: faker.datatype.uuid(),
authority: {
active_roles: [
'SECRETARIAT'
]
}
}

describe('Testing onlyOrgWithPartnerRole middleware', () => {
let status, json, res, next, getOrgRepository, orgRepo
beforeEach(() => {
status = sinon.stub()
json = sinon.spy()
res = { json, status }
next = sinon.spy()
status.returns(res)
orgRepo = new OrgRepository()
getOrgRepository = sinon.stub()
getOrgRepository.returns(orgRepo)
})
context('Negative Tests', () => {
it('Should return 403 for users from orgs without a partner role ', async () => {
const req = {
ctx: {
org: stubBulkDownloadOrg.short_name,
uuid: stubBulkDownloadOrg.UUID,
repositories: {
getOrgRepository
}
}
}
const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(stubBulkDownloadOrg)

await onlyOrgWithPartnerRole(req, res, next)
expect(stub.calledOnce).to.be.true
expect(status.calledOnce).to.be.true
expect(status.args[0][0]).to.equal(403)
expect(res.json.args[0][0].error).to.equal(error.orgHasNoPartnerRole().error)
})
it('Should return 403 for users from orgs without a role ', async () => {
const req = {
ctx: {
org: stubOrgNoRole.short_name,
uuid: stubOrgNoRole.UUID,
repositories: {
getOrgRepository
}
}
}
const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(stubOrgNoRole)

await onlyOrgWithPartnerRole(req, res, next)
expect(stub.calledOnce).to.be.true
expect(status.calledOnce).to.be.true
expect(status.args[0][0]).to.equal(403)
expect(res.json.args[0][0].error).to.equal(error.orgHasNoPartnerRole().error)
})

it('Should return 404 if the requester org does not exist', async () => {
const req = {
ctx: {
org: stubCnaOrg.short_name,
uuid: stubCnaOrg.UUID,
repositories: {
getOrgRepository
}
}
}
const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(null)

await onlyOrgWithPartnerRole(req, res, next)
expect(stub.calledOnce).to.be.true
expect(status.calledOnce).to.be.true
expect(status.args[0][0]).to.equal(404)
expect(res.json.args[0][0].error).to.equal(error.orgDoesNotExist(stubCnaOrg.short_name).error)
})
})

context('Positive Tests', () => {
it('Should allow orgs with ADP partner role through by calling next() ', async () => {
const req = {
ctx: {
org: stubAdpOrg.short_name,
uuid: stubAdpOrg.UUID,
repositories: {
getOrgRepository
}
}
}
const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(stubAdpOrg)

await onlyOrgWithPartnerRole(req, res, next)
expect(stub.calledOnce).to.be.true
expect(status.calledOnce).to.be.false
expect(next.calledOnce).to.be.true
})
it('Should allow orgs with CNA partner role through by calling next() ', async () => {
const req = {
ctx: {
org: stubCnaOrg.short_name,
uuid: stubCnaOrg.UUID,
repositories: {
getOrgRepository
}
}
}
const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(stubCnaOrg)

await onlyOrgWithPartnerRole(req, res, next)
expect(stub.calledOnce).to.be.true
expect(status.calledOnce).to.be.false
expect(next.calledOnce).to.be.true
})
it('Should allow orgs with Secretariat role through by calling next() ', async () => {
const req = {
ctx: {
org: stubSecretariat.short_name,
uuid: stubSecretariat.UUID,
repositories: {
getOrgRepository
}
}
}
const stub = sinon.stub(orgRepo, 'findOneByShortName').returns(stubSecretariat)

await onlyOrgWithPartnerRole(req, res, next)
expect(stub.calledOnce).to.be.true
expect(status.calledOnce).to.be.false
expect(next.calledOnce).to.be.true
})
})
})

0 comments on commit 15825e8

Please sign in to comment.