Skip to content

Commit e37f001

Browse files
committed
apply permission check after record is pulled from ES
1 parent 89876c6 commit e37f001

File tree

4 files changed

+68
-12
lines changed

4 files changed

+68
-12
lines changed

src/common/helper.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ async function getProjectById (currentUser, id) {
464464
return _.pick(res.body, ['id', 'name'])
465465
} catch (err) {
466466
if (err.status === HttpStatus.FORBIDDEN) {
467-
throw new errors.UnauthorizedError(`You are not allowed to access the project with id ${id}`)
467+
throw new errors.ForbiddenError(`You are not allowed to access the project with id ${id}`)
468468
}
469469
if (err.status === HttpStatus.NOT_FOUND) {
470470
throw new errors.NotFoundError(`id: ${id} project not found`)

src/services/JobCandidateService.js

+23-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
const _ = require('lodash')
66
const Joi = require('joi')
77
const config = require('config')
8+
const HttpStatus = require('http-status-codes')
89
const { Op } = require('sequelize')
910
const { v4: uuid } = require('uuid')
1011
const helper = require('../common/helper')
@@ -16,6 +17,19 @@ const JobService = require('./JobService')
1617
const JobCandidate = models.JobCandidate
1718
const esClient = helper.getESClient()
1819

20+
/**
21+
* Check whether user can access associated job of a candidate.
22+
*
23+
* @param {Object} currentUser the user who perform this operation.
24+
* @param {String} jobId the job id
25+
* @returns {undefined}
26+
*/
27+
async function _checkUserAccessAssociatedJob (currentUser, jobId) {
28+
if (!currentUser.hasManagePermission && !currentUser.isMachine && !currentUser.isConnectManager) {
29+
await JobService.getJob(currentUser, jobId)
30+
}
31+
}
32+
1933
/**
2034
* Get jobCandidate by id
2135
* @param {Object} currentUser the user who perform this operation.
@@ -30,22 +44,27 @@ async function getJobCandidate (currentUser, id, fromDb = false) {
3044
index: config.esConfig.ES_INDEX_JOB_CANDIDATE,
3145
id
3246
})
47+
48+
// check whether user can access the job associated with the jobCandidate
49+
await _checkUserAccessAssociatedJob(currentUser, jobCandidate.body._source.jobId)
50+
3351
const jobCandidateRecord = { id: jobCandidate.body._id, ...jobCandidate.body._source }
3452
return jobCandidateRecord
3553
} catch (err) {
3654
if (helper.isDocumentMissingException(err)) {
3755
throw new errors.NotFoundError(`id: ${id} "JobCandidate" not found`)
3856
}
57+
if (err.httpStatus === HttpStatus.FORBIDDEN) {
58+
throw err
59+
}
3960
logger.logFullError(err, { component: 'JobCandidateService', context: 'getJobCandidate' })
4061
}
4162
}
4263
logger.info({ component: 'JobCandidateService', context: 'getJobCandidate', message: 'try to query db for data' })
4364
const jobCandidate = await JobCandidate.findById(id)
4465

45-
if (!currentUser.hasManagePermission && !currentUser.isMachine && !currentUser.isConnectManager) {
46-
// check whether user can access the job associated with the jobCandidate
47-
await JobService.getJob(currentUser, jobCandidate.jobId)
48-
}
66+
// check whether user can access the job associated with the jobCandidate
67+
await _checkUserAccessAssociatedJob(currentUser, jobCandidate.jobId)
4968

5069
return helper.clearObject(jobCandidate.dataValues)
5170
}

src/services/JobService.js

+22-4
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,19 @@ async function _validateSkills (skills) {
7474
}
7575
}
7676

77+
/**
78+
* Check whether user can access associated project of a job.
79+
*
80+
* @param {Object} currentUser the user who perform this operation.
81+
* @param {String} projectId the project id
82+
* @returns {undefined}
83+
*/
84+
async function _checkUserAccessAssociatedProject (currentUser, projectId) {
85+
if (!currentUser.hasManagePermission && !currentUser.isMachine && !currentUser.isConnectManager) {
86+
await helper.getProjectById(currentUser, projectId)
87+
}
88+
}
89+
7790
/**
7891
* Get job by id
7992
* @param {Object} currentUser the user who perform this operation.
@@ -88,6 +101,10 @@ async function getJob (currentUser, id, fromDb = false) {
88101
index: config.esConfig.ES_INDEX_JOB,
89102
id
90103
})
104+
105+
// check whether user can access the project associated with the job
106+
await _checkUserAccessAssociatedProject(currentUser, job.body._source.projectId)
107+
91108
const jobId = job.body._id
92109
const jobRecord = { id: jobId, ...job.body._source }
93110
const candidates = await _getJobCandidates(jobId)
@@ -99,16 +116,17 @@ async function getJob (currentUser, id, fromDb = false) {
99116
if (helper.isDocumentMissingException(err)) {
100117
throw new errors.NotFoundError(`id: ${id} "Job" not found`)
101118
}
119+
if (err.httpStatus === HttpStatus.FORBIDDEN) {
120+
throw err
121+
}
102122
logger.logFullError(err, { component: 'JobService', context: 'getJob' })
103123
}
104124
}
105125
logger.info({ component: 'JobService', context: 'getJob', message: 'try to query db for data' })
106126
const job = await Job.findById(id, true)
107127

108-
// check if user can access the project
109-
if (!currentUser.hasManagePermission && !currentUser.isMachine && !currentUser.isConnectManager) {
110-
await helper.getProjectById(currentUser, job.projectId)
111-
}
128+
// check whether user can access the project associated with the job
129+
await _checkUserAccessAssociatedProject(currentUser, job.projectId)
112130

113131
job.dataValues.candidates = _.map(job.dataValues.candidates, (c) => helper.clearObject(c.dataValues))
114132
return helper.clearObject(job.dataValues)

src/services/ResourceBookingService.js

+22-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
const _ = require('lodash')
66
const Joi = require('joi')
77
const config = require('config')
8+
const HttpStatus = require('http-status-codes')
89
const { Op } = require('sequelize')
910
const { v4: uuid } = require('uuid')
1011
const helper = require('../common/helper')
@@ -29,6 +30,19 @@ async function _getResourceBookingFilteringFields (currentUser, resourceBooking)
2930
return _.omit(helper.clearObject(resourceBooking), 'memberRate')
3031
}
3132

33+
/**
34+
* Check whether user can access associated project of a job.
35+
*
36+
* @param {Object} currentUser the user who perform this operation.
37+
* @param {String} projectId the project id
38+
* @returns {undefined}
39+
*/
40+
async function _checkUserAccessAssociatedProject (currentUser, projectId) {
41+
if (!currentUser.hasManagePermission && !currentUser.isMachine && !currentUser.isConnectManager) {
42+
await helper.getProjectById(currentUser, projectId)
43+
}
44+
}
45+
3246
/**
3347
* Get resourceBooking by id
3448
* @param {Object} currentUser the user who perform this operation.
@@ -43,22 +57,27 @@ async function getResourceBooking (currentUser, id, fromDb = false) {
4357
index: config.esConfig.ES_INDEX_RESOURCE_BOOKING,
4458
id
4559
})
60+
61+
// check if user can access the project associated with the resourceBooking
62+
await _checkUserAccessAssociatedProject(currentUser, resourceBooking.body._source.projectId)
63+
4664
const resourceBookingRecord = { id: resourceBooking.body._id, ...resourceBooking.body._source }
4765
return _getResourceBookingFilteringFields(currentUser, resourceBookingRecord)
4866
} catch (err) {
4967
if (helper.isDocumentMissingException(err)) {
5068
throw new errors.NotFoundError(`id: ${id} "ResourceBooking" not found`)
5169
}
70+
if (err.httpStatus === HttpStatus.FORBIDDEN) {
71+
throw err
72+
}
5273
logger.logFullError(err, { component: 'ResourceBookingService', context: 'getResourceBooking' })
5374
}
5475
}
5576
logger.info({ component: 'ResourceBookingService', context: 'getResourceBooking', message: 'try to query db for data' })
5677
const resourceBooking = await ResourceBooking.findById(id)
5778

5879
// check if user can access the project associated with the resourceBooking
59-
if (!currentUser.hasManagePermission && !currentUser.isMachine && !currentUser.isConnectManager) {
60-
await helper.getProjectById(currentUser, resourceBooking.projectId)
61-
}
80+
await _checkUserAccessAssociatedProject(currentUser, resourceBooking.projectId)
6281

6382
return _getResourceBookingFilteringFields(currentUser, resourceBooking.dataValues)
6483
}

0 commit comments

Comments
 (0)