@@ -154,7 +154,7 @@ async function searchChallenges (currentUser, criteria) {
154
154
_ . forIn ( _ . omit ( criteria , [ 'types' , 'tracks' , 'typeIds' , 'trackIds' , 'type' , 'name' , 'trackId' , 'typeId' , 'description' , 'page' , 'perPage' , 'tag' ,
155
155
'group' , 'groups' , 'memberId' , 'ids' , 'createdDateStart' , 'createdDateEnd' , 'updatedDateStart' , 'updatedDateEnd' , 'startDateStart' , 'startDateEnd' , 'endDateStart' , 'endDateEnd' ,
156
156
'tags' , 'registrationStartDateStart' , 'registrationStartDateEnd' , 'currentPhaseName' , 'submissionStartDateStart' , 'submissionStartDateEnd' ,
157
- 'registrationEndDateStart' , 'registrationEndDateEnd' , 'submissionEndDateStart' , 'submissionEndDateEnd' ,
157
+ 'registrationEndDateStart' , 'registrationEndDateEnd' , 'submissionEndDateStart' , 'submissionEndDateEnd' , 'includeAllEvents' , 'events' ,
158
158
'forumId' , 'track' , 'reviewType' , 'confidentialityType' , 'directProjectId' , 'sortBy' , 'sortOrder' , 'isLightweight' , 'isTask' , 'taskIsAssigned' , 'taskMemberId' ] ) , ( value , key ) => {
159
159
if ( ! _ . isUndefined ( value ) ) {
160
160
const filter = { match_phrase : { } }
@@ -251,7 +251,10 @@ async function searchChallenges (currentUser, criteria) {
251
251
if ( criteria . endDateEnd ) {
252
252
boolQuery . push ( { range : { endDate : { lte : criteria . endDateEnd } } } )
253
253
}
254
- const sortByProp = criteria . sortBy ? criteria . sortBy : 'created'
254
+
255
+ let sortByProp = criteria . sortBy ? criteria . sortBy : 'created'
256
+ // If property to sort is text, then use its sub-field 'keyword' for sorting
257
+ sortByProp = _ . includes ( constants . challengeTextSortField , sortByProp ) ? sortByProp + '.keyword' : sortByProp
255
258
const sortOrderProp = criteria . sortOrder ? criteria . sortOrder : 'desc'
256
259
257
260
const mustQuery = [ ]
@@ -271,6 +274,18 @@ async function searchChallenges (currentUser, criteria) {
271
274
}
272
275
}
273
276
277
+ if ( criteria . events ) {
278
+ if ( criteria . includeAllEvents ) {
279
+ for ( const e of criteria . events ) {
280
+ boolQuery . push ( { match_phrase : { 'events.key' : e } } )
281
+ }
282
+ } else {
283
+ for ( const e of criteria . events ) {
284
+ shouldQuery . push ( { match : { 'events.key' : e } } )
285
+ }
286
+ }
287
+ }
288
+
274
289
const mustNotQuery = [ ]
275
290
276
291
let groupsToFilter = [ ]
@@ -339,6 +354,29 @@ async function searchChallenges (currentUser, criteria) {
339
354
}
340
355
}
341
356
357
+ const accessQuery = [ ]
358
+ let memberChallengeIds
359
+
360
+ // FIXME: This is wrong!
361
+ // if (!_.isUndefined(currentUser) && currentUser.handle) {
362
+ // accessQuery.push({ match_phrase: { createdBy: currentUser.handle } })
363
+ // }
364
+
365
+ if ( criteria . memberId ) {
366
+ // logger.error(`memberId ${criteria.memberId}`)
367
+ memberChallengeIds = await helper . listChallengesByMember ( criteria . memberId )
368
+ // logger.error(`response ${JSON.stringify(ids)}`)
369
+ accessQuery . push ( { terms : { _id : memberChallengeIds } } )
370
+ }
371
+
372
+ if ( accessQuery . length > 0 ) {
373
+ mustQuery . push ( {
374
+ bool : {
375
+ should : accessQuery
376
+ }
377
+ } )
378
+ }
379
+
342
380
// FIXME: Tech Debt
343
381
let excludeTasks = true
344
382
// if you're an admin or m2m, security rules wont be applied
@@ -369,6 +407,8 @@ async function searchChallenges (currentUser, criteria) {
369
407
mustQuery . push ( {
370
408
bool : {
371
409
should : [
410
+ ...( _ . get ( memberChallengeIds , 'length' , 0 ) > 0 ? [ { terms : { _id : memberChallengeIds } } ] : [ ] ) ,
411
+ { bool : { must_not : { exists : { field : 'task.isTask' } } } } ,
372
412
{ match_phrase : { 'task.isTask' : false } } ,
373
413
{
374
414
bool : {
@@ -396,28 +436,6 @@ async function searchChallenges (currentUser, criteria) {
396
436
} )
397
437
}
398
438
399
- const accessQuery = [ ]
400
-
401
- // FIXME: This is wrong!
402
- // if (!_.isUndefined(currentUser) && currentUser.handle) {
403
- // accessQuery.push({ match_phrase: { createdBy: currentUser.handle } })
404
- // }
405
-
406
- if ( criteria . memberId ) {
407
- // logger.error(`memberId ${criteria.memberId}`)
408
- const ids = await helper . listChallengesByMember ( criteria . memberId )
409
- // logger.error(`response ${JSON.stringify(ids)}`)
410
- accessQuery . push ( { terms : { _id : ids } } )
411
- }
412
-
413
- if ( accessQuery . length > 0 ) {
414
- mustQuery . push ( {
415
- bool : {
416
- should : accessQuery
417
- }
418
- } )
419
- }
420
-
421
439
if ( boolQuery . length > 0 ) {
422
440
mustQuery . push ( {
423
441
bool : {
@@ -465,7 +483,7 @@ async function searchChallenges (currentUser, criteria) {
465
483
docs = await esClient . search ( esQuery )
466
484
} catch ( e ) {
467
485
// Catch error when the ES is fresh and has no data
468
- // logger.error(`Query Error from ES ${JSON.stringify(e)}`)
486
+ logger . error ( `Query Error from ES ${ JSON . stringify ( e ) } ` )
469
487
docs = {
470
488
hits : {
471
489
total : 0 ,
@@ -573,7 +591,9 @@ searchChallenges.schema = {
573
591
ids : Joi . array ( ) . items ( Joi . optionalId ( ) ) . unique ( ) . min ( 1 ) ,
574
592
isTask : Joi . boolean ( ) ,
575
593
taskIsAssigned : Joi . boolean ( ) ,
576
- taskMemberId : Joi . string ( )
594
+ taskMemberId : Joi . string ( ) ,
595
+ events : Joi . array ( ) . items ( Joi . number ( ) ) ,
596
+ includeAllEvents : Joi . boolean ( ) . default ( true )
577
597
} )
578
598
}
579
599
@@ -718,6 +738,12 @@ async function createChallenge (currentUser, challenge, userToken) {
718
738
const { track, type } = await validateChallengeData ( challenge )
719
739
if ( _ . get ( type , 'isTask' ) ) {
720
740
_ . set ( challenge , 'task.isTask' , true )
741
+ if ( _ . isUndefined ( _ . get ( challenge , 'task.isAssigned' ) ) ) {
742
+ _ . set ( challenge , 'task.isAssigned' , false )
743
+ }
744
+ if ( _ . isUndefined ( _ . get ( challenge , 'task.memberId' ) ) ) {
745
+ _ . set ( challenge , 'task.memberId' , null )
746
+ }
721
747
}
722
748
if ( challenge . phases && challenge . phases . length > 0 ) {
723
749
await helper . validatePhases ( challenge . phases )
@@ -921,25 +947,27 @@ async function getChallenge (currentUser, id) {
921
947
// }
922
948
// delete challenge.typeId
923
949
924
- // Check if challenge is task and apply security rules
925
- if ( _ . get ( challenge , 'task.isTask' , false ) && _ . get ( challenge , 'task.isAssigned' , false ) ) {
926
- if ( ! currentUser || ( ! currentUser . isMachine && ! helper . hasAdminRole ( currentUser ) && _ . toString ( currentUser . userId ) !== _ . toString ( _ . get ( challenge , 'task.memberId' ) ) ) ) {
927
- throw new errors . ForbiddenError ( `You don't have access to view this challenge` )
928
- }
929
- }
930
-
950
+ let memberChallengeIds
931
951
// Remove privateDescription for unregistered users
932
952
if ( currentUser ) {
933
953
if ( ! currentUser . isMachine ) {
934
- const ids = await helper . listChallengesByMember ( currentUser . userId )
935
- if ( ! _ . includes ( ids , challenge . id ) ) {
954
+ memberChallengeIds = await helper . listChallengesByMember ( currentUser . userId )
955
+ if ( ! _ . includes ( memberChallengeIds , challenge . id ) ) {
936
956
_ . unset ( challenge , 'privateDescription' )
937
957
}
938
958
}
939
959
} else {
940
960
_ . unset ( challenge , 'privateDescription' )
941
961
}
942
962
963
+ // Check if challenge is task and apply security rules
964
+ if ( _ . get ( challenge , 'task.isTask' , false ) && _ . get ( challenge , 'task.isAssigned' , false ) ) {
965
+ const canAccesChallenge = _ . isUndefined ( currentUser ) ? false : _ . includes ( ( memberChallengeIds || [ ] ) , challenge . id ) || currentUser . isMachine || helper . hasAdminRole ( currentUser )
966
+ if ( ! canAccesChallenge ) {
967
+ throw new errors . ForbiddenError ( `You don't have access to view this challenge` )
968
+ }
969
+ }
970
+
943
971
if ( challenge . phases && challenge . phases . length > 0 ) {
944
972
await getPhasesAndPopulate ( challenge )
945
973
}
0 commit comments