Skip to content
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
2 changes: 1 addition & 1 deletion api-docs/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
},
"servers": [
{
"url": "urlplaceholder"
"url": "https://cveawg-dev.mitre.org/api"
}
],
"paths": {
Expand Down
4 changes: 2 additions & 2 deletions src/controller/audit.controller/audit.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,10 +291,10 @@ async function getOrgAuditByOrgIdentifier (req, res, next) {
if (!targetOrg) {
logger.info({
uuid: req.ctx.uuid,
message: `No organization found with ${identifierIsUUID ? 'UUID' : 'shortname'} ${identifier}`
message: `No organization found with ${identifierIsUUID ? 'UUID' : 'shortname'} ${identifier}; returning empty audit history.`
})
await session.abortTransaction()
return res.status(404).json(error.orgDne(identifier))
return res.status(200).json([])
}

// Get the org's UUID for audit lookup
Expand Down
7 changes: 7 additions & 0 deletions src/controller/registry-org.controller/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ class RegistryOrgControllerError extends idrErr.IDRError {
return err
}

notOrgAdminOrSecretariatUpdate () {
const err = {}
err.error = 'NOT_ORG_ADMIN_OR_SECRETARIAT_UPDATE'
err.message = 'Organizations can only be updated by the Secretariat or an Org Admin.'
return err
}

notAllowedToChangeOrganization () {
const err = {}
err.error = 'NOT_ALLOWED_TO_CHANGE_ORGANIZATION'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,12 +321,18 @@ async function updateOrg (req, res, next) {
? await authContext.isRequesterSameOrg(req, repo, org, { session })
: await authContext.isRequesterSameOrg(req, repo, shortName, { session })

if (!isSecretariat && (!isAdmin || !requesterSameOrg)) {
if (!isSecretariat && !requesterSameOrg) {
logger.info({ uuid: req.ctx.uuid, message: shortName + ' organization can only be updated by the users of the same organization or the Secretariat.' })
await session.abortTransaction()
return res.status(403).json(error.notSameOrgOrSecretariat())
}

if (!isSecretariat && !isAdmin) {
logger.info({ uuid: req.ctx.uuid, message: shortName + ' organization can only be updated by the Secretariat or an Org Admin.' })
await session.abortTransaction()
return res.status(403).json(error.notOrgAdminOrSecretariatUpdate())
}

if (!isSecretariat) {
const secretariatOnlyFields = getConstants().SECRETARIAT_ONLY_FIELDS
const restrictedFieldsSent = secretariatOnlyFields.filter(field => _.has(body, field))
Expand Down
3 changes: 2 additions & 1 deletion src/repositories/baseOrgRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,13 @@ class BaseOrgRepository extends BaseRepository {
* @param {string} UUID - The UUID of the organization.
* @param {object} [options={}] - Optional settings for the repository query.
* @param {boolean} [returnLegacyFormat=false] - If true, returns the legacy format.
* @param {object} [projection={}] - Optional projection for fields to include or exclude.
* @returns {Promise<object|null>} The organization object.
*/
async findOneByUUID (UUID, options = {}, returnLegacyFormat = false, projection = {}) {
const OrgRepository = require('./orgRepository')
const legacyOrgRepo = new OrgRepository()
if (returnLegacyFormat) return await legacyOrgRepo.findOneByUUID(UUID, options)
if (returnLegacyFormat) return await legacyOrgRepo.findOneByUUID(UUID, options, projection)
return await BaseOrgModel.findOne({ UUID: UUID }, projection, options)
}

Expand Down
4 changes: 2 additions & 2 deletions src/repositories/orgRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ class OrgRepository extends BaseRepository {
return this.collection.findOne(query, projection, options)
}

async findOneByUUID (UUID) {
return this.collection.findOne().byUUID(UUID)
async findOneByUUID (UUID, options = {}, projection = {}) {
return this.collection.findOne({ UUID: UUID }, projection, options)
}

async getOrgUUID (shortName, options = {}) {
Expand Down
26 changes: 26 additions & 0 deletions test/integration-tests/audit/auditTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,32 @@ describe('Testing Audit Org endpoints', () => {
})
})

it('Should return an empty array when getting audit history for a non-existent org shortname', async () => {
const fakeShortname = uuid.v4().slice(0, 32)

await chai.request(app)
.get(`/api/audit/org/${fakeShortname}`)
.set(constants.headers)
.then((res, err) => {
expect(err).to.be.undefined
expect(res).to.have.status(200)
expect(res.body).to.deep.equal([])
})
})

it('Should return an empty array when getting audit history for a non-existent org UUID', async () => {
const fakeUUID = uuid.v4()

await chai.request(app)
.get(`/api/audit/org/${fakeUUID}`)
.set(constants.headers)
.then((res, err) => {
expect(err).to.be.undefined
expect(res).to.have.status(200)
expect(res.body).to.deep.equal([])
})
})

it('Should fail to get last X changes with invalid number', async () => {
const invalidNumber = -5
await chai.request(app)
Expand Down
38 changes: 38 additions & 0 deletions test/integration-tests/org/getOrgTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/* eslint-disable no-unused-expressions */
const chai = require('chai')
chai.use(require('chai-http'))
const expect = chai.expect

const constants = require('../constants.js')
const app = require('../../../src/index.js')

describe('Testing legacy Org GET endpoint', () => {
context('Positive Tests', () => {
it('Does not return Mongo fields when retrieving an org by UUID', async () => {
let orgUUID

await chai.request(app)
.get('/api/org/mitre')
.set(constants.headers)
.then((res, err) => {
expect(err).to.be.undefined
expect(res).to.have.status(200)
orgUUID = res.body.UUID
})

await chai.request(app)
.get(`/api/org/${orgUUID}`)
.set(constants.headers)
.then((res, err) => {
expect(err).to.be.undefined
expect(res).to.have.status(200)
expect(res.body).to.have.property('UUID', orgUUID)

const mongoFields = ['_id', '__v', '__t', 'inUse', 'in_use']
mongoFields.forEach(field => {
expect(res.body).to.not.haveOwnProperty(field)
})
})
})
})
})
13 changes: 13 additions & 0 deletions test/integration-tests/org/regularUsersTestRegistry.js
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,19 @@ describe('Testing regular user permissions for /api/registry/org/ endpoints with
describe('Testing ORG PUT endpoint with /api/registry/org', () => {
/* Negative Tests */
context('Negative Test', () => {
it('regular user cannot update their own organization', async () => {
const org = constants.nonSecretariatUserHeaders['CVE-API-ORG']
await chai.request(app)
.put(`/api/registry/org/${org}`)
.set(constants.nonSecretariatUserHeaders)
.send({
})
.then((res) => {
expect(res).to.have.status(403)
expect(res.body.error).to.contain('NOT_ORG_ADMIN_OR_SECRETARIAT_UPDATE')
expect(res.body.message).to.equal('Organizations can only be updated by the Secretariat or an Org Admin.')
})
})
it('regular user cannot update an organization', async () => {
const org = faker.datatype.uuid().slice(0, MAX_SHORTNAME_LENGTH)
await chai.request(app)
Expand Down
Loading