Skip to content

Commit 3bdb524

Browse files
authored
Merge pull request #1 from topcoder-platform/PM-2332
Replaced handle with memberId for challenge createdBy comparison prevent submitter and restricted roles from being combined
2 parents 1c47488 + 8fc15a5 commit 3bdb524

File tree

1 file changed

+66
-2
lines changed

1 file changed

+66
-2
lines changed

src/services/ResourceService.js

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,20 @@ const prisma = require('../common/prisma').getClient()
1616

1717
const payloadFields = ['id', 'challengeId', 'memberId', 'memberHandle', 'roleId', 'phaseChangeNotifications', 'created', 'createdBy', 'updated', 'updatedBy']
1818

19+
// Restricted roles that cannot be combined with submitter role
20+
const RESTRICTED_ROLE_NAMES = [
21+
'manager',
22+
'copilot',
23+
'reviewer',
24+
'iterative reviewer',
25+
'screener',
26+
'checkpoint screener',
27+
'checkpoint reviewer',
28+
'approver'
29+
]
30+
1931
let copilotResourceRoleIdsCache
32+
let restrictedRoleIdsCache
2033

2134
async function getCopilotResourceRoleIds () {
2235
if (copilotResourceRoleIdsCache) {
@@ -34,6 +47,31 @@ async function getCopilotResourceRoleIds () {
3447
return copilotResourceRoleIdsCache
3548
}
3649

50+
/**
51+
* Get resource role IDs that are restricted from being combined with submitter role.
52+
* These include: Manager, Copilot, Reviewer, Iterative Reviewer, Screener,
53+
* Checkpoint Screener, Checkpoint Reviewer, and Approver.
54+
* @returns {Promise<Array<String>>} Array of restricted role IDs
55+
*/
56+
async function getRestrictedRoleIds () {
57+
if (restrictedRoleIdsCache) {
58+
return restrictedRoleIdsCache
59+
}
60+
const roles = await prisma.resourceRole.findMany({
61+
where: {
62+
nameLower: {
63+
in: RESTRICTED_ROLE_NAMES
64+
}
65+
},
66+
select: {
67+
id: true,
68+
nameLower: true
69+
}
70+
})
71+
restrictedRoleIdsCache = roles.map(role => role.id)
72+
return restrictedRoleIdsCache
73+
}
74+
3775
/**
3876
* Check whether the user can access resources
3977
* @param {Array} resources resources of current user for specified challenge id
@@ -291,6 +329,12 @@ async function init (currentUser, challengeId, resource, isCreated) {
291329
const { memberId, email } = memberInfoFromDb
292330
handle = memberInfoFromDb.handle
293331
const userResources = allResources.filter((r) => _.toLower(r.memberHandle) === _.toLower(handle))
332+
333+
let restrictedRoleIds
334+
if (isCreated) {
335+
restrictedRoleIds = await getRestrictedRoleIds()
336+
}
337+
294338
// Retrieve the constraint - Allowed Registrants
295339
if (isCreated && resource.roleId === config.SUBMITTER_RESOURCE_ROLE_ID) {
296340
const allowedRegistrants = _.get(challenge, 'constraints.allowedRegistrants')
@@ -307,12 +351,20 @@ async function init (currentUser, challengeId, resource, isCreated) {
307351
`User ${handle} is not allowed to register.`
308352
)
309353
}
310-
if (!_.get(challenge, 'task.isTask', false) && (_.toLower(challenge.createdBy) === _.toLower(handle) ||
311-
_.some(userResources, r => r.roleId === config.REVIEWER_RESOURCE_ROLE_ID || r.roleId === config.ITERATIVE_REVIEWER_RESOURCE_ROLE_ID))) {
354+
// Prevent challenge creator from registering as submitter (for non-tasks)
355+
if (!_.get(challenge, 'task.isTask', false) && _.toLower(challenge.createdBy) === _.toLower(memberId)) {
312356
throw new errors.BadRequestError(
313357
`User ${handle} is not allowed to register.`
314358
)
315359
}
360+
// Check if user already has a restricted role (Manager, Copilot, Reviewer, etc.)
361+
const existingRestrictedRole = _.find(userResources, r => restrictedRoleIds.includes(r.roleId))
362+
if (existingRestrictedRole) {
363+
const roleNamesList = RESTRICTED_ROLE_NAMES.slice(0, -1).join(', ') + ', or ' + RESTRICTED_ROLE_NAMES.slice(-1)
364+
throw new errors.BadRequestError(
365+
`User ${handle} is already assigned a restricted role (${roleNamesList}) and cannot be registered as a submitter.`
366+
)
367+
}
316368
}
317369

318370
// Prevent from creating more than 1 submitter resources on tasks
@@ -344,6 +396,18 @@ async function init (currentUser, challengeId, resource, isCreated) {
344396
// ensure resource role existed
345397
const resourceRole = await getResourceRole(resource.roleId, isCreated)
346398

399+
// Check if user is trying to assign a restricted role and already has submitter role
400+
if (isCreated) {
401+
if (restrictedRoleIds.includes(resource.roleId)) {
402+
const existingSubmitterRole = _.find(userResources, r => r.roleId === config.SUBMITTER_RESOURCE_ROLE_ID)
403+
if (existingSubmitterRole) {
404+
throw new errors.BadRequestError(
405+
`User ${handle} is already registered as a submitter and cannot be assigned a ${resourceRole.name} role.`
406+
)
407+
}
408+
}
409+
}
410+
347411
// Verify the member has agreed to the challenge terms
348412
if (isCreated) {
349413
await helper.checkAgreedTerms(memberId, _.filter(_.get(challenge, 'terms', []), t => t.roleId === resourceRole.id))

0 commit comments

Comments
 (0)