diff --git a/src/common/helper.js b/src/common/helper.js index 8e9fd6d7..9e041361 100755 --- a/src/common/helper.js +++ b/src/common/helper.js @@ -301,11 +301,11 @@ function * getM2Mtoken () { } /** - * Get legacy challenge id if the challenge id is uuid form - * @param {String} challengeId Challenge ID - * @returns {String} Legacy Challenge ID of the given challengeId + * Function to get challenge by id + * @param {String} challengeId Challenge id + * @returns {Promise} */ -function * getLegacyChallengeId (challengeId) { +function * getChallenge (challengeId) { 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(challengeId)) { logger.debug(`${challengeId} detected as uuid. Fetching legacy challenge id`) const token = yield getM2Mtoken() @@ -313,17 +313,39 @@ function * getLegacyChallengeId (challengeId) { const response = yield request.get(`${config.CHALLENGEAPI_V5_URL}/${challengeId}`) .set('Authorization', `Bearer ${token}`) .set('Content-Type', 'application/json') - if (_.get(response.body, 'legacy.pureV5')) { - // pure V5 challenges don't have a legacy ID - return null - } - const legacyId = parseInt(response.body.legacyId, 10) - logger.debug(`Legacy challenge id is ${legacyId} for v5 challenge id ${challengeId}`) - return legacyId + return response.body } catch (err) { logger.error(`Error while accessing ${config.CHALLENGEAPI_V5_URL}/${challengeId}`) throw err } + } else { + logger.debug(`${challengeId} detected as legacy challenge id. Fetching legacy challenge id`) + const token = yield getM2Mtoken() + try { + const response = yield request.get(`${config.CHALLENGEAPI_V5_URL}?legacyId=${challengeId}`) + .set('Authorization', `Bearer ${token}`) + .set('Content-Type', 'application/json') + return response.body[0] + } catch (err) { + logger.error(`Error while accessing ${config.CHALLENGEAPI_V5_URL}?legacyId=${challengeId}`) + throw err + } + } +} + +/** + * Get legacy challenge id if the challenge id is uuid form + * @param {String} challengeId Challenge ID + * @returns {String} Legacy Challenge ID of the given challengeId + */ +function * getLegacyChallengeId (challengeId) { + 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(challengeId)) { + const challenge = yield getChallenge(challengeId) + if (_.get(challenge, 'legacy.pureV5')) { + return null + } + const legacyId = parseInt(challenge.legacyId, 10) + return legacyId } return challengeId } @@ -335,47 +357,21 @@ function * getLegacyChallengeId (challengeId) { */ function * getV5ChallengeId (challengeId) { 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(challengeId))) { - logger.debug(`${challengeId} detected as legacy challenge id. Fetching legacy challenge id`) - const token = yield getM2Mtoken() - try { - const response = yield request.get(`${config.CHALLENGEAPI_V5_URL}?legacyId=${challengeId}`) - .set('Authorization', `Bearer ${token}`) - .set('Content-Type', 'application/json') - const v5Uuid = _.get(response, 'body[0].id') - logger.debug(`V5 challenge id is ${v5Uuid} for legacy challenge id ${challengeId}`) - return v5Uuid - } catch (err) { - logger.error(`Error while accessing ${config.CHALLENGEAPI_V5_URL}?legacyId=${challengeId}`) - throw err - } + const challenge = yield getChallenge(challengeId) + return challenge.id } return challengeId } -/* +/** * Get submission phase ID of a challenge from Challenge API - * @param challengeId Challenge ID + * @param challenge Challenge * @returns {Integer} Submission phase ID of the given challengeId */ -function * getSubmissionPhaseId (challengeId) { +function getSubmissionPhaseId (challenge) { let phaseId = null - let response - challengeId = yield getV5ChallengeId(challengeId) - - try { - logger.info(`Calling to challenge API to find submission phase Id for ${challengeId}`) - const token = yield getM2Mtoken() - response = yield request.get(`${config.CHALLENGEAPI_V5_URL}/${challengeId}`) - .set('Authorization', `Bearer ${token}`) - .set('Content-Type', 'application/json') - logger.info(`returned from finding submission phase Id for ${challengeId}`) - } catch (ex) { - logger.error(`Error while accessing ${config.CHALLENGEAPI_V5_URL}/${challengeId}`) - logger.debug('Setting submissionPhaseId to Null') - response = null - } - if (response) { - const phases = _.get(response.body, 'phases', []) + if (challenge) { + const phases = _.get(challenge, 'phases', []) const checkPoint = _.filter(phases, { name: 'Checkpoint Submission', isOpen: true }) const submissionPh = _.filter(phases, { name: 'Submission', isOpen: true }) const finalFixPh = _.filter(phases, { name: 'Final Fix', isOpen: true }) @@ -393,14 +389,14 @@ function * getSubmissionPhaseId (challengeId) { return phaseId } -/* +/** * Function to check user access to create a submission * @param authUser Authenticated user * @param subEntity Submission Entity + * @param challengeDetails Challenge * @returns {Promise} */ -function * checkCreateAccess (authUser, subEntity) { - let challengeDetails +function * checkCreateAccess (authUser, subEntity, challengeDetails) { let resources const challengeId = yield getV5ChallengeId(subEntity.challengeId) @@ -412,18 +408,6 @@ function * checkCreateAccess (authUser, subEntity) { const token = yield getM2Mtoken() - try { - logger.info(`Calling to challenge API for fetch phases and winners for ${challengeId}`) - challengeDetails = yield request.get(`${config.CHALLENGEAPI_V5_URL}/${challengeId}`) - .set('Authorization', `Bearer ${token}`) - .set('Content-Type', 'application/json') - logger.info(`returned for ${challengeId} with ${JSON.stringify(challengeDetails)}`) - } catch (ex) { - logger.error(`Error while accessing ${config.CHALLENGEAPI_V5_URL}/${challengeId}`) - logger.error(ex) - throw new errors.HttpStatusError(503, `Could not fetch details of challenge with id ${challengeId}`) - } - try { resources = yield request.get(`${config.RESOURCEAPI_V5_BASE_URL}/resources?challengeId=${challengeId}`) .set('Authorization', `Bearer ${token}`) @@ -451,7 +435,7 @@ function * checkCreateAccess (authUser, subEntity) { }) // Get phases and winner detail from challengeDetails - const phases = challengeDetails.body.phases + const { phases } = challengeDetails // Check if the User is assigned as the reviewer for the contest const reviewers = _.filter(currUserRoles, { role: 'Reviewer' }) @@ -471,7 +455,7 @@ function * checkCreateAccess (authUser, subEntity) { throw new errors.HttpStatusError(403, `Register for the contest before you can submit`) } - const submissionPhaseId = yield getSubmissionPhaseId(subEntity.challengeId) + const submissionPhaseId = yield getSubmissionPhaseId(challengeDetails) if (submissionPhaseId == null) { throw new errors.HttpStatusError(403, 'You cannot create a submission in the current phase') @@ -912,6 +896,7 @@ module.exports = { cleanseReviews, getRoleIdToRoleNameMap, getV5ChallengeId, + getChallenge, adjustSubmissionChallengeId, getLatestChallenges, getLegacyScoreCardId diff --git a/src/services/SubmissionService.js b/src/services/SubmissionService.js index 6f771ca0..4ab3a88f 100755 --- a/src/services/SubmissionService.js +++ b/src/services/SubmissionService.js @@ -281,10 +281,19 @@ function * createSubmission (authUser, files, entity) { // Submission api only works with legacy challenge id // If it is a v5 challenge id, get the associated legacy challenge id - const challengeId = yield helper.getV5ChallengeId(entity.challengeId) - const legacyChallengeId = yield helper.getLegacyChallengeId(entity.challengeId) + const challenge = yield helper.getChallenge(entity.challengeId) + const { + id: challengeId, + status, + phases, + legacyId: legacyChallengeId + } = challenge const currDate = (new Date()).toISOString() + if (status !== 'Active') { + throw new errors.HttpStatusError(400, 'Challenge is not active') + } + const item = { id: submissionId, type: entity.type, @@ -313,7 +322,15 @@ function * createSubmission (authUser, files, entity) { if (entity.submissionPhaseId) { item.submissionPhaseId = entity.submissionPhaseId } else { - item.submissionPhaseId = yield helper.getSubmissionPhaseId(entity.challengeId) + item.submissionPhaseId = helper.getSubmissionPhaseId(challenge) + } + + if (item.submissionPhaseId) { + // make sure the phase is open + const openPhase = _.find(phases, { phaseId: item.submissionPhaseId, isOpen: true }) + if (!openPhase) { + throw new errors.HttpStatusError(400, `The phase ${item.submissionPhaseId} is not open`) + } } if (entity.fileType) { @@ -325,7 +342,7 @@ function * createSubmission (authUser, files, entity) { logger.info('Check User access before creating the submission') if (_.intersection(authUser.roles, ['Administrator', 'administrator']).length === 0 && !authUser.scopes) { logger.info(`Calling checkCreateAccess for ${JSON.stringify(authUser)}`) - yield helper.checkCreateAccess(authUser, item) + yield helper.checkCreateAccess(authUser, item, challenge) if (entity.submittedDate) { throw new errors.HttpStatusError(403, 'You are not allowed to set the `submittedDate` attribute on a submission')