Repository: CVEProject/cve-services
Pull request #257 (2021-01-14 21:28:00)

Adding a new GET endpoint that returns all users beloging to an org
Resolves issue #240. 


Patch:
diff --git a/src/controller/org.controller/index.js b/src/controller/org.controller/index.js
index ed19dff2..795e5113 100644
--- a/src/controller/org.controller/index.js
+++ b/src/controller/org.controller/index.js
@@ -62,6 +62,12 @@ router.get('/org/:shortname/user/:username',
   parseError,
   parseGetParams,
   controller.USER_SINGLE)
+router.get('/org/:shortname/users',
+  mw.validateUser,
+  param(['shortname']).isString().trim().escape().notEmpty(),
+  parseError,
+  parseGetParams,
+  controller.USER_ALL)
 router.post('/org/:shortname/user/:username',
   mw.onlySecretariat,
   mw.validateUser,
diff --git a/src/controller/org.controller/org.controller.js b/src/controller/org.controller/org.controller.js
index 505e1f28..dcb43f9d 100644
--- a/src/controller/org.controller/org.controller.js
+++ b/src/controller/org.controller/org.controller.js
@@ -81,6 +81,53 @@ async function getOrg (req, res, next) {
   }
 }
 
+async function getUsers (req, res, next) {
+  try {
+    const shortName = req.ctx.org
+    const orgShortName = req.ctx.params.shortname
+    const orgRepo = req.ctx.repositories.getOrgRepository()
+    const userRepo = req.ctx.repositories.getUserRepository()
+    const orgUUID = await orgRepo.getOrgUUID(orgShortName)
+    let returned = false
+
+    if (!orgUUID) {
+      returned = true
+      logger.info({message: orgShortName + ' organization does not exist.'})
+      return res.status(404).json(error.orgDneParam(orgShortName))
+    }
+
+    if (orgShortName !== shortName && !returned) {
+      returned = true
+      logger.error({ message: orgShortName + ' organization can only be viewed by the users of the same organization.' })
+      return res.status(403).json({ error: 'NOT_OWNER', message: 'This information can only be viewed by the users of the same organization.' })
+    }
+
+    if (!returned) {
+      const result = await userRepo.aggregate([
+        {
+          $match: { org_UUID: orgUUID }
+        },
+        {
+          $project: {
+            _id: false,
+            UUID: true,
+            username: true,
+            org_UUID: true,
+            name: true,
+            active: true,
+            time: true
+          }
+        }
+      ])
+
+      logger.info({ message: `The users of ${orgShortName} organization were sent to the user.` })
+      return res.status(200).json(result)
+    }
+  } catch (err) {
+    next(err)
+  }
+}
+
 // Get the details of a single user for the specified username
 async function getUser (req, res, next) {
   try {
@@ -616,6 +663,7 @@ module.exports = {
   ORG_SINGLE: getOrg,
   ORG_CREATE_SINGLE: createOrg,
   ORG_UPDATE_SINGLE: updateOrg,
+  USER_ALL: getUsers,
   ORG_ID_QUOTA: getOrgIdQuota,
   USER_SINGLE: getUser,
   USER_CREATE_SINGLE: createUser,


Test patch:
diff --git a/test/unit-tests/org/listing-usersTest.js b/test/unit-tests/org/listing-usersTest.js
new file mode 100644
index 00000000..973e1384
--- /dev/null
+++ b/test/unit-tests/org/listing-usersTest.js
@@ -0,0 +1,142 @@
+const server = require('../../../test-utils/index')
+const chai = require('chai')
+const expect = chai.expect
+chai.use(require('chai-http'))
+
+const orgFixtures = require('./mockObjects.org')
+const orgController = require('../../../src/controller/org.controller/org.controller')
+const orgParams = require('../../../src/controller/org.controller/org.middleware')
+
+const errors = require('../../../src/controller/org.controller/error')
+const error = new errors.OrgControllerError()
+
+describe('Testing the /org/:shortname/users endpoint in Org Controller', () => {
+  context('Negative Tests', () => {
+    it('should return 404 because org does not exist', (done) => {
+      class NoOrg {
+        async getOrgUUID () {
+          return null
+        }
+      }
+
+      class Blank {
+        async aggregate () {
+          return []
+        }
+      }
+
+      server.route('/org-does-not-exist/:shortname/users')
+        .get((req, res, next) => {
+          const factory = {
+            getOrgRepository: () => { return new NoOrg() },
+            getUserRepository: () => { return new Blank() }
+          }
+          req.ctx.repositories = factory
+          next()
+        }, orgParams.parseGetParams, orgController.USER_ALL)
+
+      // perform the request to the api
+      chai.request(server)
+        .get(`/org-does-not-exist/${orgFixtures.nonExistentOrg.short_name}/users`)
+        .set(orgFixtures.owningOrgHeader)
+        .end((err, res) => {
+          if (err) {
+            done(err)
+          }
+
+          // assert expected response
+          expect(res).to.have.status(404)
+          expect(res).to.have.property('body').and.to.be.a('object')
+          const errObj = error.orgDneParam(orgFixtures.nonExistentOrg.short_name)
+          expect(res.body.error).to.equal(errObj.error)
+          expect(res.body.message).to.equal(errObj.message)
+          done()
+        })
+    })
+
+    it('should return 403 forbidden because requester does not belong to the same org', (done) => {
+      class NotSameOrg {
+        async getOrgUUID () {
+          return 'not-an-org'
+        }
+      }
+
+      class Blank {
+        async aggregate () {
+          return []
+        }
+      }
+
+      server.route('/requester-does-not-belong/:shortname/users')
+        .get((req, res, next) => {
+          const factory = {
+            getOrgRepository: () => { return new NotSameOrg() },
+            getUserRepository: () => { return new Blank() }
+          }
+          req.ctx.repositories = factory
+          next()
+        }, orgParams.parseGetParams, orgController.USER_ALL)
+
+      // perform the request to the api
+      chai.request(server)
+        .get(`/requester-does-not-belong/${orgFixtures.owningOrg.short_name}/users`)
+        .set(orgFixtures.orgHeader)
+        .end((err, res) => {
+          if (err) {
+            done(err)
+          }
+
+          // assert expected response
+          expect(res).to.have.status(403)
+          expect(res).to.have.property('body').and.to.be.a('object')
+          expect(res.body.error).to.equal('NOT_OWNER')
+          expect(res.body.message).to.equal('This information can only be viewed by the users of the same organization.')
+          done()
+        })
+    })
+  })
+
+  context('Positive Tests', () => {
+    it('should list the users for cisco org', (done) => {
+      // setup
+
+      class GetOrgUUID {
+        async getOrgUUID () {
+          return orgFixtures.owningOrg.UUID
+        }
+      }
+
+      class GetAllOrgUsers {
+        async aggregate () {
+          return [orgFixtures.existentUserDummy]
+        }
+      }
+
+      server.route('/user-list-returned/:shortname/users')
+        .get((req, res, next) => {
+          const factory = {
+            getOrgRepository: () => { return new GetOrgUUID() },
+            getUserRepository: () => { return new GetAllOrgUsers() }
+          }
+          req.ctx.repositories = factory
+          next()
+        }, orgParams.parseGetParams, orgController.USER_ALL)
+
+      // execution
+      chai.request(server)
+        .get(`/user-list-returned/${orgFixtures.owningOrg.short_name}/users`)
+        .set(orgFixtures.owningOrgHeader)
+        .end((err, res) => {
+          if (err) {
+            done(err)
+          }
+
+          // assertion
+          expect(res).to.have.status(200)
+          expect(res).to.have.property('body').and.to.be.a('array').and.to.have.lengthOf(1)
+          expect(res.body[0]).to.have.property('org_UUID').and.to.equal(orgFixtures.owningOrg.UUID)
+          done()
+        })
+    })
+  })
+})
diff --git a/test/unit-tests/org/userTest.js b/test/unit-tests/org/userTest.js
index e126c299..0b45ddc9 100644
--- a/test/unit-tests/org/userTest.js
+++ b/test/unit-tests/org/userTest.js
@@ -2,6 +2,7 @@ const server = require('../../../test-utils/index')
 const chai = require('chai')
 const expect = chai.expect
 chai.use(require('chai-http'))
+
 const secretariatHeader = require('./mockObjects.org').secretariatHeader
 const owningOrgHeader = require('./mockObjects.org').owningOrgHeader
 const orgHeader = require('./mockObjects.org').orgHeader
@@ -11,9 +12,14 @@ const existentOrg = require('./mockObjects.org').existentOrg
 const owningOrg = require('./mockObjects.org').owningOrg
 const existentUserDummy = require('./mockObjects.org').existentUserDummy
 const nonExistentOrg = require('./mockObjects.org').nonExistentOrg
+
 const errors = require('../../../src/controller/org.controller/error')
 const error = new errors.OrgControllerError()
 
+const orgFixtures = require('./mockObjects.org')
+const orgController = require('../../../src/controller/org.controller/org.controller')
+const orgParams = require('../../../src/controller/org.controller/org.middleware')
+
 describe('Test user functions in Org Controller', () => {
   context('Creating a user', () => {
     it('User is not created because org does not exist', (done) => {