Skip to content

Commit 580acf4

Browse files
Merge pull request #279 from topcoder-platform/revert-275-develop
Revert "Issue Reviewer Role"
2 parents caf0462 + bef7c8a commit 580acf4

File tree

13 files changed

+55
-348
lines changed

13 files changed

+55
-348
lines changed

README.md

Lines changed: 0 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -115,84 +115,6 @@ This script will load the data from `scripts/data` directory into ES
115115
npm run start
116116
```
117117

118-
### Local Deployment
119-
0. Make sure to use Node v10+ by command `node -v`. We recommend using [NVM](https://github.com/nvm-sh/nvm) to quickly switch to the right version:
120-
121-
```bash
122-
nvm use
123-
```
124-
125-
1. 📦 Install npm dependencies
126-
127-
```bash
128-
npm install
129-
```
130-
131-
2. ⚙ Local config
132-
In the `submissions-api` root directory create `.env` file with the next environment variables. Values for **Auth0 config** should be shared with you on the forum.<br>
133-
```bash
134-
# AWS related config
135-
AWS_ACCESS_KEY_ID=
136-
AWS_SECRET_ACCESS_KEY=
137-
AWS_REGION=
138-
S3_BUCKET=
139-
ARTIFACT_BUCKET=
140-
141-
# Auth0 config
142-
AUTH0_URL=
143-
AUTH0_PROXY_SERVER_URL=
144-
TOKEN_CACHE_TIME=
145-
AUTH0_AUDIENCE=
146-
AUTH0_CLIENT_ID=
147-
AUTH0_CLIENT_SECRET=
148-
149-
# Locally deployed services (via docker-compose)
150-
ES_HOST=localhost:9200
151-
```
152-
153-
- Values from this file would be automatically used by many `npm` commands.
154-
- ⚠️ Never commit this file or its copy to the repository!
155-
156-
3. 🚢 Start docker-compose with services which are required to start Topcoder Submissions API locally
157-
158-
```bash
159-
npm run services:up
160-
```
161-
- `npm run services:down` can be used to shutdown the docker services
162-
- `npm run services:logs` can be used to view the logs from the docker services
163-
164-
4. ♻ Create tables.
165-
166-
```bash
167-
npm run create-tables
168-
```
169-
5. ♻ Create ES index.
170-
171-
```bash
172-
npm run create-index
173-
```
174-
175-
6. ♻ Init DB, ES
176-
177-
```bash
178-
npm run local:init
179-
```
180-
181-
This command will do 2 things:
182-
- Import the data to the database and index it to ElasticSearch
183-
- Note, to migrate the existing data from DynamoDB to ES, run the following script
184-
```
185-
npm run db-to-es
186-
```
187-
188-
7. 🚀 Start Topcoder Submissions API
189-
190-
```bash
191-
npm run start
192-
```
193-
The Topcoder Submissions API will be served on `http://localhost:3000`
194-
195-
196118
#### Linting JS files
197119

198120
```

app.js

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,6 @@ _.each(routes, (verbs, url) => {
127127
})
128128
}
129129

130-
if (def.blockByIp) {
131-
actions.push((req, res, next) => {
132-
req.authUser.blockIP = _.find(req.authUser, (value, key) => {
133-
return (key.indexOf('blockIP') !== -1)
134-
})
135-
if (req.authUser.blockIP) {
136-
throw new errors.HttpStatusError(403, 'Access denied')
137-
} else {
138-
next()
139-
}
140-
})
141-
}
142-
143130
actions.push(method)
144131
winston.info(`API : ${verb.toLocaleUpperCase()} ${config.API_VERSION}${url}`)
145132
apiRouter[verb](`${config.API_VERSION}${url}`, helper.autoWrapExpress(actions))

config/default.js

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* Default configuration file
33
*/
4-
require('dotenv').config()
4+
55
module.exports = {
66
DISABLE_LOGGING: process.env.DISABLE_LOGGING || false, // If true, logging will be disabled
77
LOG_LEVEL: process.env.LOG_LEVEL || 'debug',
@@ -42,15 +42,5 @@ module.exports = {
4242
AUTH0_PROXY_SERVER_URL: process.env.AUTH0_PROXY_SERVER_URL,
4343
FETCH_CREATED_DATE_START: process.env.FETCH_CREATED_DATE_START || '2021-01-01',
4444
FETCH_PAGE_SIZE: process.env.FETCH_PAGE_SIZE || 500,
45-
MIGRATE_CHALLENGES: process.env.MIGRATE_CHALLENGES || [],
46-
47-
V5TOLEGACYSCORECARDMAPPING: {
48-
'c56a4180-65aa-42ec-a945-5fd21dec0501': 30001363,
49-
'c56a4180-65aa-42ec-a945-5fd21dec0502': 123456789,
50-
'c56a4180-65aa-42ec-a945-5fd21dec0503': 30001031,
51-
'c56a4180-65aa-42ec-a945-5fd21dec0504': 987654321,
52-
'c56a4180-65aa-42ec-a945-5fd21dec0505': 987123456,
53-
'9ecc88e5-a4ee-44a4-8ec1-70bd98022510': 123789456,
54-
'd6d31f34-8ee5-4589-ae65-45652fcc01a6': 30000720
55-
}
45+
MIGRATE_CHALLENGES: process.env.MIGRATE_CHALLENGES || []
5646
}

docs/swagger.yaml

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,9 +1757,7 @@ components:
17571757
description: The scoreCardId filter of the reviews associated with the submission.
17581758
required: false
17591759
schema:
1760-
oneOf:
1761-
- type: integer
1762-
- type: string
1760+
type: integer
17631761
filterSubmissionReviewSubmissionId:
17641762
in: query
17651763
name: review.submissionId
@@ -1873,9 +1871,7 @@ components:
18731871
description: The score card id filter for reviews.
18741872
required: false
18751873
schema:
1876-
oneOf:
1877-
- type: integer
1878-
- type: string
1874+
type: integer
18791875
filterReviewSubmissionId:
18801876
in: query
18811877
name: submissionId
@@ -2151,9 +2147,7 @@ components:
21512147
example: a12bc280-65ab-42ec-a945-5fd21dec1567
21522148
description: The review reviewer id.
21532149
scoreCardId:
2154-
oneOf:
2155-
- type: integer
2156-
- type: string
2150+
type: integer
21572151
description: The review score card id.
21582152
example: 123456789
21592153
submissionId:

local/docker-compose.yml

Lines changed: 0 additions & 8 deletions
This file was deleted.

package.json

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,7 @@
1919
"test": "mocha test/unit/*.test.js --require test/unit/prepare.js --exit",
2020
"e2e": "mocha test/e2e/*.test.js --require test/e2e/prepare.js --exit",
2121
"cov": "nyc --reporter=html --reporter=text mocha test/unit/*.test.js --require test/unit/prepare.js --exit",
22-
"cov-e2e": "nyc --reporter=html --reporter=text mocha test/e2e/*.test.js --require test/e2e/prepare.js --exit",
23-
"services:up": "docker-compose -f ./local/docker-compose.yml up -d",
24-
"services:down": "docker-compose -f ./local/docker-compose.yml down",
25-
"services:logs": "docker-compose -f ./local/docker-compose.yml logs",
26-
"local:init": "npm run init-db && npm run init-es"
22+
"cov-e2e": "nyc --reporter=html --reporter=text mocha test/e2e/*.test.js --require test/e2e/prepare.js --exit"
2723
},
2824
"dependencies": {
2925
"amazon-s3-uri": "0.0.3",
@@ -34,7 +30,6 @@
3430
"common-errors": "^1.0.4",
3531
"config": "^1.26.2",
3632
"cors": "^2.8.4",
37-
"dotenv": "^8.2.0",
3833
"elasticsearch": "^15.1.1",
3934
"express": "^4.15.4",
4035
"express-fileupload": "^0.4.0",

src/common/helper.js

Lines changed: 8 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,6 @@ function * getLegacyChallengeId (challengeId) {
313313
const response = yield request.get(`${config.CHALLENGEAPI_V5_URL}/${challengeId}`)
314314
.set('Authorization', `Bearer ${token}`)
315315
.set('Content-Type', 'application/json')
316-
if (_.get(response.body, 'legacy.pureV5')) {
317-
// pure V5 challenges don't have a legacy ID
318-
return null
319-
}
320316
const legacyId = parseInt(response.body.legacyId, 10)
321317
logger.debug(`Legacy challenge id is ${legacyId} for v5 challenge id ${challengeId}`)
322318
return legacyId
@@ -379,15 +375,12 @@ function * getSubmissionPhaseId (challengeId) {
379375
const checkPoint = _.filter(phases, { name: 'Checkpoint Submission', isOpen: true })
380376
const submissionPh = _.filter(phases, { name: 'Submission', isOpen: true })
381377
const finalFixPh = _.filter(phases, { name: 'Final Fix', isOpen: true })
382-
const approvalPh = _.filter(phases, { name: 'Approval', isOpen: true })
383378
if (checkPoint.length !== 0) {
384379
phaseId = checkPoint[0].phaseId
385380
} else if (submissionPh.length !== 0) {
386381
phaseId = submissionPh[0].phaseId
387382
} else if (finalFixPh.length !== 0) {
388383
phaseId = finalFixPh[0].phaseId
389-
} else if (approvalPh.length !== 0) {
390-
phaseId = approvalPh[0].phaseId
391384
}
392385
}
393386
return phaseId
@@ -452,18 +445,7 @@ function * checkCreateAccess (authUser, subEntity) {
452445

453446
// Get phases and winner detail from challengeDetails
454447
const phases = challengeDetails.body.phases
455-
456-
// Check if the User is assigned as the reviewer for the contest
457-
const reviewers = _.filter(currUserRoles, { role: 'Reviewer' })
458-
if (reviewers.length !== 0) {
459-
throw new errors.HttpStatusError(400, `You cannot create a submission for a challenge while you are a reviewer`)
460-
}
461-
462-
// Check if the User is assigned as the iterative reviewer for the contest
463-
const iterativeReviewers = _.filter(currUserRoles, { role: 'Iterative Reviewer' })
464-
if (iterativeReviewers.length !== 0) {
465-
throw new errors.HttpStatusError(400, `You cannot create a submission for a challenge while you are an iterative reviewer`)
466-
}
448+
const winner = challengeDetails.body.winners
467449

468450
// Check if the User is assigned as the reviewer for the contest
469451
const reviewers = _.filter(currUserRoles, { role: 'Reviewer' })
@@ -486,22 +468,14 @@ function * checkCreateAccess (authUser, subEntity) {
486468
const submissionPhaseId = yield getSubmissionPhaseId(subEntity.challengeId)
487469

488470
if (submissionPhaseId == null) {
489-
throw new errors.HttpStatusError(403, 'You cannot create a submission in the current phase')
471+
throw new errors.HttpStatusError(403, 'You are not allowed to submit when submission phase is not open')
490472
}
491473

492474
const currPhase = _.filter(phases, { phaseId: submissionPhaseId })
493475

494-
if (currPhase[0].name === 'Final Fix' || currPhase[0].name === 'Approval') {
495-
// Check if the user created a submission in the Submission phase - only such users
496-
// will be allowed to submit during final phase
497-
const userSubmission = yield fetchFromES({
498-
challengeId,
499-
memberId: authUser.userId
500-
}, camelize('Submission'))
501-
502-
// User requesting submission haven't made any submission - prevent them for creating one
503-
if (userSubmission.total === 0) {
504-
throw new errors.HttpStatusError(403, 'You are not expected to create a submission in the current phase')
476+
if (currPhase[0].name === 'Final Fix') {
477+
if (!authUser.handle.equals(winner[0].handle)) {
478+
throw new errors.HttpStatusError(403, 'Only winner is allowed to submit during Final Fix phase')
505479
}
506480
}
507481
} else {
@@ -605,7 +579,7 @@ function * checkGetAccess (authUser, submission) {
605579
const appealsResponseStatus = getPhaseStatus('Appeals Response', challengeDetails.body)
606580

607581
// Appeals Response is not closed yet
608-
if (appealsResponseStatus !== 'Closed' && appealsResponseStatus !== 'Invalid') {
582+
if (appealsResponseStatus !== 'Closed') {
609583
throw new errors.HttpStatusError(403, 'You cannot access other submissions before the end of Appeals Response phase')
610584
} else {
611585
const userSubmission = yield fetchFromES({
@@ -641,21 +615,10 @@ function * checkGetAccess (authUser, submission) {
641615
* @returns {Promise}
642616
*/
643617
function * checkReviewGetAccess (authUser, submission) {
644-
let resources
645618
let challengeDetails
646619
const token = yield getM2Mtoken()
647620
const challengeId = yield getV5ChallengeId(submission.challengeId)
648621

649-
try {
650-
resources = yield request.get(`${config.RESOURCEAPI_V5_BASE_URL}/resources?challengeId=${challengeId}`)
651-
.set('Authorization', `Bearer ${token}`)
652-
.set('Content-Type', 'application/json')
653-
} catch (ex) {
654-
logger.error(`Error while accessing ${config.RESOURCEAPI_V5_BASE_URL}/resources?challengeId=${challengeId}`)
655-
logger.error(ex)
656-
throw new errors.HttpStatusError(503, `Could not determine the user's role in the challenge with id ${challengeId}`)
657-
}
658-
659622
try {
660623
challengeDetails = yield request.get(`${config.CHALLENGEAPI_V5_URL}/${challengeId}`)
661624
.set('Authorization', `Bearer ${token}`)
@@ -666,32 +629,9 @@ function * checkReviewGetAccess (authUser, submission) {
666629
return false
667630
}
668631

669-
// Get map of role id to role name
670-
const resourceRolesMap = yield getRoleIdToRoleNameMap()
671-
672-
// Check if role id to role name mapping is available. If not user's role cannot be determined.
673-
if (resourceRolesMap == null || _.size(resourceRolesMap) === 0) {
674-
throw new errors.HttpStatusError(503, `Could not determine the user's role in the challenge with id ${challengeId}`)
675-
}
676-
677-
if (resources && challengeDetails) {
678-
// Fetch all roles of the User pertaining to the current challenge
679-
const currUserRoles = _.filter(resources.body, { memberHandle: authUser.handle })
680-
681-
// Populate the role names for the current user role ids
682-
_.forEach(currUserRoles, currentUserRole => {
683-
currentUserRole.role = resourceRolesMap[currentUserRole.roleId]
684-
})
685-
632+
if (challengeDetails) {
686633
const subTrack = challengeDetails.body.legacy.subTrack
687634

688-
// Check if the User is a Copilot, Manager or Observer for that contest
689-
const validRoles = ['Copilot', 'Manager', 'Observer']
690-
const passedRoles = currUserRoles.filter(a => validRoles.includes(a.role))
691-
if (passedRoles.length !== 0) {
692-
return true
693-
}
694-
695635
// For Marathon Match, everyone can access review result
696636
if (subTrack === 'DEVELOP_MARATHON_MATCH') {
697637
logger.info('No access check for Marathon match')
@@ -706,10 +646,6 @@ function * checkReviewGetAccess (authUser, submission) {
706646

707647
return true
708648
}
709-
} else {
710-
// We don't have enough details to validate the access
711-
logger.debug('No enough details to validate the Permissions')
712-
throw new errors.HttpStatusError(503, `Not all information could be fetched about challenge with id ${submission.challengeId}`)
713649
}
714650
}
715651

@@ -754,7 +690,6 @@ function * postToBusApi (payload) {
754690
function cleanseReviews (reviews, authUser) {
755691
// Not a machine user
756692
if (!authUser.scopes) {
757-
logger.info('Not a machine user. Filtering reviews...')
758693
const admin = _.filter(authUser.roles, role => role.toLowerCase() === 'Administrator'.toLowerCase())
759694
const copilot = _.filter(authUser.roles, role => role.toLowerCase() === 'Copilot'.toLowerCase())
760695

@@ -880,21 +815,6 @@ function * getLatestChallenges (page) {
880815
}
881816
}
882817

883-
/**
884-
* Get legacy scorecard id if the scorecard id is uuid form
885-
* @param {String} scoreCardId Scorecard ID
886-
* @returns {String} Legacy scorecard ID of the given challengeId
887-
*/
888-
function getLegacyScoreCardId (scoreCardId) {
889-
if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(scoreCardId)) {
890-
logger.debug(`${scoreCardId} detected as uuid. Converting to legacy scorecard id`)
891-
892-
return config.get('V5TOLEGACYSCORECARDMAPPING')[scoreCardId]
893-
}
894-
895-
return scoreCardId
896-
}
897-
898818
module.exports = {
899819
wrapExpress,
900820
autoWrapExpress,
@@ -913,6 +833,5 @@ module.exports = {
913833
getRoleIdToRoleNameMap,
914834
getV5ChallengeId,
915835
adjustSubmissionChallengeId,
916-
getLatestChallenges,
917-
getLegacyScoreCardId
836+
getLatestChallenges
918837
}

0 commit comments

Comments
 (0)