@@ -53,7 +53,7 @@ function autoWrapExpress (obj) {
53
53
return obj
54
54
}
55
55
_ . each ( obj , ( value , key ) => {
56
- obj [ key ] = autoWrapExpress ( value ) ; //eslint-disable-line
56
+ obj [ key ] = autoWrapExpress ( value ) ; //eslint-disable-line
57
57
} )
58
58
return obj
59
59
}
@@ -299,30 +299,6 @@ function * getM2Mtoken () {
299
299
return yield m2m . getMachineToken ( config . AUTH0_CLIENT_ID , config . AUTH0_CLIENT_SECRET )
300
300
}
301
301
302
- /**
303
- * Get legacy challenge id if the challenge id is uuid form
304
- * @param {String } challengeId Challenge ID
305
- * @returns {String } Legacy Challenge ID of the given challengeId
306
- */
307
- function * getLegacyChallengeId ( challengeId ) {
308
- if ( / ^ [ 0 - 9 a - f ] { 8 } - [ 0 - 9 a - f ] { 4 } - [ 0 - 5 ] [ 0 - 9 a - f ] { 3 } - [ 0 8 9 a b ] [ 0 - 9 a - f ] { 3 } - [ 0 - 9 a - f ] { 12 } $ / i. test ( challengeId ) ) {
309
- logger . debug ( `${ challengeId } detected as uuid. Fetching legacy challenge id` )
310
- const token = yield getM2Mtoken ( )
311
- try {
312
- const response = yield request . get ( `${ config . CHALLENGEAPI_V5_URL } /${ challengeId } ` )
313
- . set ( 'Authorization' , `Bearer ${ token } ` )
314
- . set ( 'Content-Type' , 'application/json' )
315
- const legacyId = parseInt ( response . body . legacyId , 10 )
316
- logger . debug ( `Legacy challenge id is ${ legacyId } for v5 challenge id ${ challengeId } ` )
317
- return legacyId
318
- } catch ( err ) {
319
- logger . error ( `Error while accessing ${ config . CHALLENGEAPI_V5_URL } /${ challengeId } ` )
320
- throw err
321
- }
322
- }
323
- return challengeId
324
- }
325
-
326
302
/*
327
303
* Get submission phase ID of a challenge from Challenge API
328
304
* @param challengeId Challenge ID
@@ -335,20 +311,20 @@ function * getSubmissionPhaseId (challengeId) {
335
311
try {
336
312
logger . info ( `Calling to challenge API to find submission phase Id for ${ challengeId } ` )
337
313
const token = yield getM2Mtoken ( )
338
- response = yield request . get ( `${ config . CHALLENGEAPI_URL } /${ challengeId } /phases ` )
314
+ response = yield request . get ( `${ config . CHALLENGEAPI_V5_URL } /${ challengeId } ` )
339
315
. set ( 'Authorization' , `Bearer ${ token } ` )
340
316
. set ( 'Content-Type' , 'application/json' )
341
317
logger . info ( `returned from finding submission phase Id for ${ challengeId } ` )
342
318
} catch ( ex ) {
343
- logger . error ( `Error while accessing ${ config . CHALLENGEAPI_URL } /${ challengeId } /phases ` )
319
+ logger . error ( `Error while accessing ${ config . CHALLENGEAPI_V5_URL } /${ challengeId } ` )
344
320
logger . debug ( 'Setting submissionPhaseId to Null' )
345
321
response = null
346
322
}
347
323
if ( response ) {
348
- const phases = _ . get ( response . body , 'result.content ' , [ ] )
349
- const checkPoint = _ . filter ( phases , { phaseType : 'Checkpoint Submission' , phaseStatus : 'Open' } )
350
- const submissionPh = _ . filter ( phases , { phaseType : 'Submission' , phaseStatus : 'Open' } )
351
- const finalFixPh = _ . filter ( phases , { phaseType : 'Final Fix' , phaseStatus : 'Open' } )
324
+ const phases = _ . get ( response . body , 'phases ' , [ ] )
325
+ const checkPoint = _ . filter ( phases , { name : 'Checkpoint Submission' , isOpen : true } )
326
+ const submissionPh = _ . filter ( phases , { name : 'Submission' , isOpen : true } )
327
+ const finalFixPh = _ . filter ( phases , { name : 'Final Fix' , isOpen : true } )
352
328
if ( checkPoint . length !== 0 ) {
353
329
phaseId = checkPoint [ 0 ] . id
354
330
} else if ( submissionPh . length !== 0 ) {
@@ -379,31 +355,45 @@ function * checkCreateAccess (authUser, subEntity) {
379
355
380
356
try {
381
357
logger . info ( `Calling to challenge API for fetch phases and winners for ${ subEntity . challengeId } ` )
382
- challengeDetails = yield request . get ( `${ config . CHALLENGEAPI_URL } ?filter=id= ${ subEntity . challengeId } ` )
358
+ challengeDetails = yield request . get ( `${ config . CHALLENGEAPI_V5_URL } / ${ subEntity . challengeId } ` )
383
359
. set ( 'Authorization' , `Bearer ${ token } ` )
384
360
. set ( 'Content-Type' , 'application/json' )
385
361
logger . info ( `returned for ${ subEntity . challengeId } with ${ JSON . stringify ( challengeDetails ) } ` )
386
362
} catch ( ex ) {
387
- logger . error ( `Error while accessing ${ config . CHALLENGEAPI_URL } ?filter=id= ${ subEntity . challengeId } ` )
363
+ logger . error ( `Error while accessing ${ config . CHALLENGEAPI_V5_URL } / ${ subEntity . challengeId } ` )
388
364
logger . error ( ex )
389
365
throw new errors . HttpStatusError ( 503 , `Could not fetch details of challenge with id ${ subEntity . challengeId } ` )
390
366
}
391
367
392
368
try {
393
- resources = yield request . get ( `${ config . CHALLENGEAPI_URL } / ${ subEntity . challengeId } /resources ` )
369
+ resources = yield request . get ( `${ config . RESOURCEAPI_V5_BASE_URL } /resources?challengeId= ${ subEntity . challengeId } ` )
394
370
. set ( 'Authorization' , `Bearer ${ token } ` )
395
371
. set ( 'Content-Type' , 'application/json' )
396
372
} catch ( ex ) {
397
- logger . error ( `Error while accessing ${ config . CHALLENGEAPI_URL } / ${ subEntity . challengeId } /resources ` )
373
+ logger . error ( `Error while accessing ${ config . RESOURCEAPI_V5_BASE_URL } /resources?challengeId= ${ subEntity . challengeId } ` )
398
374
logger . error ( ex )
399
375
throw new errors . HttpStatusError ( 503 , `Could not determine the user's role in the challenge with id ${ subEntity . challengeId } ` )
400
376
}
401
377
378
+ // Get map of role id to role name
379
+ const resourceRolesMap = yield getRoleIdToRoleNameMap ( )
380
+
381
+ // Check if role id to role name mapping is available. If not user's role cannot be determined.
382
+ if ( resourceRolesMap == null || _ . size ( resourceRolesMap ) === 0 ) {
383
+ throw new errors . HttpStatusError ( 503 , `Could not determine the user's role in the challenge with id ${ subEntity . challengeId } ` )
384
+ }
385
+
402
386
if ( resources && challengeDetails ) {
403
- const currUserRoles = _ . filter ( resources . body . result . content , { properties : { Handle : authUser . handle } } )
387
+ const currUserRoles = _ . filter ( resources . body , { memberHandle : authUser . handle } )
388
+
389
+ // Populate the role names for the current user role ids
390
+ _ . forEach ( currUserRoles , currentUserRole => {
391
+ currentUserRole . role = resourceRolesMap [ currentUserRole . roleId ]
392
+ } )
393
+
404
394
// Get phases and winner detail from challengeDetails
405
- const phases = challengeDetails . body . result . content [ 0 ] . allPhases
406
- const winner = challengeDetails . body . result . content [ 0 ] . winners
395
+ const phases = challengeDetails . body . phases
396
+ const winner = challengeDetails . body . winners
407
397
408
398
// Check if the User is registered for the contest
409
399
const submitters = _ . filter ( currUserRoles , { role : 'Submitter' } )
@@ -419,7 +409,7 @@ function * checkCreateAccess (authUser, subEntity) {
419
409
420
410
const currPhase = _ . filter ( phases , { id : submissionPhaseId } )
421
411
422
- if ( currPhase [ 0 ] . phaseType === 'Final Fix' ) {
412
+ if ( currPhase [ 0 ] . name === 'Final Fix' ) {
423
413
if ( ! authUser . handle . equals ( winner [ 0 ] . handle ) ) {
424
414
throw new errors . HttpStatusError ( 403 , 'Only winner is allowed to submit during Final Fix phase' )
425
415
}
@@ -448,30 +438,43 @@ function * checkGetAccess (authUser, submission) {
448
438
const token = yield getM2Mtoken ( )
449
439
450
440
try {
451
- resources = yield request . get ( `${ config . CHALLENGEAPI_URL } / ${ submission . challengeId } /resources ` )
441
+ resources = yield request . get ( `${ config . RESOURCEAPI_V5_BASE_URL } /resources?challengeId= ${ submission . challengeId } ` )
452
442
. set ( 'Authorization' , `Bearer ${ token } ` )
453
443
. set ( 'Content-Type' , 'application/json' )
454
444
} catch ( ex ) {
455
- logger . error ( `Error while accessing ${ config . CHALLENGEAPI_URL } / ${ submission . challengeId } /resources ` )
445
+ logger . error ( `Error while accessing ${ config . RESOURCEAPI_V5_BASE_URL } /resources?challengeId= ${ submission . challengeId } ` )
456
446
logger . error ( ex )
457
447
throw new errors . HttpStatusError ( 503 , `Could not determine the user's role in the challenge with id ${ submission . challengeId } ` )
458
448
}
459
449
460
450
try {
461
- challengeDetails = yield request . get ( `${ config . CHALLENGEAPI_URL } ?filter=id= ${ submission . challengeId } ` )
451
+ challengeDetails = yield request . get ( `${ config . CHALLENGEAPI_V5_URL } / ${ submission . challengeId } ` )
462
452
. set ( 'Authorization' , `Bearer ${ token } ` )
463
453
. set ( 'Content-Type' , 'application/json' )
464
454
} catch ( ex ) {
465
- logger . error ( `Error while accessing ${ config . CHALLENGEAPI_URL } ?filter=id= ${ submission . challengeId } ` )
455
+ logger . error ( `Error while accessing ${ config . CHALLENGEAPI_V5_URL } / ${ submission . challengeId } ` )
466
456
logger . error ( ex )
467
457
throw new errors . HttpStatusError ( 503 , `Could not fetch details of challenge with id ${ submission . challengeId } ` )
468
458
}
469
459
460
+ // Get map of role id to role name
461
+ const resourceRolesMap = yield getRoleIdToRoleNameMap ( )
462
+
463
+ // Check if role id to role name mapping is available. If not user's role cannot be determined.
464
+ if ( resourceRolesMap == null || _ . size ( resourceRolesMap ) === 0 ) {
465
+ throw new errors . HttpStatusError ( 503 , `Could not determine the user's role in the challenge with id ${ submission . challengeId } ` )
466
+ }
467
+
470
468
if ( resources && challengeDetails ) {
471
469
// Fetch all roles of the User pertaining to the current challenge
472
- const currUserRoles = _ . filter ( resources . body . result . content , { properties : { Handle : authUser . handle } } )
473
- const subTrack = challengeDetails . body . result . content [ 0 ] . subTrack
474
- const phases = challengeDetails . body . result . content [ 0 ] . allPhases
470
+ const currUserRoles = _ . filter ( resources . body , { memberHandle : authUser . handle } )
471
+
472
+ // Populate the role names for the current user role ids
473
+ _ . forEach ( currUserRoles , currentUserRole => {
474
+ currentUserRole . role = resourceRolesMap [ currentUserRole . roleId ]
475
+ } )
476
+
477
+ const subTrack = challengeDetails . body . legacy . subTrack
475
478
476
479
// Check if the User is a Copilot
477
480
const copilot = _ . filter ( currUserRoles , { role : 'Copilot' } )
@@ -494,18 +497,18 @@ function * checkGetAccess (authUser, submission) {
494
497
495
498
// User is either a Reviewer or Screener
496
499
if ( screener . length !== 0 || reviewer . length !== 0 ) {
497
- const screeningPhase = _ . filter ( phases , { phaseType : 'Screening' , phaseStatus : 'Scheduled' } )
498
- const reviewPhase = _ . filter ( phases , { phaseType : 'Review' , phaseStatus : 'Scheduled' } )
500
+ const screeningPhaseStatus = getPhaseStatus ( 'Screening' , challengeDetails . body )
501
+ const reviewPhaseStatus = getPhaseStatus ( 'Review' , challengeDetails . body )
499
502
500
503
// Neither Screening Nor Review is Opened / Closed
501
- if ( screeningPhase . length !== 0 && reviewPhase . length !== 0 ) {
504
+ if ( screeningPhaseStatus === 'Scheduled' && reviewPhaseStatus === 'Scheduled' ) {
502
505
throw new errors . HttpStatusError ( 403 , 'You can access the submission only when Screening / Review is open' )
503
506
}
504
507
} else {
505
- const appealsResponse = _ . filter ( phases , { phaseType : 'Appeals Response' , phaseStatus : 'Closed' } )
508
+ const appealsResponseStatus = getPhaseStatus ( 'Appeals Response' , challengeDetails . body )
506
509
507
510
// Appeals Response is not closed yet
508
- if ( appealsResponse . length === 0 ) {
511
+ if ( appealsResponseStatus !== 'Closed' ) {
509
512
throw new errors . HttpStatusError ( 403 , 'You cannot access other submissions before the end of Appeals Response phase' )
510
513
} else {
511
514
const userSubmission = yield fetchFromES ( {
@@ -545,28 +548,27 @@ function * checkReviewGetAccess (authUser, submission) {
545
548
const token = yield getM2Mtoken ( )
546
549
547
550
try {
548
- challengeDetails = yield request . get ( `${ config . CHALLENGEAPI_URL } ?filter=id= ${ submission . challengeId } ` )
551
+ challengeDetails = yield request . get ( `${ config . CHALLENGEAPI_V5_URL } / ${ submission . challengeId } ` )
549
552
. set ( 'Authorization' , `Bearer ${ token } ` )
550
553
. set ( 'Content-Type' , 'application/json' )
551
554
} catch ( ex ) {
552
- logger . error ( `Error while accessing ${ config . CHALLENGEAPI_URL } ?filter=id= ${ submission . challengeId } ` )
555
+ logger . error ( `Error while accessing ${ config . CHALLENGEAPI_V5_URL } / ${ submission . challengeId } ` )
553
556
logger . error ( ex )
554
557
return false
555
558
}
556
559
557
560
if ( challengeDetails ) {
558
- const subTrack = challengeDetails . body . result . content [ 0 ] . subTrack
559
- const phases = challengeDetails . body . result . content [ 0 ] . allPhases
561
+ const subTrack = challengeDetails . body . legacy . subTrack
560
562
561
563
// For Marathon Match, everyone can access review result
562
564
if ( subTrack === 'DEVELOP_MARATHON_MATCH' ) {
563
565
logger . info ( 'No access check for Marathon match' )
564
566
return true
565
567
} else {
566
- const appealsResponse = _ . filter ( phases , { phaseType : 'Appeals Response' , phaseStatus : 'Closed' } )
568
+ const appealsResponseStatus = getPhaseStatus ( 'Appeals Response' , challengeDetails . body )
567
569
568
570
// Appeals Response is not closed yet
569
- if ( appealsResponse . length === 0 ) {
571
+ if ( appealsResponseStatus !== 'Closed' ) {
570
572
throw new errors . HttpStatusError ( 403 , 'You cannot access the review before the end of the Appeals Response phase' )
571
573
}
572
574
@@ -642,19 +644,79 @@ function cleanseReviews (reviews, authUser) {
642
644
return reviews
643
645
}
644
646
647
+ /**
648
+ * Function to get role id to role name map
649
+ * @returns {Object|null } <Role Id, Role Name> map
650
+ */
651
+ function * getRoleIdToRoleNameMap ( ) {
652
+ let resourceRoles
653
+ let resourceRolesMap = null
654
+ const token = yield getM2Mtoken ( )
655
+ try {
656
+ resourceRoles = yield request . get ( `${ config . RESOURCEAPI_V5_BASE_URL } /resource-roles` )
657
+ . set ( 'Authorization' , `Bearer ${ token } ` )
658
+ . set ( 'Content-Type' , 'application/json' )
659
+ } catch ( ex ) {
660
+ logger . error ( `Error while accessing ${ config . RESOURCEAPI_V5_BASE_URL } /resource-roles` )
661
+ logger . error ( ex )
662
+ resourceRoles = null
663
+ }
664
+ if ( resourceRoles ) {
665
+ resourceRolesMap = { }
666
+ _ . forEach ( resourceRoles . body , resourceRole => {
667
+ resourceRolesMap [ resourceRole . id ] = resourceRole . name
668
+ } )
669
+ }
670
+ return resourceRolesMap
671
+ }
672
+
673
+ /**
674
+ * Function to get phase status of phases used in an active challenge
675
+ * @param {String } phaseName the phase name for retrieving status
676
+ * @param {Object } challengeDetails the challenge details
677
+ * @returns {('Scheduled' | 'Open' | 'Closed' | 'Invalid') } status of the phase
678
+ */
679
+ function getPhaseStatus ( phaseName , challengeDetails ) {
680
+ const { phases } = challengeDetails
681
+ const queriedPhaseIndex = _ . findIndex ( phases , phase => {
682
+ return phase . name === phaseName
683
+ } )
684
+ // Requested phase name could not be found in phases hence 'Invalid'
685
+ if ( queriedPhaseIndex === - 1 ) {
686
+ return 'Invalid'
687
+ }
688
+ // If requested phase name is open return 'Open'
689
+ if ( phases [ queriedPhaseIndex ] . isOpen ) {
690
+ return 'Open'
691
+ } else {
692
+ const { actualEndDate } = phases [ queriedPhaseIndex ]
693
+ if ( ! _ . isEmpty ( actualEndDate ) ) {
694
+ const present = new Date ( ) . getTime ( )
695
+ const actualDate = new Date ( actualEndDate ) . getTime ( )
696
+ if ( present > actualDate ) {
697
+ return 'Closed'
698
+ } else {
699
+ return 'Scheduled'
700
+ }
701
+ } else {
702
+ return 'Scheduled'
703
+ }
704
+ }
705
+ }
706
+
645
707
module . exports = {
646
708
wrapExpress,
647
709
autoWrapExpress,
648
710
getEsClient,
649
711
fetchFromES,
650
712
camelize,
651
713
setPaginationHeaders,
652
- getLegacyChallengeId,
653
714
getSubmissionPhaseId,
654
715
checkCreateAccess,
655
716
checkGetAccess,
656
717
checkReviewGetAccess,
657
718
downloadFile,
658
719
postToBusApi,
659
- cleanseReviews
720
+ cleanseReviews,
721
+ getRoleIdToRoleNameMap
660
722
}
0 commit comments